CS225 Computer Organization
M. Katevenis, D. Serpanos

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.