Verilog module is the fundamental building blocks for digital designs. Each module performs a specific function and can be connected with other modules to create more complex systems. This article explains the syntax, purpose, and uses of Verilog modules, and also covers the concept of top-level modules, testbenches, and hierarchical naming.

What is a Verilog Module?

A module in Verilog is a block of code that represents a unit of functionality in a digital circuit. It can have inputs, outputs, and internal logic. You can combine smaller modules to build larger, more complex systems. Modules can also be reused in different designs, making the development process more efficient.

Syntax of a Verilog Module

A Verilog module is defined using the keywords module and endmodule. The module name comes after the module keyword, and the ports (input and output) are optionally listed in parentheses. Inside the module, you define its behavior using procedural blocks like always or initial.

Here’s the basic structure:

module <module_name> ([port_list]);
  // Module contents here
endmodule

If the module does not have ports, you can omit the port list:

module <module_name>;
  // Module contents here
endmodule

All variables, functions, tasks, and lower-level module instances must be defined within the module and endmodule keywords.

Example: D Flip-Flop (dff) with Verilog Module

Here is an example of a module for a D flip-flop (DFF) with three inputs (d, clk, rstn) and one output (q). This module assigns the value of d to q at the positive edge of the clock, unless the reset (rstn) is low, in which case the output is reset to 0.

module dff (
    input d,    // Data input
    input clk,  // Clock input
    input rstn, // Active-low reset
    output reg q // Output
);

  // Always block triggered on the positive edge of the clock
  always @ (posedge clk) begin
    if (!rstn)        // If reset is low, output q is 0
      q <= 0;
    else
      q <= d;        // Otherwise, output q takes the value of d
  end
endmodule

Hardware Schematic

When this module is synthesized, it will be converted into a digital circuit based on the logic defined in the module. For example, the module would become part of a flip-flop circuit.

hardware schematic of verilog module

Purpose of a Verilog Module

A Verilog module encapsulates a specific function, which is later translated into hardware. The inputs to a module can be manipulated to generate outputs, which makes the module reusable in various larger designs. For example, the dff module can be used to build a shift register.

Example: Shift Register Using D Flip-Flops

You can chain multiple D flip-flops together to create a shift register. Here is an example where four D flip-flops are connected to form a 4-bit shift register.

module shift_reg (
    input d,    // Data input
    input clk,  // Clock input
    input rstn, // Reset input
    output q    // Output
);

  wire [2:0] q_net; // Intermediate signals

  // Chain D flip-flops
  dff u0 (.d(d), .clk(clk), .rstn(rstn), .q(q_net[0]));
  dff u1 (.d(q_net[0]), .clk(clk), .rstn(rstn), .q(q_net[1]));
  dff u2 (.d(q_net[1]), .clk(clk), .rstn(rstn), .q(q_net[2]));
  dff u3 (.d(q_net[2]), .clk(clk), .rstn(rstn), .q(q));

endmodule

In this example, the output q from the last flip-flop is the final output of the shift register. Each flip-flop passes its output to the next one in the chain.

What Are Top-Level Modules?

A top-level module is the highest-level module in a design that contains all other modules. It is not instantiated within any other module. It includes all submodules, and it is the starting point of the entire design.

Example: Design Top-Level

In the design below, the top-level module is called design. It instantiates submodules mod1 and mod2, which in turn may contain other submodules.

//---------------------------------
//  Design code
//---------------------------------
module mod3 ([port_list]);
  reg c;
  // Design code here
endmodule

module mod4 ([port_list]);
  wire a;
  // Design code here
endmodule

module mod1 ([port_list]);
  wire y;

  mod3 mod_inst1 ( ... ); // Instance of mod3
  mod3 mod_inst2 ( ... ); // Instance of mod3
endmodule

module mod2 ([port_list]);
  mod4 mod_inst1 ( ... ); // Instance of mod4
  mod4 mod_inst2 ( ... ); // Instance of mod4
endmodule

// Top-level module
module design ([port_list]);
  wire _net;
  mod1 mod_inst1 ( ... ); // Instance of mod1
  mod2 mod_inst2 ( ... ); // Instance of mod2
endmodule

In this design, design is the top-level module, containing all other submodules such as mod1 and mod2.

What is a Testbench Top-Level Module?

In simulation, the top-level module is the testbench. The testbench provides input stimulus to the design and verifies its functionality. The design is instantiated within the testbench to simulate and verify the functionality of the entire system.

//-----------------------------------------------------------
// Testbench code
// The testbench is the top-level module for simulation
//-----------------------------------------------------------
module testbench;
  design d0 ( [port_list_connections] ); // Instantiating design module

  // Additional testbench code for simulation
endmodule

Hierarchical Names in Verilog Module

When modules are instantiated within each other, a hierarchical structure is formed. The top-level module is considered the root of the hierarchy. Each instance of a module can be accessed using a hierarchical name, which is a dot-separated path that specifies the instance and signal.

Example of Hierarchical Naming

Given the following structure:

  • design is the top-level module.
  • mod_inst1 is an instance of mod1.
  • mod_inst2 is an instance of mod2.

You can access the signals in the modules using hierarchical names:

design.mod_inst1          // Access the instance of mod_inst1
design.mod_inst1.y        // Access signal y inside mod_inst1
design.mod_inst2.mod_inst2.a // Access signal a inside mod4
testbench.d0._net;         // Access the signal _net in design from testbench

Comparison Table: Top-Level Module vs. Testbench

AspectTop-Level ModuleTestbench Module
DefinitionContains all other design modulesUsed for functional verification in simulation
PurposeCombines submodules to create a complete designVerifies design behavior by applying stimulus
InstantiationNot instantiated within other modulesInstantiates design modules for simulation
Simulation RolePart of the designTop-level for simulation

Conclusion

Verilog modules are essential building blocks for designing digital circuits. By understanding how to define, instantiate, and connect modules, you can create complex systems. Top-level modules are the highest-level modules in a design, and the testbench is the top-level module for simulation purposes. Using hierarchical names, you can easily access and manage signals across various modules.


Scroll to Top