Lecture 1: Verilog HDL Introduction
What is Verilog HDL?
Verilog Hardware Description Language (HDL):
◦ A high-level computer based language can model, represent
and simulate digital design having feature of
Hardware concurrency
Parallel Activity Flow
Verilog is combination of the words "verification"
and "logic".
Verilog is only for Digital IC not for Analog IC.
Verilog used gate level design abstraction.
Importance of HDL
With the advent of VLSI , it is not possible to verify a
complex design with millions of gates on a breadboard,
HDLs came into the existence to verify the
functionality of these circuit.
Design can be described at very abstract level by used
of HDLs.
Designers can write their RTL (Register-transfer-
level) description without choosing a specific
fabrication technology.
Reasons to use HDL
An HDL makes you more productive in three ways:
Simulation: By allowing you to simulate your design, you can
see if the design works before you build it, which gives you a
chance to try different ideas.
Documentation: This feature lets you maintain and reuse
your design more easily. Verilog's intrinsic hierarchical
modularity enables you to easily reuse portions of your design
as “intellectual property” or “macro-cells.”
Synthesis: You can design using the HDL, and let other tools
do the tedious and detailed job of hooking up the gates.
Verilog Capabilities
It is case sensitive language.
It is vendor independent (Xilinx, Altera, Modelsim
Veriwell etc.)
It support synthesis. It is the process of converting the
verilog code in to netlist.
It supports simulation. In absence of real system, we
simulate the function by taking the model of that
function.
Verilog Capabilities (Cont.)
It is very similar to C programming language. Designer
with C programming experience will find it easy to
learn.
Verilog allows different levels of abstraction to be
mixed in same module. Thus, a designer can define a
hardware model in terms of switches, gates, RTL or
behavioral code.
The Design Abstraction Hierarchy
A circuit can be described at many levels. Figure lists a few of
them, from the abstract to the detailed.
Verilog can be used from the system level down to switches.
However, Verilog is most commonly used for behavioral and
gate levels.
Levels of Abstraction
Behavioral Level: The design based on algorithms. This is the highest level of
abstraction provided by Verilog HDL. A module can be implemented in terms of
the desired design algorithm without concern for the hardware implementation
details. Designing at this level is very similar to C programming.
Data flow Level: The design based on equation. At this level, the module is
designed by specifying the data flow. The designer is aware of how data flows
between hardware registers and how the data is processed in the design.
Gate Level: The design based on the interconnection with logic gates. The module
is implemented in terms of logic gates and interconnections between these gates.
Design at this level is similar to describing a design in terms of a gate-level logic
diagram.
Switch Level: Design implementation in term of switches. This is the lowest level
of abstraction provided by Verilog. A module can be implemented in terms of
switches, storage nodes, and the interconnections between them.
Introduction to Verilog Language
Constructs
IDENTIFIERS:
Identifiers are the names you give to your wires, gates, functions, and
anything else you design or use.
The basic rules for identifiers are as follows:
May contain letters (a-z, A-Z), digits (0-9), underscores (_), and dollar
signs ($).
Must start with a letter or underscore.
Are case sensitive (unless made case insensitive by a tool option).
May be up to 1024 characters long.
WHITE SPACE:
White space is the term used to describe the characters
you use to space out your code to make it more
readable.
Verilog is not a white-space-sensitive language, you
can insert white space anywhere in your source code.
Blank spaces (\b) , tabs (\t) and newlines (\n) comprise
the whitespace. Whitespace is ignored by Verilog
except when it separates tokens. Whitespace is not
ignored in strings.
COMMENTS:
Verilog has two formats for comments: Single-line
and block.
Single-line comments are lines (or portions of lines)
that begin with “//” and end at the end of a line.
Block comments begin with “/*”, end with “*/”, and
may span multiple lines.
NUMBERS:
In Verilog, there are three pieces of information
needed to form a number. The number of bits, the
radix, and the value. The number of bits and radix are
optional. The default radix is decimal.
Figure shows the notation used in Verilog to fully
represent a number.
Radix Specifiers
For Example:
8'b10100101
16'habcd
MODULES:
The main building block in Verilog is the module.
You can create modules using the keywords module
and endmodule.
You can write all your code inside these keywords.
Modules provide necessary information about input
and output ports but hide the internal implementation.
You build circuits in Verilog by interconnecting
modules and the primitives within modules.
Module Syntax
module<module_name>(input, output);
………….
<List of Program>
……….
endmodule
Declaration of input and output
After declaration of module, next step is to define the
input and output ports.
Example: input a,b; //two input each of one bit
If input or output are more than one bits then we can
define as below
Input [3:0]a,b; // four bit input
Output [3:0]c; // four bit output
SEMICOLONS:
Each Verilog statement ends with a semicolon.
The only lines that do not need semicolons are those
lines with keywords that end a statement themselves,
such as endmodule.
VALUE SET:
For logic simulation, we need more values than just
zeroes and ones.
You also need values to describe unknown values and
high impedance (not driving).
Verilog uses the values x to represent unknown and z
to represent high impedance (not driving).
Any bit in Verilog can have any of the values 0, 1, x,
or z.
PRIMITIVES
Verilog has a set of twenty-six built-in primitives. These
primitives represent built-in gates and switches.
The primitives and, nand, or, nor, xor, and xnor represent
simple logic functions with one or more inputs and one
output.
Buffers, inverters, and three-state buffers/inverters are
represented by buf, not, bufif1, bufif0, notif1, and notif0.
MOS-level unidirectional and bidirectional switches are
represented by the remaining primitives.
List of Verilog Primitives
PORTS
Ports in Primitives
All the built-in primitives (gates) have ports. The first
port of each of the built-in primitives (gates) is the output.
module and(a,b,c);
Input a,b;
Output c;
and m1(c,a,b);
endmodule
Ports in Modules
Modules can have ports. Verilog supports three port directions:
input, output, and inout (bidirectional).
In Verilog, you must declare the ports in two places: First, as part
of the port list in the module. Second, for the direction and size of
all the module’s ports using the input, output, and inout keywords
module and(a,b.c);
input a,b;
output c;
and m1(c,a,b);
endmodule
Options for port connections
When instantiating a module, the (actual) port names in the port list must be
in one-to-one correspondence with the module’s formal names. There are
two ways to make the association.
• Connection by position: The i th port in the instantiated list corresponds
with the i th port of the formal list.
module abc (q, clk, rst);
output [2:0]q;
input clk, rst;
tff a1(q[0],clk, rst);
tff a2(q[1],clk, rst);
tff a3(q[2],clk, rst);
endmodule
• Connection by name: The formal names are mapped to the
actual names using the notation .formal name (actual name).
module abc (q, clk, rst);
output [2:0]q;
input clk, rst;
tff a1(.q(q[0]), .clk(clk), .rst(rst));
tff a2 (.q(q[1]), .clk(clk), .rst(rst));
tff a3 (.q(q[2]), .clk(clk), .rst(rst));
endmodule
INSTANCES
When you use a built-in primitive, you make an
instance or copy of the built-in gate and list its
connections.
For making an instance of a built-in gate or modules
you are required to give it a unique name called an
instance name.
System Tasks For Displaying Results
There are some special built-in commands for system
functions such as printing messages or reading and
writing files.
These special commands are called system tasks.
They all begin with the “$” symbol.
Different types of System Tasks
Most commonly used system tasks are:
1. $display
2. $write
3. $strobe
4. $monitor
$display
$display system task is the basic way to print out
results. Different forms of this task are given here.
1) $display("Hello Verilog");
This simple form of $display simply prints the string
between the quotation marks.
2) $display(a);
The form of $display prints out the value of a in the
default radix, which is decimal.
Contd.
3)$display("The value of a is %b, The value of b
is %b", a, b);
This form uses format specifiers—in this case, the
format specifier %b —and then assigns a value to the
format specifiers.
In above Example the value of a is assigned as binary
for the first %b and the value of b as binary for the
second %b.
Format Specifiers
The $display command can be used to print out
binary, decimal, hexadecimal, or octal values. The
radix is controlled with format specifiers.
The most common format specifiers are listed in
Table.
Some more Format Specifiers
$write
$write is similar to $display: They both print results
when encountered.
The only difference between the two is that $display
automatically puts in a new line at the end of the
results, whereas $write does not.
If you need to print many results on a line and need to
use more than single $display statement, use $write
statements for the first part(s) of the line and then a
$display for the rest of the line.
Example1:Two $display Statements
1. module two_display;
2. initial
3. begin
4. $display("first half ");
5. $display("second half");
6. end
7. endmodule
Results
first half
second half
Example2:Combining $write and $display
1. module write_display;
2. initial
3. begin
4. $write ("first half ");
5. $display("second half");
6. end
7. endmodule
Results
first half second half
$strobe
If you want to print out your results only after all
values are finished changing at the current time unit,
use $strobe.
$strobe waits until just before time is going to
advance, then it prints. With $strobe you always get
the new value.
$monitor
Use $monitor system task to print results as they change,
$monitor automatically prints out whenever any of the
signals it is printing changes, so you only need to call it
once.
Only one $monitor can be active at a time. If you want to
change what is being printed, just execute another $monitor
system task.
$monitor can produce a lot of output, there are two more
special system tasks for stopping and restarting $monitor.
To stop the $monitor from printing, use the $monitoroff
command. To restart the $monitor, use the $monitoron
command.
Writing to Files
By default, Verilog puts all the output that goes to your
screen into a log file called verilog.log.
Along with sending output to the screen and log file,
Verilog can write up to thirty one additional files at the
same time.
File output is accomplished by declaring an integer that is
used to represent the file and then opening the file
Files are opened with $fopen keyword.
Once the file is opened, output commands similar to the
ones previously described may be used to write to the
file.
Contd.
For each of the commands covered so far, there is an f
prefixed version of the command for printing data to
files.
Example3:Writing to Files
1. module f1;
2. integer f;
3. initial begin
4. f = $fopen("myFile");
5. $fdisplay(f, "Hello Verilog File");
6. end
7. endmodule
Reference Books
“Verilog HDL - A guide to Digital Design and
Synthesis” by Samir Palnitkar.
“A Verilog HDL Primer” by J.Bhasker.