Bird
Raised Fist0
Verilogprogramming~15 mins

Module as the basic building block in Verilog - Deep Dive

Choose your learning style10 modes available
Overview - Module as the basic building block
What is it?
A module in Verilog is like a small box that holds a piece of a digital circuit design. It groups together inputs, outputs, and the logic that connects them. Modules can be simple or complex and can be combined to build bigger circuits. Think of modules as the basic building blocks for creating hardware designs.
Why it matters
Without modules, designing complex digital circuits would be chaotic and confusing. Modules let designers break down big problems into smaller, manageable parts, making it easier to build, test, and reuse designs. Without this concept, hardware design would be slow, error-prone, and hard to understand.
Where it fits
Before learning about modules, you should understand basic digital logic concepts like signals and gates. After mastering modules, you can learn about how to connect modules together, use parameters for flexible designs, and explore advanced topics like testbenches and simulation.
Mental Model
Core Idea
A module is a self-contained unit that defines inputs, outputs, and internal logic to build parts of a digital circuit.
Think of it like...
A module is like a LEGO brick that has connectors on some sides (inputs and outputs) and a shape inside (logic). You can snap many bricks together to build a bigger model.
┌─────────────┐
│   Module    │
│ ┌─────────┐ │
│ │ Inputs  │ │
│ │  (pins) │ │
│ └─────────┘ │
│             │
│  Logic/     │
│  Behavior   │
│             │
│ ┌─────────┐ │
│ │ Outputs │ │
│ │  (pins) │ │
│ └─────────┘ │
└─────────────┘
Build-Up - 7 Steps
1
FoundationUnderstanding Verilog Modules
🤔
Concept: Introduce what a module is and its basic structure in Verilog.
In Verilog, a module starts with the keyword 'module' followed by a name and a list of ports (inputs and outputs). Inside, you describe how the outputs relate to the inputs using logic statements. The module ends with 'endmodule'. Example: module simple_module(input a, input b, output c); assign c = a & b; endmodule
Result
Defines a simple AND gate module with inputs 'a' and 'b' and output 'c'.
Understanding the module structure is the first step to organizing hardware designs into reusable parts.
2
FoundationPorts: Inputs and Outputs
🤔
Concept: Learn how to declare inputs and outputs in a module and their role.
Ports are the connection points of a module. Inputs bring signals into the module, and outputs send signals out. You declare them inside the module header and specify their direction. Example: module example(input wire x, output wire y); assign y = ~x; endmodule
Result
Creates a module that outputs the inverse of input 'x'.
Knowing how to declare ports correctly is essential for connecting modules together.
3
IntermediateInternal Signals and Logic
🤔
Concept: Introduce internal wires and registers to hold intermediate values inside a module.
Inside a module, you can declare wires or registers to store temporary signals. Wires connect combinational logic, while registers hold values across clock cycles. Example: module internal_logic(input a, input b, output reg c); always @(*) begin c = a | b; end endmodule
Result
Defines a module where output 'c' is the OR of inputs 'a' and 'b'.
Understanding internal signals lets you build more complex behavior inside a module.
4
IntermediateInstantiating Modules Inside Modules
🤔Before reading on: do you think you can use one module inside another by just writing its name? Commit to your answer.
Concept: Learn how to use one module inside another to build complex designs.
Modules can be used like building blocks inside other modules by instantiating them. You give the instance a name and connect its ports to signals. Example: module top_module(input a, input b, output c); simple_module u1(.a(a), .b(b), .c(c)); endmodule
Result
Creates a top-level module that uses 'simple_module' inside it.
Knowing how to instantiate modules enables hierarchical design, making complex circuits manageable.
5
IntermediateParameterizing Modules for Flexibility
🤔Before reading on: do you think module parameters can change the module's behavior without rewriting it? Commit to your answer.
Concept: Introduce parameters to make modules configurable and reusable.
Parameters let you set values inside a module that can be changed when you use it. This makes modules flexible. Example: module counter #(parameter WIDTH = 8)(input clk, output reg [WIDTH-1:0] count); always @(posedge clk) begin count <= count + 1; end endmodule
Result
Defines a counter module with configurable bit width.
Parameters allow one module to serve many purposes, reducing code duplication.
6
AdvancedUnderstanding Module Scope and Namespaces
🤔Before reading on: do you think signals inside a module can be accessed directly from outside? Commit to your answer.
Concept: Explain how modules create separate scopes to avoid naming conflicts.
Each module has its own scope, meaning signals inside are private unless connected through ports. This prevents accidental interference between parts of a design. Example: module A(input a, output b); wire temp; assign temp = a; assign b = temp; endmodule Signals like 'temp' cannot be seen outside module A.
Result
Signals inside modules stay private unless exposed via ports.
Understanding scope helps prevent bugs caused by unintended signal sharing.
7
ExpertHow Modules Translate to Hardware
🤔Before reading on: do you think a module is just software code or does it directly map to physical hardware? Commit to your answer.
Concept: Reveal how Verilog modules become real hardware components during synthesis.
When you write a module, synthesis tools convert it into gates and flip-flops on a chip. The module's inputs and outputs become physical pins or wires. Hierarchical modules become connected hardware blocks. This means your code is a blueprint for actual circuits, not just instructions for a computer.
Result
Modules correspond to real hardware blocks on a chip after synthesis.
Knowing that modules map directly to hardware clarifies why design choices affect performance and resource use.
Under the Hood
Underneath, a Verilog module is a container for signals and logic descriptions. The simulator or synthesis tool reads the module's ports and internal statements, builds a network of logic gates and registers, and connects them according to the code. Each module instance creates a separate copy of this network, with its own signals isolated by scope. During synthesis, the tool maps these logical descriptions to physical hardware elements like LUTs, flip-flops, and routing resources.
Why designed this way?
Modules were designed to mirror how engineers think about circuits: as smaller blocks combined to form bigger systems. This modular approach simplifies design, testing, and reuse. Alternatives like flat designs without modules would be hard to manage and error-prone. The hierarchical module system also supports incremental development and clear interfaces.
┌───────────────┐       ┌───────────────┐
│   Module A    │──────▶│   Module B    │
│ ┌───────────┐ │       │ ┌───────────┐ │
│ │ Inputs    │ │       │ │ Inputs    │ │
│ │ Outputs   │ │       │ │ Outputs   │ │
│ │ Internal  │ │       │ │ Internal  │ │
│ │ Logic     │ │       │ │ Logic     │ │
│ └───────────┘ │       │ └───────────┘ │
└───────────────┘       └───────────────┘
       │                        ▲
       └─────────────┬──────────┘
                     │
             Connections via ports
