Skip to content

Verilog · Chapter 9.2 · Design & Testbench Creation

Module Instantiation in Verilog — From Blueprint to Real Hardware

A module is a blueprint, a definition that describes a hardware block but is not itself any hardware. This page is where blueprints become real logic. Instantiation is the act of placing a module into a design as a working instance, and one definition can produce a single instance or a thousand, each an independent piece of hardware. Instantiation is also how hierarchy is built, because a module becomes a parent by holding instances of other modules inside its boundary, and a chip sits at the top of that nesting. This lesson teaches what an instance is, why every instance needs a name, how one definition is reused across many instances, and how nesting instances assembles the module tree. It stops short of the detailed rules for wiring ports, which the port mapping lesson covers next.

Foundation20 min readVerilogInstantiationHierarchyModulesStructural Modeling

Chapter 9 · Section 9.2 · Design & Testbench Creation

1. The Engineering Problem

You followed 9.1 and wrote a clean full_adder module — a well-bounded hardware block. Now you need a 32-bit adder. Do you write the addition logic over again, 32 times, in one giant module? Of course not. You wrote the 1-bit block once; you want to use it 32 times.

But here is the catch a 9.1 graduate hits immediately: a module definition, by itself, builds nothing. Writing module full_adder (...) ... endmodule describes a kind of block. It does not place any adder into your design any more than drawing a blueprint pours any concrete. So the question this page answers is:

How do you take a module definition and turn it into actual hardware inside a larger design — once, or a thousand times?

The answer is instantiation. Instantiation is the act of saying "build one of these here, and call it that." Each time you instantiate a module you create an instance — a real, independent piece of hardware. And because a module can be instantiated inside another module, instantiation is also the mechanism that builds hierarchy: the nesting of blocks within blocks that 9.1 showed as the shape of every chip. This page is about turning blueprints into hardware, and hardware into hierarchies.

2. Mental Model — Instantiation Builds Hardware From a Blueprint

Visual A — instantiation turns a definition into instances

From definition to hardware

data flow
From definition to hardwareModule definitionthe blueprint — no hardware yetInstantiationplace a copy into a designInstancereal, independent hardwareMany instancesone definition, reused N times
A definition is inert until instantiated. Each instantiation builds one instance — a concrete block of hardware — and the same definition can be instantiated as many times as the design needs. Writing the module is design-time; instantiating it is where the hardware comes into being.

3. The Hardware View — Each Instance Is Independent Silicon

The most important physical fact: every instance is its own hardware. When you instantiate the same module three times, you get three separate copies of the circuit, not one circuit shared three ways. They occupy different silicon, hold different state, and operate fully in parallel.

one definition, three independent instances
Azvya Education Pvt. Ltd.VLSI Mentor
Snippet
   register (definition / blueprint)
              │  instantiated 3x
   ┌──────────┼──────────┐
   ▼          ▼          ▼
 reg_a      reg_b      reg_c        <- three independent physical registers
 (state A)  (state B)  (state C)       each with its own value, in parallel

This is the deepest difference from software. A software function is one piece of code that many callers share; calling it more does not create more code. An instantiated module is the opposite — each instance is duplicated hardware. Three instances of a 1,000-gate block cost 3,000 gates of area. That is not waste; it is the point: you need three independent copies because they do three independent jobs at the same time.

The consequence for reasoning: when you see three instances of counter, picture three counters on the chip, each counting independently — not one counter being "called" three times. Instances exist simultaneously and permanently, like three identical chips soldered onto a board.

Visual B — instances are independent hardware

One definition produces independent hardware instancescounter (definition)blueprintu_counter_0independent siliconu_counter_1independent siliconu_counter_2independent silicon12
One module definition instantiated three times yields three independent physical blocks. They share a design (the blueprint) but not state, silicon, or behaviour at run time — each runs in parallel with its own value. More instances means more hardware, by design.

4. The Instantiation Statement

An instantiation has three parts. Here is one instance of the and_gate module from 9.1, placed inside a parent module.

instantiation-anatomy.v
Azvya Education Pvt. Ltd.VLSI Mentor
Snippet
module top (
    input  in1,
    input  in2,
    output result
);
 
    //  1            2          3 (connections — detail is 9.3)
    and_gate     u_and0   ( .a(in1), .b(in2), .y(result) );
 
endmodule

The three parts of every instantiation:

  1. Module type (and_gate) — which blueprint to build. This must name a module that has been defined somewhere in the compilation.
  2. Instance name (u_and0) — the unique label for this particular instance. You choose it; every instance needs one (§5).
  3. Connection list (( .a(in1), ... )) — how this instance's ports attach to signals in the parent. The form shown — .port(signal) — is the named connection style; the full rules for connecting ports (named vs positional, widths, traps) are Chapter 9.3. Here, read it as "the instance's a pin connects to the parent's in1," and move on.

