我正在研究一种设计,它应检测两个不同频率异步时钟的两个上升沿的第一个匹配。
这样的代码可能适用于模拟。
fork
@posedge clkA
begin
a=$time
end
@posedge clkB
begin
b=$time
end
join
if (a=b) then some code.
这段代码可能适用于模拟,但如果我想要一些可综合的硬件逻辑 我还能用什么呢?
答案 0 :(得分:2)
这个有点棘手,但是如果你能得到第三个时钟,它的速度是你需要检测的两个时钟之间的最快时钟的两倍,并且可以接受一个周期的检测延迟(一个周期在参考中)到第三个时钟域)然后它是可能的。
您需要做的是设置每个clk域的寄存器,如下所示:
input clk1, clk2'
...
reg clk1_in, clk1_out;
reg clk2_in, clk2_out;
wire clk1_posedge, clk2_posedge;
//take in the clock value, you should register this so that way jitter on the line does not mess with it
always@(posedge clk3)begin
clk1_in <= clk1;
clk2_in <= clk2;
end
always@(posedge clk3)begin
clk1_out <= clk1_in;
clk2_out <= clk2_in;
end
//now you need to detect the posedge for each signal independently, you can use and and gate for this
assign clk1_posedge = (~clk1_out && clk1_in);
assign clk2_posedge = (~clk2_out && clk2_in);
// now just and the two together
assign pulse_detected = clk1_posedge && clk2_posedge
你需要clk 3快两倍,否则你会得到别名(查找nyquist freq)
所以会发生什么?时钟域的第一个寄存器将为高电平,如果它刚刚变高,则第二个寄存器在该周期内仍然为低电平。
答案 1 :(得分:2)
无法在HW中重现您描述的行为。这样做的原因是您比较完全的时间。
首先,您需要通过“检测两个上升沿的第一个匹配”来解释您的意思。鉴于两个异步时钟具有可变(和不可预测)的相位关系,检测同时边缘的任务将(通常)以多少时间“同时”来表示。
例如:检测上升沿的时间间隔最长为5ns。
顺便说一句,我在这里假设有两个频率都是已知的。
请详细说明您的问题。
修改强> 这个问题变成了硬件问题,与Verilog无关。目前尚不清楚这里提出的任何解决方案是否有效(而且我个人认为他们不会这样做)。我在EE Stack Exchange处提交了相同的问题 - 这是一个提问硬件问题的地方,并且更有可能在那里得到答案。
答案 2 :(得分:1)
要拔掉它,先制作双边双时钟触发器。从双时钟D触发器Patent US6320442 B1开始。现在用双边D触发器Patent US5793236 A或Patent US5327019 A替换子触发器。每个专利都有电路设计图。
使用自定义触发器,创建一个小型流水线,对时钟的历史进行采样。寻找从零到一的过渡。
示例:
wire [1:0] historyA, historyB;
// dualedge_dualclock_dff ( output Q, input D, clkA, clkB, rst_n)
dualedge_dualclock_dff dedc_histA1( .Q(historyA[1]), .D(historyA[0]), .* );
dualedge_dualclock_dff dedc_histA0( .Q(historyA[0]), .D(clkA), .* );
dualedge_dualclock_dff dedc_histB1( .Q(historyB[1]), .D(historyB[0]), .* );
dualedge_dualclock_dff dedc_histB0( .Q(historyB[0]), .D(clkB), .* );
wire dual_posedge_match = ({historyA,historyB} == 4'b0101);
双边沿触发器和双时钟触发器不是常见的设计实践。将需要过多的时序分析,工具可能会抱怨细胞。此外,还需要采取措施使专利使用符合法律规定。