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
+ – * / ** Arithmetic
% Modulus
> >= < <= Relational
! Logical negation
&& Logical and
|| Logical or
== Logical equality
!= Logical inequality
=== Case equality
!== Case inequality
~ Bit-wise negation
& Bit-wise and
| Bit-wise inclusive or
^~ or ~^ Bit-wise equivalence
& Reduction and
~& Reduction nand
| Reduction or
~| Reduction nor
^ Reduction xor
~^ or ^~ Reduction xnor
<< Logical left shift
>> Logical right shift
<<< Arithmetic left shift
>>> Arithmetic right shift
? : Conditional
or Event or

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  ;
  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);

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 ;

    sum = a + b ;
    product = a * b ;
    quotient = a / b ;
    remainder = a % b ;
    difference = a - b ;

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) );
   a = 3 ;
   b = 2 ;
   #10 ;
   $display("sum : %d, product: %d, quotient: %d, difference: %d, remainder: %d",
            sum, product, quotient, difference, remainder);

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 ;

    if( a < b) result = 1 ;
    else if ( a > b ) result = 2 ;
    else if ( a >= b || a <= b ) result = 3 ;
    else result = 0 ;

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 ;

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


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  ;

    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;  


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  ;

   resultA = a << 2 ;
   resultB = a >> 2 ;
   resultC = b <<< 2 ;
   resultD = b >>> 2 ;
// 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;


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

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

1 comment on “Verilog: Operators

Leave a Reply

Your email address will not be published. Required fields are marked *