Basics of Verilog
Verilog is based on modular programming, i.e., the designs are written in small modules and then it can be combined to make a complex design. Modules can be thought of as classes, expect the fact that modules are not dynamic, i.e., objects cannot be made of modules as we can do for classes in OOPs language. But modules can be instantiated multiple times and can thus be reused just like classes.
From hardware point of view, every circuit will have a input and output port. Thus, for every module we have to also write the different I/O ports associated with it.
Verilog Template
Every module in verilog follows a common template. Steps to write Verilog module:
- First a module is declared using
modulekeyword followed by the name of the module. At the end of module statement;is a must. Each module statemtent will also have aendmoduleassociated with it, which marks the end of the module.
- If module have I/O pins then the ports are defined after the module name using simple brackets
().
- Sometimes, we may need to use some internal variables, i.e., variables which are not directly accessed from outside the modules. So we need to declare these internal variables.
- If we want to use some other module inside our module then we instantiate that module and properly connect with them. The syntax to instantiate a module is:
[module name] [identifier] ([port-connection]) - Now we write the code for this module.
So the final template looks like:
Example
In this example, we will design a 1-bit half adder. For half adder, there are 2 inputs, in this case, A & B and 2 outputs, sum & carry.
Testbench
To run any code, we need to provide some inputs to the code. As in Verilog we are representing hardware, thus the inputs and outputs will be in the form of signals. To give the input as signals we need to make a test bench, from which we can provide inputs to our design and get the output. In technical terms, the design which is tested is known as Device under Test (DUT) or Device under verification (DUV).
Steps to write the testbench:
- Declare a module for testbench as we do in design. But for testbench module, there is commonly no I/O ports required as we will generate the input for our design in this module.
- Declare internal variables which will act as the input/output to our design.
- Instantiate the design module and connect the internal variables with correct I/O ports.
- Generate different inputs.
Example
Let's see how the test bench for the half adder module will be like.