【问题标题】:Is this "glitch safe" clock mux really glitch safe?这种“故障安全”时钟复用器真的故障安全吗?
【发布时间】:2014-09-05 14:25:37
【问题描述】:

我在http://www.vlsi-world.com/content/view/64/47/1/1/找到了这个时钟多路复用器设计

作者声称它是安全的,但我认为如果时钟信号到各个或门(or_three,or_four)的路由延迟大于路由延迟+时钟输出,它仍然可能存在故障当 q3/q4 的输出变低时,延迟 q3/q4 到或门。为了避免这些毛刺,q3/q4 的输出必须在时钟的上升沿变为高电平,在时钟的下降沿变为低电平。我在这个评估中是否正确?

另请注意,我链接的页面上的示意图与 verilog 不完全匹配(verilog 中未使用 q3 的 qbar 输出),并且用于生成模拟的测试台转置了 clk_a 和 clk_b。

`timescale 1ns/100ps

module clk_switch (
   // Outputs
   out_clk,
   // Inputs
   clk_a, clk_b, select
   );

   input clk_a;
   input clk_b;
   input select;

   output out_clk;
wire   out_clk;

reg q1,q2,q3,q4;
wire or_one, or_two,or_three,or_four;

always @ (posedge clk_a)
begin
    if (clk_a == 1'b1)
    begin
       q1 <= q4;
       q3 <= or_one;
    end
end

always @ (posedge clk_b)
begin
    if (clk_b == 1'b1)
    begin
        q2 <= q3;
        q4 <= or_two;
    end
end

assign or_one   = (!q1) | (!select);
assign or_two   = (!q2) | (select);
assign or_three = (q3)  | (clk_a);
assign or_four  = (q4)  | (clk_b);

assign out_clk  = or_three & or_four;

endmodule 

我用 VHDL 编写了一个快速翻译,因此更熟悉该语言的聪明人将能够检查它,并且没有人会对这里的 VHDL 标签提出问题。

entity clk_switch is
   port(
      out_clk : out std_logic;
      clk_a   : in  std_logic;
      clk_b   : in  std_logic;
      sel     : in  std_logic;
   );
end clk_switch;

architecture rtl of clk_switch is
   signal q1 : std_logic;
   signal q2 : std_logic;
   signal q3 : std_logic;
   signal q4 : std_logic;

   signal or_one   : std_logic;
   signal or_two   : std_logic;
   signal or_three : std_logic;
   signal or_four  : std_logic;
begin
   process(clk_a)
   begin
      if (clk_a'event and clk_a='1') then
         q1 <= q4;
         q3 <= or_one;
      end if;
   end process;

   process(clk_b)
   begin
      if (clk_b'event and clk_b='1') then
         q2 <= q3;
         q4 <= or_two;
      end if;
   end process;

or_one <= not q1 or not sel;
or_two <= not q2 or sel;
or_three <= q3 or clk_a;
or_four  <= q4 or clk_b;

out_clk <= or_three and or_four;

end rtl;

【问题讨论】:

  • 这部分对我来说很奇怪always @ (posedge clk_a) if (clk_a == 1'b1),因为 posedge 只会在clk_a==1'b1 时触发,所以这似乎是一个多余的语句,我认为它不会可靠地改变综合的输出(不同的工具可以处理它不同,即添加多路复用器/忽略它)。
  • selector_twoq4 的亚稳态路径需要在clk_b 的高波特率期间进行q4 亚稳态恢复。对于not selector_oneq2 也是如此,这两种情况都适用于select 上的任意开关。这是时钟速度限制,可能的触发器速度的一半减去or_oneor_two 门和布线延迟,以允许亚稳态恢复。克服速度限制需要更长的无时钟周期(更多触发器,重新计时select)。
  • 是的,我注意到了亚稳态问题,但是假设 select 满足活动时钟的设置/保持(它实际上改变了 or_one/or_two 值的那个)会导致故障吗?我想是的,但我不是 100% 确定。
  • 门控'关闭' thruor_threeor_four 在相应时钟为高电平时发生,新时钟在高电平时启用。 or_threeor_four De Morgan 等效与门。 out_clk De Morgan OR 门产品。在亚稳态恢复施加的触发器速度限制内,它应该是无故障的。每个时钟依赖于另一个时钟在启用之前被禁用。

标签: vhdl verilog fpga hdl


【解决方案1】:

我继续为 VHDL 转换创建了一个测试平台和模拟,在 clk_b to or_four 上具有很小的 (10 ps) 路由延迟。当然,在真正的 FPGA 中,q4/C to or_four 路径上会有几个延迟,但clk_b to or_four 的路由延迟可能仍然更长。输出的整个门控也将被吸收到单个 4 输入 LUT 中,但这不会改变这种输出行为。

我担心的故障可以在 480 ns 附近看到:

谁能想到这不会/不可能在目标上发生的原因?静态时序分析会阻止这种情况吗?

library ieee;
use ieee.std_logic_1164.all;
entity clk_switch is
   port(
      out_clk : out std_logic;
      clk_a   : in  std_logic;
      clk_b   : in  std_logic;
      sel     : in  std_logic
   );
end clk_switch;

architecture rtl of clk_switch is
   signal q1 : std_logic;
   signal q2 : std_logic;
   signal q3 : std_logic;
   signal q4 : std_logic;

   signal or_one   : std_logic;
   signal or_two   : std_logic;
   signal or_three : std_logic;
   signal or_four  : std_logic;

   signal clk_b_routed : std_logic;
begin
   clk_b_routed <= clk_b after 10 ps;

   process(clk_a)
   begin
      if (clk_a'event and clk_a='1') then
         q1 <= q4;
         q3 <= or_one;
      end if;
   end process;

   process(clk_b)
   begin
      if (clk_b'event and clk_b='1') then
         q2 <= q3;
         q4 <= or_two;
      end if;
   end process;

    or_one <= not q1 or not sel;
    or_two <= not q2 or sel;
    or_three <= q3 or clk_a;
    or_four  <= q4 or clk_b_routed;
    out_clk <= or_three and or_four;
end rtl;

library ieee;
use ieee.std_logic_1164.all;
entity tb_clk_switch is
end tb_clk_switch;
architecture testbench of tb_clk_switch is
    component clk_switch is
        port(
            clk_a   : in  std_logic;
            clk_b   : in  std_logic;
            out_clk   : out std_logic;
            sel     : in  std_logic
        );
    end component;

    signal clk_a : std_logic := '0';
    signal clk_b : std_logic := '0';
    signal out_clk : std_logic := '0';
    signal sel   : std_logic := '0';
begin
    clk_a <= not clk_a after 10 ns; --periods arbitrary
    clk_b <= not clk_b after 23 ns;
    sel   <= not sel   after 200 ns;
    uut : clk_switch
    port map (
        clk_a => clk_a,
        clk_b => clk_b,
        out_clk => out_clk,
        sel   => sel
    );
end testbench;

【讨论】:

  • 这是人为造成问题的一种方法。它没有显示来自 clk_b 的 Q4 持有人过度/输出延迟。很容易想象 q4 和 or_four 跨越 clk_b 时钟树上的两个不同分支,或者在 clk_b 到 or_four 上有 10 ps 的延迟。 q4 的输出延迟为零或者 q4 到 or_four 的路由延迟也为 0 的可能性要小一些。具有部分定时模型或在定时模型的情况下没有定时约束目标是不公平的,这毕竟是时钟。
【解决方案2】:

...我认为如果时钟信号到相应或门(or_three,or_four)的路由延迟大于路由延迟+时钟到输出延迟,它仍然可能会出现故障当 q3/q4 的输出变低时,q3/q4 的输出到或门。

这可能会澄清一点。

图片可以单独放大查看,比这里显示的要大。正如 Emmett Brown 博士所说,我为模型的粗糙表示歉意,它是我手边唯一的原理图编辑器。目的是显示 De Morgan 门等效项,显示时钟在高电平时被门控,q3 和 q4 的输出延迟从其各自时钟的上升沿开始,q3 和 q4 具有各自时钟的高波特率的剩余部分用于输出延迟和时钟路由延迟。

正如问题的 cmets 中所讨论的,对于特定时钟,从 select 到 or_one 或 or_two 到 q3 或 q4 的 D 输入之间存在亚稳态路径,如果一个或两个时钟与 select 无关(sel在 VHDL 源代码中),如果门控选择无法满足受影响触发器的建立或保持时间,q3 或 q4 的亚稳态恢复时间必须小于其各自时钟的高波特率。这是一个时钟速度限制,可以通过增加从两个时钟域运行之间的无时钟启用时间段来解决。

【讨论】:

  • 我完全同意由于异步选择而禁用时钟的时钟速度限制。我更关心什么时候要激活的新时钟(在两个时钟都被禁用之后)几乎在时钟上升的同时从门控中释放出来。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2015-12-17
  • 2012-10-05
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-06-14
  • 1970-01-01
相关资源
最近更新 更多