能否在 verilog 中的 always 块内合成时钟边沿事件?

Can clock edge events be synthesized inside always blocks in verilog?

我有两个时钟,clk0 和 clk1。我想要一个计数器来计数 clk0 的 posedge 但在 clk1 的 posedge 重置。需要注意的重要一点是,复位应该只发生在 posedge 上,而不是在 clk1 为高电平时。所以下面的代码是不可能的。

always @(posedge clk0 or posedge clk1)
begin
     if (clk1)
              count <= 0;
     else
              count <= count + 1;
end

我们也不能从两个 always 块中驱动计数器。所以下面是不可能的:

always @ (posedge clk0)
begin
     count <= count + 1;
end

always @ (posedge clk1)
begin
     count <= 0;
end

所以我的问题是:什么提供了类似

的功能
always @(posedge clk0 or posedge clk1)
begin
     if (posedge clk1)
              count <= 0;
     else
              count <= count + 1;
end

可合成吗?

我想要一个计数器,它在 clk0 的 posedge 上计数并在 clk1 的 posedge 上重置。 clk0 比 clk1 快一个数量级。设计需要可综合。

您需要将 'event' 从 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 时钟周期。