Vous êtes sur la page 1sur 30

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 Analysis (cont.)


The #1 operation inside a block signals the module that the block at that point should stop running for 1 unit of simulation time (much like a task that is preempted from the CPU into suspend state). The module counts X units of simulation time whenever a #X operation is executed. This is essential in order to synchronize between the various tasks (blocks) of the system (module).

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 Analysis (cont.)


In the example given, the system task $stop is executed from within an initial block after 20 units of simulation time. It is important to understand, that if the #1 operation was not given in the always block, 20 units of simulation time would never be counted by the module, the $stop task would not be executed and the always block would run forever.

Example Special Notes


In order to conclude the module, at the bottom of the file write endmodule (without a ;). All keywords are written with lower case letters. Pay attention to correct syntax (;, lower case letters, etc.), since locating parse errors can be a real burden sometimes.

Example Special Notes (cont.)


A block can be given a name - follow the begin reserved word with :BlockName. Similarly to the C language, when only one operation is included in a block, begin and end are optional (not a must). Besides assignment statements (i.e. x = 5;), other operations that can be used inside a block include selection statements (if/else, case) and repetition statements (for, while, repeat). These statements also use begin/end in order to scope the code they execute.

More About Modules


The semantics of the module construct in Verilog is very different from subroutines, procedures and functions in other languages. A module is never called. It is instantiated at the start of the program and stays around throughout the lifetime of the program. We shall now continue with an example of a sub module called NAND, a sub module called AND that includes 2 instances of NAND, and a toplevel module called Test that includes instances of both and runs tasks in order to test their output

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.

Data Types (cont.)


Unlike the reg variables, a variable of type wire does not store a value. Just like a wire, it needs to be electrically charged continuously in order to store data, and is used in order to connect between two modules (by passing that data from one module to the other). This variable can be charged using the assignment statement assign (not inside blocks, which means it is continuously assigned). It can be passed to other modules as input or output, which means it can be assigned a value from within them (much like passing a variable to a function by reference in the C language). Its size is 1 bit by default, but it can be declared bigger. For example, wire[0:3] X is a 4-bit wire.

Data Types - Values


Each bit in a register or a wire may have any of the following values: 0 false 1 true x unknown Register bits have the value x until they are assigned 0 or 1. Wire bits have the value x unless (or until) they are connected to something.

Data Types Values (cont.)


Unlike with programs in the C language for example, where you would expect your program to crash if you did not initialize your memory variables, modules in Verilog do not crash under the same circumstances. If you think about it, when some program crashes, you get an error message (a blue screen one in the worst case). The hardware itself does not cease to operate (you wouldnt get that message otherwise).

Data Types Values (cont.)


Therefore, the x (unknown) value is taken in consideration and is treated like so: This value merely states that the flip flop can be charged with either 0 or 1. For example, if register A has the value x, then As value can be either 0 or 1: 1) The result of A & 1 can be either 0 or 1 and is therefore x. 2) The result of A & 0, on the other hand, can only be 0 (and is therefore 0).

Data Types Notes


As in the previous example, when designing a module with ports, it is required to declare which ones are for input and which ones are for output. Just like registers and wires, the size of ports is 1 bit by default, but can be declared bigger When passing data from one module to another, the input can be passed only by value (register variables, constant numbers or the passing modules input ports). The output is passed only by reference (wire variables or the passing modules output port).

Data Types Notes (cont.)


Apart from setting the size of the variable, the indices inside the [ ] also determine the order of the bits: Reg[0:3] X is a 4 bit register whose MSB is the last bit. Reg[3:0] X is a 4 bit register whose MSB is the first bit. This is important when referring to the numeric value of the whole register (and not just to the value of specific bits in it).

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

System Tasks and Functions


Here are a few useful built-in tasks (always starting with a $): 1) $display() Displays text to the screen much like the printf function (%b, %c, %d, %h, %o and %s specify the format of the printed argument). This task is executes once, when invoked. 2) $monitor() Acts the same as the $display task, only it continues executing until the module operation is terminated. Displays the text whenever variables in it change (thus allowing us to monitor changes in them).

System Tasks and Funcs (cont.)


1) 2) 3) 4) 5)

$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).

Compile and Execute


Verilog modules run on a virtual machine and not directly on the CPU (much like Java programs). In order to build a Byte Code from the file Mudule.txt, run the command line: iverilog -o Module.out Module.txt If no parse errors are detected, a file named Module.out is created. In order to execute the module in the file Module.out, run the command line: vvp Module.out *The initials txt and out are used here only as an example and are not a must

Vous aimerez peut-être aussi