Basics

What is a module?

A module describes a chunk of hardware intended to perform a specific task.

It can contain:

module MAJ(a, b, c, m);
            input a, b, c;
            output m;
        
            and a1(ab, a, b);
            and a2(ac, a, c);
            and a3(bc, b, c);
            or o(m, ab, ac, bc);
        endmodule

The module described above is a 3-bit majority module—it takes in 3 bits as inputs (a, b, c), and outputs m as 1 if 2 or more of the inputs are 1, or 0 if not.

What is a reg?

A reg (register) is a data structure in Verilog that has memory. That is, it can retain its values across ‘time steps’.

For example, if you wanted a value to be updated at a regular (or irregular) time interval, like the positive edge of a clock, you would store it in a reg.

What is a wire?

A wire is a data structure in Verilog that doesn’t have memory, and is continuously ‘driven’ a value. For example, the outputs of a module are usually wires since they are continuously assigned a value by the logic it contains.

What are module ports?

A port is an input or output to a module.

In the MAJ module described above, a, b, c, and m are ports. While the first 3 are input ports, the latter is an output port.

Ports can be connected to other modules, and allow data to be transported in and out of the module.

module Majority(SW, LEDG);
            input [2:0] SW;
            output [0:0] LEDG;
            
            MAJ maje(.a(SW[2]), 
                    .b(SW[1]), 
                    .c(SW[0]), 
                    .m(LEDG[0]));
        endmodule

For example, the above module Majority contains an instance of MAJ called maje. It connects different indices of SW to input ports a, b, and c of maje, and LEDG to the output port m.

This method of instantiating the ports is called connecting ports by name. We can also connect them by order:

MAJ maje(SW[2], 
                SW[1], 
                SW[0], 
                LEDG[0]);

In this case, SW and LEDG are connected to the ports of maje in the order in which they were declared in MAJ’s module header:

module MAJ(a, b, c, m);

SW[2] gets connected to a, SW[1] to b, SW[0] to c, and LEDG[0] to m.

Ports are wires by default. In some situations, you may want specific ports to be of a different type (e.g. reg) which you can do by specifying so (output reg <name of port>).

What is a testbench?

A testbench is a special type of module used to test other modules. It typically doesn’t have input or output ports. Instead, it instantiates the modules to be tested, and has regs and wires to simulate their behavior.

`timescale 1 ns/1 ns    // time scale for simulation
        
        module TestBench();
            reg [2:0] SW;
            wire [0:0] LEDG;
        
            MAJ M(.a(SW[2]), .b(SW[1]), .c(SW[0]), .m(LEDG[0]));
        
        // Test Procedure
            initial begin
                SW = 3'b000; #5;
                SW = 3'b001; #5;
                SW = 3'b010; #5;
                SW = 3'b011; #5;
                SW = 3'b100; #5;
                SW = 3'b101; #5;
                SW = 3'b110; #5;
                SW = 3'b111; #5;
            end
        endmodule

The above code block describes a testbench for the MAJ module. It passes in all possible combinations of SW as inputs to the module. A waveform simulator (such as Modelsim), can then be used to view the outputs generated by the module for each of these SW combinations.