Myth Busters - 3 Common Misconceptions
Quick: Do you think signals declared inside a module can be accessed directly from outside the module? Commit to yes or no.
Common Belief:Signals inside a module are globally accessible anywhere in the design.
Tap to reveal reality
Reality:Signals declared inside a module are private to that module and cannot be accessed directly from outside. Only ports expose signals externally.
Why it matters:Assuming internal signals are global can cause confusion and errors when trying to connect modules or debug signal behavior.
Quick: Do you think instantiating a module creates a shared copy of its signals or a separate copy? Commit to your answer.
Common Belief:All instances of a module share the same signals and state.
Tap to reveal reality
Reality:Each module instance has its own separate copy of signals and state, isolated from others.
Why it matters:Misunderstanding this leads to bugs when expecting changes in one instance to affect another.
Quick: Do you think a Verilog module is just software code that runs on a CPU? Commit to yes or no.
Common Belief:Verilog modules are software programs executed by a processor.
Tap to reveal reality
Reality:Verilog modules describe hardware structure and behavior that synthesis tools convert into physical circuits, not software.
Why it matters:Treating modules like software can cause wrong assumptions about timing, concurrency, and resource use.
Expert Zone
1
Modules can have parameters that affect not only values but also structural aspects like bus widths and number of instances, enabling highly flexible designs.
2
The order of port declarations and connections matters in some contexts, especially when using positional port mapping versus named mapping.
3
Modules support generate statements for conditional or repeated hardware instantiation, which is a powerful but often overlooked feature for scalable designs.
When NOT to use
Modules are not suitable for describing purely behavioral testbench code or software algorithms; for those, use testbench constructs or high-level languages. Also, for very simple glue logic, inline continuous assignments might be simpler than creating a separate module.
Production Patterns
In real-world designs, modules are organized hierarchically with clear interfaces. Designers use parameterized modules for reusable IP blocks, instantiate vendor-provided modules for common functions, and separate design and testbench modules. Naming conventions and directory structures help manage large module collections.
Connections
Object-Oriented Programming Classes
Modules in Verilog are similar to classes in OOP as both encapsulate data and behavior into reusable units.
Understanding modules as hardware 'classes' helps bridge software and hardware design thinking, showing how encapsulation aids reuse and organization.
Systems Engineering Modular Design
Both use modular building blocks to manage complexity by breaking systems into smaller, manageable parts.
Recognizing this connection highlights the universal value of modularity in engineering disciplines for scalability and maintainability.
Biological Cells
Modules are like cells that have defined boundaries and internal processes, working together to form complex organisms.
This analogy from biology shows how independent units with interfaces combine to create complex, functioning systems.
Common Pitfalls
#1Trying to access internal signals of a module directly from outside.
Wrong approach:module top; wire internal_signal; // Trying to connect directly to internal_signal of another module endmodule
Correct approach:module top; wire external_signal; submodule u1(.port_name(external_signal)); endmodule
Root cause:Misunderstanding module scope and how ports expose signals.
#2Using positional port connections and mixing up the order of signals.
Wrong approach:submodule u1(a, b, c); // ports connected by position, easy to mix order
Correct approach:submodule u1(.a(signal_a), .b(signal_b), .c(signal_c)); // named port mapping
Root cause:Not using named port mapping leads to connection errors and hard-to-find bugs.
#3Assuming module parameters can be changed inside the module body.
Wrong approach:module m #(parameter WIDTH = 8)(); parameter WIDTH = 16; // trying to override inside module endmodule
Correct approach:module m #(parameter WIDTH = 8)(); // Override parameter when instantiating: m #(.WIDTH(16)) instance_name(); endmodule
Root cause:Confusing parameter declaration with parameter override; parameters are set at instantiation.
Key Takeaways
Modules are the fundamental units in Verilog that encapsulate inputs, outputs, and internal logic to build digital circuits.
They create clear boundaries and scopes, preventing signal conflicts and enabling hierarchical design.
Parameters make modules flexible and reusable across different designs without rewriting code.
Instantiating modules inside others allows building complex systems from simple blocks.
Understanding that modules describe hardware structure, not software, is key to designing efficient and correct circuits.

