Only use fvectors for nets and vars.
This commit is contained in:
parent
31aa85ce7d
commit
794ce68a6c
|
|
@ -1,7 +1,7 @@
|
|||
/*
|
||||
* Copyright (c) 2001 Stephen Williams (steve@icarus.com)
|
||||
*
|
||||
* $Id: README.txt,v 1.35 2001/08/10 04:31:27 steve Exp $
|
||||
* $Id: README.txt,v 1.36 2001/08/25 17:22:32 steve Exp $
|
||||
*/
|
||||
|
||||
VVP SIMULATION ENGINE
|
||||
|
|
@ -254,56 +254,12 @@ holds references to those functors that are fed it.
|
|||
|
||||
The <label> is required and is used to locate the net object that is
|
||||
represents. This label does not map to a functor, so only references
|
||||
that know they want access .nets are able to locate the symbol. In
|
||||
that know they want to access .nets are able to locate the symbol. In
|
||||
particular, this includes behavioral %load and %wait instructions. The
|
||||
references to net and reg objects are done through the .net label
|
||||
instead of a general functor symbol. The instruction stores the
|
||||
functor pointer, though.
|
||||
|
||||
X A .net statement creates a functor for each bit of the vector in
|
||||
X exactly the same way that a .var creates functors. The truth table for
|
||||
X a .net functor is the same, as well. The net has an output that may be
|
||||
X connected to something, but need not. The 0 (zero) input of each bit
|
||||
X functor is the normal input, and is connected to the output of a
|
||||
X functor or another net.
|
||||
|
||||
X The second functor input is a force net. This connects to an
|
||||
X expression that is announced by a force statement of some sort. The
|
||||
X third input is the only input settable by behavioral code, it selects
|
||||
X between the normal input and the force input. These inputs work
|
||||
X exactly the same as those for the .var functors.
|
||||
|
||||
X Since .var items are written by behavioral code, there is no worry
|
||||
X about how to connect their inputs. You don't. But .net items do have
|
||||
X inputs that need to be connected to the outputs of other
|
||||
X functors. Nets are also complicated by the fact that they come in
|
||||
X vectors, so the inputs of all the functors in the array need to be
|
||||
X connected. Fortunately, there is only one input per .net functor that
|
||||
X can be connected, and that is input 0.
|
||||
|
||||
X The force input and selector input are manipulated exactly the same
|
||||
X way as with .var force and selector inputs, so there is no need for a
|
||||
X syntax to handle them.
|
||||
|
||||
X Since there is exactly one input per bit in the vector, it is easy
|
||||
X enough to just list the vvp_ipoint_t symbols in order. Each symbol
|
||||
X references a functor, and connects the corresponding .net input to the
|
||||
X output of that functor, as if the .net is an <N> bit wide functor. The
|
||||
X bits of the vector are connected least-significant-bit first. It is
|
||||
X legal to leave a bit unconnected. To do that, simply leave the
|
||||
X position for that bit blank. Bits of .nets are initialized to
|
||||
X z. Unconnected bits keep the value z throughout the simulation.
|
||||
|
||||
X The special input symbols "C<0>", "C<1>", "C<x>" and "C<z>" and magic
|
||||
X symbols that set the net to a constant value instead of accepting an
|
||||
X input from a functor. This can happen, for example, when a wire is
|
||||
X declared like so:
|
||||
|
||||
X wire foo = 1'b1;
|
||||
|
||||
X This prevents any real functor being created and connected, and
|
||||
X instead leaves the input unconnected and initializes the wire with the
|
||||
X specified value, instead of the default z.
|
||||
|
||||
MEMORY STATEMENTS:
|
||||
|
||||
|
|
|
|||
151
vvp/compile.cc
151
vvp/compile.cc
|
|
@ -17,7 +17,7 @@
|
|||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
||||
*/
|
||||
#if !defined(WINNT)
|
||||
#ident "$Id: compile.cc,v 1.96 2001/08/10 04:31:09 steve Exp $"
|
||||
#ident "$Id: compile.cc,v 1.97 2001/08/25 17:22:32 steve Exp $"
|
||||
#endif
|
||||
|
||||
# include "arith.h"
|
||||
|
|
@ -167,6 +167,39 @@ static symbol_table_t sym_vpi = 0;
|
|||
*/
|
||||
|
||||
|
||||
/*
|
||||
* Add a functor to the symbol table
|
||||
*/
|
||||
#if 0
|
||||
static void define_fvector_symbol(char*label, vvp_fvector_t v)
|
||||
{
|
||||
symbol_value_t val;
|
||||
val.ptr = v;
|
||||
sym_set_value(sym_functors, label, val);
|
||||
}
|
||||
#endif
|
||||
|
||||
#if 0
|
||||
static void define_functor_symbol(char*label, vvp_ipoint_t ipt, unsigned wid)
|
||||
{
|
||||
vvp_fvector_t v = vvp_fvector_continuous_new(wid, ipt);
|
||||
define_fvector_symbol(label, v);
|
||||
}
|
||||
#else
|
||||
static void define_functor_symbol(const char*label, vvp_ipoint_t ipt)
|
||||
{
|
||||
symbol_value_t val;
|
||||
val.num = ipt;
|
||||
sym_set_value(sym_functors, label, val);
|
||||
}
|
||||
|
||||
static vvp_ipoint_t lookup_functor_symbol(const char*label)
|
||||
{
|
||||
symbol_value_t val = sym_get_value(sym_functors, label);
|
||||
return val.num;
|
||||
}
|
||||
#endif
|
||||
|
||||
/*
|
||||
* The resolv_list_s is the base class for a symbol resolve action, and
|
||||
* the resolv_list is an unordered list of these resolve actions. Some
|
||||
|
|
@ -217,20 +250,20 @@ struct functor_resolv_list_s: public resolv_list_s {
|
|||
|
||||
bool functor_resolv_list_s::resolve(bool mes)
|
||||
{
|
||||
symbol_value_t val = sym_get_value(sym_functors, source);
|
||||
vvp_fvector_t vec = (vvp_fvector_t) val.ptr;
|
||||
vvp_ipoint_t tmp = lookup_functor_symbol(source);
|
||||
|
||||
if (vec) {
|
||||
vvp_ipoint_t tmp = vvp_fvector_get(vec, idx);
|
||||
if (tmp) {
|
||||
tmp = ipoint_index(tmp, idx);
|
||||
|
||||
functor_t fport = functor_index(tmp);
|
||||
functor_t iobj = functor_index(port);
|
||||
|
||||
iobj->port[ipoint_port(port)] = fport->out;
|
||||
fport->out = port;
|
||||
|
||||
free(source);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
if (mes)
|
||||
fprintf(stderr, "unresolved functor reference: %s\n", source);
|
||||
|
|
@ -264,22 +297,19 @@ struct fvector_resolv_list_s: public resolv_list_s {
|
|||
|
||||
bool fvector_resolv_list_s::resolve(bool mes)
|
||||
{
|
||||
symbol_value_t val = sym_get_value(sym_functors, source);
|
||||
vvp_fvector_t svec = (vvp_fvector_t) val.ptr;
|
||||
|
||||
if (svec) {
|
||||
vvp_ipoint_t tmp = vvp_fvector_get(svec, idx);
|
||||
vvp_ipoint_t tmp = lookup_functor_symbol(source);
|
||||
if (tmp) {
|
||||
tmp = ipoint_index(tmp, idx);
|
||||
vvp_fvector_set(vec, vidx, tmp);
|
||||
free(source);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
if (mes)
|
||||
if (mes) {
|
||||
fprintf(stderr,
|
||||
"unresolved functor reference (net input): %s\n",
|
||||
source);
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
|
@ -403,16 +433,38 @@ struct code_functor_resolv_list_s: public resolv_list_s {
|
|||
|
||||
bool code_functor_resolv_list_s::resolve(bool mes)
|
||||
{
|
||||
symbol_value_t val = sym_get_value(sym_functors, label);
|
||||
vvp_ipoint_t tmp;
|
||||
|
||||
/* First, look to see if the symbol is a signal, whether net
|
||||
or reg. If so, get the correct bit out. */
|
||||
symbol_value_t val = sym_get_value(sym_vpi, label);
|
||||
if (val.ptr) {
|
||||
vvp_fvector_t v = (vvp_fvector_t) val.ptr;
|
||||
code->iptr = vvp_fvector_get(v, idx);
|
||||
if (code->iptr) {
|
||||
vpiHandle vpi = (vpiHandle) val.ptr;
|
||||
assert((vpi->vpi_type->type_code == vpiNet)
|
||||
|| (vpi->vpi_type->type_code == vpiReg));
|
||||
|
||||
__vpiSignal*sig = (__vpiSignal*)vpi;
|
||||
tmp = vvp_fvector_get(sig->bits, idx);
|
||||
if (tmp == 0)
|
||||
goto error_out;
|
||||
|
||||
assert(tmp);
|
||||
|
||||
code->iptr = tmp;
|
||||
free(label);
|
||||
return true;
|
||||
}
|
||||
|
||||
/* Failing that, look for a general functor. */
|
||||
tmp = lookup_functor_symbol(label);
|
||||
if (tmp) {
|
||||
code->iptr = ipoint_index(tmp, idx);
|
||||
free(label);
|
||||
return true;
|
||||
}
|
||||
|
||||
error_out:
|
||||
/* lookup failed. Possibly try again. */
|
||||
if (mes)
|
||||
fprintf(stderr,
|
||||
"unresolved code reference to functor: %s\n",
|
||||
|
|
@ -505,23 +557,6 @@ void compile_vpi_time_precision(long pre)
|
|||
vpip_set_time_precision(pre);
|
||||
}
|
||||
|
||||
/*
|
||||
* Add a functor to the symbol table
|
||||
*/
|
||||
|
||||
static void define_fvector_symbol(char*label, vvp_fvector_t v)
|
||||
{
|
||||
symbol_value_t val;
|
||||
val.ptr = v;
|
||||
sym_set_value(sym_functors, label, val);
|
||||
}
|
||||
|
||||
static void define_functor_symbol(char*label, vvp_ipoint_t ipt, unsigned wid)
|
||||
{
|
||||
vvp_fvector_t v = vvp_fvector_continuous_new(wid, ipt);
|
||||
define_fvector_symbol(label, v);
|
||||
}
|
||||
|
||||
/*
|
||||
* Run through the arguments looking for the functors that are
|
||||
* connected to my input ports. For each source functor that I
|
||||
|
|
@ -609,7 +644,7 @@ void compile_functor(char*label, char*type, unsigned argc, struct symb_s*argv)
|
|||
vvp_ipoint_t fdx = functor_allocate(1);
|
||||
functor_t obj = functor_index(fdx);
|
||||
|
||||
define_functor_symbol(label, fdx, 1);
|
||||
define_functor_symbol(label, fdx);
|
||||
|
||||
assert(argc <= 4);
|
||||
|
||||
|
|
@ -727,7 +762,7 @@ void compile_arith_mult(char*label, long wid,
|
|||
}
|
||||
|
||||
vvp_ipoint_t fdx = functor_allocate(wid);
|
||||
define_functor_symbol(label, fdx, wid);
|
||||
define_functor_symbol(label, fdx);
|
||||
|
||||
vvp_arith_mult*arith = new vvp_arith_mult(fdx, wid);
|
||||
|
||||
|
|
@ -754,7 +789,7 @@ void compile_arith_sub(char*label, long wid, unsigned argc, struct symb_s*argv)
|
|||
}
|
||||
|
||||
vvp_ipoint_t fdx = functor_allocate(wid);
|
||||
define_functor_symbol(label, fdx, wid);
|
||||
define_functor_symbol(label, fdx);
|
||||
|
||||
vvp_arith_sub*arith = new vvp_arith_sub(fdx, wid);
|
||||
|
||||
|
|
@ -781,7 +816,7 @@ void compile_arith_sum(char*label, long wid, unsigned argc, struct symb_s*argv)
|
|||
}
|
||||
|
||||
vvp_ipoint_t fdx = functor_allocate(wid);
|
||||
define_functor_symbol(label, fdx, wid);
|
||||
define_functor_symbol(label, fdx);
|
||||
|
||||
vvp_arith_sum*arith = new vvp_arith_sum(fdx, wid);
|
||||
|
||||
|
|
@ -800,7 +835,7 @@ void compile_cmp_ge(char*label, long wid, unsigned argc, struct symb_s*argv)
|
|||
}
|
||||
|
||||
vvp_ipoint_t fdx = functor_allocate(wid);
|
||||
define_functor_symbol(label, fdx, wid);
|
||||
define_functor_symbol(label, fdx);
|
||||
|
||||
vvp_cmp_ge*cmp = new vvp_cmp_ge(fdx, wid);
|
||||
|
||||
|
|
@ -819,7 +854,7 @@ void compile_cmp_gt(char*label, long wid, unsigned argc, struct symb_s*argv)
|
|||
}
|
||||
|
||||
vvp_ipoint_t fdx = functor_allocate(wid);
|
||||
define_functor_symbol(label, fdx, wid);
|
||||
define_functor_symbol(label, fdx);
|
||||
|
||||
vvp_cmp_gt*cmp = new vvp_cmp_gt(fdx, wid);
|
||||
|
||||
|
|
@ -883,7 +918,7 @@ void compile_shiftl(char*label, long wid, unsigned argc, struct symb_s*argv)
|
|||
}
|
||||
|
||||
vvp_ipoint_t fdx = functor_allocate(wid);
|
||||
define_functor_symbol(label, fdx, wid);
|
||||
define_functor_symbol(label, fdx);
|
||||
|
||||
vvp_shiftl*dev = new vvp_shiftl(fdx, wid);
|
||||
|
||||
|
|
@ -911,7 +946,7 @@ void compile_shiftr(char*label, long wid, unsigned argc, struct symb_s*argv)
|
|||
}
|
||||
|
||||
vvp_ipoint_t fdx = functor_allocate(wid);
|
||||
define_functor_symbol(label, fdx, wid);
|
||||
define_functor_symbol(label, fdx);
|
||||
|
||||
vvp_shiftr*dev = new vvp_shiftr(fdx, wid);
|
||||
|
||||
|
|
@ -925,7 +960,7 @@ void compile_resolver(char*label, char*type, unsigned argc, struct symb_s*argv)
|
|||
vvp_ipoint_t fdx = functor_allocate(1);
|
||||
functor_t obj = functor_index(fdx);
|
||||
|
||||
define_functor_symbol(label, fdx, 1);
|
||||
define_functor_symbol(label, fdx);
|
||||
|
||||
assert(argc <= 4);
|
||||
|
||||
|
|
@ -999,7 +1034,7 @@ void compile_udp_functor(char*label, char*type,
|
|||
vvp_ipoint_t fdx = functor_allocate(nfun);
|
||||
functor_t obj = functor_index(fdx);
|
||||
|
||||
define_functor_symbol(label, fdx, nfun);
|
||||
define_functor_symbol(label, fdx);
|
||||
free(label);
|
||||
|
||||
for (unsigned idx = 0; idx < argc; idx += 4)
|
||||
|
|
@ -1069,7 +1104,7 @@ void compile_memory_port(char *label, char *memid,
|
|||
|
||||
vvp_ipoint_t ix = functor_allocate(nfun);
|
||||
|
||||
define_functor_symbol(label, ix, nfun);
|
||||
define_functor_symbol(label, ix);
|
||||
free(label);
|
||||
|
||||
inputs_connect(ix, argc, argv);
|
||||
|
|
@ -1100,7 +1135,7 @@ void compile_event(char*label, char*type,
|
|||
vvp_ipoint_t fdx = functor_allocate(1);
|
||||
functor_t obj = functor_index(fdx);
|
||||
|
||||
define_functor_symbol(label, fdx, 1);
|
||||
define_functor_symbol(label, fdx);
|
||||
|
||||
assert(argc <= 4);
|
||||
|
||||
|
|
@ -1148,7 +1183,7 @@ void compile_named_event(char*label, char*name)
|
|||
vvp_ipoint_t fdx = functor_allocate(1);
|
||||
functor_t obj = functor_index(fdx);
|
||||
|
||||
define_functor_symbol(label, fdx, 1);
|
||||
define_functor_symbol(label, fdx);
|
||||
|
||||
obj->ival = 0xaa;
|
||||
obj->oval = 2;
|
||||
|
|
@ -1173,7 +1208,7 @@ void compile_event_or(char*label, unsigned argc, struct symb_s*argv)
|
|||
vvp_ipoint_t fdx = functor_allocate(1);
|
||||
functor_t obj = functor_index(fdx);
|
||||
|
||||
define_functor_symbol(label, fdx, 1);
|
||||
define_functor_symbol(label, fdx);
|
||||
|
||||
obj->ival = 0xaa;
|
||||
obj->oval = 2;
|
||||
|
|
@ -1193,10 +1228,9 @@ void compile_event_or(char*label, unsigned argc, struct symb_s*argv)
|
|||
/* Link the outputs of the named events to me. */
|
||||
|
||||
for (unsigned idx = 0 ; idx < argc ; idx += 1) {
|
||||
symbol_value_t val = sym_get_value(sym_functors, argv[idx].text);
|
||||
vvp_fvector_t vec = (vvp_fvector_t) val.ptr;
|
||||
assert(vec);
|
||||
vvp_ipoint_t tmp = vvp_fvector_get(vec, argv[idx].idx);
|
||||
vvp_ipoint_t tmp = lookup_functor_symbol(argv[idx].text);
|
||||
assert(tmp);
|
||||
tmp = ipoint_index(tmp, argv[idx].idx);
|
||||
|
||||
functor_t fport = functor_index(tmp);
|
||||
assert(fport);
|
||||
|
|
@ -1455,7 +1489,7 @@ void compile_variable(char*label, char*name, int msb, int lsb,
|
|||
vvp_ipoint_t fdx = functor_allocate(wid);
|
||||
|
||||
vvp_fvector_t vec = vvp_fvector_continuous_new(wid, fdx);
|
||||
define_fvector_symbol(label, vec);
|
||||
define_functor_symbol(label, fdx);
|
||||
|
||||
for (unsigned idx = 0 ; idx < wid ; idx += 1) {
|
||||
functor_t obj = functor_index(ipoint_index(fdx,idx));
|
||||
|
|
@ -1504,7 +1538,7 @@ void compile_net(char*label, char*name, int msb, int lsb, bool signed_flag,
|
|||
unsigned wid = ((msb > lsb)? msb-lsb : lsb-msb) + 1;
|
||||
|
||||
vvp_fvector_t vec = vvp_fvector_new(wid);
|
||||
define_fvector_symbol(label, vec);
|
||||
//define_fvector_symbol(label, vec);
|
||||
|
||||
assert(argc == wid);
|
||||
|
||||
|
|
@ -1587,16 +1621,15 @@ void compile_net(char*label, char*name, int msb, int lsb, bool signed_flag,
|
|||
*/
|
||||
vvp_ipoint_t debug_lookup_functor(const char*name)
|
||||
{
|
||||
symbol_value_t val = sym_get_value(sym_functors, name);
|
||||
vvp_fvector_t vec = (vvp_fvector_t) val.ptr;
|
||||
if (!vec)
|
||||
return 0;
|
||||
return vvp_fvector_get(vec, 0);
|
||||
return lookup_functor_symbol(name);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* $Log: compile.cc,v $
|
||||
* Revision 1.97 2001/08/25 17:22:32 steve
|
||||
* Only use fvectors for nets and vars.
|
||||
*
|
||||
* Revision 1.96 2001/08/10 04:31:09 steve
|
||||
* Neaten and document the resolv object.
|
||||
*
|
||||
|
|
|
|||
Loading…
Reference in New Issue