Verilog Operators

Verilog provides a rich set of operators for arithmetic, logic, and bit manipulation. Understanding these is essential for writing efficient RTL code.

Arithmetic Operators

Operator Description Example
+ Addition a + b
- Subtraction a - b
* Multiplication a * b
/ Division a / b
% Modulus a % b
** Power 2 ** 8 = 256
Arithmetic Examples
wire [7:0] a = 8'd15;
wire [7:0] b = 8'd4;
wire [7:0] sum  = a + b;   // 19
wire [7:0] diff = a - b;   // 11
wire [15:0] prod = a * b;  // 60 (wider result!)
wire [7:0] quot = a / b;   // 3
wire [7:0] rem  = a % b;   // 3

Synthesis Consideration

Division (/) and modulus (%) are expensive in hardware. Use power-of-2 division (shift right) when possible.

Bitwise Operators

Bitwise operators perform operations on each bit independently:

Operator Description Example
~ NOT (invert) ~4'b1010 = 4'b0101
& AND 4'b1100 & 4'b1010 = 4'b1000
| OR 4'b1100 | 4'b1010 = 4'b1110
^ XOR 4'b1100 ^ 4'b1010 = 4'b0110
~^ or ^~ XNOR 4'b1100 ~^ 4'b1010 = 4'b1001
Bitwise Operations
wire [3:0] a = 4'b1100;
wire [3:0] b = 4'b1010;
wire [3:0] inv   = ~a;       // 0011
wire [3:0] and_r = a & b;    // 1000
wire [3:0] or_r  = a | b;    // 1110
wire [3:0] xor_r = a ^ b;    // 0110
// Common use: masking
wire [7:0] data = 8'hAB;
wire [7:0] masked = data & 8'h0F;  // Keep lower nibble: 0x0B

Logical Operators

Logical operators treat the entire operand as true (non-zero) or false (zero):

Operator Description Result
! Logical NOT 1-bit result (0 or 1)
&& Logical AND 1-bit result
|| Logical OR 1-bit result
Logical vs Bitwise
wire [3:0] a = 4'b1100;  // Non-zero (true)
wire [3:0] b = 4'b0000;  // Zero (false)
// Logical operators: 1-bit result
wire log_not = !a;       // 0 (a is non-zero, so NOT gives 0)
wire log_and = a && b;   // 0 (true AND false = false)
wire log_or  = a || b;   // 1 (true OR false = true)
// Bitwise operators: multi-bit result
wire [3:0] bit_not = ~a; // 4'b0011
wire [3:0] bit_and = a & b; // 4'b0000

Reduction Operators

Reduction operators apply a bitwise operation across all bits of a single operand, producing a 1-bit result:

Operator Description Example
& AND all bits &4'b1111 = 1
| OR all bits |4'b0001 = 1
^ XOR all bits (parity) ^4'b1011 = 1
~& NAND all bits ~&4'b1111 = 0
~| NOR all bits ~|4'b0000 = 1
~^ XNOR all bits ~^4'b1011 = 0
Reduction Operator Examples
wire [7:0] data = 8'b10110100;
// Check if all bits are 1
wire all_ones = &data;       // 0 (not all 1s)
// Check if any bit is 1
wire any_one = |data;        // 1 (some bits are 1)
// Parity calculation (odd number of 1s = 1)
wire parity = ^data;         // 0 (even parity)
// Check if data is zero
wire is_zero = ~|data;       // 0 (data is not zero)

Shift Operators

Operator Description Example
<< Logical left shift 8'b00001111 << 2 = 8'b00111100
>> Logical right shift 8'b11110000 >> 2 = 8'b00111100
<<< Arithmetic left shift Same as logical
>>> Arithmetic right shift Sign-extends MSB
Shift Operations
wire [7:0] data = 8'b11110000;
// Logical shifts (fill with 0)
wire [7:0] left  = data << 2;   // 8'b11000000
wire [7:0] right = data >> 2;   // 8'b00111100
// Arithmetic right shift (sign extend)
wire signed [7:0] signed_data = 8'sb11110000;  // -16
wire signed [7:0] arith_right = signed_data >>> 2;  // 8'sb11111100 (-4)
// Multiply/divide by powers of 2
wire [7:0] times_4 = data << 2;  // Multiply by 4
wire [7:0] div_4   = data >> 2;  // Divide by 4

Concatenation & Replication

Concatenation and Replication
wire [3:0] upper = 4'hA;
wire [3:0] lower = 4'h5;
// Concatenation: { }
wire [7:0] byte_val = {upper, lower};  // 8'hA5
// Replication: {n{value}}
wire [7:0] all_ones = {8{1'b1}};       // 8'hFF
wire [15:0] pattern = {4{4'b1010}};   // 16'hAAAA
// Sign extension using replication
wire signed [7:0] small = 8'sb11110001;  // -15
wire signed [15:0] extended = {{8{small[7]}}, small};  // Sign-extend to 16-bit

Common Interview Questions

  1. What's the difference between & and &&?

    & is bitwise AND (multi-bit result); && is logical AND (1-bit result).

  2. How do you calculate parity of a bus?

    Use the reduction XOR operator: ^bus

  3. How do you check if a value is zero?

    Use reduction NOR: ~|value returns 1 if all bits are 0.