Professional Documents
Culture Documents
The Verilog Language
The Verilog Language
The Verilog Language
The Verilog Language describes a digital system as a set of modules. Usually, we have a few sub modules that define the behavior of the system, and a top-level module that invokes instances of sub modules and defines the system as a hierarchical interconnection between them.
Modules
The structure of a module is the following: module <module name>(<port list>); <declares> <module items> endmodule We shall start with an example of a very simple top-level module that does not include any sub modules
Example
module Simple; reg [0:7] A,B; reg C; Here is the beginning of a module named Simple. It has no ports (input or output). It stores two 8-bit registers and a 1-bit register (flipflop). Keywords used: module, reg.
Example (cont.)
initial begin A = 0; $display(Time A B C); $monitor(%d %b %b %b,$time,A,B,C); end Here is a module item an initial block. begin and end are equivalent to { } in the C language. The $ words are special system tasks and functions, and will be discussed later. Keywords used: initial, begin, end.
Example (cont.)
always begin #1 A = A + 1; #1 B[0:3] = ~A[4:7]; #1 C = A[6] & A[7]; end Here is another module item an always block. The contents of registers A, B and C are manipulated using arithmetic and boolean operations. The # operation will be discussed later. Keywords used: always, begin, end.
Example Analysis
The module runs the initial and always blocks concurrently (much like a CPU executing tasks).
Within each block, the operations are executed sequentially (much like operations inside a function). Hence, the order of the blocks within the module does not matter, but the order of the operations within each block does.
The initial block runs only once whereas the always block runs over and over (as an infinite loop).
Example (cont.)
As mentioned, the always block in the module will run forever, like an infinite loop. In order to terminate the modules operation, we need to add a termination task (block): initial begin #20 $stop; end The special system task $stop terminates the modules operation. Here, it is executed after 20 units of simulation time.
Example
module NAND(in1,in2,out); input in1,in2; output out; assign out = ~(in1 & in2); endmodule Module NAND has three ports. Two of them, in1 and in2, are 1-bit input ports and the third, out is a 1-bit output port. The module item here is an assignment statement that puts a value into the output port. Keywords used: input, output, assign
Example (cont.)
module AND(in1,in2,out); input in1,in2; output out; wire w; NAND Nand1(in1,in2,w); NAND Nand2(w,w,out); endmodule This module has two instances of the NAND module called Nand1 and Nand2, connected together by a 1-bit wire called w. Keywords used: input, output, wire
Example (cont.)
module Test; reg A,B; wire Out1,Out2; AND AndGate(A,B,Out1); NAND NandGate(A,B,Out2); initial begin :TestData A = 0; B = 0; //Until 1 unit of time passes: Out1=0, Out2=1 #1 A = 1; //After 1 unit of time passes: Out1=0, Out2=1 #1 B = 1; //After another unit of time: Out1=1, Out2=0 #1 A = 0; //After another unit of time: Out1=0, Out2=1 end //Since no always block is defined, the program endmodule //terminates after 3 units of simulation time
Data Types
Since the purpose of Verilog is to simulate digital systems, the primary data types simulate registers and wires. A variable of type reg stores the last value that was assigned to it. This variable can only be assigned from within a block. It can be passed to other modules only as input, which means it cannot be assigned a value from within them (much like passing a variable to a function by value in the C language). Its size is 1 bit by default, but it can be declared bigger. For example, reg[0:3] X is a 4-bit register.
Timing Control
The Verilog language provides two ways of timing control: 1) You can have a task (block) waiting until X units of simulation time have passed. You do that by placing #X in the tasks code. 2) You can have a task (block) waiting until a certain change in the contents of X has occurred. You do that by placing @X in the tasks code. If there is no timing control, simulation time does not advance!!!
Examples
#10 A = 0; Wait 10 units of simulation time. This is the most basic way of timing control. It relies only on the systems timer. @clock1 A = 1; Wait until there is a change in the value of the register clock1. This timing control relies on changes in the value of your variable, making it easier for you to control the timing of certain operations in your module.
Examples (cont.)
@(posedge clock2) A = 2; //Wait until the value of the register clock2 changes from 0 to 1 (posedge is a special system function that must be followed by a 1-bit expression). @(negedge clock3) A = 3; //Wait until the value of the register clock3 changes from 1 to 0 (negedge is a special system function that must be followed by a 1-bit expression). wait (A == 3) B = 1; //Wait until the value of register A is 3. This timing control can be used for counting down before proceeding to the next operation.
Simulating a Clock
The delay operation #X is not very useful when you wish to control the timing of certain operations. It only delays these operations until X units of simulation time have passed, but it is not always easy to know precisely when that happens. As a convention, use it only to change the value of a clock register from 0 to 1 and viseversa. Then, use the clock register for all the other operations you wish to have timing control over.
Example
reg clock; initial clock = 0; always #1 clock = !clock; No need for begin and end in these blocks since they include only one operation always begin @(posedge clock); A = A + 1; B = B * A; end
$display $monitor $time Returns the current simulation time (must be used within an expression). $stop Terminates the operation of the module. $dumpvars(file_name) Writes the values of all the variables of the module into a file. This can later help in analyzing the modules behavior (using GTKWave, for example).