Put vec8 and vec4 nets into seperate net classes.

This commit is contained in:
steve 2005-11-25 17:55:26 +00:00
parent 3f108f08ed
commit 35951510c5
11 changed files with 297 additions and 75 deletions

View File

@ -17,7 +17,7 @@
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*/
#ifdef HAVE_CVS_IDENT
#ident "$Id: vvp_scope.c,v 1.137 2005/10/12 17:26:17 steve Exp $"
#ident "$Id: vvp_scope.c,v 1.138 2005/11/25 17:55:26 steve Exp $"
#endif
# include "vvp_priv.h"
@ -31,9 +31,12 @@
struct vvp_nexus_data {
/* draw_net_input uses this */
const char*net_input;
unsigned drivers_count;
int flags;
/* draw_net_in_scope uses this */
ivl_signal_t net;
};
#define VVP_NEXUS_DATA_STR 0x0001
static struct vvp_nexus_data*new_nexus_data()
{
@ -655,7 +658,8 @@ static const char* draw_net_input_drive(ivl_nexus_t nex, ivl_nexus_ptr_t nptr)
* does *not* check for a previously calculated string. Use the
* draw_net_input for the general case.
*/
static char* draw_net_input_x(ivl_nexus_t nex, ivl_nexus_ptr_t omit)
static char* draw_net_input_x(ivl_nexus_t nex, ivl_nexus_ptr_t omit,
struct vvp_nexus_data*nex_data)
{
ivl_signal_type_t res;
char result[512];
@ -669,6 +673,9 @@ static char* draw_net_input_x(ivl_nexus_t nex, ivl_nexus_ptr_t omit)
char*nex_private = 0;
/* Accumulate nex_data flags. */
int nex_flags = 0;
res = signal_type_of_nexus(nex);
switch (res) {
case IVL_SIT_TRI:
@ -676,9 +683,11 @@ static char* draw_net_input_x(ivl_nexus_t nex, ivl_nexus_ptr_t omit)
break;
case IVL_SIT_TRI0:
resolv_type = "tri0";
nex_flags |= VVP_NEXUS_DATA_STR;
break;
case IVL_SIT_TRI1:
resolv_type = "tri1";
nex_flags |= VVP_NEXUS_DATA_STR;
break;
case IVL_SIT_TRIAND:
resolv_type = "triand";
@ -705,6 +714,14 @@ static char* draw_net_input_x(ivl_nexus_t nex, ivl_nexus_ptr_t omit)
&& (ivl_nexus_ptr_drive1(nptr) == IVL_DR_HiZ))
continue;
/* Mark the strength-aware flag if the driver can
generate values other then the standard "6"
strength. */
if (ivl_nexus_ptr_drive0(nptr) != IVL_DR_STRONG)
nex_flags |= VVP_NEXUS_DATA_STR;
if (ivl_nexus_ptr_drive1(nptr) != IVL_DR_STRONG)
nex_flags |= VVP_NEXUS_DATA_STR;
/* Save this driver. */
if (ndrivers >= adrivers) {
adrivers += 4;
@ -715,6 +732,13 @@ static char* draw_net_input_x(ivl_nexus_t nex, ivl_nexus_ptr_t omit)
ndrivers += 1;
}
/* If the caller is collecting nexus information, then save
the nexus driver count in the nex_data. */
if (nex_data) {
nex_data->drivers_count = ndrivers;
nex_data->flags |= nex_flags;
}
/* If the nexus has no drivers, then send a constant HiZ into
the net. */
if (ndrivers == 0) {
@ -813,7 +837,7 @@ const char*draw_net_input(ivl_nexus_t nex)
}
assert(nex_data->net_input == 0);
nex_data->net_input = draw_net_input_x(nex, 0);
nex_data->net_input = draw_net_input_x(nex, 0, nex_data);
return nex_data->net_input;
}
@ -894,10 +918,19 @@ static void draw_net_in_scope(ivl_signal_t sig)
}
if (nex_data->net == 0) {
fprintf(vvp_out, "V_%p .net%s \"%s\", %d, %d, %s;\n",
sig, datatype_flag,
const char*vec8 = "";
if (nex_data->drivers_count > 1)
vec8 = "8";
if (nex_data->flags & VVP_NEXUS_DATA_STR)
vec8 = "8";
fprintf(vvp_out, "V_%p .net%s%s \"%s\", %d, %d, %s;"
" %u drivers%s\n",
sig, vec8, datatype_flag,
vvp_mangle_name(ivl_signal_basename(sig)),
msb, lsb, arg);
msb, lsb, arg,
nex_data->drivers_count,
nex_data->flags&VVP_NEXUS_DATA_STR?", strength-aware":"");
nex_data->net = sig;
} else {
/* Detect that this is an alias of nex_data->net. Create
@ -1828,7 +1861,7 @@ static void draw_lpm_part_bi(ivl_lpm_t net)
break;
}
assert(ptr != 0);
p_str = draw_net_input_x(nex, ptr);
p_str = draw_net_input_x(nex, ptr, 0);
nex = ivl_lpm_data(net,0);
for (idx = 0 ; idx < ivl_nexus_ptrs(nex) ; idx += 1) {
@ -1836,7 +1869,7 @@ static void draw_lpm_part_bi(ivl_lpm_t net)
if (ivl_nexus_ptr_lpm(ptr) == net)
break;
}
v_str = draw_net_input_x(nex, ptr);
v_str = draw_net_input_x(nex, ptr, 0);
/* Pad the part-sized input out to a common width... */
fprintf(vvp_out, "L_%p/i .part/pv %s, %u, %u, %u;\n",
@ -2077,6 +2110,9 @@ int draw_scope(ivl_scope_t net, ivl_scope_t parent)
/*
* $Log: vvp_scope.c,v $
* Revision 1.138 2005/11/25 17:55:26 steve
* Put vec8 and vec4 nets into seperate net classes.
*
* Revision 1.137 2005/10/12 17:26:17 steve
* MUX nodes get inputs from nets, not from net inputs,
* Detect and draw alias nodes to reduce net size and

View File

@ -1,7 +1,7 @@
/*
* Copyright (c) 2001 Stephen Williams (steve@icarus.com)
*
* $Id: README.txt,v 1.73 2005/11/10 13:25:31 steve Exp $
* $Id: README.txt,v 1.74 2005/11/25 17:55:26 steve Exp $
*/
VVP SIMULATION ENGINE
@ -289,6 +289,8 @@ exactly the same as the .var statement:
<label> .net "name", <msb>, <lsb>, <symbol>;
<label> .net/s "name", <msb>, <lsb>, <symbol>;
<label> .net8 "name", <msb>, <lsb>, <symbol>;
<label> .net8/s "name", <msb>, <lsb>, <symbol>;
<label> .net/real "name", <msb>, <lsb>, <symbol>;
<label> .alias "name", <msb>, <lsb>, <symbol>;
@ -298,13 +300,13 @@ the basename and dimensions given as parameters. The symbol is a
functor that feeds into the vector of the net, and the vpiHandle
holds references to that functor.
NOTE: Nets also, unlike .vars, should also have a way of getting
at the strengths of each bit. I haven't worked out how that will
happen, yet.
The input of a .net is replicated to its output. In this sense, it
acts like a diode. The purpose of this node is to hold various VPI
and event trappings.
and event trappings. The .net and .net8 nodes are vector types. They
both may represent wires, but the .net8 nodes preserve strength values
that arrive through them, while .net nodes reduce strength values to
4-value logic. The .net8 nodes should only be used when strength
information really is possible.
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

View File

@ -19,7 +19,7 @@
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*/
#ifdef HAVE_CVS_IDENT
#ident "$Id: compile.h,v 1.76 2005/10/12 17:23:15 steve Exp $"
#ident "$Id: compile.h,v 1.77 2005/11/25 17:55:26 steve Exp $"
#endif
# include <stdio.h>
@ -322,6 +322,7 @@ extern void compile_var_real(char*label, char*nane,
extern void compile_net(char*label, char*name,
int msb, int lsb, bool signed_flag,
bool net8_flag,
unsigned argc, struct symb_s*argv);
extern void compile_net_real(char*label, char*name,
int msb, int lsb,
@ -336,6 +337,9 @@ extern void compile_alias_real(char*label, char*name,
/*
* $Log: compile.h,v $
* Revision 1.77 2005/11/25 17:55:26 steve
* Put vec8 and vec4 nets into seperate net classes.
*
* Revision 1.76 2005/10/12 17:23:15 steve
* Add alias nodes.
*

View File

@ -19,7 +19,7 @@
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*/
#ifdef HAVE_CVS_IDENT
#ident "$Id: lexor.lex,v 1.56 2005/10/12 17:23:15 steve Exp $"
#ident "$Id: lexor.lex,v 1.57 2005/11/25 17:55:26 steve Exp $"
#endif
# include "parse_misc.h"
@ -109,6 +109,8 @@
".extend/s" { return K_EXTEND_S; }
".functor" { return K_FUNCTOR; }
".net" { return K_NET; }
".net8" { return K_NET8; }
".net8/s" { return K_NET8_S; }
".net/real" { return K_NET_R; }
".net/s" { return K_NET_S; }
".param" { return K_PARAM; }
@ -202,6 +204,9 @@ int yywrap()
/*
* $Log: lexor.lex,v $
* Revision 1.57 2005/11/25 17:55:26 steve
* Put vec8 and vec4 nets into seperate net classes.
*
* Revision 1.56 2005/10/12 17:23:15 steve
* Add alias nodes.
*

View File

@ -19,7 +19,7 @@
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*/
#ifdef HAVE_CVS_IDENT
#ident "$Id: parse.y,v 1.78 2005/10/12 17:23:15 steve Exp $"
#ident "$Id: parse.y,v 1.79 2005/11/25 17:55:26 steve Exp $"
#endif
# include "parse_misc.h"
@ -63,6 +63,7 @@ extern FILE*yyin;
%token K_CMP_GE K_CMP_GE_S K_CMP_GT K_CMP_GT_S
%token K_CONCAT K_DFF
%token K_EVENT K_EVENT_OR K_EXTEND_S K_FUNCTOR K_NET K_NET_S K_NET_R
%token K_NET8 K_NET8_S
%token K_PARAM K_PART K_PART_PV
%token K_PART_V K_REDUCE_AND K_REDUCE_OR K_REDUCE_XOR
%token K_REDUCE_NAND K_REDUCE_NOR K_REDUCE_XNOR K_REPEAT
@ -453,11 +454,19 @@ statement
| T_LABEL K_NET T_STRING ',' signed_t_number ',' signed_t_number
',' symbols_net ';'
{ compile_net($1, $3, $5, $7, false, $9.cnt, $9.vect); }
{ compile_net($1, $3, $5, $7, false, false, $9.cnt, $9.vect); }
| T_LABEL K_NET_S T_STRING ',' signed_t_number ',' signed_t_number
',' symbols_net ';'
{ compile_net($1, $3, $5, $7, true, $9.cnt, $9.vect); }
{ compile_net($1, $3, $5, $7, true, false, $9.cnt, $9.vect); }
| T_LABEL K_NET8 T_STRING ',' signed_t_number ',' signed_t_number
',' symbols_net ';'
{ compile_net($1, $3, $5, $7, false, true, $9.cnt, $9.vect); }
| T_LABEL K_NET8_S T_STRING ',' signed_t_number ',' signed_t_number
',' symbols_net ';'
{ compile_net($1, $3, $5, $7, true, true, $9.cnt, $9.vect); }
| T_LABEL K_NET_R T_STRING ',' signed_t_number ',' signed_t_number
',' symbols_net ';'
@ -713,6 +722,9 @@ int compile_design(const char*path)
/*
* $Log: parse.y,v $
* Revision 1.79 2005/11/25 17:55:26 steve
* Put vec8 and vec4 nets into seperate net classes.
*
* Revision 1.78 2005/10/12 17:23:15 steve
* Add alias nodes.
*

View File

@ -17,7 +17,7 @@
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*/
#ifdef HAVE_CVS_IDENT
#ident "$Id: vpi_callback.cc,v 1.39 2005/07/06 04:29:25 steve Exp $"
#ident "$Id: vpi_callback.cc,v 1.40 2005/11/25 17:55:26 steve Exp $"
#endif
/*
@ -130,8 +130,8 @@ static struct __vpiCallback* make_value_change(p_cb_data data)
struct __vpiSignal*sig;
sig = reinterpret_cast<__vpiSignal*>(data->obj);
vvp_fun_signal*sig_fun;
sig_fun = dynamic_cast<vvp_fun_signal*>(sig->node->fun);
vvp_fun_signal_base*sig_fun;
sig_fun = dynamic_cast<vvp_fun_signal_base*>(sig->node->fun);
assert(sig_fun);
/* Attach the __vpiCallback object to the signal. */
@ -495,6 +495,21 @@ void vvp_fun_signal::get_value(struct t_vpi_value*vp)
}
}
void vvp_fun_signal8::get_value(struct t_vpi_value*vp)
{
switch (vp->format) {
case vpiScalarVal:
vp->value.scalar = value(0);
break;
case vpiSuppressVal:
break;
default:
fprintf(stderr, "vpi_callback: value "
"format %d not supported\n",
vp->format);
}
}
void vvp_fun_signal_real::get_value(struct t_vpi_value*vp)
{
char*rbuf = need_result_buf(64 + 1, RBUF_VAL);
@ -555,6 +570,9 @@ void vvp_fun_signal_real::get_value(struct t_vpi_value*vp)
/*
* $Log: vpi_callback.cc,v $
* Revision 1.40 2005/11/25 17:55:26 steve
* Put vec8 and vec4 nets into seperate net classes.
*
* Revision 1.39 2005/07/06 04:29:25 steve
* Implement real valued signals and arith nodes.
*

View File

@ -17,7 +17,7 @@
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*/
#ifdef HAVE_CVS_IDENT
#ident "$Id: vpi_signal.cc,v 1.70 2005/09/21 01:04:59 steve Exp $"
#ident "$Id: vpi_signal.cc,v 1.71 2005/11/25 17:55:26 steve Exp $"
#endif
/*
@ -178,7 +178,9 @@ static char *signal_vpiDecStrVal(struct __vpiSignal*rfp, s_vpi_value*vp)
? (rfp->msb - rfp->lsb + 1)
: (rfp->lsb - rfp->msb + 1);
vvp_fun_signal*vsig = dynamic_cast<vvp_fun_signal*>(rfp->node->fun);
vvp_fun_signal_vec*vsig = dynamic_cast<vvp_fun_signal_vec*>(rfp->node->fun);
assert(vsig);
/* FIXME: bits should be an array of vvp_bit4_t. */
unsigned char* bits = new unsigned char[wid];
@ -295,7 +297,7 @@ static void signal_get_ScalarVal(struct __vpiSignal*rfp, s_vpi_value*vp)
static void signal_get_StrengthVal(struct __vpiSignal*rfp, s_vpi_value*vp)
{
vvp_fun_signal*vsig = dynamic_cast<vvp_fun_signal*>(rfp->node->fun);
vvp_fun_signal_vec*vsig = dynamic_cast<vvp_fun_signal_vec*>(rfp->node->fun);
unsigned wid = signal_width(rfp);
s_vpi_strengthval*op;
@ -351,7 +353,8 @@ static void signal_get_value(vpiHandle ref, s_vpi_value*vp)
unsigned wid = signal_width(rfp);
vvp_fun_signal*vsig = dynamic_cast<vvp_fun_signal*>(rfp->node->fun);
vvp_fun_signal_vec*vsig = dynamic_cast<vvp_fun_signal_vec*>(rfp->node->fun);
assert(vsig);
char *rbuf = 0;
@ -489,12 +492,6 @@ static void signal_get_value(vpiHandle ref, s_vpi_value*vp)
* equivalent instruction would cause.
*/
static void functor_poke(struct __vpiSignal*rfp, unsigned idx,
vvp_scalar_t val, unsigned long dly =0)
{
fprintf(stderr, "XXXX functor_poke not implemented\n");
}
static vvp_vector4_t from_stringval(const char*str, unsigned wid)
{
unsigned idx;
@ -825,6 +822,9 @@ vpiHandle vpip_make_net(const char*name, int msb, int lsb,
/*
* $Log: vpi_signal.cc,v $
* Revision 1.71 2005/11/25 17:55:26 steve
* Put vec8 and vec4 nets into seperate net classes.
*
* Revision 1.70 2005/09/21 01:04:59 steve
* Support put_value of string values.
*

View File

@ -17,7 +17,7 @@
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*/
#ifdef HAVE_CVS_IDENT
#ident "$Id: vthread.cc,v 1.148 2005/09/19 21:45:37 steve Exp $"
#ident "$Id: vthread.cc,v 1.149 2005/11/25 17:55:26 steve Exp $"
#endif
# include "config.h"
@ -553,7 +553,8 @@ bool of_ASSIGN_V0X1(vthread_t thr, vvp_code_t cp)
unsigned delay = cp->bit_idx[0];
unsigned bit = cp->bit_idx[1];
vvp_fun_signal*sig = reinterpret_cast<vvp_fun_signal*> (cp->net->fun);
vvp_fun_signal_vec*sig
= reinterpret_cast<vvp_fun_signal_vec*> (cp->net->fun);
assert(sig);
assert(wid > 0);
@ -1515,7 +1516,8 @@ bool of_FORCE_LINK(vthread_t thr, vvp_code_t cp)
vvp_net_t*dst = cp->net;
vvp_net_t*src = cp->net2;
vvp_fun_signal*sig = reinterpret_cast<vvp_fun_signal*>(dst->fun);
vvp_fun_signal_base*sig
= reinterpret_cast<vvp_fun_signal_base*>(dst->fun);
assert(sig);
/* Detect the special case that we are already forced the
@ -1846,7 +1848,7 @@ bool of_LOAD_NX(vthread_t thr, vvp_code_t cp)
unsigned idx = thr->words[cp->bit_idx[1]].w_int;
vvp_fun_signal*fun = dynamic_cast<vvp_fun_signal*>(sig->node->fun);
vvp_fun_signal_vec*fun = dynamic_cast<vvp_fun_signal_vec*>(sig->node->fun);
assert(sig != 0);
vvp_bit4_t val = fun->value(idx);
@ -1881,7 +1883,7 @@ bool of_LOAD_VEC(vthread_t thr, vvp_code_t cp)
/* For the %load to work, the functor must actually be a
signal functor. Only signals save their vector value. */
vvp_fun_signal*sig = dynamic_cast<vvp_fun_signal*> (net->fun);
vvp_fun_signal_vec*sig = dynamic_cast<vvp_fun_signal_vec*> (net->fun);
assert(sig);
vvp_vector4_t sig_value = sig->vec4_value();
@ -1932,7 +1934,7 @@ bool of_LOAD_X(vthread_t thr, vvp_code_t cp)
// For the %load to work, the functor must actually be a
// signal functor. Only signals save their vector value.
vvp_fun_signal*sig = dynamic_cast<vvp_fun_signal*> (net->fun);
vvp_fun_signal_vec*sig = dynamic_cast<vvp_fun_signal_vec*> (net->fun);
assert(sig);
vvp_bit4_t val = index >= sig->size()? BIT4_X : sig->value(index);
@ -2710,7 +2712,7 @@ bool of_RELEASE_NET(vthread_t thr, vvp_code_t cp)
{
vvp_net_t*net = cp->net;
vvp_fun_signal*sig = reinterpret_cast<vvp_fun_signal*>(net->fun);
vvp_fun_signal_base*sig = reinterpret_cast<vvp_fun_signal_base*>(net->fun);
assert(sig);
/* XXXX Release for %force/link not yet implemented. */
@ -2726,7 +2728,7 @@ bool of_RELEASE_REG(vthread_t thr, vvp_code_t cp)
{
vvp_net_t*net = cp->net;
vvp_fun_signal*sig = reinterpret_cast<vvp_fun_signal*>(net->fun);
vvp_fun_signal_base*sig = reinterpret_cast<vvp_fun_signal_base*>(net->fun);
assert(sig);
/* XXXX Release for %force/link not yet implemented. */
@ -3187,6 +3189,9 @@ bool of_JOIN_UFUNC(vthread_t thr, vvp_code_t cp)
/*
* $Log: vthread.cc,v $
* Revision 1.149 2005/11/25 17:55:26 steve
* Put vec8 and vec4 nets into seperate net classes.
*
* Revision 1.148 2005/09/19 21:45:37 steve
* Spelling patches from Larry.
*

View File

@ -16,7 +16,7 @@
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*/
#ident "$Id: vvp_net.cc,v 1.47 2005/11/10 13:27:16 steve Exp $"
#ident "$Id: vvp_net.cc,v 1.48 2005/11/25 17:55:26 steve Exp $"
# include "config.h"
# include "vvp_net.h"
@ -588,6 +588,19 @@ bool vector4_to_value(const vvp_vector4_t&vec, unsigned long&val)
return true;
}
template <class T> T coerce_to_width(const T&that, unsigned width)
{
if (that.size() == width)
return that;
assert(that.size() > width);
T res (width);
for (unsigned idx = 0 ; idx < width ; idx += 1)
res.set_bit(idx, that.value(idx));
return res;
}
#if 0
vvp_vector4_t coerce_to_width(const vvp_vector4_t&that, unsigned width)
{
if (that.size() == width)
@ -600,7 +613,7 @@ vvp_vector4_t coerce_to_width(const vvp_vector4_t&that, unsigned width)
return res;
}
#endif
vvp_vector2_t::vvp_vector2_t()
{
@ -1349,13 +1362,8 @@ void vvp_fun_signal::recv_vec4(vvp_net_ptr_t ptr, const vvp_vector4_t&bit)
case 1: // Continuous assign value
continuous_assign_active_ = true;
if (type_is_vector8_()) {
bits8_ = vvp_vector8_t(bit,6);
vvp_send_vec8(ptr.ptr()->out, bits8_);
} else {
bits4_ = bit;
vvp_send_vec4(ptr.ptr()->out, bits4_);
}
bits4_ = bit;
vvp_send_vec4(ptr.ptr()->out, bits4_);
run_vpi_callbacks();
break;
@ -1407,17 +1415,10 @@ void vvp_fun_signal::recv_vec4_pv(vvp_net_ptr_t ptr, const vvp_vector4_t&bit,
void vvp_fun_signal::recv_vec8(vvp_net_ptr_t ptr, vvp_vector8_t bit)
{
// Only port-0 supports vector8_t inputs.
assert(ptr.port() == 0);
if (! continuous_assign_active_) {
bits8_ = bit;
needs_init_ = false;
vvp_send_vec8(ptr.ptr()->out, bit);
run_vpi_callbacks();
}
recv_vec4(ptr, reduce4(bit));
}
void vvp_fun_signal::release(vvp_net_ptr_t ptr, bool net)
{
force_active_ = false;
@ -1433,8 +1434,6 @@ unsigned vvp_fun_signal::size() const
{
if (force_active_)
return force_.size();
else if (type_is_vector8_())
return bits8_.size();
else
return bits4_.size();
}
@ -1443,8 +1442,6 @@ vvp_bit4_t vvp_fun_signal::value(unsigned idx) const
{
if (force_active_)
return force_.value(idx);
else if (type_is_vector8_())
return bits8_.value(idx).value();
else
return bits4_.value(idx);
}
@ -1453,8 +1450,6 @@ vvp_scalar_t vvp_fun_signal::scalar_value(unsigned idx) const
{
if (force_active_)
return vvp_scalar_t(force_.value(idx), 6, 6);
else if (type_is_vector8_())
return bits8_.value(idx);
else
return vvp_scalar_t(bits4_.value(idx), 6, 6);
}
@ -1463,12 +1458,104 @@ vvp_vector4_t vvp_fun_signal::vec4_value() const
{
if (force_active_)
return force_;
else if (type_is_vector8_())
return reduce4(bits8_);
else
return bits4_;
}
vvp_fun_signal8::vvp_fun_signal8(unsigned wid)
: bits8_(wid)
{
}
void vvp_fun_signal8::recv_vec4(vvp_net_ptr_t ptr, const vvp_vector4_t&bit)
{
recv_vec8(ptr, bit);
}
void vvp_fun_signal8::recv_vec8(vvp_net_ptr_t ptr, vvp_vector8_t bit)
{
switch (ptr.port()) {
case 0: // Normal input (feed from net, or set from process)
if (!continuous_assign_active_) {
if (needs_init_ || !bits8_.eeq(bit)) {
bits8_ = bit;
needs_init_ = false;
vvp_send_vec8(ptr.ptr()->out, bit);
run_vpi_callbacks();
}
}
break;
case 1: // Continuous assign value
continuous_assign_active_ = true;
bits8_ = bit;
vvp_send_vec8(ptr.ptr()->out, bits8_);
run_vpi_callbacks();
break;
case 2: // Force value
// Force from a node may not have been sized completely
// by the source, so coerce the size here.
if (bit.size() != size())
force_ = coerce_to_width(bit, size());
else
force_ = bit;
force_active_ = true;
vvp_send_vec8(ptr.ptr()->out, force_);
run_vpi_callbacks();
break;
default:
assert(0);
break;
}
}
void vvp_fun_signal8::release(vvp_net_ptr_t ptr, bool net)
{
force_active_ = false;
if (net) {
vvp_send_vec8(ptr.ptr()->out, bits8_);
run_vpi_callbacks();
} else {
bits8_ = force_;
}
}
unsigned vvp_fun_signal8::size() const
{
if (force_active_)
return force_.size();
else
return bits8_.size();
}
vvp_bit4_t vvp_fun_signal8::value(unsigned idx) const
{
if (force_active_)
return force_.value(idx).value();
else
return bits8_.value(idx).value();
}
vvp_vector4_t vvp_fun_signal8::vec4_value() const
{
if (force_active_)
return reduce4(force_);
else
return reduce4(bits8_);
}
vvp_scalar_t vvp_fun_signal8::scalar_value(unsigned idx) const
{
if (force_active_)
return force_.value(idx);
else
return bits8_.value(idx);
}
vvp_fun_signal_real::vvp_fun_signal_real()
{
}
@ -1986,6 +2073,9 @@ vvp_bit4_t compare_gtge_signed(const vvp_vector4_t&a,
/*
* $Log: vvp_net.cc,v $
* Revision 1.48 2005/11/25 17:55:26 steve
* Put vec8 and vec4 nets into seperate net classes.
*
* Revision 1.47 2005/11/10 13:27:16 steve
* Handle very wide % and / operations using expanded vector2 support.
*

View File

@ -18,7 +18,7 @@
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*/
#ident "$Id: vvp_net.h,v 1.47 2005/11/10 13:27:16 steve Exp $"
#ident "$Id: vvp_net.h,v 1.48 2005/11/25 17:55:26 steve Exp $"
# include "config.h"
# include <stddef.h>
@ -245,7 +245,7 @@ extern vvp_bit4_t compare_gtge(const vvp_vector4_t&a,
extern vvp_bit4_t compare_gtge_signed(const vvp_vector4_t&a,
const vvp_vector4_t&b,
vvp_bit4_t val_if_equal);
extern vvp_vector4_t coerce_to_width(const vvp_vector4_t&that, unsigned width);
template <class T> extern T coerce_to_width(const T&that, unsigned width);
/*
* These functions extract the value of the vector as a native type,
@ -783,7 +783,21 @@ class vvp_fun_signal_base : public vvp_net_fun_t, public vvp_vpi_callback {
virtual void release(vvp_net_ptr_t ptr, bool net) =0;
};
class vvp_fun_signal : public vvp_fun_signal_base {
/*
* This abstract class is a little more specific the the signa_base
* class, in that in adds vector access methods.
*/
class vvp_fun_signal_vec : public vvp_fun_signal_base {
public:
// For vector signal types, this returns the vector count.
virtual unsigned size() const =0;
virtual vvp_bit4_t value(unsigned idx) const =0;
virtual vvp_scalar_t scalar_value(unsigned idx) const =0;
virtual vvp_vector4_t vec4_value() const =0;
};
class vvp_fun_signal : public vvp_fun_signal_vec {
public:
explicit vvp_fun_signal(unsigned wid);
@ -808,12 +822,37 @@ class vvp_fun_signal : public vvp_fun_signal_base {
private:
vvp_vector4_t bits4_;
vvp_vector8_t bits8_;
bool type_is_vector8_() const { return bits8_.size() > 0; }
vvp_vector4_t force_;
};
class vvp_fun_signal8 : public vvp_fun_signal_vec {
public:
explicit vvp_fun_signal8(unsigned wid);
void recv_vec4(vvp_net_ptr_t port, const vvp_vector4_t&bit);
void recv_vec8(vvp_net_ptr_t port, vvp_vector8_t bit);
// Part select variants of above
//void recv_vec4_pv(vvp_net_ptr_t port, const vvp_vector4_t&bit,
// unsigned base, unsigned wid, unsigned vwid);
// Get information about the vector value.
unsigned size() const;
vvp_bit4_t value(unsigned idx) const;
vvp_scalar_t scalar_value(unsigned idx) const;
vvp_vector4_t vec4_value() const;
// Commands
void release(vvp_net_ptr_t port, bool net);
void get_value(struct t_vpi_value*value);
private:
vvp_vector8_t bits8_;
vvp_vector8_t force_;
};
class vvp_fun_signal_real : public vvp_fun_signal_base {
public:
@ -958,6 +997,9 @@ inline void vvp_send_vec4_pv(vvp_net_ptr_t ptr, const vvp_vector4_t&val,
/*
* $Log: vvp_net.h,v $
* Revision 1.48 2005/11/25 17:55:26 steve
* Put vec8 and vec4 nets into seperate net classes.
*
* Revision 1.47 2005/11/10 13:27:16 steve
* Handle very wide % and / operations using expanded vector2 support.
*

View File

@ -17,7 +17,7 @@
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*/
#ifdef HAVE_CVS_IDENT
#ident "$Id: words.cc,v 1.5 2005/10/12 17:28:07 steve Exp $"
#ident "$Id: words.cc,v 1.6 2005/11/25 17:55:26 steve Exp $"
#endif
# include "compile.h"
@ -77,18 +77,23 @@ void compile_variable(char*label, char*name, int msb, int lsb,
*
* <label> .net <name>, <msb>, <lsb>, <input> ;
* <label> .net/s <name>, <msb>, <lsb>, <input> ;
* <label> .net8 <name>, <msb>, <lsb>, <input> ;
* <label> .net8/s <name>, <msb>, <lsb>, <input> ;
*
* Create a VPI handle to represent it, and fill that handle in with
* references into the net.
*/
void compile_net(char*label, char*name, int msb, int lsb, bool signed_flag,
void compile_net(char*label, char*name, int msb, int lsb,
bool signed_flag, bool net8_flag,
unsigned argc, struct symb_s*argv)
{
unsigned wid = ((msb > lsb)? msb-lsb : lsb-msb) + 1;
vvp_net_t*node = new vvp_net_t;
vvp_fun_signal*vsig = new vvp_fun_signal(wid);
vvp_fun_signal_base*vsig = net8_flag
? new vvp_fun_signal8(wid)
: new vvp_fun_signal(wid);
node->fun = vsig;
/* Add the label into the functor symbol table. */
@ -181,6 +186,9 @@ void compile_alias_real(char*label, char*name, int msb, int lsb,
/*
* $Log: words.cc,v $
* Revision 1.6 2005/11/25 17:55:26 steve
* Put vec8 and vec4 nets into seperate net classes.
*
* Revision 1.5 2005/10/12 17:28:07 steve
* Fix compile of net/real aliases.
*