verilog語法實例學習(3)


Verilog 操作運算符

算術運算符

+,-,*,/,**(加/減/乘/除/冪運算),乘法運算的結果的位寬是乘數和被乘數位寬的和。

在進行整數的除法運算時,結果要略去小數部分,只取整數部分;而進行取模運算時(%,亦稱作求余運算符)結果的符號位采用模運算符中第一個操作數的符號。

-10%3 =-1 11%-3 結果為2

注意:在進行算術運算時,如果某一個操作數有不確定的值x,則整個結果也為不確定值x。下面的代碼演示了算術運算符的操作,其結果為:

如果不指定reg signed類型,負數的運算會被當作無符號數運算,從而得到錯誤的結果

Compiler version M-2017.03-SP2-11; Runtime version M-2017.03-SP2-11;  Dec 28 09:33 2018
          32 +          15 =          47
          32 -          15 =          17
          15 -          32 =         -17
          32 *          15 =         480
          32 *         -32 =       -1024
          32 /          15 =           2
         -32 mod          15 =          -2
          32 mod          -3 =           2
           3 **           2 =           9
         32 +         15 =         47
         32 -         15 =         17
         15 -         32 = 4294967279
         32 *         15 =        480
         32 * 4294967264 = 4294966272
         32 /         15 =          2
4294967264 mod         15 =         14
         32 mod 4294967293 =         32
          3 **          2 =          9

            V C S   S i m u l a t i o n   R e p o r t


`timescale 1ns/1ns

module operator;

  reg signed [31:0] a = 32;
  reg signed [31:0] b = 15;
  reg signed [31:0] c = -32;
  reg signed [31:0] d = -3;
  reg signed [31:0] e = 3;
  reg signed [31:0] f = 2;
  reg signed [31:0] r = 1;
  reg  [31:0] a1 = 32;
  reg  [31:0] b1 = 15;
  reg  [31:0] c1 = -32;
  reg  [31:0] d1 = -3;
  reg  [31:0] e1 = 3;
  reg  [31:0] f1 = 2;
  reg  [31:0] r1 = 1;
  initial begin
          r = a + b;
	  $display("%d + %d = %d",a, b, r);
          r = a - b;
	  $display("%d - %d = %d",a, b, r);
          r = b - a;
	  $display("%d - %d = %d",b, a, r);
          r = a * b;
	  $display("%d * %d = %d",a, b, r);
          r = a * c;
	  $display("%d * %d = %d",a, c, r);
          r = a / b;
	  $display("%d / %d = %d",a, b, r);
          r = c % b;
	  $display("%d mod %d = %d",c, b, r);
          r = a % d;
	  $display("%d mod %d = %d",a, d, r);
          r = e ** f;
	  $display("%d ** %d = %d",e, f, r);

          r1 = a1 + b1;
	  $display("%d + %d = %d",a1, b1, r1);
          r1 = a1 - b1;
	  $display("%d - %d = %d",a1, b1, r1);
          r1 = b1 - a1;
	  $display("%d - %d = %d",b1, a1, r1);
          r1 = a1 * b1;
	  $display("%d * %d = %d",a1, b1, r1);
          r1 = a1 * c1;
	  $display("%d * %d = %d",a1, c1, r1);
          r1 = a1 / b1;
	  $display("%d / %d = %d",a1, b1, r1);
          r1 = c1 % b1;
	  $display("%d mod %d = %d",c1, b1, r1);
          r1 = a1 % d1;
	  $display("%d mod %d = %d",a1, d1, r1);
          r1 = e1 ** f1;
	  $display("%d ** %d = %d",e1, f1, r1);
  end

endmodule


位運算符

按位取反~ 、按位與 & 、按位或 | 、按位異或 ^ 、按位同或 ^~(~^),在不同長度的數據進行位運算時,系統會自動的將兩個數右端對齊,位數少的操作數會在相應的高位補0。

下面位運算符的代碼例子:

Compiler version M-2017.03-SP2-11; Runtime version M-2017.03-SP2-11;  Dec 28 10:00 2018
0101010110101010 & 11111111 = 0000000010101010
0101010110101010 | 11111111 = 0101010111111111
~0101010110101010  1010101001010101
0101010110101010 ^ 11111111 = 0101010101010101
0101010110101010 ~^ 11111111 = 1010101010101010
0101010110101010 ^~ 11111111 = 1010101010101010
            V C S   S i m u l a t i o n   R e p o r t

`timescale 1ns/1ns

