Verilog Tutorial
Verilog Tutorial
If you can express working of a digital circuit and visualize the flow of data inside a IC, then
learning any HDL or Hardware Description Language is very easy. This chapter is a overview of how
Verilog code looks like.
A B Y
0 0 0
0 1 0
1 0 0
1 1 1
In verilog, one circuit is represented by set of "modules". We can consider a module as a black
box. With this assumption, if you draw a block diagram of the circuit with a set of signals connection each
other, that is called top level design. Then go on writing modules for each black box, then design that
black box with in the same way. This is how we are designing a circuit. You will understand this concept
after studying some examples. A module may be one gate, one flip-flop, one register, one ALU one
controller or one SOC. Go back to the example. Here, module is keyword, andgate is the name given to
the module in this examples and a, b and y are the ports or connections to the module. Every modules
and with the keyword endmodule.
In the beginning of a module, we have to declare all ports as input output or inout. By default,
ports will have one pin or one bit.
Using 'assign' statement, we connected inputs and outputs via AND gate. A will be ANDed with B
and will be connected to Y. Here, we are not going to store the values, and hence we did not declare any
registers. By default, all the ports will be considered as wires. If we want the output to be latched, we
have to declare it using the keyword 'reg'.
input a, b;
output y;
wire a, b, y;
Next we will write a testbench to test the gate that we have created. Testbench is another verilog
code that creates a circuit involving the circuit to be tested. This code will send different inputs to the
code under test and get the output and displays to check the accuracy.
module andgate_tb;
wire t_y;
reg t_a, t_b;
initial
begin
t_a = 1'b0;
t_b = 1'b0;
#5
t_a = 1'b0;
t_b = 1'b1;
#5
t_a = 1'b1;
t_b = 1'b0;
#5
t_a = 1'b1;
t_b = 1'b1;
end
endmodule
Here we have created another module andgate_tb which will include the module andgate. We
have to give values to input, so we need to store or latch the input data. So, t_a and t_b are declared as
reg and t_y as wire fto get the outut value from the gate. Now, we create an instance of andgate. i.e., we
are placing the and gate that we have created previously inside this module. We can use two different
notations to connect the ports.
We can write andgate my_gate(t_a, t_b, t_y);. This is called instanciating by order. Here, all the ports
should be in the order as we declared in the module definition. If we write as given in the example, we
can change the order. That is,
andgate my_gate( .a(t_a), .b(t_b), .y(t_y) ); is equal to
andgate my_gate( .b(t_b), .y(t_y), .a(t_a) );. This is called instanciation by name. Like this, we can use any number
of instances of same module in a design.
'a' in the andgate will be connected to t_a in the andgate_tb and so on. If some of the statements
in our code is to be executed only in the beginning of the execution, we can write them using initial block.
initial block executes only once and starts at time=0. Your program may have any number of initial
blocks. initial block begins with begin and ends with end. Inside an initial block, statements will execute
sequentially. In next chapter, we will learn more about flow of execution of a program.
$monitor is a system task used to display the values in variable whenever value of one of its
arguments changes. After that we will assign different values to t_a and t_b. Here 1'b0 indicates a low
signal and 1'b1 represents a high signal. Meaning of this notation is, a 1 bit variable expressed in binary
as 1. Similarly we can also indicates decimal, hex, octal numbers as follows.