相信剛剛接觸verilog的讀者,多少對阻塞賦值和非阻塞賦值仍有一些困惑。筆者在這篇文章,帶領大家深入的理解這兩者的區別。
首先筆者給一些實驗及仿真數據。通過修改testbench文件,利用modelsim軟件來觀察兩者的不同。
同樣也可以這樣寫:
輸出波形如下:
稍作改動:
輸入波形如下:
細心的讀者會發現是 " = " 與 " <= "的區別。
1> 當使用 " = " ,記爲阻塞賦值。從開始時刻開始,經過2個週期置1,持續4個週期後置0。也就是說在執行一條語句時,其他的語句不能執行。
打個比方,有很多車都要上高架,由於道路堵塞,一次只能通過一輛車,其他車只能等這輛過去後,才能過。
2 > 當使用 " <= " ,記爲非阻塞賦值。從開始時刻開始,經過2個週期置1;從開始時刻,經過4個週期後置0。你會發現,經過四個週期後,test信號始終維持低電平,好像最後一句賦值沒發生一樣。
再打個比方,還是很多車準備過高速路口,通常有多個出口。現在有三輛車都過,這三輛車是互不影響的。
實際上也就是延遲三個週期置高電平,可是延遲兩個週期已經置高電平了,可以分析這句一定是同時進行的。
通過作者的分析,相信讀者可能加深了對兩者區別的理解。
在此筆者推薦用阻塞賦值的方法,書寫testbench腳本初始化模塊,這樣時序較爲容易分析。
那麼以上兩者對電路有那種影響呢?
採用非阻塞賦值,部分代碼如下:
always @(posedge clk)
begin
b <= a;
z <= b;
end
其綜合對應的電路如下:
採用阻塞賦值,部分代碼及綜合電路如下:
always @(posedge clk)
begin
b = a;
z = b;
end
區別已經很明顯了,具體區別就不再贅述,不過在這裏,我想說的是,不要以爲加入寄存器變量,一定意味着添加寄存器,這是錯誤的。
對於阻塞賦值,b爲寄存器變量,可沒有輸出爲b的寄存器喲。
綜上所述,阻塞賦值和非阻塞賦值各佔一片天。always 裏面一定是非阻塞賦值,這可不一定喲。
具體問題具體分析,我相信,即使最簡單的語法知識,深入分析之後,也會收穫很多的。