module operator;

  reg  [15:0] a = 16'b0101010110101010;
  reg  [7:0] b = 8'hff;
  reg  [15:0] r = 1;
  initial begin
          r = a & b;
	  $display("%b & %b = %b",a, b, r);
          r = a | b;
	  $display("%b | %b = %b",a, b, r);
          r = ~a ;
	  $display("~%b  %b", a, r);
          r = a ^ b;
	  $display("%b ^ %b = %b",a, b, r);
          r = a ~^ b;
	  $display("%b ~^ %b = %b",a, b, r);
          r = a ^~ b;
	  $display("%b ^~ %b = %b",a, b, r);

  end

endmodule


邏輯運算符

邏輯運算符用來連接條件表達式,它的返回值是1位的。邏輯運算符包括邏輯與 &&、邏輯或 ||、邏輯非 !,其中&&和||是雙目運算符,其優先級別低於關系運算符,而 !高於算術運算符。

關系運算符

< 、 > 、 <= 、 >= 如果關系運算是假的,則返回值是0,如果聲明的關系是真的,則返回值是1。 關系運算符的優先級別低於算數運算符。關系運算返回值也是1位的

邏輯運算符,關系運算符,包括下面的等式運算符,通常都是用來作條件判斷的,比如if語句的判斷條件。

下面的代碼演示了這三種運算的結果:

Compiler version M-2017.03-SP2-11; Runtime version M-2017.03-SP2-11;  Dec 28 12:42 2018
(0 && 1) = 0
(0 || 1) = 1
(!0) = 1
(00010100 >= 01011010) = 0
(00010100 < 01011010) = 1
(00010100 == 01011010) = 0
(0 == x) = x
(0 === x) = 0

$finish called from file "operator2.v", line 35.

`timescale 1ns/1ns

module operator;

  reg   a = 1'b0;
  reg   b = 1'b1;
  reg   r = 1'b1;
  reg  [7:0] c = 8'd20;
  reg  [7:0] d = 8'd90;
  initial begin
          r = (a && b);
	  $display("(%b && %b) = %b",a, b, r);
	  #10
          r = (a || b);
	  $display("(%b || %b) = %b",a, b, r);
	  #10
          r = !a;
	  $display("(!%b) = %b",a, r);
	  #10
          r = (c>=d);
	  $display("(%b >= %b) = %b",c, d, r);
	  #10
          r = (c<d);
	  $display("(%b < %b) = %b",c, d, r);
	  #10
          r = (c==d);
	  $display("(%b == %b) = %b",c, d, r);
	  #10
          r = (a==1'bx);
	  $display("(%b == x) = %b",a, r);
	  #10
          r = (a===1'bx);
	  $display("(%b === x) = %b",a, r);
	  #10
          $finish;
  end

endmodule


等式運算符

== 、!= 、===、!== 符號之間不能有空格。

“==”和“!=”稱作邏輯等式運算符,其結果由兩個操作數的值決定。由於操作數可能是x或z,其結果可能為x;

“===”和“!==”常用於case表達式的判別,又稱作case等式運算符。其結果只為0和1,如果操作數中存在x和z,那么操作數必須完全相同結果才為1,否則為0

邏輯等式運算符和case等式運算符的區別

===

0

1

x

z

==

0

1

x

z

0

1

0

0

0

0

1

0

x

x

1

0

1

0

0

1

0

1

x

x

x

0

0

1

0

x

x

x

x

x

z

0

0

0

1

z

x

x

x

x

移位運算符

邏輯移位運算符:<< 、 >> , a>>n其中a代表要進行移位的操作數,n代表要移幾位。這兩種移位運算都用0來填補移出的空位。算術移位運算符:<<<, >>>, <<<右邊補0,>>>左邊補MSB(最高有效位,僅對有符號數),若MSB是x或z,則填x。


Compiler version M-2017.03-SP2-11; Runtime version M-2017.03-SP2-11;  Dec 28 13:17 2018
(10101001011100000001001000110100>>1) = 01010100101110000000100100011010
(10101001011100000001001000110100>>1) = 01010010111000000010010001101000
(10101001011100000001001000110100>>>1) = 01010100101110000000100100011010
(10101001011100000001001000110100<<<1) = 01010010111000000010010001101000
(10101001011100000001001000110100>>>5) = 11111101010010111000000010010001
(10101001011100000001001000110100>>5) = 00000101010010111000000010010001
$finish called from file "operator3.v", line 26.

`timescale 1ns/1ns

