zoukankan      html  css  js  c++  java
  • 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; 红色的都是缩减运算符

    **

    幂运算符

    *, /, %

    + -

    二元

    加减运算

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

    < , <=, > , >=

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

    &

    二元

    ^, ^~, ~^

    二元

    异或和同或

    |

    二元

    &&

    ||

    ?:

    条件运算

  • 相关阅读:
    iOS 项目中的NSNotification简单使用
    IOS开发之格式化日期时间的使用 && 编程中常见问题
    linker command failed with exit code 1 (use -v to see invocation),经典Xcode编译错误的出现和解决!
    CocoaPods安装和使用教程
    机器学习算法--贝叶斯分类器(二)
    机器学习算法--贝叶斯分类器(一)
    Linux系统初始化过程及运行级别简介
    Linux基本符号
    索引节点inode详解
    Linux文件类型介绍
  • 原文地址:https://www.cnblogs.com/mikewolf2002/p/10183351.html
Copyright © 2011-2022 走看看