Practice

(1/5)
1.

What is the main purpose of a module in Verilog?

easy
A. It defines a reusable block of hardware design.
B. It runs software programs inside the chip.
C. It stores data permanently like a hard drive.
D. It controls the power supply of the circuit.

Solution

  1. Step 1: Understand what a module represents

    A module in Verilog is a block that describes hardware behavior or structure.
  2. Step 2: Identify the purpose of modules

    Modules help organize and reuse hardware design parts, not software or power control.
  3. Final Answer:

    It defines a reusable block of hardware design. -> Option A
  4. Quick Check:

    Module = reusable hardware block [OK]
Hint: Modules are like building blocks for hardware [OK]
Common Mistakes:
  • Thinking modules run software code
  • Confusing modules with memory storage
  • Assuming modules control power
2.

Which of the following is the correct way to start and end a Verilog module named my_module?

?
easy
A. start my_module; finish
B. module my_module(); endmodule
C. begin my_module() end
D. module: my_module() endmodule:

Solution

  1. Step 1: Recall Verilog module syntax

    A module starts with the keyword module followed by the module name and ends with endmodule.
  2. Step 2: Check each option

    module my_module(); endmodule uses correct keywords and syntax. Others use invalid keywords or punctuation.
  3. Final Answer:

    module my_module(); endmodule -> Option B
  4. Quick Check:

    module ... endmodule = correct syntax [OK]
