Verilog Basics - Modules, Vectors and Numbers

Hierarchical Verilog Design

  • Concept: Designs are built as a hierarchy of modules. A higher-level module instantiates lower-level ones (like PCB → IC → flip-flop).
  • Each module definition is standalone, not nested.
  • Hierarchy enables modularity, reuse, and scalability.
  • Hierarchical names use dot . notation: top.u1.u2.signal.

Modules – The Core of Verilog

  • Syntax:

    module <name> #(parameter ... ) (port list);
        // declarations
        // functionality
    endmodule
    
  • Modules describe behavior, structure, or both.
  • Can contain:
    • Ports (input, output, inout)
    • Nets / regs
    • Continuous assignments
    • Procedural blocks (initial/always)
  • macromodule is an alias for module (rarely used).

Declaring & Instantiating Modules

  • Declaration: always starts with module … endmodule.
  • Instantiation:

    mod_name inst_name (.port1(sig1), .port2(sig2)); // named mapping
    mod_name inst_name (sig1, sig2);                 // ordered mapping
    
  • Multiple instances allowed in the same module.

Port Mapping Styles

  1. By order: Ports matched in the order declared.

    adder u1 (a, b, sum);
    

    ⚠️ Risky: Errors occur if order changes.

  2. By name: Ports explicitly named.

    adder u1 (.x(a), .y(b), .z(sum));
    

    ✅ Recommended: Safer against future changes.

Port Declaration Keywords

  • input – read-only inside the module.
  • output – driven inside, observed outside.
  • inout – bidirectional (used in buses like I²C, data buses).
  • Defaults & caveats:
    • If type not specified, ports default to net type wire.
    • Must explicitly declare reg if procedural assignment needed.
    • Example:

      module m(input clk, input [7:0] data, output reg q, inout bus);
      

Vectors

Declaring Vectors

  • Syntax:

    <type> [msb:lsb] <name>;
    
    • msb = most significant bit index
    • lsb = least significant bit index
  • Example:

    wire [7:0] data_bus;   // 8-bit wide bus (data_bus[7]..data_bus[0])
    reg  [15:0] acc;       // 16-bit register
    
  • Indexing direction:
    • [7:0]descending (bit 7 = MSB, bit 0 = LSB) — most common.
    • [0:7]ascending (bit 0 = MSB, bit 7 = LSB) — allowed, but less used.
    • Both are legal in IEEE 1364-2005.

⚠️ Gotcha: A vector’s indexing direction matters in part-selects and concatenations.

Bit Selection

  • Access individual bits:

    data_bus[0]   // LSB
    acc[15]       // MSB
    
  • Index must be constant in synthesis (simulation allows variable indices, but not synthesizable in many tools).

Part Selection

  • Extract a subset of contiguous bits.
  • Syntax:

    vector[msb:lsb]   // fixed part-select
    vector[base +: width]   // indexed part-select (2001+)
    vector[base -: width]
    
  • Examples:

    data_bus[7:4]   // upper nibble of 8-bit bus
    acc[11:8]       // 4 bits from acc
    
    // Indexed part-select (IEEE 1364-2001 & 2005)
    acc[3 +: 4]     // acc[6:3]  (4 bits starting at index 3, ascending)
    acc[7 -: 4]     // acc[7:4]  (4 bits descending from 7)
    

✅ Indexed part-select avoids confusion when ranges flip.

Concatenation {}

  • Combines multiple signals or vectors into a larger one.
  • Syntax:

    {expr1, expr2, expr3}
    
  • Examples:

    wire [3:0] a = 4'b1010;
    wire [3:0] b = 4'b1100;
    wire [7:0] c;
    
    assign c = {a, b};  // c = 1010_1100
    
  • Replication operator:
    • {N{expr}} repeats an expression N times.
    • Example:

      {4{1'b1}}    // 1111 (4-bit all ones)
      {2{a}}       // {a,a} → duplicates a vector
      

Mixed Concatenation

  • Scalars and vectors can mix:

    {a[3:0], 2'b11, b[1]}   // concatenates 4+2+1 = 7 bits
    
  • Concatenation result width = sum of operand widths.

Assignments & Truncation

  • If RHS wider than LHS → truncated (MSBs dropped).
  • If RHS narrower → zero-filled (if unsigned) or sign-extended (if signed).

    reg [3:0] x;
    x = 8'hAB;   // x = 4'hB  (truncated)
    

Vector Operations

  • Bitwise operators apply bit-by-bit:
    • & | ^ ~ ^~ ~^
    • Example:

      assign out = a & b;   // AND each bit
      
  • Reduction operators collapse vector → single bit:
    • &a, |a, ^a, ~&a, ~|a, ~^a
    • Example:

      wire parity = ^data_bus;  // XOR all bits → parity
      
  • Shift operators:
    • a << n, a >> n (logical shift, fill with zeros).
    • >>> (arithmetic right shift, preserves sign bit for signed values).
    • Example:

      reg signed [7:0] s = -8'd8;  // 1111_1000
      $display("%b", s >>> 2);     // 1111_1110 = -2
      

Corner Cases & Pitfalls

  • Out-of-range index: Returns x (unknown).

    wire [3:0] a = 4'b1010;
    $display("%b", a[10]);  // x
    
  • Empty concatenation: Illegal in Verilog-2005.
  • Mix signed/unsigned: Width/sign extension rules can surprise. Always cast explicitly if needed.

Logic States in Verilog

  • Four states:
    • 0 → logic zero
    • 1 → logic one
    • z/Z → high impedance (tri-stated)
    • x/X → unknown (simulation only!)
  • Hardware reality: Only 0, 1, Z exist. X indicates indeterminate logic (conflict, uninitialized, timing issue) in simulation.

Number Representation <size>'<base><value>

  • Format:
    • <size>: number of bits
    • <base>: b (binary), o (octal), d (decimal), h (hex)
    • <value>: digits
  • Examples:

    4'b1010   // 4-bit binary
    8'hFF     // 8-bit hex
    'd25      // 32-bit decimal (unsized default)
    

Sized vs Unsized

  • Sized: Width is explicit → 4'b1010
  • Unsized: Defaults to 32 bits'hF = 32-bit hex F.

Defaults

  • Base: Decimal if unspecified.
  • Case: Base (d/h/o/b) and digits are case-insensitive.
  • Readability: _ allowed → 16'b1010_1100_1111_0000.

Negative Numbers

  • Preferred syntax:

    -8'd6    // 8-bit signed decimal -6
    4'shF    // signed 4-bit hex = -1
    
  • Note: 8'd-6 is illegal.
  • Signed constants ('sd) are sign-extended when assigned.

Real Number Representation

  • Decimal: 12.34, 0.1
  • Scientific: 1.2e3, 4.5E-2
  • Must have digit before and after decimal point.
  • _ can be used for readability: 236.123_763_e-12
  • Follows IEEE 754 double precision.

Concept understood? Let's apply and learn for real

Practice now