FPGA Verilog語言中阻塞賦值與非阻塞賦值區(qū)別的個(gè)人看法 -------(本文與新浪博客同步) 對(duì)于Verilog 初學(xué)者來說,阻塞賦值與非阻塞賦值應(yīng)該要區(qū)別一下子,我估計(jì)對(duì)于這兩種賦值方式的應(yīng)用解說,什么時(shí)候該用阻塞賦值,什么時(shí)候該用非阻塞賦值,通常見到的一句話是,時(shí)序邏輯里面通常用非阻塞賦值,組合邏輯里面通常使用阻塞賦值。但是這必然是含糊不清的,也并不意味著時(shí)序邏輯里面就不可以阻塞賦值了,組合邏輯里面就不可以用非阻塞賦值了。所以我覺得有必要弄清楚一下阻塞賦值和非阻塞賦值的細(xì)微區(qū)別。 首先還是回歸下定義,所謂阻塞賦值,例如 a=b; 當(dāng)這個(gè)賦值語句執(zhí)行的時(shí)候是不允許有其它語句執(zhí)行的,這就是阻塞的原因。而非阻塞賦值,例如a<=b;當(dāng)這個(gè)賦值語句執(zhí)行的時(shí)候是不阻礙其它語句執(zhí)行的。對(duì)于FPGA來講,跟單片機(jī)相比(即使是高速單片機(jī)),它本身的優(yōu)點(diǎn)是語句執(zhí)行的并行性,而單片機(jī)語句執(zhí)行是順序執(zhí)行的。所以如果說我們要充分利用好FPGA這個(gè)優(yōu)點(diǎn),那么我們應(yīng)該盡量使用非阻塞賦值。 下面我想從一個(gè)簡(jiǎn)單的例子來淺析一下兩者的區(qū)別。 這是一個(gè)簡(jiǎn)單的分頻程序,目的是將clk時(shí)鐘四分頻。Count初始值是0,(個(gè)人經(jīng)驗(yàn)認(rèn)為的,因?yàn)?font face="Times New Roman">verilog里面似乎沒法對(duì)變量進(jìn)行初始化),然后第一個(gè)時(shí)鐘的上升沿到來時(shí),count自加1后變成了1,if語句執(zhí)行為假,然后第二個(gè)時(shí)鐘上升沿到來時(shí),count又自加1變成了2,if語句執(zhí)行條件為真,則執(zhí)行if語句內(nèi)的內(nèi)容,將data_a數(shù)據(jù)翻轉(zhuǎn),count重新賦值為0,所以該程序就是每?jī)蓚(gè)時(shí)鐘的上升沿,data_a數(shù)據(jù)翻轉(zhuǎn)一次,得到四分頻的效果。 下圖為仿真波形,是完全對(duì)得住分析的。 上面的程序用的是阻塞賦值,也就是 count執(zhí)行自加1的時(shí)候,其它任何語句都是不能執(zhí)行的,因此這里就有點(diǎn)想單片機(jī)里面的C語言了,一個(gè)順序執(zhí)行的always塊。 如果把上面的程序賦值全改成非阻塞賦值,效果會(huì)怎樣呢? 首先我們先不作分析,先對(duì)比一下仿真波形。 從仿真波形來看,這個(gè)程序確變成了對(duì)clk時(shí)鐘的六分頻,顯然不是我們之前的思路分析結(jié)果。實(shí)際上它是這樣子執(zhí)行的。 首先可以這樣理解,1、非阻塞賦值是always塊結(jié)束才賦值的,個(gè)人理解是程序見到always塊的結(jié)束標(biāo)記end后才賦值,但是并不代表當(dāng)程序最開始看到該語句時(shí)沒有任何動(dòng)作,而是先把后面的值給計(jì)算出來放在一個(gè)寄存器中暫存,到了塊結(jié)束才賦值,比如上述中的先把count+1計(jì)算出來后,到了塊結(jié)束才把那個(gè)結(jié)果賦值給count。2、非阻塞賦值是并行執(zhí)行的,因此不管有多少個(gè)always塊,不管每個(gè)always塊里面有多少條非阻塞賦值,它都是瞬間一塊并行執(zhí)行的,互不干擾。 所以上面的程序就好分析了 Count初始值是0,第一個(gè)時(shí)鐘的上升沿到來時(shí),count<=count+1 這條語句先不賦值(前面說了塊結(jié)束才賦值),但是count+1已經(jīng)計(jì)算出來放在寄存器中存儲(chǔ)著,先執(zhí)行的是if語句,if語句此時(shí)條件仍然是(count=0),條件為假,不執(zhí)行if內(nèi)部語句,接著遇到always塊結(jié)束標(biāo)記end,這才執(zhí)行count<=的賦值,count此時(shí)為1,然后第二個(gè)時(shí)鐘上升沿到來,同樣先執(zhí)行if語句,條件仍然為假,然后再執(zhí)行count自加1,count變?yōu)?font face="Times New Roman">2,第三個(gè)時(shí)鐘上升沿到來,先執(zhí)行if語句,條件滿足,至于此時(shí) 有三個(gè)非阻塞賦值的語句出現(xiàn) count<=count+1; data_a<=!data_a; count<=0; 這三個(gè)語句按道理講也是并行執(zhí)行的,但是,有兩個(gè)語句同時(shí)對(duì)count進(jìn)行了賦值。。那么咋整呢,這點(diǎn)筆者尚未清楚,懇請(qǐng)達(dá)人解析,或者待日后筆者弄清楚在來看看了。。。 7月25日,經(jīng)過龍哥點(diǎn)撥,上述問題終于有了一個(gè)合理的解釋。 參閱許多資料可以得出的結(jié)論是:在begin 。。end 中非阻塞賦值實(shí)際上是并行中的順序執(zhí)行。此話的理解是,begin 。。end 語句塊中得非阻塞賦值語句與其它塊中的非阻塞賦值語句是并行的,但是對(duì)于單個(gè)begin 。。end 塊中的語句卻是順序執(zhí)行的。所以在verilog語言中是不允許在兩個(gè)塊中對(duì)同一變量進(jìn)行賦值的,而在單一塊中,如果有兩個(gè)或兩個(gè)以上的非阻塞語句對(duì)同一個(gè)變量進(jìn)行了賦值,那么該變量的值由最后一個(gè)語句所決定。
|