ASIC-WORLD Verilog(6)运算符

 写在前面

        在自己准备写一些简单的verilog教程之前,参考了许多资料----asic-world网站的这套verilog教程即是其一。这套教程写得极好,奈何没有中文,在下只好斗胆翻译过来(加了自己的理解)分享给大家。

        这是网站原文:Verilog Tutorial

        这是系列导航:Verilog教程系列文章导航

算术运算符(Arithmetic Operators)         

  • 二元运算符:+、-、*、/、%(取模运算符)
  • 一元运算符:+、-(这个用来指定符号)
  • 整数除法截断任何小数部分
  • 模运算的结果符号取第一个操作数的符号
  • 如果任何操作数位值是未知值 x,则整个结果值是 x
  • 寄存器数据类型用作无符号值(负数以补码形式存储)

       

        这是一些算术运算的示例:

module arithmetic_operators();

initial begin
  $display (" 5  +  10 = %d", 5  + 10);
  $display (" 5  -  10 = %d", 5  - 10);
  $display (" 10 -  5  = %d", 10 - 5);
  $display (" 10 *  5  = %d", 10 * 5);
  $display (" 10 /  5  = %d", 10 / 5);
  $display (" 10 /  -5 = %d", 10 / -5);
  $display (" 10 %s  3  = %d","%", 10 % 3);
  $display (" +5       = %d", +5);
  $display (" -5       = %d", -5);
  #10 $finish;
end

endmodule

        

        这是仿真结果:

  5  +  10 =  15
  5  -  10 =  -5
  10 -  5  =   5
  10 *  5  =  50
  10 /  5  =  2
  10 /  -5 = -2
  10 %  3  =   1
  +5       =  5
  -5       =  -5

关系运算符(Relational Operators)

运算符

描述

a < b

a 小于 b

a > b

a 大于 b

a <= b

a 小于等于 b

a >= b

a 大于等于 b
  • 结果是一个标量值(例如 a < b)
  • 如果关系为假则结果为0(a 比 b 大)
  • 如果关系为真则结果为1(a 小于 b)
  • 如果任何操作数具有未知的 x 位则结果为x(如果 a 或 b 包含 X)

        注:如果任何操作数是 x 或 z,则该测试的结果将被视为假 (0)

        这是一些关系运算的示例:

module relational_operators();

