我有两个时钟,clk0和clk1。我想要一个计数器依靠clk0的posedge但重置clk1的posedge。需要注意的重要一点是,复位应仅在posedge上发生,而不是在clk1为高时发生。所以下面的代码是不可能的。
<select>
我们也不能从两个常常块中驱动计数器。所以下面是不可能的:
always @(posedge clk0 or posedge clk1)
begin
if (clk1)
count <= 0;
else
count <= count + 1;
end
所以我的问题是:什么提供类似的功能,如
always @ (posedge clk0)
begin
count <= count + 1;
end
always @ (posedge clk1)
begin
count <= 0;
end
可以合成吗?
我想要一个计数器,它依赖于clk0的构成并重置clk1的构成。 clk0比clk1快一个数量级。设计需要合成。
答案 0 :(得分:4)
您需要将'事件'从clk1传输到clk0。这是一个时钟域交叉问题,因此需要同步。
reg clk1_meta,clk1_sync,clk1_prev;
always @(posedge clk0 or negedge reset_n) // async low reset as example
begin
if (!reset_n)
begin
clk1_meta <= 1'b0;
clk1_sync <= 1'b0;
clk1_prev <= 1'b0;
counter <= 'b0;
end
else
begin
// transfer clk1 to clk0
clk1_meta <= clk1;
clk1_sync <= clk1_meta;
// Now we have a safe signal: clk1_sync
clk1_prev <= clk1_sync;
// A rising edge is when clk1_sync1 is high but previously it was low
if (clk1_sync==1'b1 && clk1_prev==1'b0)
counter <= 'b0;
else
counter <= counter + 1;
end
end
由于同步,在clk1到达clk0域之前,存在~2 clk0时钟周期的不可避免的延迟。