多时钟生成 [Verilog] [使用 fork-join]

Multiple clock generation [Verilog] [Using fork-join]

我生成了以下代码:

module clk_gen();
    reg clk, clk1 , clk2, clk3 , clk4 ;  

always 
    fork 
       #5 clk = ~clk ;
       #1 clk1 = ~clk1 ;
       #3 clk2 = ~clk2 ;
       #4 clk3 = ~clk3 ;
       #3 clk4 = ~clk4 ;
    join


 initial begin
    clk = 1'b0 ;  
    clk1 = 1'b0 ;  
    clk2 = 1'b0 ;  
    clk3 = 1'b0 ;  
    clk4 = 1'b0 ;  
    $monitor ("Time : %0t ,RealTime : %0t ,Clk Value : %0d,Clk1 Value : %0d,Clk2 Value : %0d,Clk3 Value : %0d,Clk4 Value : %0d,$time,$realtime,clk,clk1,clk2,clk3,clk4) ;

    #30 $finish ;
 end

endmodule : clk_gen

我无法使用 fork-join 生成时钟 statement.All 生成的时钟具有相同的频率,即 #5 延迟。

join 将等待所有线程完成,因此实际上是最长的线程(#5)。这就是为什么所有时钟都以 5 个周期同步的原因。

那里不需要叉子。只需使用多个 always 语句。

always 
   #5 clk = ~clk ;
always
   #1 clk1 = ~clk1 ;
always    
   #3 clk2 = ~clk2 ;
   ...

您可以像这样使用 fork/join:

initial begin
    fork
        forever #5 clk = ~clk;
        forever #4 clk1 = ~clk1;
        ...
    join 
 end

这与使用多堆初始块相同

 initial forever #5 clk = ~clk;

这种时钟生成方式无法通过任何 fork-join 方法(fork-join、fork-join_any、fork-join_none)完成。

原因是

  • 对于fork-join,它会等待最长的线程完成,因此周期等于最长的线程延迟。
  • 使用 fork-join_any,它会在第一个最短延迟线程完成后立即完成,但之后它会产生多个线程,因此周期将等于最短线程延迟。
  • 使用fork-join_none,将生成无限线程。

因此,理想的解决方案是为每个时钟制作单独的 always 块。

always #5 clk = ~clk ;
always #1 clk1 = ~clk1 ;
always #3 clk2 = ~clk2 ;
always #4 clk3 = ~clk3 ;
always #3 clk4 = ~clk4 ;