相關(guān)文章
Verilog基礎(chǔ)專欄https://blog.csdn.net/weixin_45791458/category_12263729.html
表達(dá)式位寬
????????如果想要在計算表達(dá)式時獲得和諧一致的結(jié)果,那么控制表達(dá)式中的位寬就很重要。很多時候方法很簡單。例如,如果在兩個16位數(shù)據(jù)的reg變量上做位與操作,那么計算結(jié)果很顯然就是16位。但是在某種情況下,計算應(yīng)該用多少位或者結(jié)果應(yīng)該是多少位就不那么明顯。
????????例如,對兩個16位數(shù)據(jù)做加法操作是選擇用16位進(jìn)行計算呢,還是為了包含可能的進(jìn)位而選擇用17位進(jìn)行計算呢?這里就牽扯到了Verilog用來確定表達(dá)式位寬的規(guī)則。
例1
? ? reg [15 : 0] a, b;
reg [15 : 0] sumA;
reg [16 : 0] sumB;
sumA = a + b;//賦值表達(dá)式右端按照a和b都為16位來計算,結(jié)果仍為16位,最后賦值給sumA且進(jìn)位溢出;
sumB = a + b;//a和b首先根據(jù)規(guī)則補零拓展(選擇這種拓展是因為賦值表達(dá)式右端存在無符號數(shù)a,b)到17位,然后再執(zhí)行相加,結(jié)果為17位,最后賦值給sumB,因此進(jìn)位得以保留。
表達(dá)式位寬規(guī)則
為了在現(xiàn)實的情況下方便地解決位寬問題,Verilog規(guī)定了如下的表達(dá)式位寬規(guī)則。
-
表達(dá)式的位寬由表達(dá)式中的操作數(shù)本身或表達(dá)式所處的上下文決定。Verilog把所有表達(dá)式中的操作數(shù)分為自決定和上下文決定兩類。
-
自決定表達(dá)式(self-determined expression)就是表達(dá)式(或整個表達(dá)式中的子表達(dá)式)中所有操作數(shù)的位寬完全由自己決定。
-
上下文決定表達(dá)式(context-determined expression)就是表達(dá)式(整個表達(dá)式中的子表達(dá)式)中所有操作數(shù)的位寬由整個表達(dá)式上下文環(huán)境中最大的位寬決定。
-
混合自決定和上下文決定表達(dá)式就是表達(dá)式(或整個表達(dá)式中的子表達(dá)式)中操作數(shù)部分自決定,部分上下文決定。
下面的圖1和圖2給出了表達(dá)式的位寬規(guī)則。注:圖2來自官方文檔。
圖1?各操作數(shù)位寬規(guī)則
圖2 各表達(dá)式位寬規(guī)則
????????根據(jù)以上兩圖,我們就可以知道例1的表達(dá)式位寬計算過程。首先我們從圖1得知,=操作符右端的操作數(shù)(不管是單個操作數(shù)還是子表達(dá)式作為操作數(shù),以下不經(jīng)特殊說明的操作數(shù)均作此解釋)是由上下文環(huán)境決定位寬的,且根據(jù)注釋我們還可以得知除了=右端的操作數(shù),=操作符左端的操作數(shù)也會加入到上下文環(huán)境中。這是什么意思呢?我們可以用例1進(jìn)行演示。
????????sumA = a + b;執(zhí)行這個語句時,+號兩端的操作數(shù)是上下文環(huán)境決定位寬,且=左邊也被加入上下文環(huán)境,所以sumA,a,b都被加入上下文環(huán)境,此時這三個變量的位寬是相同的16位,所以沒有數(shù)據(jù)會拓展,可以直接進(jìn)行運算,根據(jù)圖2,a+b結(jié)果的位寬為max(L(a), L(b)),所以是16位,進(jìn)位被舍去,最后將右端的16位值賦給左端的sumA;
????????sumB=a+b;前面的步驟相同,當(dāng)sumB,a,b都被加入上下文環(huán)境后,最大的位寬為17位,所以a,b首先被位補0拓展至17位,然后再執(zhí)行加法得到17位的結(jié)果,因此保留了進(jìn)位,最后將右端的17位值賦給左端的sumB;
????????我們可以多看幾個例子來有一個更加形象的認(rèn)識。
例2
reg [5 : 0] a = 6'b010101;
reg [3 : 0] b = 4'b1111;
reg [7 : 0] c;
c = a & b;
????????在例2中,a&b這個自決定作為子表達(dá)式成為了=右邊的操作數(shù),即是上下文決定位寬的,且我們根據(jù)圖1又可以知道&運算符兩邊的操作數(shù)也是上下文決定位寬,也就是說,和例1的加法一樣,如果一個表達(dá)式作為子表達(dá)式(或說操作數(shù))會被加入上下文環(huán)境(作為=的右操作數(shù)),且表達(dá)式自己也是上下文決定表達(dá)式,那么表達(dá)式內(nèi)部的所有操作數(shù)(a,b)都會被加入上下文環(huán)境,即上下文環(huán)境的嵌套不改變操作數(shù)的上下文性質(zhì)。所以計算過程為:c,a,b都會被加入上下文環(huán)境,最大的位寬是8位,所以a,b首先被補零拓展至8位,然后執(zhí)行按位與運算,根據(jù)圖2,運算結(jié)果仍然是8位,最后將8位結(jié)果賦值給左端的c;過程如下面所示。
例3
reg [5 : 0] a = 6'b010101;
reg [3 : 0] b = 4'b1111;
reg [7 : 0] c;
c = a & (& b);
????????在例3中,只有最后一步是有變化的,按位與操作符&的右操作數(shù)被換成了一個縮減運算子表達(dá)式,如果子表達(dá)式仍然是上下文決定表達(dá)式,那這和上面的兩個例子沒有任何差別,即a,b,c都會被加入上下文環(huán)境,只不過是嵌套的計數(shù)不同。但我們從圖1,圖2都可以注意到,縮減運算符的操作數(shù)是自決定的!這時的運算規(guī)則就有變化,自決定運算符中的變量不會被加入上下文環(huán)境,即b不會被加入上下文環(huán)境,而是由自己決定,即b的位寬就是6位,但(&b)作為一整體成為按位與操作符&的右操作數(shù),它的結(jié)果的位寬還是會被加入上下文環(huán)境(a,c沒有這種問題,像上面兩例一樣被加入上下文環(huán)境)。根據(jù)上面的規(guī)則,我們知道縮減運算的結(jié)果是1位,小于c的8位,所以此時最大位寬依然是8位。所以(&b)的結(jié)果和a都會被補零拓展至8位,然后按位與,得到結(jié)果是8位,最后賦值給c。過程如下面所示。
例4
? ? reg [15 : 0] a, b, answer;
answer = (a + b) >> 1;
????????如果你搞明白了上面三個例子,那么例4你就能自己解決。在看答案前,先自己按照規(guī)則嘗試著想出表達(dá)式的運算過程。
答案:
????????這里涉及到了一個混合運算符——右移>>,由規(guī)則我們可以知道,此運算符的左邊即被移操作數(shù)為上下文決定,右邊即移位量為自決定。我們可以首先找到被加入上下文環(huán)境的操作數(shù),a和b作為+操作符的操作數(shù),是上下文決定的,(a+b)作為整體位與移位操作符的左邊也是上下文決定的,(a+b)>>1作為整體是=操作符的右操作數(shù),也是上下文決定的,因此answer(因為=),a,b(因為三層上下文嵌套)都被加入上下文環(huán)境中,這三個變量的位寬都是一樣的,所以他們?nèi)齻€在運算前不會有拓展。因此首先執(zhí)行a+b,根據(jù)規(guī)則,結(jié)果為16位,進(jìn)位被丟失,然后再右移一位,最高位補0,最后賦值給同為16位的answer。這里的1(不加基數(shù),位寬的常數(shù))默認(rèn)是32位,且為自決定。
如果想要進(jìn)位不被丟失應(yīng)該怎么樣?你可以先自己想一想,方法有很多。
-
把a+b;改成a+b+0;因為0(32位)此時和a,b一樣被加入了上下文環(huán)境,所以此時最大位寬為32,所以a,b都會被補零拓展到32位,所以進(jìn)位得以保留,兩次加法結(jié)果任然是32位,移位后結(jié)果任然是32位,最后將32位值賦值給16位的answer,高位被截斷。
-
把a+b;改成a+b+17'b0;原因同上,此時a,b被補零拓展至17位,所以相加后能保留進(jìn)位。
-
把reg [15:0]answer;改為reg [16:0]answer;原因也是類似的,=左端的answer被添加到上下文環(huán)境后,最大位寬變?yōu)?7,此時a,b被補零拓展至17位,所以相加后能保留進(jìn)位。
例5
reg [3 : 0] a, b, c;
reg [4 : 0] d;
initial begin
a = 9;
b = 8;
c = 1;
$display("answer = %b", c ? (a & b) : d);
end
????????運行結(jié)果是什么,為什么是這樣?(注意,這里的表達(dá)式?jīng)]有了賦值運算符,這是與之前的例子最大的區(qū)別)
? ? ? ? 答案:運行結(jié)果為answer = 01000。
????????從規(guī)則中我們知道,三目運算符的第一個操作符(條件項)是自決定的,而第二和第三操作符是上下文環(huán)境決定,而在這里第二操作符又是一個以上下文決定子表達(dá)式,根據(jù)上下文嵌套的規(guī)則,a,b和d都被加入上下文環(huán)境,最大位寬為5,c不會加入上下文環(huán)境,也不會受上下文環(huán)境影響。所以a,b被補零拓展為5位,然后執(zhí)行與運算得到5位結(jié)果01000,然后根據(jù)c等于1,最后表達(dá)式的結(jié)果為01000(三目運算符結(jié)果的位寬為第二和第三操作數(shù)中最大的那個,在此例中都為5)。
例6
reg [3 : 0] a;
reg [5 : 0] b;
reg [15 : 0]c;
initial begin
a = 4'hF;
b = 6'hA;
$display("a * b = %h", a * b);
c = {a ** b};
$display("a ** b = %h", c);
c = a ** b;
$display("c = %h", c);
end
運行結(jié)果如下所示:
a * b = 16
a ** b = 1
c = ac61
解析:在第一個系統(tǒng)函數(shù)中,只有一個簡單的乘式,又因為*兩邊的操作數(shù)是上下文決定的,將a和b加入上下文環(huán)境中,最大的位寬為6位,所以a首先被補零拓展到6位,然后和b相乘,結(jié)果根據(jù)規(guī)則,也是6位,假設(shè)位寬無限,那么結(jié)果為96h也就是10010110b,但是因為結(jié)果只取低六位即010110,所以以16進(jìn)制展現(xiàn)出來就是16。
????????第二個系統(tǒng)函數(shù)用來展示c,c在之前被賦值,c = {a ** b};我們發(fā)現(xiàn)a**b居然被放在了拼接運算符里面,這看上去拼接沒有什么影響,如果你是這么覺得,你就會得到意想不到的答案。我們一步一步來,**乘方運算符的第一個操作數(shù)(底數(shù))是上下文決定的,而第二個操作數(shù)(指數(shù))是自決定的,按理說a應(yīng)該被加入上下文環(huán)境,但在這里a**b作為自決定表達(dá)式拼接運算符{}的子表達(dá)式,所以a與b會被強制轉(zhuǎn)換為自決定,所以在這里,意思就是上下文的嵌套不能穿過自決定表達(dá)式,在這里只有{a ** b}會作為=運算符的右操作數(shù)和c被加入上下文環(huán)境(就像例3一樣),所以直接按原本的位寬計算a**b,按照規(guī)則,乘方運算結(jié)果的位寬與底數(shù)位寬相同,所以結(jié)果為4位,即取二進(jìn)制數(shù)1000011001000011000010101010110001100001的低4位,也就是0001,上下文環(huán)境中最大位寬為16位,所以0001被補零拓展至0000000000000001,最后賦值給c。
????????最后一個系統(tǒng)函數(shù),展示的是沒有拼接運算符{}的賦值結(jié)果,此時上下文關(guān)系得以傳遞,a和c都被加入上下文環(huán)境,a首先被拓展至16位,然后執(zhí)行乘方,乘方運算結(jié)果的位寬與底數(shù)位寬相同,所以結(jié)果為16位,即取二進(jìn)制數(shù)1000011001000011000010101010110001100001的低16位,也就是ac61h。
????????相信通過以上幾個例子,你已經(jīng)可以自己解決關(guān)于表達(dá)式運算過程中的位寬問題了,但還有一個問題,為什么這里面遇到的都是補零拓展呢,什么時候會遇到符號拓展呢?但這又成為了一個新的專題,感興趣的讀者可以參看下面的文章。文章來源:http://www.zghlxwxcb.cn/news/detail-416957.html
Verilog基礎(chǔ):表達(dá)式符號的確定_日晨難再的博客-CSDN博客如果所有操作數(shù)有符號,結(jié)果才是有符號的。有兩個系統(tǒng)函數(shù)就是為了調(diào)整表達(dá)式符號,分別是$signed和$unsigned,它們的返回值就是被轉(zhuǎn)換符號后的數(shù)值。否則必須在基數(shù)前聲明s標(biāo)志才表示這個常數(shù)為有符號的,如3'd4是無符號數(shù),3'sd4是有符號數(shù)。拼接操作符的結(jié)果是無符號的,不管操作數(shù)是否有符號,即使是只有一個有符號操作數(shù)也是如此。域選的結(jié)果是無符號數(shù),不管域選操作數(shù)是否有符號,即使域選的結(jié)果是整個向量。比較操作符的結(jié)果是無符號的,不管操作數(shù)是否有符號。位選的結(jié)果是無符號數(shù),不管位選操作數(shù)是否有符號。https://blog.csdn.net/weixin_45791458/article/details/128840843?spm=1001.2014.3001.5502文章來源地址http://www.zghlxwxcb.cn/news/detail-416957.html
到了這里,關(guān)于Verilog基礎(chǔ):表達(dá)式位寬的確定(位寬拓展)的文章就介紹完了。如果您還想了解更多內(nèi)容,請在右上角搜索TOY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!