沒想到啊沒想到啊,有一天會被濃眉大眼的assign背刺!想當(dāng)年在always消失術(shù)里,在X態(tài)分析里,在xprop平替策略里,把a(bǔ)ssign捧的這么高,優(yōu)點說了800多項,然后今天一仿真出bug了?!
還有有符號數(shù)和無符號數(shù),我都吹出去了已經(jīng)大成大成了,這還能出錯?!
萬事皆有可能,于是就出現(xiàn)了這個事。
事情的根源簡化完就是下面這個語法,當(dāng)sel為0時輸出i_a高位補(bǔ)零的右移結(jié)果(相當(dāng)于視i_a為無符號數(shù)),sel為1時輸出i_a高位補(bǔ)符號位的輸出結(jié)果相當(dāng)于視i_a為有符號數(shù)):
//test
wire [31:0]i_a = 32'hff00_0000;
wire sel = 1'b1;
wire [31:0]en0 = (sel == 1'b0) ? i_a > >> 8 :
$signed(i_a) > >> 8;
wire [31:0]en1_mid = $signed(i_a) > >> 8;
wire [31:0]en1 = (sel == 1'b0) ? i_a > >> 8 : en1_mid;
好,大家先看著這en0和en1的值。
en0和en1的值分別是啥呢?
en0 = 32'h00ff_0000;
en1 = 32'hffff_0000;
問題出在哪呢?前面咱們總結(jié)過:有符號數(shù)和無符號數(shù)運算,結(jié)果為無符號數(shù)。這句話不太嚴(yán)謹(jǐn),應(yīng)該完善為:有符號數(shù)和無符號數(shù)運算,所有的運算數(shù)會被視為無符號數(shù),結(jié)果為無符號數(shù)。
因為en0運算公式中,有符號數(shù)和無符號數(shù)混合運算了,有符號數(shù)和無符號數(shù)混合時會自動將所有的變量視為無符號數(shù)進(jìn)行運算,而這個混合運算很難發(fā)現(xiàn):
wire [31:0]en0 = (sel == 1'b0) ? i_a > >> 8 : $signed(i_a) > >> 8;
對,i_a >>> 8是個無符號數(shù)的運算!/(ㄒoㄒ)/~~所以帶著signed(i_a) >>> 8也變成了無符號數(shù)的運算。所以說如果把signed(i_a) >>> 8單提出來先算好,再參與選擇邏輯就是預(yù)期的結(jié)果了。
那么最后一個小問題,選擇邏輯參與不參與這個有符號數(shù)和無符號數(shù)的爭端呢?不參與,比如代碼改成這樣:
wire [31:0]en0 = (sel == 1'b0) ? $signed(i_a > >> 8) : $signed(i_a) > >> 8;
我把前面的運算結(jié)果通過$signed擴(kuò)了一下,然后再仿真:
這說明了兩個問題:
1.選擇邏輯沒有參與到有符號數(shù)和無符號數(shù)的判定中;
2.判定時signed(i_a) >>> 8,看的是同一級別的其他運算項的符號屬性,比如此時他看的是signed(...);
再改一下就又回去了:
wire [31:0]en0 = (sel == 1'b0) ? $signed(i_a > >> 8) + 1'b1 : $signed(i_a) > >> 8;
-
仿真器
+關(guān)注
關(guān)注
14文章
1018瀏覽量
83744
發(fā)布評論請先 登錄
相關(guān)推薦
評論