Vhdl 这是不是;“故障安全”;时钟多路复用器真的故障安全吗?
我发现这个设计是在 作者声称它是故障安全的,但我认为,当q3/q4的输出变低时,如果到相应的或门(或_三,或_四)的时钟信号的路由延迟大于到或门的路由延迟+q3/q4到或门的时钟输出延迟,它仍然可能有故障。为了避免这些小故障,第三季度/第四季度的输出必须在时钟上升沿上走高,在时钟下降沿上走低。我的评估正确吗 还要注意,我链接的页面上的示意图与verilog不太匹配(verilog中没有使用q3的qbar输出),并且用于生成模拟的测试台将clk_a和clk_b转换Vhdl 这是不是;“故障安全”;时钟多路复用器真的故障安全吗?,vhdl,verilog,fpga,hdl,Vhdl,Verilog,Fpga,Hdl,我发现这个设计是在 作者声称它是故障安全的,但我认为,当q3/q4的输出变低时,如果到相应的或门(或_三,或_四)的时钟信号的路由延迟大于到或门的路由延迟+q3/q4到或门的时钟输出延迟,它仍然可能有故障。为了避免这些小故障,第三季度/第四季度的输出必须在时钟上升沿上走高,在时钟下降沿上走低。我的评估正确吗 还要注意,我链接的页面上的示意图与verilog不太匹配(verilog中没有使用q3的qbar输出),并且用于生成模拟的测试台将clk_a和clk_b转换 `timescale 1ns/1
`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
`时标1ns/100ps
模块时钟开关(
//输出
外钟,
//投入
时钟a,时钟b,选择
);
输入时钟;
输入时钟;
输入选择;
输出时钟;
电线连接到时钟;
注册第一季度、第二季度、第三季度、第四季度;
电线或一号线、二号线、三号线或四号线;
始终@(posedge clk_a)
开始
如果(时钟a==1'b1)
开始
q1…我认为,当q3/q4的输出变低时,如果到相应的或门(或三或四)的时钟信号的路由延迟大于到或门的路由延迟+q3/q4到或门的时钟输出延迟,那么它仍然可能会有小故障。
这可能会澄清一点
图像可以单独缩放查看,它比这里显示的要大。正如埃米特·布朗博士可能会说的那样,我为模型的粗糙性道歉,它是我手边唯一的原理图编辑器。目的是显示De Morgan门等效值,显示时钟在高电平时被选通,q3和q4的输出延迟从各自时钟的上升沿开始,q3和q4具有各自时钟的剩余高波特率,用于输出延迟和时钟路由延迟
正如对问题的评论中所讨论的,对于特定时钟,存在从select到q3或q4的D输入的亚稳态路径,其中如果一个或两个时钟与select无关(VHDL源中的sel),如果选通选择未能满足受影响触发器的设置或保持时间,则q3或q4的亚稳态恢复时间必须小于其各自时钟的高波特率。这是一个时钟速度限制,可以通过增加从两个时钟域操作之间的无时钟启用周期来解决。我继续为VHDL转换创建了一个测试台和模拟,在clk_b到或_four
上有一个小的(10 ps)路由延迟。当然,在真正的FPGA中,q4/C到或_-four
路径上会有几个延迟,但是clk-b到或_-four
的路由延迟仍然可能更长。输出的整个选通也将被吸收到单个4输入LUT中,但这不会改变这种输出行为
我担心的小故障可以在480ns附近看到:
有谁能想出这样一个原因:这不会/不可能在目标上发生?静态时序分析会阻止这种情况吗
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;
ieee库;
使用ieee.std_logic_1164.all;
实体clk_开关为
港口(
输出时钟:输出标准逻辑;
时钟a:在标准逻辑中;
clk_b:标准逻辑中;
sel:在标准逻辑中
);
终端时钟开关;
clk_交换机的体系结构rtl是
信号q1:std_逻辑;
信号q2:std_逻辑;
信号q3:std_逻辑;
信号q4:std_逻辑;
信号或一:标准逻辑;
信号或二:标准逻辑;
信号或三:标准逻辑;
信号或四:标准逻辑;
信号时钟b_路由:标准逻辑;
开始
clk_b_routed这个部分对我来说看起来很奇怪总是@(posedge clk_a)if(clk_a==1'b1)
,因为posedge只会在clk_a==1'b1
时触发,所以看起来是一个冗余语句,我认为它不会可靠地改变合成的输出(不同的工具可以以不同的方式处理它,例如添加mux/忽略它)。有一个亚稳态路径,从select
到或_two
和q4
,需要在clk\u b
的高波特率期间恢复q4亚稳态。对于不选择通过或_one
和q2
,这两种情况同样适用于任意打开选择的情况。这是一个时钟速度限制,可能的触发器速度减去或_-one
或或_-two
门和路由延迟的一半,以允许亚稳态恢复。克服速度限制需要更长的非时钟周期(更多的触发器,重新计时select
)。是的,我注意到了亚稳态问题,但假设select满足活动时钟的设置/保持(它实际改变或_-one/或_-two的值)会导致故障吗?我想是的,但我不是100%确定。通过或_three
或或_three
的选通“关闭”发生在相应的时钟高时,新时钟在高时启用<代码>或_三个
和
或_四个
De Morgan等效和门out_clk
De Morgan或gate产品。在亚稳态恢复施加的触发器速度限制内,它应该是无故障的。每个时钟取决于启用前禁用的另一个时钟。我完全同意由于异步选择而禁用的时钟的时钟速度限制。我更关心的是要激活的新时钟(在两个时钟都被禁用后)何时在时钟上升的几乎同一时间从选通中释放。这是人为造成问题的一种方式。它没有显示来自clk_b的第四季度保持器过电压/输出延迟。很容易想象第四季度和/或四横跨时钟树上的两个不同分支,或者在时钟树上有10 ps的延迟。第四季度的输出延迟为零,或者第四季度到第四季度的路由延迟为零,这就有点不太可能了
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;