前段時(shí)間有人在網(wǎng)上問(wèn)以下一段代碼,代表什么意思。

初看這段代碼,發(fā)現(xiàn)這里的din有兩次進(jìn)行賦值,首先是進(jìn)行din的自加1操作,然后去判斷en的值,為1的話然后將另外一個(gè)值減1在賦值給din,那最終的結(jié)果應(yīng)該為什么了?
為此,特意寫了一段代碼,以及給代碼的測(cè)試激勵(lì)來(lái)測(cè)試輸出結(jié)果為什么。
代碼如下:


用modelsim進(jìn)行仿真。其仿真圖如下所示:
從上圖中進(jìn)行分析
在復(fù)位信號(hào)為低電平,即復(fù)位信號(hào)有效。輸出b的結(jié)果一直為0.
當(dāng)復(fù)位信號(hào)沒(méi)有效的時(shí)候,而且en為低電平,每當(dāng)一個(gè)時(shí)鐘的上升沿,輸出b的值自加1一次。
當(dāng)en為高電平的時(shí)候,輸出b的值為輸入a的值。。
其實(shí),對(duì)于verilog中的always塊中的信號(hào)賦值,如果采用的是非阻塞,也就是<=賦值。
每次<=賦值后,值不是立即更新,而是要等待所有的<=賦值結(jié)束后,才進(jìn)行更新。而<=右邊的值,都是最初始的值,不是計(jì)算后的值。
分析上面那段代碼,在時(shí)鐘的上升沿,
b <= b + 1'b1; b的值自加1,但是因?yàn)槭?lt;=賦值,因此b的值還沒(méi)有改變,依然還是沒(méi)有自加1時(shí)候的b。
if( en ) b <= a; 當(dāng)判斷en為1的時(shí)候,a的值就賦值給b,但是也不是立刻改變,要等所有always塊中的<=賦值結(jié)束后,才會(huì)改變。
這個(gè)時(shí)候,我們就發(fā)現(xiàn)了矛盾,首先b的值自加1,但是同時(shí)再把a(bǔ)的值給b,這就給人一種雙重賦值的感覺(jué),因?yàn)関erilog的語(yǔ)句是并行執(zhí)行,兩個(gè)都同時(shí)執(zhí)行,那最后b的值為什么。
其實(shí),這就要追朔到verilog這個(gè)語(yǔ)言對(duì)<=賦值的規(guī)定了。。。verilog規(guī)定,所有的<=賦值后,值不是立刻改變,而是要等所有的<=賦值后才進(jìn)行改變,而對(duì)同一個(gè)變量,如果進(jìn)行多次<=賦值,那最終的賦值結(jié)果以最后一個(gè)<=賦值結(jié)果為準(zhǔn)。
所以說(shuō),對(duì)于上面那個(gè)代碼,雖然對(duì)b進(jìn)行了兩次<=賦值操作,但是最后一個(gè)<=賦值是 b<=a,所以最后的結(jié)果是把a(bǔ)的值賦值給b,仿真結(jié)果說(shuō)明了這點(diǎn)。
其實(shí),上面那個(gè)代碼功能其實(shí)是一個(gè)選擇器,當(dāng)en為1的時(shí)候,輸出的值b等于輸入的值a,否則輸出的值b就自加1.
由上面代碼,可總結(jié)到,對(duì)于同一個(gè)alywas塊中的<=賦值,如果同一個(gè)信號(hào)進(jìn)行多次<=賦值,那么結(jié)果,那個(gè)信號(hào)以最后一個(gè)賦值結(jié)果為準(zhǔn),也就是前面的賦值都是無(wú)效的。。
所以說(shuō),以下賦值:(假設(shè)初始a的值為0)
a < = a+1’b1;
a <= a +1’b1;
a <= a +1’b1;
**** (若干次對(duì)a賦值)
a <= a +1’b1;
最后a的值都是為1。也就是初始的a的值加1,也就是最后一句語(yǔ)句表達(dá)的。。。。其中間的賦值通通都被省略了。。。
|