1. 程式人生 > >FPGA學習一:阻塞賦值和非阻塞賦值的理解

FPGA學習一:阻塞賦值和非阻塞賦值的理解

賦值語句共有兩種,即非阻塞賦值,和阻塞賦值。
(1)非阻塞賦值
   非阻塞賦值方式所賦值的變數不能立即就為下面語句所用,只有當塊結束後才能得到上一次所附的值,這種賦值方式是編寫可綜合的時序邏輯時常用的賦值方式。例如

實際上,上面的非阻塞賦值的RTL是一個移位暫存器

如果開始時,a=1,b=2,c=x;那麼,當一個clk上升沿到達後,a=1,b=1,c=2,實際從12x變成了112,即向後移了一位,最後,輸出會變成a=1,b=1,c=1。

也可以直接理解非阻塞賦值時並行執行語句,即begin裡面的兩個非阻塞賦值語句是同時執行的,當clk上升沿到達後,a的值賦值給b,在a賦值給b的同時,b的值賦值給c,於是,a=1,b=1,c=2。

非阻塞賦值方式所賦值的變數不能立即就為下面語句所用,我的理解就是當時賦值的語句被鎖存了,必須等下一個上升沿觸發後才能賦值給下個語句。

(2)阻塞賦值
與非阻塞賦值不同,賦值語句執行完後塊才結束,b 的值在賦值語句結束後立刻改變,但是在時序邏輯電路中可能會出問題。
always @(clk or clr);
    begin
        b=a;
        c=b;
    end

阻塞賦值就是順序執行語句,類似於C語言結構化程式設計一樣,語句是按順序執行的,該語句的RTL如下圖:

如果開始a=1,b=2,c=2;當上升沿到達後,a=1,b=1,c=1.

學習到的重點: 
1)時序電路建模時,用非阻塞賦值; 
2)鎖存器電路建模時,用非阻塞賦值; 
3)用always塊建立組合邏輯模型時,用阻塞賦值; 
4)在同一個always塊中建立時序和組合邏輯電路時,用非阻塞賦值; 
5)在同一個alway塊中,不要即用非阻塞又用阻塞賦值; 
6)不要在一個以上的always塊中為同一個變數賦值; 
7)用$strobe系統任務來顯示用非阻塞賦值的變數值; 
8)在賦值時不要使用#0延遲。