Read the statement as a sentence: "Build one and_gate, call it u_and0, and wire its pins to these signals." That is instantiation — naming a blueprint, naming the copy, and attaching it to the surrounding design.

Scope note: this page teaches the instance — its type, its name, and that it connects. The precise mechanics of the connection list belong to 9.3. Treat the .port(signal) form here as a given.

5. Instance Names — Why Every Instance Needs One

The instance name is not decoration. It is the instance's identity in the design, and it does real work:

  • Uniqueness within a parent. Two instances in the same module must have different names. u_and0 and u_and1 are two distinct pieces of hardware; the names are how the tools (and you) tell them apart. Duplicate names are an error (§10, DebugLab 1).
  • Hierarchical path. The names chain into a full path — top.u_cpu.u_alu.u_adder — that uniquely identifies one block anywhere in the hierarchy. This path is how waveform tools, debuggers, and reports refer to a specific instance among thousands.
  • Debug and waveforms. When a simulation dumps signals or a timing report flags a violation, it names the instance (top.u_fifo_3.count). Good instance names make a failure locatable; names like u1, u2, xxx make debugging miserable at scale.

The industry convention is a u_ prefix and a descriptive role: u_fetch, u_alu, u_uart_tx. The name is part of how the whole design is navigated — choose it as deliberately as the module name itself.

6. Multiple Instances — Reuse in Action

One definition, instantiated many times, is the entire reason modules exist. Each instance is independent (§3); only the blueprint is shared.

multiple-instances.v — three independent gates from one definition
Azvya Education Pvt. Ltd.VLSI Mentor
Snippet
module triple_and (
    input  a0, b0, a1, b1, a2, b2,
    output y0, y1, y2
);
    and_gate u_and0 ( .a(a0), .b(b0), .y(y0) );   // instance 1
    and_gate u_and1 ( .a(a1), .b(b1), .y(y1) );   // instance 2
    and_gate u_and2 ( .a(a2), .b(b2), .y(y2) );   // instance 3
endmodule

Three instances of the same and_gate definition, each wired to different signals, each independent silicon. Change the and_gate definition once and all three update — that is the maintainability win. Place a fourth instance and you have a fourth gate — that is the reuse win. (When you need dozens of identical instances, a generate loop creates them programmatically — that is Chapter 14.7; here, instantiate explicitly.)

7. Building Hierarchy — Instances Inside Modules

This is the idea that makes instantiation the backbone of design: a module becomes a parent by containing instances of other modules. Nesting instances inside modules, level after level, builds the tree 9.1 described.

adder2.v — a 2-bit adder built from two full_adder instances
Azvya Education Pvt. Ltd.VLSI Mentor
Snippet
// Leaf block (the blueprint), defined once.
module full_adder (
    input  a, b, cin,
    output sum, cout
);
    assign {cout, sum} = a + b + cin;
endmodule
 
// Parent block: built structurally from two full_adder INSTANCES.
module adder2 (
    input  [1:0] a, b,
    input        cin,
    output [1:0] sum,
    output       cout
);
    wire carry;   // internal net linking the two instances
 
    full_adder u_fa0 ( .a(a[0]), .b(b[0]), .cin(cin),   .sum(sum[0]), .cout(carry) );
    full_adder u_fa1 ( .a(a[1]), .b(b[1]), .cin(carry), .sum(sum[1]), .cout(cout)  );
endmodule

adder2 contains no addition logic of its own — it is built entirely by instantiating two full_adder blocks and wiring them with an internal carry net. This is structural modeling: describing hardware by composing sub-blocks rather than writing the logic directly. adder2 is now a parent; u_fa0 and u_fa1 are its children. Instantiate adder2 inside a bigger block and the tree grows another level. Scale this idea and you get a CPU built from datapath + control, each built from registers + ALUs, each built from gates — a hierarchy assembled entirely through instantiation.

Visual C — hierarchy is built by nesting instances

Hierarchy built by instantiating sub-modulesadder2 (parent)contains instancesu_fa0full_adder instanceu_fa1full_adder instancewire carryinternal connection12
A parent module (adder2) is built by instantiating child modules (two full_adder instances) and wiring them together. Each child can itself be a parent of further instances. Nesting instances level after level is exactly how the module tree — and every real chip — is assembled.

8. Elaboration — How Instances Become a Netlist

