Verilog Subset Manual
&
VeriWell Subset User's Guide
by
M. Katevenis
C. Spyridakis
Spring '99
1. About this paper
You can find it online at http://www.csd.uch.gr/~hy225/veriwell/verilog_manual.html.
Also some usefull papers can be found at :
1."Handbook on Verilog
HDL" by Dr. Daniel Hyde (http://www.cs.usask.ca/undergrads/smd125/verilog/verilog-manual.html).
2."VeriWell User's
Guide" (http://www.cs.tamu.edu/course-info/cpsc321/spring98/bhuyan/veriwell.txt).
2.1 Lexical Conventions
The lexical conventions are close to the programming
language C++. Comments are designated by // to the end of a line
or by /* to */ across several lines. Keywords, e. g.,
module, are reserved and in all lower case letters. The language is
case sensitive, meaning upper and lower case letters
are different. Spaces are important in that they delimit tokens in the
language.
Numbers are specified in the traditional form of a series
of digits with or without a sign but also in the following form:
<size><base format><number>
where <size> contains decimal digits that specify
the size of the constant in the number of bits. The <size> is optional.
The <base format> is the single character ' followed
by one of the following characters b, d, o and h, which stand for
binary, decimal, octal and hex, respectively. The <number>
part contains digits which are legal for the <base format>.
Some examples:
549 // decimal
number
' h 8FF //
hex number
'o765 // octal
number
4'b11 // 4-bit
binary number 0011
3'b10x //
3-bit binary number with least
/ / significant
bit unknown
5'd3
// 5-bit decimal number
-4'b11 //
4-bit two's complement of 0011 or 1101
The <number> part may not contain a sign. Any sign
must go on the front.
An identifier is specified by a letter or underscore
followed by zero or more letters, digits, dollar signs and underscores.
Identifiers can be up to 1024 characters.
2.2 Program Structure
The Verilog language describes a digital system as a
set of modules. Each of these modules has an interface to other
modules to describe how they are interconnected. The
modules may run concurrently, but usually we have one top level module
which specifies
a closed system containing both test data and hardware
models. The top level module invokes instances of other modules.
A structural specification expresses the behavior of
a digital system (module) as a hierarchical
interconnection of sub modules. At the bottom of the
hierarchy the components must be primitives or specified
behaviorally. Verilog primitives include gates, e. g.,
nand, as well as pass transistors (switches).
The structure of a module is the following:
module <module
name> (<port list>);
<declares>
<module
items>
endmodule
The <module name> is an identifier that uniquely names
the module. The <port list> is a list of input, inout and output
ports which are used to connect to other modules. The
<declares> section specifies data objects as registers, memories
and wires.
The <module items> may be initial constructs, always
constructs, continuous assignments or instances of modules.
Module items run concurrently.
The semantics of the module construct in Verilog is very
different from subroutines, procedures and functions in other
languages. A module is never called! A module is instantiated
at the start of the program and stays around for the life of the
program. A Verilog module instantiation is used to model
a hardware circuit where we assume no one unsolders or
changes the wiring.
The general form to invoke an instance of a module is
:
<module name> <parameter list> <instance name> (<port list>);
where <parameter list> are values of parameters passed
to the instance. An example parameter passed would be the
delay for a gate.
2.3 Data Types
2.3.1 Physical Data Types
Since the purpose of Verilog HDL is to model digital
hardware, the primary data types are for modeling registers (reg)
and wires (wire). The reg variables store the last value
that was procedurally assigned to them whereas the wire
variables represent physical connections between structural
entities such as gates. A wire does not store a value.
The reg and wire data objects may have the following
possible values:
0 logical
zero or false
1 logical
one or true
x unknown
logical value
z high impedance
of tristate gate
The reg variables are initialized to x at the start of
the simulation. Any wire variable not connected to something has the x
value.
You may specify the size of a register or wire in the
declaration For example, the declarations
reg [0:7]
A, B;
wire [0:3]
Dataout;
reg [7:0]
C;
specify registers A and B to be 8-bit wide with the most
significant bit the zeroth bit, whereas the most significant bit of
register C is bit seven. The wire Dataout is 4 bits wide.
The bits in a register or wire can be referenced by the
notation [<start-bit>:<end-bit>].
For example, in the second procedural assignment statement
initial begin:
int1
A = 8'b01011010;
B = {A[0:3]
| A[4:7], 4'b0000};
end
B is set to the first four bits of A bitwise or-ed with
the last four bits of A and then concatenated with 0000. B now holds a
value of 11110000. The {} brackets means the bits of
the two or more arguments separated by commas are concatenated
together.
An argument may be replicated by specifying a repetition
number of the form:
{repetition_number{exp1, exp2, ... , expn}}
Here are some examples:
C = {2{4'b1011}};
//C assigned the bit vector 8'b10111011
C = {{4{A[4]}},
A[4:7]}; // first 4 bits are sign extension
The range referencing in an expression must have constant
expression indices. However, a single bit may be referenced by
a variable. For example:
reg [0:7]
A, B;
B = 3;
A[0: B] =
3'b111; // ILLEGAL - indices MUST be constant!!
A[B] = 1'b1;
// A single bit reference is LEGAL
Why such a strict requirement of constant indices in
register references? Since we are describing hardware, we want only
expressions which are realizable.
Memories are specified as vectors of registers. For example,
Mem is 1K words each 32-bits.
reg [31:0]
Mem [0:1023];
The notation Mem[0] references the zeroth word of memory.
The array index for memory (register vector) may be a
register. Notice that one can not reference a memory
at the bit-level in Verilog HDL. If you want a specific range of bits in
a word of memory, you must first transfer the data in
the word to a temporary register.
2.4 Operators
2.4.1 Bitwise Operators
Bitwise operators operate on the bits of the operand
or operands. For example, the result of A & B is the AND of each
corresponding bit of A with B. Operating on an unknown
(x) bit results in the expected value. For example, the AND of
an x with a FALSE is an x. The OR of an x with a TRUE
is a TRUE.
Operator Name Comments
~ Bitwise
negation
& Bitwise
AND
| Bitwise
OR
^ Bitwise
XOR
~& Bitwise
NAND
~| Bitwise
NOR
~^ or ^~ Equivalence
Bitwise NOT XOR
2.4.2 Unary Reduction Operators
Unary reduction operators produce a single bit result
from applying the operator to all of the bits of the operand. For
example, &A will AND all the bits of A.
Operator Name Comments
& AND
reduction
|
OR reduction
^ XOR reduction
~& NAND
reduction
~| NOR reduction
~^ XNOR reduction
2.5 Continuous Assignment
Continuous assignments drive wire variables and are evaluated
and updated whenever an input operand changes value.
The following ands the values on the wires in1 and in2
and drives the wire out. The keyword assign is used to
distinguish the continuous assignment from the procedural
assignment. See Section 2.3 for more discussion on continuous
assignment.
assign out = ~(in1 & in2);
2.6 Timing Control
2.6.1 Delay Control ( #)
A delay control expression specifies the time duration
between initially encountering the statement and when the statement
actually executes. For example:
#10 A = A + 1;
specifies to delay 10 time units before executing the
procedural assignment statement. The # may be followed by an
expression with variables.
2.7 Compiler directives.
`include "filename"
//inserts contents of file into current file; write it anywhere in code.
`define <text1> <text2>
// e.g. `define WIDTH 32
2.8. Using the VeriWell Simulator
2.8.1 Creating the Model File
Enter the Verilog code using your favorite editor. We
recommend that you use ".v" as the extension on the source file.
2.8.2 Starting the Simulator
VeriWell is run from the UNIX shell window. In
order to do this put in your .cshrc file the command :
set path = (~hy225/veriwell/sparc_bin
$path); rehash
Type "veriwell" followed by the names of the files containing
the models and
the options. The options can appear in any order and
anywhere on the command line. For example:
host-name%
veriwell cpu.v bus.v top.v -s
This will load each of the files into memory, compile
them, and enter interactive mode. Removing the "-s" option would
cause the simulation to begin immediately. Options are
processed in the order that they appear on the command line. Files
are processed in the order that they appear after the
options are processed. Note that the file
that contains the top module
is processed last.
Also a MS Windows platform
version of veriwell is installed at the PCs located at the white building's
basement.
2.8.3 How to Exit the
Simulator?
To exit the simulator, you
can type $finish; or press Control-d.
To stop the simulation,
you press Control-c. Executing a $stop; system task in the code will also
stop the simulation.
2.8.4 Simulator Options
Commonly used options typed on the command line are shown
below. One should consult the VeriWell User's Guide for
the others.
-i <inputfilename>
Specifies a file that contains interactive commands to
be executed as soon as interactive command mode is entered. This
option should be used with the "-s" option. This can
be used to initialize variables and set time limits on the simulation.
-s
Causes interactive mode to be entered before the simulation
begins.
-t
Causes all statements to be traced. Trace mode may be
disabled with the $cleartrace system task.
2.8.5 Debugging Using VeriWell's Interactive Mode
VeriWell is interactive. Once invoked, the simulation
can be controlled with simple commands. Also, VeriWell accepts any
Verilog statement (but new modules or declarations cannot
be added).
Interactive mode is entered in one of three ways:
1). When the "-s" option is used on the command line
(or in a command file), interactive mode is entered before the
simulation begins,
2). When the simulation encounters the $stop system task,
or,
3). When the user types Control-c during simulation (but
not during compilation).
Interactive Commands
Continue ('.') [period]
--> Resume execution from the current location.
Single-step with trace (',') [comma]
--> Execute a single statement and display the trace for that statement.
Single-step without trace (';') [semicolon]
--> Execute a single statement without trace.
Current location (':') [colon]
--> Display the current location.
Control-d or $finish; --> Exit VeriWell
simulator.
Typically, the kinds of Verilog statements executed interactively
are used for debugging and information-gathering.
$display and $showvars can be typed at the interactive
prompt to show the values of variables. Notice the complete
system task statement must be typed including parameters
and semicolon. $scope(<name>); and $showscopes; can be
typed to traverse the model hierarchy. $settrace; and
$cleartrace; will enter and exit trace mode. Typing "#100;
$stop;" will stop the execution after 100 simulation
units.
Also registers can be modified
using assignment statements while in interactive mode.
3. System Tasks and Functions
System tasks are not part of the Verilog language but
are build-in tasks contained in a library. A few of the more
commonly used one are described below. The Verilog Language
Reference Manual has many more.
3.1 $cleartrace
The $cleartrace; system task turns off the trace.
See $settrace system task to set the trace.
3.2 $display
Displays text to the screen much like the printf statement
from the language C. The general form is
$display(<parameter>,
<parameter>, ... <parameter>);
where <parameter> may be a quoted string, an expression
that returns a value or a null parameter. For example, the
following displays a header.
$display("Registers:
A B C");
The special character % indicates that the next character
is a format specification. For each % character that appears in the
string, a corresponding expression must be supplied after
the string. For example, the following prints the value of A in
binary, octal, decimal and hex.
$display("A=%b
binary %o octal %d decimal %h hex",A,A,A,A);
produces the following output
A=00001111
binary 017 octal 15 decimal 0f hex
The commonly used format specifiers are
%b display
in binary format
%c display
in ASCII character format
%d display
in decimal format
%h display
in hex format
%o display
in octal format
%s display
in string format
Escape sequences may be included in a string. The commonly
used escape sequences are the following:
\n the newline
character
\t the tab
character
\\ the \ character
\" the " character
%% the percent
sign
A null parameter produces a single space character in
the display. A null parameter is characterized by two adjacent
commas in the parameter list.
3.3 $finish
The $finish system task exits the simulator to the host
operating system. Don't forget to type the semicolon while in
interactive mode
3.4 $monitor
The $monitor; system task provides the ability to monitor
and display the values of any variable or expression specified as
parameters to the task. The parameters are specified
in exactly the same manner as the $display system task. When you
invoke the $monitor task, the simulator sets up a mechanism
whereby each time a variable or an expression in the
parameter list changes value, with the exception of $time,
the entire parameter list is displayed at the end of the time step
as if reported by the $display task. If two or more parameters
change values at the same time, however, only one
display is produced. For example, the following will
display a line anytime one of the registers A, B or C changes.
$monitor("
%0d %b %b "%b, $time, A, B, C);
Only one $monitor statement may be active at any one
time. The monitoring may be turned off and on by the following:
$monitoroff;
<some code>
$monitoron;
3.5 $scope
The $scope system task lets the user assign a particular
level of hierarchy as the interactive scope for identifying objects.
$scope is useful during debugging as the user may change
the scope to inspect the values of variables in different modules.
$scope(<name>);
The <name> parameter must be the complete hierarchical
name of a module, or named block. See
$showscopes system task to display the names.
3.6 $settrace
The $settrace system task enables tracing of simulation
activity. The trace consists of various information, including the
current simulation time, the line number, the file name,
module and any results from executing the statement.
You can turn off the trace using the $cleartrace system
task.
3.7 $showscopes
The $showscopes system task displays a complete lists
of all the modules, tasks, functions and named blocks that are
defined at the current scope level.
3.8 $showvars
The $showvars system task produces status information
for register and net (wires) variables, both scalar and vector.
When invoked without parameters, $showvars displays the
status of all variables in the current scope. When invoked with
a list of variables, it shows only the status of the
specified variables.
$showvars;
$showvars(<list of variables>);
3.9 $stop
The $stop system task puts the simulator into a halt
mode, issues an interactive command prompt and passes control to
the user. See Section 3.5 on using VeriWell's interactive
mode.
3.10 $time
The $time system function returns the current simulation
time as a 64-bit integer. $time must be used in an expression.
3.11 $readmemb, $readmemh
The $readmemb and $readmemh system tasks are used to
load information stored in
disk files into Verilog memories. The "b" version reads
binary numbers and the "h"
version reads hexadecimal numbers.
The general syntax for the task call is:
$readmemx ("filename", <memname>,
<start_addr>
,<finish_addr>);
where:
x is"b"
(binary numbers) or"h" (hexadecimal
numbers)
<memname> specifies the Verilog
IDENTIFIER of the memory to be loaded.
<start_addr> optionally specifies
the starting address of the data. If none is specified, the left-hand address
given in the memory declaration is used.
If the <finish_addr>
is specified, loading begins at the <start_addr> and continues
to the <finish_addr>.
<finish_addr> is the last address
to be written into.
Addresses can be specified within the file as well. The
construct "@hhh within the file specifies
the hexadecimal address to use as the starting address.
Subse quent data is loaded starting at
that memory address. Note that the "h" specifies hexadecimal
digits only. There is no length or
base format specified.