Verilog -- initial塊中阻塞與非阻塞賦值問題


Verilog testbench的initial塊中阻塞與非阻塞賦值問題

問題描述

在testbench的編寫中經常要做的就是在initial塊中對一些信號變化進行描述。
比如希望信號start在仿真開始后第10個周期上升沿置為高電平。
對於仿真時鍾一般都會這么寫:

 always #1 clk = ~clk;
  • 如果初始化clk = 0,那么實際上start應該在 #21;start=1; 也就是十個半周期后置高。
  • 如果初始化clk = 1,那么實際上start應該在 #20;start=1; 也就是准確的十個周期后置高。

這種寫法實際上不符合實際電路中的運行規則
如果start在上層模塊是通過其他FF給出的,則這樣的寫法往往會導致數據提前一拍,因為#20;start=1;的寫法是跟時鍾上升沿無關的,因此在該處時鍾上升沿實際上和start的值同時改變,而我們知道,實際上FF的原理是一般都是基於正負latch,其采樣和保持都需要一定的延時(clk-Q),所以用clk去驅動FF時,FF的Q端數據一般都是在上升沿之后的一段延時后才改變。
這也是為什么verilog中要使用“<=”非阻塞賦值的一個因素,因為非阻塞賦值契合了實際電路中的這一特性,如果該FF之后又級聯了一個FF,則在這個clk上升沿,如果不考慮時鍾skew,那么后面級聯的FF實際上采樣到的數據還是前級FF賦值之前的數值,非阻塞賦值可以保證這一特性。

  • 阻塞:在本語句中“右式計算”和“左式更新”完全完成之后,才開始執行下一條語句(遇到等式時堵住值直到更新才釋放);
  • 非阻塞:當前語句的執行不會阻塞下一語句的執行(遇到等式立馬就把右邊值給左邊,不等其更新)。

所以在tb里initial塊中一般使用

@ (posedge clk);
 start<=1;

這種寫法來保證非阻塞的特性,也就是在時鍾上升沿之后reg值才變化。實際上沒有@ posedge也可以,只要賦值語句是非阻塞的,則等式的執行實際上相對當前的時間觸發會有一定的延時,而@ posedge clk可以方便的間隔一定時間知道clk的上升沿到來。
下面是一段測試程序,以便更好的理解兩者的差別:

module test();
  reg clk;
  reg req0;
  reg req1;
  reg test_sig;
  always #1 clk = ~clk;
  initial begin
  clk = 0;
  req0 = 0;
  req1 = 0;
  test_sig = 0;
  #10;
  @ (posedge clk);
  req0 <= 1;
  req1 <= req0;
  repeat (1) @ (posedge clk)
  req0 <= 1;
  req1 <= req0;

  #10;
  req0 = 0;
  req1 = req0;
 end
always@(posedge clk) begin
    if(req0==1) test_sig <= 1;
    else test_sig <= 0;
end

initial begin
    $fsdbDumpvars();
    $fsdbDumpMDA();
    $dumpvars();
    #100 $finish;
 end
endmodule 

其中,test_sig依賴req0的值。可以發現,當使用@ (posedge clk);配合“<="賦值時,test_sig的值在req0變化的下一周期才改變,req1也是如此,符合時序電路的規范。而下面使用"#"延時和阻塞賦值的語句則導致test_sig、req1跟着req0的值同時改變。

再來看一個例子:

對於用阻塞賦值並加一定延時的情況,可以發現a信號的改變是等待上一句執行結束以后才進行的。所以其中的延時是累加起來的。 而對於非阻塞賦值的情況則是下圖:
其中,信號的變化由於是非阻塞賦值,所以是三個賦值同時進行,也就是說延時是並行的。

另外,如果把延時信息放到賦值的前面,會發生什么呢?
首先,可以知道的是對於阻塞賦值,不管放在哪里都是一樣的,都是串行執行,所以延時會累加。
那么,對於非阻塞賦值的情況呢?下圖進行了實驗:

可見,此時信號賦值的延時又變成了串行的,所以可以發現,如果延時信息放在賦值式之間, 也就是等號右邊,則會當作賦值的一部分而變為非阻塞也就是並行處理,而放在其他地方則跟非阻塞賦值無關,表現為串行的延時。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM