Skip to content

Numbers representation in Verilog

Introduction

Verilog allows designers to represent numbers in various bases, sizes, and signed/unsigned formats. Understanding number representation is essential for writing correct and synthesizable RTL code.

Syntax for Number Representation

In Verilog, a number is generally represented as:

<size_in_bits>'<base><value>

Where:

  • <size_in_bits> → optional, specifies the width (e.g., 4, 8, 10, 16 etc).
  • <base> → 'b' (binary), 'o' (octal), 'd' (decimal), 'h' (hexadecimal).
  • <value> → the actual numeric value in that base.

Examples

4'b1010  // 4-bit binary 1010, decimal 10
8'hFF    // 8-bit hexadecimal FF, decimal 255
16'd1234 // 16-bit decimal 1234
5'o17    // 5-bit octal 17, decimal 15

Unsigned vs Signed Numbers

  • By default, numbers are unsigned.
  • To define a signed number, use the signed keyword:
reg signed [7:0] a;
a = -8'd10; // signed decimal -10
  • Signed numbers are stored in two's complement representation.

To declare a signed variable, use the signed keyword, such as

reg signed [7:0] my_signed_reg; 

When declaring a negative literal, the '-' sign can be placed before the size and base, like -8'd23, which Verilog automatically converts to its two's complement equivalent. This eliminates the need for separate addition and subtraction circuits, as the same hardware can perform both operations. The Verilog compiler handles the underlying two's complement logic transparently for arithmetic operations, though the designer must use the signed type to ensure correct interpretation, especially when mixing signed and unsigned values.

Default Width

  • If size is omitted, Verilog assigns 32 bits by default in expressions:
reg [3:0] a;
a = 10; // 10 is treated as 32-bit decimal, truncated to 4 bits -> 1010
  • Be careful with truncation or sign-extension in assignments.

Unknown and High-Impedance Values

Verilog supports four-state logic:

  • 0 → logic 0
  • 1 → logic 1
  • x → unknown value
  • z → high-impedance

Example:

reg [3:0] a;
a = 4'b1x0z; // bit 3=1, bit 2=unknown, bit1=0, bit0=high-Z

This is crucial for simulation and modeling tri-state buses.

Literal Examples

Literal Meaning
4'b1101 4-bit binary 1101
8'hA3 8-bit hexadecimal A3
16'd100 16-bit decimal 100
5'o17 5-bit octal 17
'b1 Binary 1, width inferred
'd255 Decimal 255, width inferred

Number Width and Operations

  • Width matters in expressions: Verilog pads or truncates automatically.
  • Binary operations may extend numbers to the largest operand width:
reg [3:0] a = 4'b1010;
reg [7:0] b;
b = a + 8'd15; // a is zero-extended to 8 bits before addition
  • Signed numbers propagate sign during operations.

Practical Tips

  • Always specify width for constants to avoid simulation/synthesis mismatches.
  • Use binary or hexadecimal for bit-accurate hardware modeling.
  • Avoid implicit type assumptions — clarify signed/unsigned when needed.
  • For tri-state buses, use 'z to represent high-impedance signals.

Summary

Feature Verilog Representation
Binary 4'b1010
Octal 5'o17
Decimal 16'd1234
Hexadecimal 8'hFF
Signed number reg signed [7:0] a; a=-8'd5;
Four-state value 0, 1, x, z
Default width 32-bit if unspecified
Width mismatch handling Truncation or zero/sign-extension