Verilog語法之四:運算子
本文首發於微信公眾號“花螞蟻”,想要學習FPGA及Verilog的同學可以關注一下。
Verilog HDL語言的運算子範圍很廣,其運算子按其功能可分為以下幾類:
1) 算術運算子(+,-,×,/,%)
2) 賦值運算子(=,<=)
3) 關係運算符(>,<,>=,<=)
4) 邏輯運算子(&&,||,!)
5) 條件運算子(?:)
6) 位運算子(~,|,^,&,^~)
7) 移位運算子(<<,>>)
8) 拼接運算子({ })
9) 其它
在Verilog HDL語言中運算子所帶的運算元是不同的,按其所帶運算元的個數運算子可分為三種:
1)單目運算子(unary operator):可以帶一個運算元,運算元放在運算子的右邊。
2)二目運算子(binary operator):可以帶二個運算元,運算元放在運算子的兩邊。
3)三目運算子(ternary operator):可以帶三個操作,這三個運算元用三目運算子分隔開。
見下例:
clock = ~clock; // ~是一個單目取反運算子, clock是運算元。
c = a | b; // 是一個二目按位或運算子, a 和 b是運算元。
r = s ? t : u; // ?: 是一個三目條件運算子, s,t,u是運算元。
下面對常用的幾種運算子進行介紹。
1.算術運算子
在Verilog HDL語言中,算術運算子又稱為二進位制運算子,共有下面幾種:
1) + (加法運算子,或正值運算子,如 rega+regb,+3)
2) - (減法運算子,或負值運算子,如 rega-3,-3)
3) × (乘法運算子,如rega*3)
4) / (除法運算子,如5/3)
5) % (模運算子,或稱為求餘運算子,要求%兩側均為整型資料。如7%3的值為1)
在進行整數除法運算時,結果值要略去小數部分,只取整數部分。而進行取模運算時,結果值的符號位採用模運算式裡第一個運算元的符號位。見下例。
模運算表示式 結果 說明 10%3 1 餘數為1 11%3 2 餘數為2 12%3 0 餘數為0即無餘數 -10%3 -1 結果取第一個運算元的符號位,所以餘數為-1 11%3 2 結果取第一個運算元的符號位,所以餘數為2.
注意:在進行算術運算操作時,如果某一個運算元有不確定的值x,則整個結果也為不定值x。
2.位運算子
Verilog HDL作為一種硬體描述語言,是針對硬體電路而言的。在硬體電路中訊號有四種狀態值1,0,x,z.在電路中訊號進行與或非時,反映在Verilog HDL中則是相應的運算元的位運算。Verilog HDL提供了以下五種位運算子:
1) ~ //取反
2) & //按位與
3) | //按位或
4) ^ //按位異或
5) ^~ //按位同或(異或非)
說明:
- 位運算子中除了~是單目運算子以外,均為二目運算子,即要求運算子兩側各有一個運算元.
- 位運算子中的二目運算子要求對兩個運算元的相應位進行運算操作。
下面對各運算子分別進行介紹:
1)"取反"運算子~
~是一個單目運算子,用來對一個運算元進行按位取反運算。
其運算規則見下表:
舉例說明:
rega='b1010;//rega的初值為'b1010
rega=~rega;//rega的值進行取反運算後變為'b0101
2)"按位與"運算子&
按位與運算就是將兩個運算元的相應位進行與運算,
其運算規則見下表:
3)"按位或"運算子|
按位或運算就是將兩個運算元的相應位進行或運算。
其運算規則見下表:
4)"按位異或"運算子^(也稱之為XOR運算子)
按位異或運算就是將兩個運算元的相應位進行異或運算。
其運算規則見下表:
5)"按位同或"運算子^~
按位同或運算就是將兩個運算元的相應位先進行異或運算再進行非運算.
其運算規則見下表:
6)不同長度的資料進行位運算
兩個長度不同的資料進行位運算時,系統會自動的將兩者按右端對齊.位數少的運算元會在相應的高位用0填滿,以使兩個運算元按位進行操作.
3邏輯運算子
在Verilog HDL語言中存在三種邏輯運算子:
1) && 邏輯與
2) || 邏輯或
3) ! 邏輯非
"&&"和"||"是二目運算子,它要求有兩個運算元,如(a>b)&&(b>c),(a<b)||(b<c)。
"!"是單目運算子,只要求一個運算元,如!(a>b)。
下表為邏輯運算的真值表。它表示當a和b的值為不同的組合時,各種邏輯運算所得到的值。
邏輯運算子中"&&"和"||"的優先級別低於關係運算符,"!" 高於算術運算子。見下例:
- (a>b)&&(x>y) 可寫成: a>b && x>y
- (a==b)||(x==y) 可寫成:a==b || x==y
- (!a)||(a>b) 可寫成: !a || a>b
為了提高程式的可讀性,明確表達各運算子間的優先關係,建議使用括號.
4.關係運算符
關係運算符共有以下四種:
a < b a小於b
a > b a大於b
a <= b a小於或等於b
a >= b a大於或等於b
在進行關係運算時,如果宣告的關係是假的(flase),則返回值是0,如果宣告的關係是真的(true),則返回值是1,如果某個運算元的值不定,則關係是模糊的,返回值是不定值。
所有的關係運算符有著相同的優先級別。關係運算符的優先級別低於算術運算子的優先級別。見下例:
a < size-1 //這種表達方式等同於下面
a < (size-1) //這種表達方式。
size - ( 1 < a ) //這種表達方式不等同於下面
size - 1 < a //這種表達方式。
從上面的例子可以看出這兩種不同運算子的優先級別。當表示式size-(1<a)進行運算時,關係表示式先被運算,然後返回結果值0或1被size減去。而當表示式 size-1<a 進行運算時,size先被減去1,然後再同a相比。
5.等式運算子
在Verilog HDL語言中存在四種等式運算子:
1) == (等於)
2) != (不等於)
3) === (等於)
4) !== (不等於)
這四個運算子都是二目運算子,它要求有兩個運算元。"=="和"!="又稱為邏輯等式運算子。其結果由兩個運算元的值決定。由於運算元中某些位可能是不定值x和高阻值z,結果可能為不定值x。
而"==="和"!=="運算子則不同,它在對運算元進行比較時對某些位的不定值x和高阻值z也進行比較,兩個運算元必需完全一致,其結果才是1,否則為0。"==="和"!=="運算子常用於case表示式的判別,所以又稱為"case等式運算子"。這四個等式運算子的優先級別是相同的。下面畫出==與===的真值表,幫助理解兩者間的區別。
下面舉一個例子說明“==”和“===”的區別。
例:
if(A==1’bx) $display(“AisX”); (當A等於X時,這個語句不執行)
if(A===1’bx) $display(“AisX”); (當A等於X時,這個語句執行)
6.移位運算子
在Verilog HDL中有兩種移位運算子:
<< (左移位運算子) 和 >>(右移位運算子)。
其使用方法如下:
a >> n;//a右移n位
a << n;//a左移n位
a代表要進行移位的運算元,n代表要移幾位。這兩種移位運算都用0來填補移出的空位。下面舉例說明:
module shift;
reg [3:0] start, result;
initial
begin
start = 1; //start在初始時刻設為值0001
result = (start<<2);
//移位後,start的值0100,然後賦給result。
end
endmodule
從上面的例子可以看出,start在移過兩位以後,用0來填補空出的位。
進行移位運算時應注意移位前後變數的位數,下面將給出一例。
例:
4’b1001<<1 = 5’b10010;
4’b1001<<2 = 6’b100100;
1<<6 = 32’b1000000;
4’b1001>>1 = 4’b0100;
4’b1001>>4 = 4’b0000;
7.位拼接運算子(Concatation)
在Verilog HDL語言有一個特殊的運算子:位拼接運算子{}。用這個運算子可以把兩個或多個訊號的某些位拼接起來進行運算操作。其使用方法如下:
{訊號1的某幾位,訊號2的某幾位,..,..,訊號n的某幾位}
即把某些訊號的某些位詳細地列出來,中間用逗號分開,最後用大括號括起來表示一個整體訊號。見下例:
{a,b[3:0],w,3’b101}
也可以寫成為
{a,b[3],b[2],b[1],b[0],w,1’b1,1’b0,1’b1}
在位拼接表示式中不允許存在沒有指明位數的訊號。這是因為在計算拼接訊號的位寬的大小時必需知道其中每個訊號的位寬。
位拼接還可以用重複法來簡化表示式。見下例:
{4{w}} //這等同於{w,w,w,w}
位拼接還可以用巢狀的方式來表達。見下例:
{b,{3{a,b}}} //這等同於{b,a,b,a,b,a,b}
用於表示重複的表示式如上例中的4和3,必須是常數表示式。
8.縮減運算子(reduction operator)
縮減運算子是單目運算子,也有與或非運算。
其與或非運算規則類似於位運算子的與或非運算規則,但其運算過程不同。位運算是對運算元的相應位進行與或非運算,運算元是幾位數則運算結果也是幾位數。
而縮減運算則不同,縮減運算是對單個運算元進行或與非遞推運算,最後的運算結果是一位的二進位制數。
縮減運算的具體運算過程是這樣的:第一步先將運算元的第一位與第二位進行或與非運算,第二步將運算結果與第三位進行或與非運算,依次類推,直至最後一位。
例如:
reg [3:0] B;
reg C;
C = &B;
相當於:
C =( (B[0]&B[1]) & B[2] ) & B[3];
由於縮減運算的與、或、非運算規則類似於位運算子與、或、非運算規則,這裡不再詳細講述,請參照位運算子的運算規則介紹。
9.優先級別
下面對各種運算子的優先級別關係作一總結。見下表:
優先順序不用記,原因:
1.極少在一條語句裡用多個操作符,如果用了,說明你的邏輯寫的不好
2.如果有,加括號更保險
本文首發於微信公眾號“花螞蟻”,想要學習FPGA及Verilog的同學可以關注一下。