module operator;

  reg [31:0]  a = 32'ha9701234;
  reg signed [31:0]  b = 32'ha9701234;
  reg [31:0]  r = 32'b1;
  initial begin
          r = (a >> 1);
	  $display("(%b>>1) = %b",a, r);
	  #10
          r = (a << 1);
	  $display("(%b>>1) = %b",a, r);
	  #10
          r = (a >>> 1);
	  $display("(%b>>>1) = %b",a, r);
	  #10
          r = (a <<< 1);
	  $display("(%b<<<1) = %b",a, r);
	  #10
          r = (b >>> 5);
	  $display("(%b>>>5) = %b",b, r);
	  #10
          r = (b >> 5);
	  $display("(%b>>5) = %b",b, r);
          $finish;
  end

endmodule

位拼接運算符

{信號1的某幾位,信號2的某幾位,......信號n的某幾位} 將某些信號的某些位列出來,中間用逗號分開,最后用大括號括起來表示一個整體的信號。

在位拼接的表達式中不允許存在沒有指明位數的信號。

{a,b[3:0],w,3'b101} //等同於  {a,b[3],b[2],b[1],b[0],w,1b'1,1'b0,1'b1}

{4{w}} //等同於{w,w,w,w}

{b,{3{a,b}}} //等同於{b,a,b,a,b,a,b} 這里面的3、4必須是常量表達式。

縮減運算符

這是單目運算符,也包括與、或、非運算。運算規則與位運算相似,不過是對單個運算符的每一位逐步運算,最后的運算結果是一位的二進制數。

c=&B; //意思同c=((B[0]&B[1]) &B[2] ) & B[3];

條件運算符

A?B:C, 如果表達式A為true(1),則結果為B,如果為false(0)結果為C。若A結果為模糊值(X或Z),則B,C都被執行,則是2驅動源,按下表輸出結果,如果B,C不同,或者B,C中有x,z,則輸出x。

?:

0

1

x

z

0

0

x

x

x

1

x

1

x

x

x

x

x

x

x

z

x

x

x

x


運算符的優先級


小括號優先級最高,在不清楚其它運算符優先級的情況下,可以加小括號來保證想要的表達式執行順序。條件運算符是從右向左關聯的,其它運算符都是從左向右關聯的。

Verilog中運算符優先級如下表

優先級

運算符

操作數

備注

+, -, !, ~,&,~&,|,~|,^,~^,^~

一元

b=-a,b=+a,b=!a,b=~a; 紅色的都是縮減運算符

**

冪運算符

*, /, %

+ -

二元

加減運算

<<, >> ,<<<, >>>

< , <=, > , >=

==, !=,===,!==

&

二元

^, ^~, ~^

二元

異或和同或

|

二元

&&

||

?:

條件運算


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM