Verilog: Operators

Operators are single-, double-, or triple-character sequences and are used in expressions.Following operators are available in Verilog HDL. Please note that not all operators are synthesizable.

Concatenation Operators A concatenation is the joining together of bits resulting from two or more expressions. The concatenation shall be expressed using the brace characters { and }, with commas separating the expressions within.

module concat () ; reg [7:0] a, b, c ; reg [3:0] data ; initial begin data = 4'b1010; a = {4'b0000,4'b1111} ; b = {data,data} ; c = {2{data}}; // same as {data,data} $display ( "A: %b, B: %b, C: %b ", a, b, c); end endmodule

Arithmetic Operators Arithmetic operators lets you do common mathematical functions like addition and multiplication. Look at the following code.

module dut ( sum, product, quotient, difference, remainder, a , b ) ; output [3:0] sum, product, quotient, difference, remainder ; input [1:0] a , b ; reg [3:0] sum , product, quotient, difference, remainder ;

always@(*) begin sum = a + b ; product = a * b ; quotient = a / b ; remainder = a % b ; difference = a - b ; end endmodule

The operators are self-explanatory. For sake of completeness, I will add one testbench for simulating this. For all subsequent examples, assume that a similar testbench is used.

module tb; reg [1:0] a ; reg [1:0] b ; wire [3:0] sum,product,quotient,remainder,difference ;

// DUT instantiation in testbench dut dut_inst (.sum(sum), .product(product), .quotient(quotient), .remainder(remainder), .difference(difference), .a(a), .b(b) ); initial begin a = 3 ; b = 2 ; #10 ; $display("sum : %d, product: %d, quotient: %d, difference: %d, remainder: %d", sum, product, quotient, difference, remainder); end endmodule

Relational Operators Relational operators compare two operands. Examples are greater than and less than.

module dut ( result, a , b ) ; output [3:0] result ; input [1:0] a , b ; reg [3:0] result ;

always@(*) begin if( a < b) result = 1 ; else if ( a > b ) result = 2 ; else if ( a >= b || a <= b ) result = 3 ; else result = 0 ; end endmodule

You can use this testbench to simulate.

Logical Operators & Bit-wise operators

  • The operators logical and (&&) and logical or (||) are logical connectives.The result of the evaluation of a logical comparison shall be 1 (defined as true), 0 (defined as false), or, if the result is ambiguous, the unknown value (x). The precedence of && is greater than that of ||, and both are lower than relational and equality operators. A third logical operator is the unary logical negation operator (!).The negation operator converts a nonzero or true operand into 0 and a zero or false operand into 1. An ambiguous truth value remains as x.
  • The bit-wise operators shall perform bit-wise manipulations on the operands—that is, the operator shall combine a bit in one operand with its corresponding bit in the other operand to calculate one bit for the result.

The following code gives logical and bit-wise and, or and negation example. Run this and look at the differences.

module dut ( resultA, resultB, a , b ) ; output [3:0] resultA, resultB ; input [1:0] a , b ; reg [3:0] resultA, resultB ;

always@(*) begin if( !a ) // Logical Negation begin if( a == b) // Logical equality begin resultA = a&&b ; // Logical AND resultB = a || b ; // Logical OR end else begin resultA = a&b ; // Bit-wise AND resultB = a|b ; // Bit-wise inclusive end end else begin if( a != b) // Logical inequality begin resultA = a^b ; // Bit-wise XOR resultB = a~^b ; // Bit-wise equivalency end else resultA = ~a ; // Bit-wise negation resultB = ~b ; end end endmodule

Testbench Case Equality & Case Inequality In the above example we have use == and != for logical equality and logical inequality. Verilog also has another type operator called `Case Equality` and `Case Inequalit`y.

if( a === b) // case equality if( a !== b) // case inequality

These statements also take x or z bits. a == b can give an unknown value (x) whereas case equality statement will always return a 0 or 1.

Reduction Operators The unary reduction operators shall perform a bit-wise operation on a single operand to produce a single bit result. For reduction and, reduction or, and reduction xor operators, the first step of the operation shall apply the operator between the first bit of the operand and the second. The second and subsequent steps shall apply the operator between the 1-bit result of the prior step and the next bit of the operand. For reduction nand, reduction nor, and reduction xnor operators, the result shall be computed by inverting the result of the reduction and, reduction or, and reduction xor operation respectively.

Consider that a testbench is supplying `a = 4'b1010 ;`

module dut ( resultAND, resultNAND,resultOR, resultNOR, resultXOR, resultXNOR, a ) ; output resultAND, resultNAND, resultOR, resultNOR, resultXOR,resultXNOR ; input [3:0] a ; reg resultAND, resultNAND, resultOR, resultNOR, resultXOR,resultXNOR ;

always@(*) begin resultAND = &a ; // Equivalent to 1&0, 0&1, 0&1.0&0. Result is 0 resultNAND = ~&a; resultOR = |a;
resultNOR = ~|a;
resultXOR = ^a;
resultXNOR = ~^a;
end endmodule

Testbench Shift Operators There are two types of shift operators, the logical shift operators, << and >>, and the arithmetic shift operators, <<< and >>>. The left shift operators, << and <<<, shall shift their left operand to the left by the number by the number of bit positions given by the right operand. In both cases, the vacated bit positions shall be filled with zeroes. The right shift operators, >> and >>>, shall shift their left operand to the right by the number of bit positions given by the right operand. The logical right shift shall fill the vacated bit positions with zeroes. The arithmetic right shift shall fill the vacated bit positions with zeroes if the result type is unsigned. It shall fill the vacated bit positions with the value of the most-significant (i.e., sign) bit of the left operand if the result type is signed. If the right operand has an unknown or high impedance value, then the result shall be unknown. The right operand is always treated as an unsigned number and has no effect on the signedness of the result.

module dut ( resultA, resultB, resultC, resultD , a , b ) ; output [7:0] resultA, resultB, resultC, resultD ; input [7:0] a, b ; reg [7:0] resultA, resultB, resultC, resultD ;

always@(*) begin resultA = a << 2 ; resultB = a >> 2 ; resultC = b <<< 2 ; resultD = b >>> 2 ; end endmodule

// tb reg [7:0] a; reg signed [7:0] b;

Conditional Operator The conditional operator is also known as ternary operator as it takes three operands. Syntax :: `expression1 ? expression2 : expression3`

expression1 is evaluated first. If it evaluates to true (value 1), expression2 is evaluated. If expression1 evalues to false (value 0), expression3 is evaluated.If expression1 evaluates to ambiguous value (x or z), then both expression2 and expression3 shall beevaluated and their results shall be combined, bit by bit to calculate the final result unless expression2 or expression3 is real, in which case the result shall be 0.

module dut ( bus_enable, data ) ; input bus_enable ; input [15:0] data ;

wire busa = bus_enable ? data : 16'bz;

endmodule

Event or The event or operator shall perform an or of events. The , operator does the same thing. e.g.

@(trig or enable) rega = regb ; @(trig , enable) rega = regb ;