177 lines
6.8 KiB
Plaintext
177 lines
6.8 KiB
Plaintext
|
|
WHAT IS VVM
|
|
|
|
The vvm target is C++ output that uses the VVM library for a
|
|
runtime. The Verilog module that is elaborated must have no ports, as
|
|
the output program is self contained. It is useful to write a "main"
|
|
module that tests a part being designed. This output type is most
|
|
useful for batch simulation.
|
|
|
|
The iverilog target ``vvm'' generates code that uses the vvm library,
|
|
and takes care of compiling the code into an executable program.
|
|
|
|
The vvm library can also be used directly by C++ programmers if
|
|
desired, ir order to skip the Verilog compilation step and write
|
|
simulations in C++.
|
|
|
|
WRITING SIMULATIONS IN C++/VVM
|
|
|
|
It is possible to write simulations using C++ and the vvm library. The
|
|
library classes fairly directly represent hardware devices and signal
|
|
values, so writing such a simulation should be relatively obvious. The
|
|
library also supports calling VPI modules written to work with Icarus
|
|
Verilog. There are routines for loading and interfacing with VPI
|
|
modules so that they think you are Verilog.
|
|
|
|
The details of the various classes are covered by comments in the
|
|
various header files. The core header file is vvm.h, but the header
|
|
files vvm_gates.h and vvm_signal.h are also important.
|
|
|
|
NEXUS, GATES AND DRIVERS
|
|
|
|
The vvm library allows the user (the t-vvm code generator from its
|
|
point of view) to build up a netlist of gates that operate like
|
|
hardware components. The basic unit of connectivity in the vvm_nexus
|
|
class.
|
|
|
|
A vvm_nexus object represents a nexus of a netlist: that is, a point
|
|
where drivers and receivers are connected together. The nexus class
|
|
defines the sub-classes (not derived classes) driver_t and recvr_t
|
|
that objects and code use to connect to the nexus. The nexus also has
|
|
a reg_assign() method for simulating procedural assignment.
|
|
|
|
The driver_t class is a means to drive (as opposed to assign) a value
|
|
onto the nexus. Gates with outputs have drive_t objects that they can
|
|
connect to exactly one nexus.
|
|
|
|
The recvr_t class is where the nexus delivers the resolved
|
|
value. Receiver objects are actually able to represent many pins of a
|
|
device, although a nexus is connected to only one. This is managed by
|
|
passing to the nexus a pointer to the object and a key that the
|
|
receiver uses to identify the pin. This is done so that the gate class
|
|
can derive from the recvr_t class and support multiple input pins.
|
|
|
|
The vvm_nexus class connects to any number of drivers and any number
|
|
of receivers. This is how fan-in and fan-out are achieved in a design
|
|
under test. When a connected driver gets a new value, the vvm_nexus
|
|
object scans all the drivers and collects the values that are being
|
|
driven. It passes the set to a resolution function that calculates the
|
|
actual value that the vvm_nexus will take, then passes that value to
|
|
all the receivers.
|
|
|
|
If there are no drivers, the vvm_nexus can also receive a value from
|
|
procedural assignment, via the reg_assign() method. When assigned in
|
|
this manner, the vvm_nexus simply takes the value given to it and
|
|
passes it to all the receivers. The vvm_nexus holds the last value
|
|
assigned, and does not perform any resolution.
|
|
|
|
The vvm/vvm_nexus.h header file describes the vvm_nexus and related
|
|
classes.
|
|
|
|
ATTRIBUTES
|
|
|
|
(none)
|
|
|
|
INITIALIZATION OF THE SIMULATION
|
|
|
|
The t-vvm generates initialization code that causes gates to get
|
|
initial values for their inputs, if any were specified by the
|
|
programmer, and outputs if the device is sequential. This
|
|
initialization code goes into the generated design_init() function.
|
|
|
|
The t-vvm also generates startup code that causes gates to generate
|
|
outputs from the initial inputs. This cannot be done in the
|
|
design_init() function because of the possibilities of cycles and
|
|
other complexities in the netlist.
|
|
|
|
|
|
THREADS
|
|
|
|
The generated code does not actually use threads. It instead supports
|
|
threads of verilog behavior by reducing the sequential process into
|
|
basic blocks, and calling those basic blocks as needed.
|
|
|
|
SMALL SEQUENTIAL UDP GATES
|
|
|
|
For gates with 8 or fewer inputs, vvm has a table based
|
|
representation. When a transition happens, the transition is converted
|
|
into a table index that addresses the next output value. This is a
|
|
compact method for representing even the most degenerate UDP
|
|
transition tables, but these degenerate tables can get pretty
|
|
large. Hence the practical limit.
|
|
|
|
The index into the transtion table is made up of the current output
|
|
and current inputs with the following recursive formula:
|
|
|
|
I[0] = X
|
|
I[N] = X[N] + 3 * I[N-1]
|
|
|
|
where X[N], the value of pin N, is 0 for V0, 1 for V1 and 2 for Vx. In
|
|
other words:
|
|
|
|
unsigned state = current_output;
|
|
for (unsigned idx = 1 ; idx < npins ; idx += 1)
|
|
state = 3*state + current_input[idx];
|
|
|
|
The state indexes into an array of 32bit words that contain all the
|
|
transitions out of that state. Each pin transition is represented by 4
|
|
bits--two bits for each possible transition for the pin. The 4 bits
|
|
represent transitions as in this table:
|
|
|
|
bits [3:2] bits [1:0]
|
|
0 -> 1 0 -> x
|
|
1 -> 0 1 -> x
|
|
x -> 0 x -> 1
|
|
|
|
The values of the bit pairs in the table entry are 2b'00 for V0, 2b'01
|
|
for V1 and 2b'10 for Vx. The transitions are arranged in the 32bit
|
|
entry with the last pin in the lowest 4 bits, the next to last pin in
|
|
the next 4 bits, and so on. So, if P is the changing pin on a 7 pin
|
|
UDP, and E is the 32bit entry for the current state, the transition
|
|
bits are at:
|
|
|
|
(E >> 4*(6-P)) & 0xf
|
|
|
|
/*
|
|
* Copyright (c) 1998-1999 Stephen Williams (steve@icarus.com)
|
|
*
|
|
* This source code is free software; you can redistribute it
|
|
* and/or modify it in source code form under the terms of the GNU
|
|
* General Public License as published by the Free Software
|
|
* Foundation; either version 2 of the License, or (at your option)
|
|
* any later version.
|
|
*
|
|
* This program is distributed in the hope that it will be useful,
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
* GNU General Public License for more details.
|
|
*
|
|
* You should have received a copy of the GNU General Public License
|
|
* along with this program; if not, write to the Free Software
|
|
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
|
*/
|
|
|
|
$Id: vvm.txt,v 1.6 2000/05/11 01:44:52 steve Exp $
|
|
$Log: vvm.txt,v $
|
|
Revision 1.6 2000/05/11 01:44:52 steve
|
|
No need for nobufz.
|
|
|
|
Revision 1.5 2000/03/16 19:03:04 steve
|
|
Revise the VVM backend to use nexus objects so that
|
|
drivers and resolution functions can be used, and
|
|
the t-vvm module doesn't need to write a zillion
|
|
output functions.
|
|
|
|
Revision 1.4 1999/12/30 17:37:14 steve
|
|
Remove the now useless sigfold functor.
|
|
|
|
Revision 1.3 1999/08/18 03:45:36 steve
|
|
Update compile command line.
|
|
|
|
Revision 1.2 1999/08/15 01:23:56 steve
|
|
Convert vvm to implement system tasks with vpi.
|
|
|
|
Revision 1.1 1999/04/29 16:29:04 steve
|
|
Add vvm target documentation
|
|
|