Loading header...

Verilog Modules, Ports, Wires, and Regs

A Verilog design is built from modules. A module has ports on the outside and signals inside. Once this feels natural, larger FPGA projects become much less mysterious.

Learning Objectives

You will learn to:

  • write a clean module header;
  • choose port directions and widths;
  • understand wire, reg, and logic;
  • instantiate one module inside another;
  • avoid width and connection mistakes.

Module Skeleton

module module_name (
    input  wire       clk,
    input  wire       rst,
    input  wire [3:0] data_in,
    output wire [3:0] data_out
);
    // internal logic here
endmodule

The bracket range [3:0] means a 4-bit bus. Bit 3 is the most significant bit. Bit 0 is the least significant bit.

Wires

Use wire for signals driven by continuous assignments or by another module output.

wire both_on;
assign both_on = sw0 & sw1;

If two different things drive the same wire, you probably have a bug unless you are intentionally building tri-state behavior at an I/O boundary.

Regs and Logic

Old Verilog uses reg for signals assigned inside always blocks:

reg [7:0] count;

SystemVerilog commonly uses logic:

logic [7:0] count;

The word reg does not always mean a flip-flop. A reg assigned in a combinational always @* block can synthesize into LUT logic. A reg assigned in always @(posedge clk) usually synthesizes into flip-flops.

Module Instantiation

Create a small reusable block:

module majority3 (
    input  wire a,
    input  wire b,
    input  wire c,
    output wire y
);
    assign y = (a & b) | (a & c) | (b & c);
endmodule

Use it in a top module:

module top (
    input  wire sw0,
    input  wire sw1,
    input  wire sw2,
    output wire led
);
    majority3 u_majority (
        .a(sw0),
        .b(sw1),
        .c(sw2),
        .y(led)
    );
endmodule

Named port connections are easier to review than positional connections.

Width Rules

wire [7:0] a;
wire [3:0] b;
wire [7:0] y;

assign y = a + b;

This can be valid, but you should know how b is extended. Beginners should make width conversions explicit when the design matters.

Exercise

Write a module nibble_swap:

  • input: din[7:0]
  • output: dout[7:0]
  • behavior: upper nibble and lower nibble are swapped

Expected mapping:

dout[7:4] = din[3:0]
dout[3:0] = din[7:4]

Then instantiate it in a top module.

Common Mistakes

  • Forgetting bus widths in module ports.
  • Connecting ports by position and accidentally swapping signals.
  • Assigning to a wire inside an always block.
  • Assuming reg always means a physical register.
  • Ignoring synthesis warnings about width truncation or extension.

Summary

Modules are the reusable blocks of Verilog design. Ports define the boundary; wires and regs/logics define internal connections and assigned values. Clean module boundaries make simulation, synthesis, and review much easier.

Next: Combinational Logic in Verilog.

Further Reading

  • Verilator warnings for width and port mismatches
  • Yosys Verilog frontend notes
  • FPGA vendor coding templates

Mind Map

mindmap root((Verilog Modules)) Core concept Module is hardware block Ports define boundary wire connects logic reg holds procedural value Applications Applications Reusable blocks Top level wiring Design checks Checks Port widths Direction Common mistakes Common mistakes Implicit nets Width truncation