Verilog學習筆記基本語法篇(三)·········賦值語句

在Verilog HDL語言中,信號有兩種賦值方式。

A)非阻塞賦值(Non-Blocking)方式(如:b<=a;)

(1)在語句塊中,上面語句所賦值的變量不能立即爲下面的語句所用;

(2)塊結束後才能完成這次賦值操作,賦值的職位上次賦值得到的;

(3)在編寫可綜合的時序邏輯模塊時,這是最常用的複製方法。

 

B)阻塞賦值(Blocking)方式(如:b=a;)

(1)賦值語句完成後,塊才結束;

(2)b的值在賦值語句執行完後立刻改變。

(3)在時序邏輯中使用時,可能會產生意想不到的結果。

 

補充:

首先規定兩個縮寫:

RHS--賦值等號右邊的表達式或變量可以寫作RHS表達式或RHS變量;

LHS--賦值等號左邊的表達式或變量可以寫作LHS表達式或LHS變量。

B)阻塞賦值

 阻塞賦值的詳細過程是先計算等號右手方向的RHS的值,這是賦值語句不允許別的任何Verilog語句的干擾,直到它的賦值完成,即把RHS賦給LHS的時刻,才允許別的賦值語句執行。一般可以綜合的阻塞賦值不能在RHS設置延遲(零延遲也不可以)。阻塞賦值的執行可以認爲是隻有一個步驟的操作,即計算RHS的值並更新LHS,此時不允許任何其他語句的干擾,所謂的阻塞的概念就是值在同一個always塊中,其後面的賦值語句從概念上來講是在前面一條語句賦值完成後才執行的。

如果在一個過程塊中阻塞賦值的變量RHS正好是另一個always塊中阻塞賦值的LHS變量,這兩個過程又通過同一個時鐘沿觸發,這是阻塞賦值會出現問題,有可能出現競爭。如果這兩個賦值語句操作由同一個時鐘沿觸發,則執行的順序是無法確定的。

複製代碼
 1 module fbosc(y1,y2,clk,rst);
 2   input clk,rst;
 3   output y1,y2;
 4   reg y1,y2;
 5   always @(posedge clk or posedge rst)
 6   begin
 7   if(rst) y1=0;
 8   else y1=y2;
 9   end
10   always @(posedge clk or posedge rst)
11   begin
12   if(rst) y2=1;
13   else y2=y1;
14   end
15  endmodule
複製代碼

如果清零信號已經從1到0(已經reset過),並且上面的always塊比下面的always塊的時鐘沿早幾個皮秒到達,那麼最後y1=1,y2=1;但是如果下面的always塊的時鐘沿先到達,那麼輸出y1=0,y2=0;這就說明折個模塊是不穩定的,肯定會產生競爭和冒險。

A)非阻塞賦值

非阻塞賦值在賦值開始的時刻就開始計算RHS的值,但是到賦值結束的時刻才更新LHS。在計算RHS和更新LHS的時刻其他的Verilog語句,包括其他非阻塞賦值語句都能同時進行計算RHS和更新LHS。非阻塞賦值允許其他的Verilog語句同時進行操作。非阻塞賦值只能用於對存儲器型變量進行賦值,因此只能用在initial塊和always塊中,並且不允許用assign賦值。

非阻塞賦值可以看做兩個步驟:

1)在賦值開始時刻,計算非阻塞賦值RHS表達式;

2)在賦值結束時刻,更新非阻塞賦值LHS的值。

複製代碼
 1 module fbosc(y1,y2,clk,rst);
 2   input clk,rst;
 3   output y1,y2;
 4   reg y1,y2;
 5   always @(posedge clk or posedge rst)
 6   begin
 7   if(rst) y1<=0;
 8   else y1<=y2;
 9   end
10   always @(posedge clk or posedge rst)
11   begin
12   if(rst) y2<=1;
13   else y2<=y1;
14   end
15  endmodule
複製代碼

按照IEEE的標準,兩個always塊是並行執行的。在復位後,無論哪一個always的有效沿先到達,兩個always塊中的非阻塞賦值都在賦值開始計算RHS的表達式,而在結束時刻才更新LHS。所以復位之後,無論哪個邊沿先到達,y1=1;y2=0是確定的,因爲實質上y1被賦值的是信號沿上升時刻的y2的值,此時y2還沒有改變,而y2被賦的值是信號上升沿時y1的值;若以後保持rst爲零的話,每一個時鐘沿到來之後,y1和y2被賦值的都是上一個週期的y2和y1,從結果來看兩個賦值語句是並行執行的。

在使用阻塞賦值和非阻塞賦值時的八大原則:

1)時序電路建模時,採用非阻塞賦值;

2)鎖存器電路建模時,採用非阻塞賦值;

3)用always塊建立組合邏輯模型時,採用阻塞賦值;

4)用always塊建立時序和組合邏輯混合電路時,採用非阻塞賦值;

5)不要在同一個always塊中同時使用非阻塞賦值和阻塞賦值;

6)不要在一個以上的always塊中爲同一個變量賦值;

7)用$strobe系統任務來顯示用非阻塞賦值的變量值;

8)在賦值時,不要用#0延遲;

發佈了233 篇原創文章 · 獲贊 195 · 訪問量 55萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章