Logo

Verilog Modules

01 Sep 2021
3 mins

Modules are basic building block of a Verilog program. These are the blocks which represent functionalities of a hardware. Modules can be embedded inside another module, or one module can be connected to another module to make complex designs.

Module declaration

A module is declared using a module keyword followed by the name of the module. Name of the module should follow the identifier rules as discussed earlier. Also, ports can be declared after the name, if required.

Top Level Module

There can be many modules in a Verilog design. The top module is the one which is not instantiated inside any other module, which means it can be directly accessed. This can also be considered as the entry point of the code from where execution starts.

In Design

The module which contains all other modules of the design is the top module. All outside connection to the design is through the top module only.

In test bench

Whenever, we make a testbench, it is always the topmost module. It is not instantiated in any other module, but the design in instantiated inside the test bench.

Parameterized Modules

In Verilog, we modularize our design and different modules can be reused in other application also. Thus, to make the modules more flexible we parameterize it, to increase the reusability. parameter data type is used to define the parameters for the module. By default the parameter has a width of 32 bits, which can be changed by providing any other width.

Ex – Parameters can be used to define the width of the adder.

Syntax

To parameterize the modules, we use #() after the module name and before the port list.

In the below example the module param_demo is parameterised. The parameter name is WIDTH, which has a default value of 16. In the module, the width of the different port depends upon the WIDTH parameter which can be changed during instantiation.
In the tb_top module, the param_demo module is instantized 2 times, but with different parameters (8 and 32). Thus, making a module parameterized makes it more flexible and reusable.

// Declaration of parameterised module
module param_demo #(parameter [7:0] WIDTH=16)(
    input  wire[WIDTH-1:0] a, b,
    output wire[WIDTH-1:0] sum
);
    assign sum = a+b;
endmodule

module tb_top;
    reg [7:0] a, b;
    wire [7:0] sum;
    // Instantiation of parameterised module
    param_demo#(8) dut( 
                .a(a),
                .b(b),
                .sum(sum));

    param_demo#(32) dut2( 
                .a(a),
                .b(b),
                .sum(sum));
endmodule
Try this code in EDA Playground