- AboutUs
- Academic
- Admission
- Department
- Sciences
- ArchiTecture
- BioTechnology
- CHemical
- CiVil engineering
- Computer Science
- Electrical & Electronics
- Electronics & Communications
- Industrial engg. Management
- Information Science
- Instrumentation Technology
- Mechanical Engineering
- Medical Electronics
- Telecommunication Engineering
- M B A
- M C A
- Humanities
- Activities
- Facilities
- PhotoGal
- SIS
- CheckMail
- ContactUs
- News
VERILOG TUTORIAL1
Verilog Tutorial
1.0 Syntax – comments, punctuation, variable names, signalvalues, constants, parameters, and memory.
• Comments – Verilog comments are the same as in C++. Use // for a single line comment or /* … */ for a multiline comment.
• Punctuation – white spaces are ignored in Verilog. A semicolon is used to indicate the end of a command line and commas are typically used to separate elements in a list. Like C++, Verilog is case sensitive.
• Identifiers – An identifier is usually a variable. You can use any letter, digit, the underscore, or $. Identifiers may not begin with a digit and may not be the same as a Verilog key word. As in C++ variable names should be chosen to assist in documentation. May use any character by escaping with a backslash ( \ ) at the beginning of the identifier, and terminating with a white space. May contain the characters a-z A-Z 0-9 _ and $
|
Examples |
Notes |
|
adder |
legal identifier name |
|
XOR |
uppercase identifier is unique from xor keyword |
|
\reset* |
an escaped identifier (must be followed by a white space) |
• Signal values – signals in Verilog have one of four values. These are 0 (logic 0), 1 (logic 1), ?, X, or x ( don’t care or unknown), and Z or z for high impedance tri-state.
• Constants – The generic declaration for a constant in Verilog is
[size]['radix] constant_value
In this declaration size indicates the number of bits and 'radix gives the number base (d = decimal, b = binary, o = octal, h = hex). The default radix is decimal.
Examples
16 //The number 16 base 10
4'b1010 //The binary number 1010
8'bx //An 8-bit binary number of unknown value
12'habc //The hex number abc = 1010 1011 1100 in binary
8'b10 //The binary number 0000 0010
• Parameters – a parameter in Verilog can be any Verilog constant. Parameters are used to generalize a design. For example a 4-bit adder becomes more useful as a design if it is put together as an n-bit adder where n is a parameter specified by the user before compilation. Parameter declarations are done immediately after the module declaration.
Here are some typical parameter examples:
parameter n = 12;
parameter [3:0]p1 = 4'b1011;
parameter n = 12, m = 32;
• Memory – Verilog allows for two dimensional arrays which typically get used for memory spaces.
Example reg[7:0] m[63:0]; declares m to be a two-dimensional array consisting of 64 eight-bit words. You can access any word as m[2] for example but you do not get access to the bits in the word unless you copy the word to another 8-bit reg variable.
2.0 Structure – Modules, ports, and signals.
• Module – A module in Verilog is used to define a circuit or a sub circuit. The module is the fundamental circuit building block in Verilog. Modules have the following
structure: (keywords in bold). Note that the module declaration ends with a semicolon but the keyword endmodule does not.
module module_name (port_name list);
[declarations]
[assign statements]
[initial block]
[always block]
[gate instantiations]
[other module instantiations]
endmodule
• Ports – Ports in Verilog can be of type input, output¸ or inout. The module ports are given in the port name list and are declared in the beginning of the module. Here is a sample module with input and output ports.
module mymodule(aIn,bOut);
input aIn;
output bOut;
…
endmodule
;
The port names input and output default to type wire. Either can be a vector and the output variables can be of redeclared to type reg. The output and input variables in a module are typically names for the output and input pins on the implementation chip.
Signals – a signal is represented by either a net type or a variable type in Verilog. The net type represents a circuit node and these can be of several types. The two net types most often used are wire and tri. Type nets do not have to be declared in Verilog since Verilog assumes that all signals are nets unless they are declared otherwise. Variables are either of type reg or integer. Integers are always 32-bits where the reg type of variables may be of any length. Typically we use integers as loop counters and reg variables for all other variables.
The generic form for representing a signal in Verilog is:
type[range] signal_name
The range is omitted for scalar variables but used for vectors.
The net types are typically used for input signals and for intermediate signals within combinational logic.
Variables are used for sequential circuits or for outputs which are assigned a value within a sequential always block.
Examples:
wire w; //w is a single net of type wire
wire[2:0] wVect; //Declares wVect[2], wVect[1], wVect[0]
tri[7:0] bus //An 8-bit tri state bus
integer i; //i is a 32-bit integer used for loop control
reg r; //r is a 1-bit register
reg[7:0] buf; //buf is an 8-bit register
reg[3:0] r1, r2 //r1 and r2 are both 4-bit registers
3.0 Combinational Circuits – Gates, continuous assignment and operators.
Gate – The general form for declaring the instance of a gate in Verilog is
gate_type [gate_name](out_port, in_port …);
The gate_type specifies the type of gate you want to use such as and, or, xor, etc. The gate name is optional and is user assigned. The port list in parenthesis, typically
consists of an output port (always first) followed by a comma separated list of input ports. Here are some gate instantiation examples:
module AndOr(f, u, v, s);
input s, u, v;
output f;
wire w1, w2; wire ns;
and A1(w1, u, s);
not N1(ns, s);
and A2(w2, v, ns);
or O1(f, w1, w2);
endmodule
Figure 1 Verilog code for a 2 to 1 multiplexer
module mux4to1(f, s0, s1, aIn);
output f;
input s0, s1;
input [3:0]aIn;
wire ns0, ns1;
wire a0, a1, a2, a3;
//
not nots0(ns0, s0);
not nots1(ns1, s1);
//
and and0(a0, ns0, ns1, aIn[0]);
and and1(a1, s0, ns1, aIn[1]);
and and2(a2, ns0, s1, aIn[2]);
and and3(a3, s0, s1, aIn[3]);
//
or or1(f, a0, a1, a2, a3);
endmodule
Figure 2 Verilog code for a 4 to 1 multiplexer
Note that gates declared in this fashion are said to be concurrent. In other words, sequential ordering of gates is not considered; all gates are done in parallel.
• Continuous Assignment Statement – In Verilog the assign statement is used to assign a value to a net type (wire or tri) outside of an always block. The assign statement is implied when you assign a value to a wire during its declaration. Thus wire w1 = a ^ b; is the same as wire w1; assign w1 = a ^ b; Note that continuous assignment statements are concurrent. In other words, if we write two assignment statements such as:
assign w1 = a ^ b;
assign w2 = c | d;
Verilog takes the two assignment statements as happening at the same time in parallel and not sequentially as shown. This is very different from most programming languages. The three modules in Figure 3 have the same result. The order of assignment statements is of no importance since all assignment statements are done in parallel.
module mux4to1Asn(f, s1, s0, aIn);
output f;
input s1, s0;
input [3:0]aIn;
assign f = ~s1&~s0&~aIn[0] | ~s1&s0&aIn[1] |
s1&~s0&aIn[2] | s1&s0&aIn[3];
endmodule
Figure 4 The Verilog code for the 4 to 1 multiplexer using the assignment operator.
• Operators – Operators in Verilog are similar to those in C++. The list below shows some examples and notes differences from what would be expected in C++.
Bitwise operators – The bitwise operators work as in C++. The don't care (x) and high impedance (z) states can also be used with these operators. The result is always another variable.
Logical operators – These operators work the same as C++ and return either true(1) or false (0). If an operand has an x or z bit the result is x or z. Note that the logical not operator inverts true or false and that x inverts to x. This is different from the bitwise not operator (~) which returns an inverted bit.
Reduction operators – These operators are not in C++. They operate in a unary fashion on all of the bits in a single variable. For example y = &x would make y become the logical AND of all of the bits in x. xor and xnor can be used to quickly determine parity.
Arithmetic operators – These operators work the same as in C++ except if any bit in an operand is x then the result is x.
Relational operators – The relational operators return true (1) or false (0). If any bit is an x then these operators return x. If any bit is a z then these operators fail.
Equality operators – The == and the != operators are the same as in C++ with the exception that if any operand has an x bit then the result is x. The === and !== operators compare x to x and z to z and return true (1) or false (0). (=== and !== are for simulation only.)
Miscellaneous operators – The shift operators work the same as in C++. The concatenation operator allows you to stick words or bits together to form new words. For example c = {a[0], b[7:1]}; forms a new 8-bit word consisting of the 0th bit of a and the most significant 7 bits of b. The repetition operator allows you to concatenate multiple words. For example
c = {3{a}};
makes c the same as {a, a, a}
4.0 Control Structures – Control constructs, always, if, case, for, and while
• Control Constructs – Verilog's control constructs can be thought of as existing in two categories called concurrent constructs and sequential constructs. Concurrent constructs happen in parallel and sequential constructs happen like they are written as in a computer program. The two concurrent constructs here are gate instantiation and the continuous assignment statement.
Sequential constructs commonly used in Verilog include the always and initial blocks, the if and case structures, and the for and while loops.
Always and Initial blocks – The always and initial blocks are similar in structure. The Initial block provides initial values for simulation purposes and does not play a role in circuit synthesis. The initial block, then is used in conjunction with a Verilog simulator to establish initial values. For example, initial values may be needed for testing purposes in a simulated environment. For circuit synthesis we use the Always block and such a block must contain all sequential constructs. Thus the if, case, for loop, and while loop must appear inside an always block. The general syntax for an Always block looks like this:
Always @(sensitivity_list)
[begin]
[sequential statements consisting of assignment, if, case,
while, and for loops. May also include task and
function calls.
]
[end]
The sensitivity list is a list of the variables which, if changed, would produce a different output in the always block.
The @ sign is referred to as event control operator. The sensitivity list is used by Verilog simulators to determine when the always block should be executed and updated.
The sensitivity list consists of variables separated by the word or as in always @(a or b or c).
Verilog 2001 allows for a comma separated list as in always @(a, b, c)
Note that the statements in an always block between begin/end are executed sequentially just as they are written. For modules that have multiple always blocks however, all of the always blocks are executed in parallel.
Variables assigned a value inside and always block must be of type reg or integer. You may not assign type wire or tri (nets) a value inside an always block. (This would be very confusing since continuous assignments to wires are concurrent operations and the code inside an always block is sequential.)
