1. 程式人生 > 其它 >reg型變數怎麼賦值_使用阻塞賦值和非阻塞賦值建模的分頻時鐘

reg型變數怎麼賦值_使用阻塞賦值和非阻塞賦值建模的分頻時鐘

技術標籤:reg型變數怎麼賦值

76e81505afa0c9a8b1c3fd69e77de0c5.png

我們常常能看到一個Verilog RTL Coding guideline :在建模時序邏輯的時候,使用非阻塞賦值。

但事實上,當我們遵循使用非阻塞賦值來建模分頻時鐘(時鐘路徑)時,可能會存在競爭冒險的問題。

module Non_blocking(
  input clk ,
  input rst_n,
  input data_in,
  output data_out)
  reg clk_div ,
  [email protected](posedgeclk or negedge rst_n) begin
    if(!rst_n) begin
      clk_div<= 0 ;
    end
    else begin
      clk_div <= ~clk_div ;   //update value  after delta
    end
  end
   
  reg data_reg ;
  
[email protected]
(posedgeclk or negedge rst_n) begin if(!rst_n) begin data_reg<= 0 ; end else begin data_reg <= data_in ; //update value after delta end end [email protected](posedgeclk_div or negedge rst_n) begin if(!rst_n) begin data_out<= 0 ; end else begin data_out <= data_reg ; end end endmodule

Testbench:

module Non_blocking_tb;
  reg clk;
  reg rst_n;
  reg data_in;
  wire data_out;
  initial begin
    clk= 0  ;
    rst_n = 1 ;
    #10 rst_n = 0 ;
    #10 rst_n = 1 ;
  end
  always #2 clk =~clk ;
  initial begin
    data_in = 0 ;
    repeat(20) begin
      @(posedge clk) data_in  =$random%2 ;
    end
  end
Non_blocking Non_blocking(
  .clk(clk) ,
  .rst_n(rst_n),
  .data_in(data_in),
  .data_out(data_out)
);
endmodule

上述程式碼可以理解為master clock生成的generated clock和master clock生成的data之間存在競爭冒險,也可以理解為非阻塞賦值去除了master clock和generated clock之間的同步關係,這種同步關係在綜合的時候是需要有STA工具來保證的。

907d06ff2a51868b6032ac6473eace1c.png

上述程式碼data_out取樣到的是data_reg更新後錯誤的值。

也就是說上述的程式碼風格(在時鐘路徑上使用非阻塞賦值),導致了綜合前後模擬的不匹配。

非阻塞賦值“<=”主要用來建模硬體上觸發器賦值行為,它分為兩步:

1、計算“<=”表示式右邊的值

2、在delta延時之後,將表示式右邊的值賦給左邊的變數。

避免這種綜合前後模擬的不匹配,最簡單的方式就是使用阻塞賦值來建模分頻時鐘(時鐘路徑)。

[email protected](posedgeclk or negedge rst_n) begin
    if(!rst_n) begin
      clk_div  = 0 ;
    end
    else begin
      clk_div  = ~clk_div ;   //update value immediately
    end
  end

使用同樣的Testbench,模擬結果:

c8235380cb4def81df51df1d5dd62d27.png

上述程式碼data_out取樣到的是data_reg更新前正確的值。

這種使用阻塞賦值的方式來建模時鐘路徑時序邏輯也不會存在任何綜合上的問題。

所以之前大家熟知的guideline,應該精確為:

在建模資料路徑上時序邏輯的時候,使用非阻塞賦值;在建模時鐘路徑上時序邏輯的時候,使用阻塞賦值。