我在http://www.vlsi-world.com/content/view/64/47/1/1/
找到了这个时钟多路复用器的设计作者声称它是毛刺安全的,但我认为如果时钟信号到相应或门(or_three,or_four)的路由延迟大于路由延迟+时钟输出,它仍可能有一个小故障当q3 / q4的输出变低时,q3 / q4延迟到或门。为了避免这些毛刺,q3 / q4的输出必须在时钟的上升沿变高,在时钟下降沿变低。我在这次评估中是否正确?
另请注意,我链接的页面上的原理图与verilog不完全匹配(qil的qbar输出未在verilog中使用),并且用于生成模拟的测试平台转换为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;
答案 0 :(得分:1)
我继续为clk_b to or_four
创建了一个测试平台和模拟VHDL转换,路由延迟很小(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;
答案 1 :(得分:0)
...我认为如果时钟信号到相应或门(or_three,or_four)的路由延迟大于路由延迟+时钟输出延迟,它仍可能有毛刺当q3 / q4的输出变低时,q3 / q4到或门。
这可能有点澄清。
图像可以单独缩放查看,比此处显示的图像大。正如Emmett Brown博士所说,我为模型的粗糙而道歉,它是我唯一得心应用的原理图编辑器。目的是显示De Morgan门等效,显示时钟在高电平时门控,q3和q4从各自时钟的上升沿输出延迟q3和q4具有其各自时钟的高波特率的剩余部分用于输出延迟和时钟路由延迟。
正如对问题的评论中所讨论的那样,从选择到or_one或or_two到q3或q4的D输入相对于特定时钟存在亚稳态路径,其中如果一个或两个时钟与select无关(sel)在VHDL源中,如果门控选择不能满足受影响触发器的建立或保持时间,则q3或q4的亚稳态恢复时间必须小于它们各自时钟的高波特率。这是一个时钟速度限制,可以通过增加两个时钟域之间的无时钟启用周期来解决。