Verilog is a hardware description language (HDL) that one could easily learn and use because it looks like C language in syntax – the control flow statements like if and while, language operators and their precedence etc are similar to that of C. The language differs from the conventional programming language as the execution of statements is not strictly linear. Oh!! I forget to tell what a HDL is.. HDL is any language used for the formal description of electronic circuits. It describes the circuits operation and through simulations we can check if the circuit is behaving as we intend. With that the formal introduction of this article ends. Now let us do some Verilog-ing.
As a first step one need to design the circuit and then he has to decide how to use Verilog to describe it. For the time being let me focus on gate level modeling.
X = AB + C :: this is what I want to simulate using Verilog. The operation can be implemented using a single AND gate and an OR gate.
W0 is the wire where we get ‘a’ AND ‘b’ which is ORed with ‘c’ to get ‘x’. Now the circuit can be described by Verilog as follows:
The Verilog design consists of hierarchy of modules. Modules are defined and then instantiated in other modules. Module is defined using the keywords module and endmodule. Following the keyword module is the user defined module name, followed by a list of signals. Signals are interface of the module to other modules (think them as ports). Each port can be defined as input, output, inout etc… Another type called “wire” is used to define signals used to make simple connections between basic elements – in this case w0.
Next we have the body of the module. Verilog predefines AND, OR, NOT, NAND, NOR, XOR, XNOR and BUF. The convention for built-in gates is that their output signal is first port and the remaining ports are input.
Anything written after // is a comment as in the case with C.
Before using this module within other modules we need to test if everything is working according to our wish. In Verilog it’s a common practice to define a special module without any ports to test another module. It is commonly referred to as testbench. The following module represents a testbench for the module fun.
$monitor(“a=%b b=%b c=%b out=%b, expected out=%b time=%d”, l,m,n,f,expected,$time);
You can see assignment statements within the body of module test. This is a way to set a signal to a particular logic value at a particular time. The left hand side of assignments should be of type ‘reg’.
The fourth line is where we instantiate module fun with a local name test_fun. What follows is a list of connections between our local signals and the ports of module fun each one preceded by a ‘.’.
The initial keyword says that everything in the following block should be done at the start of simulation. The “#” followed by a number denote the time at which that statement is to be executed. The first statement will be executed at 0ns from the time of simulation, the second at 10ns from previous, etc… And the simulation ends with $finish.
The last step is to do something so that we could observe the simulation. For this we use another “initial” block which uses a special built-in function named $monitor which watches the signals that are connected to it and prints out whenever any one of them change. “%b” denotes that the number is represented in binary and “%d” for decimal. The simulation time is obtained from $time
This is what we get when we run the program
a=0 b=0 c=0 out=0, expected out=0 time= 0
a=0 b=0 c=1 out=1, expected out=1 time= 10
a=0 b=1 c=0 out=0, expected out=0 time= 20
a=0 b=1 c=1 out=1, expected out=1 time= 30
a=1 b=0 c=0 out=0, expected out=0 time= 40
a=1 b=0 c=1 out=1, expected out=1 time= 50
a=1 b=1 c=0 out=1, expected out=1 time= 60
a=1 b=1 c=1 out=1, expected out=1 time= 70
That looks cute, right?