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延遲。