簡介
非阻塞賦值操作符用小於等於號(即<=)表示。為在賦值操作時刻開始時計算非阻塞賦值符的RHS表達式,賦值操作時刻結束時更新LHS。在計算非阻塞賦值的RHS表達式和更新LHS期間,其他的Verilog語句,包括其他的Verilog非阻塞賦值語句都能同時計算RHS表達式和更新LHS。非阻塞賦值允許其他的Verilog語句同時進行操作。
非阻塞賦值是由時鐘節拍決定,在時鐘上升到來時,執行賦值語句右邊,然後將begin-end之間的所有賦值語句同時賦值到賦值語句的左邊,注意:是begin—end之間的所有語句,一起執行,且一個時鐘只執行一次。
使用要點
主要是下面兩個要點:
(1)在描述組合邏輯的always塊中用阻塞賦值,則綜合成組合邏輯的電路結構:
(2)在描述時序邏輯的always塊中用非阻塞賦值,則綜合成時序邏輯的電路結構。
為什麼一定要這樣做呢?這是因為要使綜合前仿真和綜合後仿真一致的緣故。如果不按照上面兩個要點來編寫Verilog代碼,也有可能綜合出正確的邏輯,但前後仿真的結果就會不一致。
為了更好地理解上述要點,需要對Verilog語言中的阻塞賦值和非阻塞賦值的功能和執行時間上的差別有深入的了解。為了解釋問題方便,下面定義兩個縮寫字:
RHS——方程式右手方向的表達式或變數可分別縮寫為RHS表達式或RHS變數;
LHS——方程式左手方向的表達式或變數可分別縮寫為LHS表達式或LHS變數。
IEEEVerilog標準定義了有些語句有確定的執行時間,有些語句沒有確定的執行時間。若有兩條或兩條以上語句準備在同一時刻執行,但由於語句的排列順序不同(而這種排列順序的不同是IEEEVerilog標準所允許的),卻產生了不同的輸出結果。這就是造成Verilog模組冒險和競爭現象的原因。
操作過程
非阻塞賦值的操作可以看作為兩個步驟的過程;
(1)在賦值時刻開始時,計算非阻塞賦值RHS表達式;
(2)在賦值時刻結束時,更新非阻塞賦值LHS表達式。
非阻塞賦值操作只能用於對暫存器類型變數進行賦值,因此只能用在"initial”塊和“al—ways"塊等過程塊中,而非阻塞賦值不允許用於連續賦值。
與阻塞賦值區別
在狀態變數的賦值或開關變數的賦值中,已明確建議大家使用非阻塞賦值。這不但是因為綜合工具要求這樣做,最根本的原因是與非阻塞賦值語句語意對應的電路結構正是我們想要實現的。這兩種賦值語句對應著兩種不同的電路結構。阻塞賦值對應的電路結構往往與觸發沿沒有關係,只與輸入電平的變化有關係。而非阻塞賦值對應的電路結構往往與觸發沿有關係,只有在觸發沿時才有可能發生賦值的情況。
阻塞和非阻塞賦值的區別在阻塞是順序執行而非阻塞是並行執行。
以下面的語句舉例
非阻塞賦值
always@(posedge clk)
begin
b<=a;
c<=b;
end
阻塞賦值
always@(posedge clk)
begin
b=a;
c=b;
end
兩種不同的賦值方式結果是不同的,非阻塞賦值b<=a;c<=b;兩條語句是同時執行的,而阻塞賦值b=a;c=b;兩條語句先執行b=a後執行c=b。
編程語句
結合編程語句區分如下:
· 非阻塞(non-blocking) 賦值語句(b<= a):
- 塊內的賦值語句同時賦值;
- b的值被賦成新值a的操作, 是與塊內其他賦值語句同時完成的;
- 建議在可綜合風格的模組中使用非阻塞賦值。
· 阻塞(blocking) 賦值語句(b = a):
- 完成該賦值語句後才能做下一句的操作;
- b的值立刻被賦成新值a;
- 硬體沒有對應的電路,因而綜合結果未知。