Hint: Modules always start with 'module' and end with 'endmodule' [OK]
Common Mistakes:
  • Using wrong keywords like start or finish
  • Missing parentheses after module name
  • Adding colons or semicolons incorrectly
3.

What will be the output of the following Verilog module when input_a = 1 and input_b = 0?

module simple_and(input input_a, input input_b, output reg out);
  always @(*) begin
    out = input_a & input_b;
  end
endmodule
medium
A. out = input_b
B. out = 1
C. out = input_a
D. out = 0

Solution

  1. Step 1: Understand the operation inside the module

    The module assigns out as the AND of input_a and input_b.
  2. Step 2: Calculate the AND of inputs

    Given input_a = 1 and input_b = 0, 1 & 0 = 0.
  3. Final Answer:

    out = 0 -> Option D
  4. Quick Check:

    1 AND 0 = 0 [OK]
Hint: AND output is 1 only if both inputs are 1 [OK]
Common Mistakes:
  • Assuming output equals one input directly
  • Confusing AND with OR operation
  • Ignoring that output is reg type
4.

Identify the error in this Verilog module code:

module faulty_module(input a, input b, output reg c);
  always @(*) begin
    c = a | b
  end
endmodule
medium
A. Wrong sensitivity list in always block.
B. Incorrect use of 'reg' for output.
C. Missing semicolon after assignment inside always block.
D. Module name should be capitalized.

Solution

  1. Step 1: Check syntax inside always block

    The assignment c = a | b is missing a semicolon at the end.
  2. Step 2: Verify other parts

    Using reg for output is correct; sensitivity list @(*) is valid; module names can be lowercase.
  3. Final Answer:

    Missing semicolon after assignment inside always block. -> Option C
  4. Quick Check:

    Statements inside always need semicolons [OK]
Hint: Always end statements inside always block with semicolon [OK]
Common Mistakes:
  • Forgetting semicolon after assignment
  • Thinking output cannot be reg
  • Believing sensitivity list must list signals explicitly
5.

You want to create a Verilog module named counter that counts from 0 to 3 repeatedly using a 2-bit output count. Which module header and port declaration is correct?

hard
A. module counter(input clk, output reg [1:0] count); endmodule
B. module counter(output reg [2:0] count, input clk); endmodule
C. module counter(input clk, output [1:0] count); endmodule
D. module counter(input clk, output reg count[1:0]); endmodule

Solution

  1. Step 1: Identify correct port order and types

    The clock input clk should be input, and count is a 2-bit register output, declared as output reg [1:0] count.
  2. Step 2: Check each option

    module counter(input clk, output reg [1:0] count); endmodule correctly declares ports and types. module counter(output reg [2:0] count, input clk); endmodule has wrong bit width. module counter(input clk, output [1:0] count); endmodule misses reg for output assigned inside always block. module counter(input clk, output reg count[1:0]); endmodule uses incorrect syntax for bus declaration.
  3. Final Answer:

    module counter(input clk, output reg [1:0] count); endmodule -> Option A
  4. Quick Check:

    Output reg [1:0] count with input clk = correct [OK]
Hint: Use 'output reg [bits]' for outputs assigned in always blocks [OK]
Common Mistakes:
  • Forgetting 'reg' for output assigned in always block
  • Incorrect bus declaration syntax
  • Swapping input and output order
Recommended

Ready to prove it?

Pass the test and this pattern moves unknown strong while earning +1 Grip toward your certificate.

10 questions~5 mineasy hard