One conceptual point ties it together. When the tool reads your design, it performs elaboration: it starts at the top module and recursively expands every instantiation into the actual block it names, building the full tree of real hardware.

elaboration expands the instance tree
Azvya Education Pvt. Ltd.VLSI Mentor
Snippet
   top                         (read the top module)
    └── u_adder : adder2        (expand: build an adder2 here)
         ├── u_fa0 : full_adder   (expand: build a full_adder)
         └── u_fa1 : full_adder   (expand: build another full_adder)

Elaboration is where "blueprint + instantiation" becomes a concrete, fully-built design. Before elaboration you have definitions and instantiation statements; after it you have a complete tree of real instances — the netlist the simulator runs and the synthesizer maps to gates. The mental takeaway: the design you write is a set of blueprints plus instructions for placing copies; elaboration carries those instructions out and produces the actual hardware tree. (Elaboration is also when parameters — Chapter 6 — fix each instance's configuration; that interaction is previewed here and drilled with parameterized instantiation later.)

Visual D — elaboration builds the tree from definitions + instantiations

Elaboration — from source to instance tree

data flow
Elaboration — from source to instance treeDefinitionsblueprints (modules)Instantiationsplace-a-copy instructionsElaborationexpand top → leavesInstance treethe real hardware / netlist
Elaboration consumes the blueprints and the instantiation statements and expands them, starting at the top module, into a complete tree of concrete instances — the netlist. This is the step that turns 'a definition plus place-it-here instructions' into actual hardware.

9. Worked Examples

Three instantiations, growing from one instance to a hierarchy.

9.1 Example 1 — instantiate one module

single-instance.v
Azvya Education Pvt. Ltd.VLSI Mentor
Snippet
module top (
    input  x, y,
    output z
);
    and_gate u_and ( .a(x), .b(y), .y(z) );
endmodule

The minimum: one and_gate definition becomes one u_and instance inside top. top now contains a gate. Read it as hardware — top is a box with an AND gate placed inside it, its pins wired to top's ports.

9.2 Example 2 — multiple instances of one definition

quad-register.v — four independent registers
Azvya Education Pvt. Ltd.VLSI Mentor
Snippet
module quad_reg (
    input        clk,
    input  [3:0] d0, d1, d2, d3,
    output [3:0] q0, q1, q2, q3
);
    // One register blueprint, four independent instances.
    reg4 u_reg0 ( .clk(clk), .d(d0), .q(q0) );
    reg4 u_reg1 ( .clk(clk), .d(d1), .q(q1) );
    reg4 u_reg2 ( .clk(clk), .d(d2), .q(q2) );
    reg4 u_reg3 ( .clk(clk), .d(d3), .q(q3) );
endmodule

Four instances of a reg4 definition — four independent 4-bit registers, each holding its own value, all clocked together but otherwise unrelated. This is reuse: one blueprint, four pieces of hardware, four unique instance names.

9.3 Example 3 — a hierarchy

ripple-adder.v — a parent built from instances
Azvya Education Pvt. Ltd.VLSI Mentor
Snippet
module adder4 (
    input  [3:0] a, b,
    input        cin,
    output [3:0] sum,
    output       cout
);
    wire c1, c2, c3;   // internal carry chain between instances
 
    full_adder u_fa0 ( .a(a[0]), .b(b[0]), .cin(cin), .sum(sum[0]), .cout(c1)   );
    full_adder u_fa1 ( .a(a[1]), .b(b[1]), .cin(c1),  .sum(sum[1]), .cout(c2)   );
    full_adder u_fa2 ( .a(a[2]), .b(b[2]), .cin(c2),  .sum(sum[2]), .cout(c3)   );
    full_adder u_fa3 ( .a(a[3]), .b(b[3]), .cin(c3),  .sum(sum[3]), .cout(cout) );
endmodule

A 4-bit ripple-carry adder built structurally from four full_adder instances, the carry-out of each feeding the carry-in of the next. adder4 has no adder logic of its own — it is pure composition. This is how real datapaths are assembled: small verified blocks, instantiated and wired into bigger ones. Instantiate adder4 itself inside a larger block and the hierarchy deepens.

10. Common Mistakes

Five mistakes rooted in misunderstanding instances and definitions.

  1. Duplicate instance names. Two instances in the same parent with the same name is illegal — each instance needs a unique label (§5, DebugLab 1).
  2. Instantiating an undefined module. Naming a module type that was never defined (a typo, a missing file) leaves an instance with no blueprint to build (§10 → DebugLab 2).
  3. Confusing the definition with the instance. Editing a definition expecting to change one instance, or thinking the definition is itself hardware. The definition is shared by all instances; the instance is the hardware.
  4. Forgetting the instance name entirely. Writing and_gate ( .a(x), ... ); with no name. Every instantiation requires an instance name.
  5. Treating instantiation like a function call. Expecting an instance to "run and return a value." An instance is permanent parallel hardware, not a call — it is built once and is always on (DebugLab 3).

11. Debugging Lab

Three instantiation debug post-mortems

12. Industry Perspective

Instantiation is the load-bearing operation of real design.

  • Structural composition is most of RTL integration. Above the leaf blocks, large designs are assembled almost entirely by instantiation — a chip's top level is page after page of sub-block instances wired together, with little logic of its own. Integration engineers spend their days instantiating and connecting, not writing gate logic.
  • IP reuse is instantiation. A purchased or in-house IP block (a PCIe controller, a memory subsystem) is delivered as a module and used by instantiating it. The entire semiconductor-IP economy runs on "instantiate this verified block into your chip."
  • Regular structures are arrays of instances. Ripple adders, register files, crossbars, memory arrays — repeated hardware is repeated instances of one block (written explicitly, or generated with a generate loop for large counts). The blueprint is authored once; the array is instances.
  • Instance names are the design's coordinate system. Across thousands of instances, the hierarchical instance path is how every tool — simulation, timing, power, physical layout — refers to a specific block. Disciplined instance naming is a real, valued engineering practice.

13. Interview Q&A

14. Exercises

Four exercises, progressive.

Exercise 1 — Identify the parts of an instantiation

For the statement below, name the three parts: the module type, the instance name, and the connection list.

Azvya Education Pvt. Ltd.VLSI Mentor
Snippet
full_adder u_fa2 ( .a(a[2]), .b(b[2]), .cin(c2), .sum(sum[2]), .cout(c3) );

Exercise 2 — Instantiate a single module

Given a defined module inverter with ports input a, output y, write a top module with inputs in, output out, that contains one inverter instance named u_inv connecting in to a and out to y.

Exercise 3 — Build a small hierarchy

Given a defined full_adder (input a, b, cin, output sum, cout), write a adder2 module (inputs [1:0] a, b, input cin, outputs [1:0] sum, output cout) that instantiates two full_adders, chaining the carry from the first to the second with an internal wire. Give each instance a unique name.

Exercise 4 — Find the instantiation bugs

The module below has three instantiation-related problems. Identify each (referencing §10) and state the fix in one line per bug — do not rewrite the whole module.

Azvya Education Pvt. Ltd.VLSI Mentor
Snippet
module top (input a0, b0, a1, b1, output y0, y1);
    and_gate u_and ( .a(a0), .b(b0), .y(y0) );
    andgate  u_and ( .a(a1), .b(b1), .y(y1) );
endmodule

15. Summary

Instantiation turns a module definition (a blueprint that is not hardware) into a concrete instance (real, independent hardware) placed inside a design. It is the step where blueprints become silicon, and the mechanism by which hierarchy is built.

The core ideas:

  • Definition vs instance. The module is the blueprint, written once; the instance is hardware built from it. One definition → many instances, each independent silicon with its own state.
  • The instantiation statement has three parts — module type (which blueprint), instance name (this copy's unique identity), and connection list (how it attaches; detailed rules in 9.3).
  • Every instance needs a unique name, which forms the hierarchical path used to locate any block in the design.
  • Each instance is independent hardware — three instances are three circuits, not one shared three ways. This is the core difference from a software function call.
  • Hierarchy is built by nesting instances — a module becomes a parent by containing instances of other modules. This is structural modeling.
  • Elaboration expands definitions + instantiations, from the top module down, into the complete instance tree (the netlist).

The discipline this page instils:

  • Name every instance uniquely and descriptively (the u_ convention) — names are the design's coordinate system.
  • Instantiate to reuse — write a block once, place it everywhere; don't duplicate logic.
  • Compose, don't call — an instance is permanent parallel hardware, never a function that runs and returns.

You can now turn the blueprints from 9.1 into real, reusable hardware and assemble them into hierarchies. What remains is the precise art of connecting them: Chapter 9.3 Module Port Mapping drills how an instance's ports attach to the surrounding design — named vs positional connections, width and direction matching, and the wiring traps that the simple .port(signal) form here glossed over.

  • Module Structure & Elements — Chapter 9.1; the module definition (blueprint) that this page instantiates.
  • Design & Testbench Creation — Chapter 9 overview; where module hierarchy and the design loop were introduced.
  • parameter — Chapter 6.1; the build-time constants resolved per instance at elaboration.
  • RTL Designing — Chapter 3; the register-transfer model the instantiated blocks implement.