Verilog語言表達式基本使用
表達式
表達式由操作符和操作數(shù)構成,其目的是根據(jù)操作符的意義得到一個計算結果。表達式可以在出現(xiàn)數(shù)值的任何地方使用。例如:
a^b ; //a與b進行異或操作 address[9:0] + 10'b1 ; //地址累加 flag1 && flag2 ; //邏輯與操作
操作數(shù)
操作數(shù)可以是任意的數(shù)據(jù)類型,只是某些特定的語法結構要求使用特定類型的操作數(shù)。
操作數(shù)可以為常數(shù),整數(shù),實數(shù),線網,寄存器,時間,位選,域選,存儲器及函數(shù)調用等。
module test; //實數(shù) real a, b, c; c = a + b ; //寄存器 reg [3:0] cprmu_1, cprmu_2 ; always @(posedge clk) begin cprmu_2 = cprmu_1 ^ cprmu_2 ; end //函數(shù) reg flag1 ; flag = calculate_result(A, B); //非法操作數(shù) reg [3:0] res; wire [3:0] temp; always@ (*)begin res = cprmu_2 – cprmu_1 ; //temp = cprmu_2 – cprmu_1 ; //不合法,always塊里賦值對象不能是wire型 end endmodule
操作符
Verilog 中提供了大約 9 種操作符,分別是算術、關系、等價、邏輯、按位、歸約、移位、拼接、條件操作符。
大部分操作符與 C 語言中類似。同類型操作符之間,除條件操作符從右往左關聯(lián),其余操作符都是自左向右關聯(lián)。圓括號內表達式優(yōu)先執(zhí)行。例如下面每組的 2 種寫法都是等價的。
//自右向左關聯(lián),兩種寫法等價 A+B-C ; (A+B)-C ; //自右向左關聯(lián),兩種寫法等價,結果為 B、D 或 F A ? B : C ? D : F ; A ? B : (C ? D : F) ; //自右向左關聯(lián),兩種寫法不等價 (A ? B : C) ? D : F ; //結果 D 或 F A ? B : C ? D : F ; //結果為 B、D 或 F
不同操作符之間,優(yōu)先級是不同的。下表列出了操作符優(yōu)先級從高至低的排列順序。當沒有圓括號時,Verilog 會根據(jù)操作符優(yōu)先級對表達式進行計算。為了避免由操作符優(yōu)先級導致的計算混亂,在不確定優(yōu)先級時,建議用圓括號將表達式區(qū)分開來。
算術操作符
算術操作符包括單目操作符和雙目操作符。
雙目操作符對 2 個操作數(shù)進行算術運算,包括乘(*)、除(/)、加(+)、減(-)、求冪(**)、取模(%)。
reg [3:0] a, b; reg [4:0] c ; a = 4'b0010 ; b = 4'b1001 ; c = a+b; //結果為c=b'b1011 c = a/b; //結果為c=4,取整
如果操作數(shù)某一位為 X,則計算結果也會全部出現(xiàn) X。例如:
b = 4'b100x ; c = a+b ; //結果為c=4'bxxxx
對變量進行聲明時,要根據(jù)變量的操作符對變量的位寬進行合理聲明,不要讓結果溢出。上述例子中,相加的 2 個變量位寬為 4bit,那么結果寄存器變量位寬最少為 5bit。否則,高位將被截斷,導致結果高位丟失。無符號數(shù)乘法時,結果變量位寬應該為 2 個操作數(shù)位寬之和。
reg [3:0] mula ; reg [1:0] mulb; reg [5:0] res ; mula = 4'he ; mulb = 2'h3 ; res = mula * mulb ; //結果為res=6'h2a, 數(shù)據(jù)結果沒有丟失位數(shù)
- 和 - 也可以作為單目操作符來使用,表示操作數(shù)的正負性。此類操作符優(yōu)先級最高。
-4 //表示負4 +3 //表示正3
負數(shù)表示時,可以直接在十進制數(shù)字前面增加一個減號 -,也可以指定位寬。因為負數(shù)使用二進制補碼來表示,不指定位寬來表示負數(shù),編譯器在轉換時,會自動分配位寬,從而導致意想不到的結果。例如:
mula = -4'd4 ; mulb = 2 ; res = mula * mulb ; //計算結果為res=-6'd8, 即res=6'h38,正常 res = mula * (-'d4) ; //(4的32次冪-4) * 2, 結果異常
關系操作符
關系操作符有大于(>),小于(<),大于等于(>=),小于等于(<=)。
關系操作符的正常結果有 2 種,真(1)或假(0)。
如果操作數(shù)中有一位為 x 或 z,則關系表達式的結果為 x。
A = 4 ; B = 3 ; X = 3'b1xx ; A > B //為真 A <= B //為假 A >= Z //為X,不確定
等價操作符
等價操作符包括邏輯相等(==),邏輯不等(!=),全等(===),非全等(!==) 。
等價操作符的正常結果有 2 種:為真(1)或假(0)。
邏輯相等/不等操作符不能比較 x 或 z,當操作數(shù)包含一個 x 或 z,則結果為不確定值。
全等比較時,如果按位比較有相同的 x 或 z,返回結果也可以為 1,即全等比較可比較 x 或 z。所以,全等比較的結果一定不包含 x。舉例如下:
A = 4 ; B = 8'h04 ; C = 4'bxxxx ; D = 4'hx ; A == B //為真 A == (B + 1) //為假 A == C //為X,不確定 A === C //為假,返回值為0 C === D //為真,返回值為1
邏輯操作符
邏輯操作符主要有 3 個:&&(邏輯與), ||(邏輯或),!(邏輯非)。
邏輯操作符的計算結果是一個 1bit 的值,0 表示假,1 表示真,x 表示不確定。
如果一個操作數(shù)不為 0,它等價于邏輯 1;如果一個操作數(shù)等于 0,它等價于邏輯 0。如果它任意一位為 x 或 z,它等價于 x。
如果任意一個操作數(shù)包含 x,邏輯操作符運算結果不一定為 x。
邏輯操作符的操作數(shù)可以為變量,也可以為表達式。例如:
A = 3; B = 0; C = 2'b1x ; A && B // 為假 A || B // 為真 ! A // 為假 ! B // 為真 A && C // 為X,不確定 A || C // 為真,因為A為真 (A==2) && (! B) //為真,此時第一個操作數(shù)為表達式
按位操作符
按位操作符包括:取反(),與(&),或(|),異或(^),同或(^)。
按位操作符對 2 個操作數(shù)的每 1bit 數(shù)據(jù)進行按位操作。
如果 2 個操作數(shù)位寬不相等,則用 0 向左擴展補充較短的操作數(shù)。
取反操作符只有一個操作數(shù),它對操作數(shù)的每 1bit 數(shù)據(jù)進行取反操作。
下圖給出了按位操作符的邏輯規(guī)則。
A = 4'b0101 ; B = 4'b1001 ; C = 4'bx010 ; ~A //4'b1010 A & B //4'b0001 A | B //4'b1101 A^B //4'b1100 A ~^ B //4'b0011 B | C //4'b1011 B&C //4'bx000
歸約操作符
歸約操作符包括:歸約與(&),歸約與非(&),歸約或(|),歸約或非(|),歸約異或(^),歸約同或(~^)。
歸約操作符只有一個操作數(shù),它對這個向量操作數(shù)逐位進行操作,最終產生一個 1bit 結果。
邏輯操作符、按位操作符和歸約操作符都使用相同的符號表示,因此有時候容易混淆。區(qū)分這些操作符的關鍵是分清操作數(shù)的數(shù)目,和計算結果的規(guī)則。
A = 4'b1010 ; &A ; //結果為 1 & 0 & 1 & 0 = 1'b0,可用來判斷變量A是否全1 ~|A ; //結果為 ~(1 | 0 | 1 | 0) = 1'b0, 可用來判斷變量A是否為全0 ^A ; //結果為 1 ^ 0 ^ 1 ^ 0 = 1'b0
移位操作符
移位操作符包括左移(<<),右移(>>),算術左移(<<<),算術右移(>>>)。
移位操作符是雙目操作符,兩個操作數(shù)分別表示要進行移位的向量信號(操作符左側)與移動的位數(shù)(操作符右側)。
算術左移和邏輯左移時,右邊低位會補 0。
邏輯右移時,左邊高位會補 0;而算術右移時,左邊高位會補充符號位,以保證數(shù)據(jù)縮小后值的正確性。
A = 4'b1100 ; B = 4'b0010 ; A = A >> 2 ; //結果為 4'b0011 A = A << 1; //結果為 4'b1000 A = A <<< 1 ; //結果為 4'b1000 C = B + (A>>>2); //結果為 2 + (-4/4) = 1, 4'b0001
拼接操作符
拼接操作符用大括號 {,} 來表示,用于將多個操作數(shù)(向量)拼接成新的操作數(shù)(向量),信號間用逗號隔開。
拼接符操作數(shù)必須指定位寬,常數(shù)的話也需要指定位寬。例如:
A = 4'b1010 ; B = 1'b1 ; Y1 = {B, A[3:2], A[0], 4'h3 }; //結果為Y1='b1100_0011 Y2 = {4{B}, 3'd4}; //結果為 Y2=7'b111_1100 Y3 = {32{1'b0}}; //結果為 Y3=32h0,常用作寄存器初始化時匹配位寬的賦初值
條件操作符
條件表達式有 3 個操作符,結構描述如下:
condition_expression ? true_expression : false_expression
計算時,如果 condition_expression 為真(邏輯值為 1),則運算結果為 true_expression;如果 condition_expression 為假(邏輯值為 0),則計算結果為 false_expression。
assign hsel = (addr[9:8] == 2'b0) ? hsel_p1 : hsel_p2 ; //當信號 addr 高 2bit 為 0 時,hsel 賦值為 hsel_p1; 否則,將 hsel_p2 賦值給 hsel。
其實,條件表達式類似于 2 路(或多路)選擇器,其描述方式完全可以用 if-else 語句代替。
當然條件操作符也能進行嵌套,完成一個多次選擇的邏輯。例如:
assign hsel = (addr[9:8] == 2'b00) ? hsel_p1 : (addr[9:8] == 2'b01) ? hsel_p2 : (addr[9:8] == 2'b10) ? hsel_p3 : (addr[9:8] == 2'b11) ? hsel_p4 ;
以上就是Verilog語言表達式基本使用的詳細內容,更多關于Verilog語言表達式的資料請關注腳本之家其它相關文章!
相關文章
linux Shell學習筆記最后一節(jié),溫故與知新
linux Shell學習筆記最后一節(jié),這節(jié)是對前面章節(jié)的小結,學習shell編程的朋友可以參考下。2010-12-12