时钟边缘事件可以在verilog中的始终块内合成吗?

时间:2018-06-01 15:02:42

标签: events verilog hdl synthesis

我有两个时钟,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快一个数量级。设计需要合成。

1 个答案:

答案 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时钟周期的不可避免的延迟。