initial begin
  $display (" 5     <=  10 = %b", (5     <= 10));
  $display (" 5     >=  10 = %b", (5     >= 10));
  $display (" 1'bx  <=  10 = %b", (1'bx  <= 10));
  $display (" 1'bz  <=  10 = %b", (1'bz  <= 10));  
  #10 $finish;
end

endmodule

        这是仿真结果:

  5     <=  10 = 1
  5     >=  10 = 0
  1'bx  <=  10 = x
  1'bz  <=  10 = x

相等运算符(Equality operators)

        有两种类型的相等运算符。

运算符

描述

a === b

a等于b, 包括 x 和 z

a !== b

a不等于b, 包括 x 和 z

a == b

a等于b, 结果可能是未知

a != b

a不等于b, 结果可能是未知
  • 操作数逐位比较,如果两个操作数的长度不相同,则补零
  • 结果为 0(假)或 1(真)
  • 对于 == 和 != 运算符,如果任一操作数包含 x 或 z,则结果为 x
  • 对于 === 和 !== 运算符,带有 x 和 z 的位包含在比较中并且必须匹配才能使结果为真

          注:结果始终为 0 或 1。

        这是一些相等运算的示例:

module equality_operators();

initial begin
  // Case Equality
  $display (" 4'bx001 ===  4'bx001 = %b", (4'bx001 ===  4'bx001));
  $display (" 4'bx0x1 ===  4'bx001 = %b", (4'bx0x1 ===  4'bx001));
  $display (" 4'bz0x1 ===  4'bz0x1 = %b", (4'bz0x1 ===  4'bz0x1));
  $display (" 4'bz0x1 ===  4'bz001 = %b", (4'bz0x1 ===  4'bz001));
  // Case Inequality
  $display (" 4'bx0x1 !==  4'bx001 = %b", (4'bx0x1 !==  4'bx001));
  $display (" 4'bz0x1 !==  4'bz001 = %b", (4'bz0x1 !==  4'bz001));  
  // Logical Equality
  $display (" 5       ==   10      = %b", (5       ==   10));
  $display (" 5       ==   5       = %b", (5       ==   5));
  // Logical Inequality
  $display (" 5       !=   5       = %b", (5       !=   5));
  $display (" 5       !=   6       = %b", (5       !=   6));
  #10 $finish;
end

endmodule

        

        这是仿真结果:

  4'bx001 ===  4'bx001 = 1
  4'bx0x1 ===  4'bx001 = 0
  4'bz0x1 ===  4'bz0x1 = 1
  4'bz0x1 ===  4'bz001 = 0
  4'bx0x1 !==  4'bx001 = 1
  4'bz0x1 !==  4'bz001 = 1
  5       ==   10      = 0
  5       ==   5       = 1
  5       !=   5       = 0
  5       !=   6       = 1

逻辑运算符(Logical Operators

运算符

描述

!

逻辑非

&&

逻辑与

||

逻辑或
  • && 和 || 连接的表达式 从左到右计算
  • 结果是一个标量值:
    • 如果关系为假则为 0;如果关系为真则为 1
    • 如果任何操作数有 x(未知)位则结果为x

        这是一些逻辑运算的示例:

module logical_operators();

initial begin
  // Logical AND
  $display ("1'b1 && 1'b1 = %b", (1'b1 && 1'b1));
  $display ("1'b1 && 1'b0 = %b", (1'b1 && 1'b0));
  $display ("1'b1 && 1'bx = %b", (1'b1 && 1'bx));
  // Logical OR
  $display ("1'b1 || 1'b0 = %b", (1'b1 || 1'b0));
  $display ("1'b0 || 1'b0 = %b", (1'b0 || 1'b0));
  $display ("1'b0 || 1'bx = %b", (1'b0 || 1'bx));
  // Logical Negation
  $display ("! 1'b1       = %b", (!  1'b1));
  $display ("! 1'b0       = %b", (!  1'b0));
  #10 $finish;
end

endmodule

        

        这是仿真结果:

 1'b1 && 1'b1 = 1
 1'b1 && 1'b0 = 0
 1'b1 && 1'bx = x
 1'b1 || 1'b0 = 1
 1'b0 || 1'b0 = 0
 1'b0 || 1'bx = x
 ! 1'b1       = 0
 ! 1'b0       = 1

按位运算符(Bit-wise Operators

        按位运算符对两个操作数执行按位运算。他们取一个操作数中的每一位,然后用另一个操作数中的相应位执行操作。如果一个操作数比另一个短,它将在左侧用零扩展以匹配较长操作数的长度。

运算符

描述

~

非        

&

|

或        

^

异或

^~ or ~^

同或

  • 计算包括未知位,方式如下:
    • ~x = x
    • 0 & x = 0
    • 1 & x = x & x = x
    • 1 | x = 1
    • 0 | x = x | x = x
    • 0 ^ x = 1 ^ x = x ^ x = x
    • 0 ^ ~x = 1 ^ ~x = x ^ ~x = x
  • 当操作数的位长度不相等时,较短的操作数将在最高有效位位置补零

        

        这是一些按位运算的示例:

module bitwise_operators();

initial begin
  // Bit Wise Negation
  $display (" ~4'b0001           = %b", (~4'b0001));
  $display (" ~4'bx001           = %b", (~4'bx001));
  $display (" ~4'bz001           = %b", (~4'bz001));
  // Bit Wise AND
  $display (" 4'b0001 &  4'b1001 = %b", (4'b0001 &  4'b1001));
  $display (" 4'b1001 &  4'bx001 = %b", (4'b1001 &  4'bx001));
  $display (" 4'b1001 &  4'bz001 = %b", (4'b1001 &  4'bz001));
  // Bit Wise OR
  $display (" 4'b0001 |  4'b1001 = %b", (4'b0001 |  4'b1001));
  $display (" 4'b0001 |  4'bx001 = %b", (4'b0001 |  4'bx001));
  $display (" 4'b0001 |  4'bz001 = %b", (4'b0001 |  4'bz001));
  // Bit Wise XOR
  $display (" 4'b0001 ^  4'b1001 = %b", (4'b0001 ^  4'b1001));
  $display (" 4'b0001 ^  4'bx001 = %b", (4'b0001 ^  4'bx001));
  $display (" 4'b0001 ^  4'bz001 = %b", (4'b0001 ^  4'bz001));
  // Bit Wise XNOR
  $display (" 4'b0001 ~^ 4'b1001 = %b", (4'b0001 ~^ 4'b1001));
  $display (" 4'b0001 ~^ 4'bx001 = %b", (4'b0001 ~^ 4'bx001));
  $display (" 4'b0001 ~^ 4'bz001 = %b", (4'b0001 ~^ 4'bz001));
  #10 $finish;
end

endmodule

        这是仿真结果:

  ~4'b0001           = 1110
  ~4'bx001           = x110
  ~4'bz001           = x110
  4'b0001 &  4'b1001 = 0001
  4'b1001 &  4'bx001 = x001
  4'b1001 &  4'bz001 = x001
  4'b0001 |  4'b1001 = 1001
  4'b0001 |  4'bx001 = x001
  4'b0001 |  4'bz001 = x001
  4'b0001 ^  4'b1001 = 1000
  4'b0001 ^  4'bx001 = x000
  4'b0001 ^  4'bz001 = x000
  4'b0001 ~^ 4'b1001 = 0111
  4'b0001 ~^ 4'bx001 = x111
  4'b0001 ~^ 4'bz001 = x111

规约运算符(Reduction Operators) 

运算符

描述

&

规约与

~&

规约与非

|

规约或

~|

规约或非

^

规约异或

^~ or ~^

规约同或
  • 归约运算符是一元的。
  • 它们对单个操作数执行按位运算以产生单个位结果。
  • 归约一元 NAND 和 NOR 运算符分别作为 AND 和 OR 运行,但它们的输出取反。
    • 如前所述处理未知位。

        这是一些规约运算的示例:

module reduction_operators();

initial begin
  // Bit Wise AND reduction
  $display (" &  4'b1001 = %b", (&  4'b1001));
  $display (" &  4'bx111 = %b", (&  4'bx111));
  $display (" &  4'bz111 = %b", (&  4'bz111));
  // Bit Wise NAND reduction
  $display (" ~& 4'b1001 = %b", (~& 4'b1001));
  $display (" ~& 4'bx001 = %b", (~& 4'bx001));
  $display (" ~& 4'bz001 = %b", (~& 4'bz001));
  // Bit Wise OR reduction
  $display (" |  4'b1001 = %b", (|  4'b1001));
  $display (" |  4'bx000 = %b", (|  4'bx000));
  $display (" |  4'bz000 = %b", (|  4'bz000));
  // Bit Wise OR reduction
  $display (" ~| 4'b1001 = %b", (~| 4'b1001));
  $display (" ~| 4'bx001 = %b", (~| 4'bx001));
  $display (" ~| 4'bz001 = %b", (~| 4'bz001));
  // Bit Wise XOR reduction
  $display (" ^  4'b1001 = %b", (^  4'b1001));
  $display (" ^  4'bx001 = %b", (^  4'bx001));
  $display (" ^  4'bz001 = %b", (^  4'bz001));
  // Bit Wise XNOR
  $display (" ~^ 4'b1001 = %b", (~^ 4'b1001));
  $display (" ~^ 4'bx001 = %b", (~^ 4'bx001));
  $display (" ~^ 4'bz001 = %b", (~^ 4'bz001));
  #10 $finish;
end

endmodule

        这是仿真结果: 

  &  4'b1001 = 0
  &  4'bx111 = x
  &  4'bz111 = x
  ~& 4'b1001 = 1
  ~& 4'bx001 = 1
  ~& 4'bz001 = 1
  |  4'b1001 = 1
  |  4'bx000 = x
  |  4'bz000 = x
  ~| 4'b1001 = 0
  ~| 4'bx001 = 0
  ~| 4'bz001 = 0
  ^  4'b1001 = 0
  ^  4'bx001 = x
  ^  4'bz001 = x
  ~^ 4'b1001 = 1
  ~^ 4'bx001 = x
  ~^ 4'bz001 = x 

移位运算符(Shift Operators)

运算符

描述

<<

左移

>>

右移

  • 左操作数移动右操作数给定的位数
  • 腾出来的位置用零填充

        

        这是一些移位运算的示例:

module shift_operators();

initial begin
  // Left Shift
  $display (" 4'b1001 << 1 = %b", (4'b1001 << 1));
  $display (" 4'b10x1 << 1 = %b", (4'b10x1 << 1));
  $display (" 4'b10z1 << 1 = %b", (4'b10z1 << 1));
  // Right Shift
  $display (" 4'b1001 >> 1 = %b", (4'b1001 >> 1));
  $display (" 4'b10x1 >> 1 = %b", (4'b10x1 >> 1));
  $display (" 4'b10z1 >> 1 = %b", (4'b10z1 >> 1));
  #10 $finish;
end

endmodule

        这是仿真结果: 

  4'b1001 << 1 = 0010
  4'b10x1 << 1 = 0x10
  4'b10z1 << 1 = 0z10
  4'b1001 >> 1 = 0100
  4'b10x1 >> 1 = 010x
  4'b10z1 >> 1 = 010z

拼接运算符(Concatenation Operator)

  • 拼接使用大括号字符 { 和 } 表示,用逗号分隔其中的表达式
    • 示例:+ {a, b[3:0], c, 4'b1001} // 如果 a 和 c 是 8 位数字,则结果有 24 位
  • 拼接中不允许有未定大小的常数

        

        这是一些拼接运算的示例:

module concatenation_operator();

initial begin
  // concatenation
  $display (" {4'b1001,4'b10x1}  = %b", {4'b1001,4'b10x1});
  #10 $finish;
end

endmodule

        这是仿真结果:

  {4'b1001,4'b10x1}  = 100110x1

复制运算符(Replication Operators)

        复制运算符用于将一组位复制 n 次。假设你有一个 4 位变量,你想复制它 4 次以获得一个 16 位变量:那么我们可以使用复制运算符。

运算符

描述

{n{m}}

复制m的值n次

  •  可以使用重复的乘数(必须是常量):
    • {3{a}} // 这相当于 {a, a, a}
  • 嵌套拼接和复制运算符是可能的:
    • {b, {3{c, d}}} // 这相当于 {b, c, d, c, d, c, d}

        

        这是一些复制运算的示例:

module replication_operator();

initial begin
  // replication
  $display (" {4{4'b1001}}      = %b", {4{4'b1001}});
  // replication and concatenation
  $display (" {4{4'b1001,1'bz}} = %b", {4{4'b1001,1'bz}});
  #10 $finish;
end

endmodule

        这是仿真结果: 

  {4{4'b1001}       = 1001100110011001
  {4{4'b1001,1'bz}  = 1001z1001z1001z1001z

条件运算符(Conditional Operators)

  • 条件运算符具有以下类似 C 的格式:
    • cond_expr ? true_expr : false_expr
  • true_expr 或 false_expr 的计算结果取决于 cond_expr 的计算结果(true 或 false)

        这是一些条件运算的示例:

module conditional_operator();

wire out;
reg enable,data;
// Tri state buffer
assign out = (enable) ? data : 1'bz;

initial begin
  $display ("time\t enable data out");
  $monitor ("%g\t %b      %b    %b",$time,enable,data,out);
  enable = 0;
  data = 0;
  #1 data = 1;
  #1 data = 0;
  #1 enable = 1;
  #1 data = 1;
  #1 data = 0;
  #1 enable = 0;
  #10 $finish;
end	

endmodule

        这是仿真结果: 

 time     enable data out
 0     0      0    z
 1     0      1    z
 2     0      0    z
 3     1      0    0
 4     1      1    1
 5     1      0    0
 6     0      0    z

你可能感兴趣的:(Verilog语法,fpga开发,Verilog,xilinx,altera,IC)