Create the vvp_wire_base class to handle wires.
Take wires out of the signals/variables and move them into a filter instead. This is a big shift, and finally starts us on the path to divide wires out of signals.
This commit is contained in:
parent
6ef9243a10
commit
8bbb7ff7db
|
|
@ -870,9 +870,9 @@ vvp_vector4_t array_get_word(vvp_array_t arr, unsigned address)
|
|||
vpiHandle word = arr->nets[0];
|
||||
struct __vpiSignal*vsig = vpip_signal_from_handle(word);
|
||||
assert(vsig);
|
||||
vvp_fun_signal_vec*sig = dynamic_cast<vvp_fun_signal_vec*> (vsig->node->fun);
|
||||
vvp_signal_value*sig = dynamic_cast<vvp_signal_value*> (vsig->node->fun);
|
||||
assert(sig);
|
||||
return vvp_vector4_t(sig->size(), BIT4_X);
|
||||
return vvp_vector4_t(sig->value_size(), BIT4_X);
|
||||
}
|
||||
|
||||
vpiHandle word = arr->nets[address];
|
||||
|
|
|
|||
|
|
@ -157,12 +157,12 @@ static struct __vpiCallback* make_value_change(p_cb_data data)
|
|||
struct __vpiSignal*sig;
|
||||
sig = reinterpret_cast<__vpiSignal*>(data->obj);
|
||||
|
||||
vvp_fun_signal_base*sig_fun;
|
||||
sig_fun = dynamic_cast<vvp_fun_signal_base*>(sig->node->fun);
|
||||
assert(sig_fun);
|
||||
vvp_net_fil_t*sig_fil;
|
||||
sig_fil = dynamic_cast<vvp_net_fil_t*>(sig->node->fil);
|
||||
assert(sig_fil);
|
||||
|
||||
/* Attach the __vpiCallback object to the signal. */
|
||||
sig_fun->add_vpi_callback(obj);
|
||||
sig_fil->add_vpi_callback(obj);
|
||||
break;
|
||||
|
||||
case vpiRealVar:
|
||||
|
|
@ -577,7 +577,7 @@ void vvp_vpi_callback::run_vpi_callbacks()
|
|||
}
|
||||
}
|
||||
|
||||
void vvp_fun_signal4::get_value(struct t_vpi_value*vp)
|
||||
void vvp_signal_value::get_signal_value(struct t_vpi_value*vp)
|
||||
{
|
||||
switch (vp->format) {
|
||||
case vpiScalarVal:
|
||||
|
|
@ -595,7 +595,7 @@ void vvp_fun_signal4::get_value(struct t_vpi_value*vp)
|
|||
case vpiVectorVal:
|
||||
case vpiStringVal:
|
||||
case vpiRealVal: {
|
||||
unsigned wid = size();
|
||||
unsigned wid = value_size();
|
||||
vvp_vector4_t vec4(wid);
|
||||
for (unsigned idx = 0; idx < wid; idx += 1) {
|
||||
vec4.set_bit(idx, value(idx));
|
||||
|
|
@ -614,6 +614,11 @@ void vvp_fun_signal4::get_value(struct t_vpi_value*vp)
|
|||
}
|
||||
}
|
||||
|
||||
void vvp_fun_signal4::get_value(struct t_vpi_value*vp)
|
||||
{
|
||||
get_signal_value(vp);
|
||||
}
|
||||
|
||||
void vvp_fun_signal8::get_value(struct t_vpi_value*vp)
|
||||
{
|
||||
switch (vp->format) {
|
||||
|
|
@ -688,3 +693,13 @@ void vvp_fun_signal_real::get_value(struct t_vpi_value*vp)
|
|||
vp->format);
|
||||
}
|
||||
}
|
||||
|
||||
void vvp_wire_vec4::get_value(struct t_vpi_value*value)
|
||||
{
|
||||
get_signal_value(value);
|
||||
}
|
||||
|
||||
void vvp_wire_vec8::get_value(struct t_vpi_value*value)
|
||||
{
|
||||
assert(0);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -134,13 +134,13 @@ char *generic_get_str(int code, vpiHandle ref, const char *name, const char *ind
|
|||
* They work with full or partial signals.
|
||||
*/
|
||||
|
||||
static void format_vpiBinStrVal(vvp_fun_signal_vec*sig, int base, unsigned wid,
|
||||
static void format_vpiBinStrVal(vvp_signal_value*sig, int base, unsigned wid,
|
||||
s_vpi_value*vp)
|
||||
{
|
||||
char *rbuf = need_result_buf(wid+1, RBUF_VAL);
|
||||
long offset = wid - 1 + base;
|
||||
long end = base + (signed)wid;
|
||||
long ssize = (signed)sig->size();
|
||||
long ssize = (signed)sig->value_size();
|
||||
|
||||
for (long idx = base ; idx < end ; idx += 1) {
|
||||
if (idx < 0 || idx >= ssize) {
|
||||
|
|
@ -154,13 +154,13 @@ static void format_vpiBinStrVal(vvp_fun_signal_vec*sig, int base, unsigned wid,
|
|||
vp->value.str = rbuf;
|
||||
}
|
||||
|
||||
static void format_vpiOctStrVal(vvp_fun_signal_vec*sig, int base, unsigned wid,
|
||||
static void format_vpiOctStrVal(vvp_signal_value*sig, int base, unsigned wid,
|
||||
s_vpi_value*vp)
|
||||
{
|
||||
unsigned dwid = (wid + 2) / 3;
|
||||
char *rbuf = need_result_buf(dwid+1, RBUF_VAL);
|
||||
long end = base + (signed)wid;
|
||||
long ssize = (signed)sig->size();
|
||||
long ssize = (signed)sig->value_size();
|
||||
unsigned val = 0;
|
||||
|
||||
rbuf[dwid] = 0;
|
||||
|
|
@ -210,13 +210,13 @@ static void format_vpiOctStrVal(vvp_fun_signal_vec*sig, int base, unsigned wid,
|
|||
vp->value.str = rbuf;
|
||||
}
|
||||
|
||||
static void format_vpiHexStrVal(vvp_fun_signal_vec*sig, int base, unsigned wid,
|
||||
static void format_vpiHexStrVal(vvp_signal_value*sig, int base, unsigned wid,
|
||||
s_vpi_value*vp)
|
||||
{
|
||||
unsigned dwid = (wid + 3) / 4;
|
||||
char *rbuf = need_result_buf(dwid+1, RBUF_VAL);
|
||||
long end = base + (signed)wid;
|
||||
long ssize = (signed)sig->size();
|
||||
long ssize = (signed)sig->value_size();
|
||||
unsigned val = 0;
|
||||
|
||||
rbuf[dwid] = 0;
|
||||
|
|
@ -270,12 +270,12 @@ static void format_vpiHexStrVal(vvp_fun_signal_vec*sig, int base, unsigned wid,
|
|||
vp->value.str = rbuf;
|
||||
}
|
||||
|
||||
static void format_vpiDecStrVal(vvp_fun_signal_vec*sig, int base, unsigned wid,
|
||||
static void format_vpiDecStrVal(vvp_signal_value*sig, int base, unsigned wid,
|
||||
int signed_flag, s_vpi_value*vp)
|
||||
{
|
||||
unsigned hwid = (sig->size()+2) / 3 + 1;
|
||||
unsigned hwid = (sig->value_size()+2) / 3 + 1;
|
||||
char *rbuf = need_result_buf(hwid, RBUF_VAL);
|
||||
long ssize = (signed)sig->size();
|
||||
long ssize = (signed)sig->value_size();
|
||||
long end = base + (signed)wid;
|
||||
|
||||
/* Do we have an end outside of the real signal vector. */
|
||||
|
|
@ -313,7 +313,7 @@ static void format_vpiDecStrVal(vvp_fun_signal_vec*sig, int base, unsigned wid,
|
|||
vp->value.str = rbuf;
|
||||
}
|
||||
|
||||
static void format_vpiIntVal(vvp_fun_signal_vec*sig, int base, unsigned wid,
|
||||
static void format_vpiIntVal(vvp_signal_value*sig, int base, unsigned wid,
|
||||
int signed_flag, s_vpi_value*vp)
|
||||
{
|
||||
vvp_vector4_t sub = sig->vec4_value().subvalue(base, wid);
|
||||
|
|
@ -322,11 +322,11 @@ static void format_vpiIntVal(vvp_fun_signal_vec*sig, int base, unsigned wid,
|
|||
vp->value.integer = val;
|
||||
}
|
||||
|
||||
static void format_vpiRealVal(vvp_fun_signal_vec*sig, int base, unsigned wid,
|
||||
static void format_vpiRealVal(vvp_signal_value*sig, int base, unsigned wid,
|
||||
int signed_flag, s_vpi_value*vp)
|
||||
{
|
||||
vvp_vector4_t vec4(wid);
|
||||
long ssize = (signed)sig->size();
|
||||
long ssize = (signed)sig->value_size();
|
||||
long end = base + (signed)wid;
|
||||
if (end > ssize) end = ssize;
|
||||
|
||||
|
|
@ -338,7 +338,7 @@ static void format_vpiRealVal(vvp_fun_signal_vec*sig, int base, unsigned wid,
|
|||
vector4_to_value(vec4, vp->value.real, signed_flag);
|
||||
}
|
||||
|
||||
static void format_vpiStringVal(vvp_fun_signal_vec*sig, int base, unsigned wid,
|
||||
static void format_vpiStringVal(vvp_signal_value*sig, int base, unsigned wid,
|
||||
s_vpi_value*vp)
|
||||
{
|
||||
/* The result will use a character for each 8 bits of the
|
||||
|
|
@ -351,7 +351,7 @@ static void format_vpiStringVal(vvp_fun_signal_vec*sig, int base, unsigned wid,
|
|||
for (long idx = base+(signed)wid-1; idx >= base; idx -= 1) {
|
||||
tmp <<= 1;
|
||||
|
||||
if (idx >=0 && idx < (signed)sig->size() &&
|
||||
if (idx >=0 && idx < (signed)sig->value_size() &&
|
||||
sig->value(idx) == BIT4_1) {
|
||||
tmp |= 1;
|
||||
}
|
||||
|
|
@ -371,10 +371,10 @@ static void format_vpiStringVal(vvp_fun_signal_vec*sig, int base, unsigned wid,
|
|||
vp->value.str = rbuf;
|
||||
}
|
||||
|
||||
static void format_vpiScalarVal(vvp_fun_signal_vec*sig, int base,
|
||||
static void format_vpiScalarVal(vvp_signal_value*sig, int base,
|
||||
s_vpi_value*vp)
|
||||
{
|
||||
if (base >= 0 && base < (signed)sig->size()) {
|
||||
if (base >= 0 && base < (signed)sig->value_size()) {
|
||||
switch (sig->value(base)) {
|
||||
case BIT4_0:
|
||||
vp->value.scalar = vpi0;
|
||||
|
|
@ -398,7 +398,7 @@ static void format_vpiScalarVal(vvp_fun_signal_vec*sig, int base,
|
|||
}
|
||||
}
|
||||
|
||||
static void format_vpiStrengthVal(vvp_fun_signal_vec*sig, int base,
|
||||
static void format_vpiStrengthVal(vvp_signal_value*sig, int base,
|
||||
unsigned wid, s_vpi_value*vp)
|
||||
{
|
||||
long end = base + (signed)wid;
|
||||
|
|
@ -408,7 +408,7 @@ static void format_vpiStrengthVal(vvp_fun_signal_vec*sig, int base,
|
|||
need_result_buf(wid * sizeof(s_vpi_strengthval), RBUF_VAL);
|
||||
|
||||
for (long idx = base ; idx < end ; idx += 1) {
|
||||
if (idx >=0 && idx < (signed)sig->size()) {
|
||||
if (idx >=0 && idx < (signed)sig->value_size()) {
|
||||
vvp_scalar_t val = sig->scalar_value(idx);
|
||||
|
||||
/* vvp_scalar_t strengths are 0-7, but the vpi strength
|
||||
|
|
@ -452,7 +452,7 @@ static void format_vpiStrengthVal(vvp_fun_signal_vec*sig, int base,
|
|||
vp->value.strength = op;
|
||||
}
|
||||
|
||||
static void format_vpiVectorVal(vvp_fun_signal_vec*sig, int base, unsigned wid,
|
||||
static void format_vpiVectorVal(vvp_signal_value*sig, int base, unsigned wid,
|
||||
s_vpi_value*vp)
|
||||
{
|
||||
long end = base + (signed)wid;
|
||||
|
|
@ -465,7 +465,7 @@ static void format_vpiVectorVal(vvp_fun_signal_vec*sig, int base, unsigned wid,
|
|||
|
||||
op->aval = op->bval = 0;
|
||||
for (long idx = base ; idx < end ; idx += 1) {
|
||||
if (base >= 0 && base < (signed)sig->size()) {
|
||||
if (base >= 0 && base < (signed)sig->value_size()) {
|
||||
switch (sig->value(idx)) {
|
||||
case BIT4_0:
|
||||
op->aval &= ~(1 << obit);
|
||||
|
|
@ -659,7 +659,7 @@ static void signal_get_value(vpiHandle ref, s_vpi_value*vp)
|
|||
|
||||
unsigned wid = signal_width(rfp);
|
||||
|
||||
vvp_fun_signal_vec*vsig = dynamic_cast<vvp_fun_signal_vec*>(rfp->node->fun);
|
||||
vvp_signal_value*vsig = dynamic_cast<vvp_signal_value*>(rfp->node->fil);
|
||||
assert(vsig);
|
||||
|
||||
switch (vp->format) {
|
||||
|
|
|
|||
|
|
@ -989,12 +989,12 @@ 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_vec*sig
|
||||
= reinterpret_cast<vvp_fun_signal_vec*> (cp->net->fun);
|
||||
vvp_signal_value*sig
|
||||
= reinterpret_cast<vvp_signal_value*> (cp->net->fun);
|
||||
assert(sig);
|
||||
|
||||
// We fell off the MSB end.
|
||||
if (off >= (long)sig->size()) return true;
|
||||
if (off >= (long)sig->value_size()) return true;
|
||||
else if (off < 0 ) {
|
||||
// We fell off the LSB end.
|
||||
if ((unsigned)-off >= wid ) return true;
|
||||
|
|
@ -1009,7 +1009,7 @@ bool of_ASSIGN_V0X1(vthread_t thr, vvp_code_t cp)
|
|||
vvp_vector4_t value = vthread_bits_to_vector(thr, bit, wid);
|
||||
|
||||
vvp_net_ptr_t ptr (cp->net, 0);
|
||||
schedule_assign_vector(ptr, off, sig->size(), value, delay);
|
||||
schedule_assign_vector(ptr, off, sig->value_size(), value, delay);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
|
@ -1026,12 +1026,12 @@ bool of_ASSIGN_V0X1D(vthread_t thr, vvp_code_t cp)
|
|||
vvp_time64_t delay = thr->words[cp->bit_idx[0]].w_int;
|
||||
unsigned bit = cp->bit_idx[1];
|
||||
|
||||
vvp_fun_signal_vec*sig
|
||||
= reinterpret_cast<vvp_fun_signal_vec*> (cp->net->fun);
|
||||
vvp_signal_value*sig
|
||||
= reinterpret_cast<vvp_signal_value*> (cp->net->fun);
|
||||
assert(sig);
|
||||
|
||||
// We fell off the MSB end.
|
||||
if (off >= (long)sig->size()) return true;
|
||||
if (off >= (long)sig->value_size()) return true;
|
||||
else if (off < 0 ) {
|
||||
// We fell off the LSB end.
|
||||
if ((unsigned)-off >= wid ) return true;
|
||||
|
|
@ -1046,7 +1046,7 @@ bool of_ASSIGN_V0X1D(vthread_t thr, vvp_code_t cp)
|
|||
vvp_vector4_t value = vthread_bits_to_vector(thr, bit, wid);
|
||||
|
||||
vvp_net_ptr_t ptr (cp->net, 0);
|
||||
schedule_assign_vector(ptr, off, sig->size(), value, delay);
|
||||
schedule_assign_vector(ptr, off, sig->value_size(), value, delay);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
|
@ -1062,12 +1062,12 @@ bool of_ASSIGN_V0X1E(vthread_t thr, vvp_code_t cp)
|
|||
long off = thr->words[1].w_int;
|
||||
unsigned bit = cp->bit_idx[0];
|
||||
|
||||
vvp_fun_signal_vec*sig
|
||||
= reinterpret_cast<vvp_fun_signal_vec*> (cp->net->fun);
|
||||
vvp_signal_value*sig
|
||||
= dynamic_cast<vvp_signal_value*> (cp->net->fun);
|
||||
assert(sig);
|
||||
|
||||
// We fell off the MSB end.
|
||||
if (off >= (long)sig->size()) {
|
||||
if (off >= (long)sig->value_size()) {
|
||||
thr->event = 0;
|
||||
thr->ecount = 0;
|
||||
return true;
|
||||
|
|
@ -1091,9 +1091,9 @@ bool of_ASSIGN_V0X1E(vthread_t thr, vvp_code_t cp)
|
|||
vvp_net_ptr_t ptr (cp->net, 0);
|
||||
// If the count is zero then just put the value.
|
||||
if (thr->ecount == 0) {
|
||||
schedule_assign_vector(ptr, off, sig->size(), value, 0);
|
||||
schedule_assign_vector(ptr, off, sig->value_size(), value, 0);
|
||||
} else {
|
||||
schedule_evctl(ptr, value, off, sig->size(), thr->event,
|
||||
schedule_evctl(ptr, value, off, sig->value_size(), thr->event,
|
||||
thr->ecount);
|
||||
}
|
||||
|
||||
|
|
@ -1307,12 +1307,12 @@ bool of_CASSIGN_X0(vthread_t thr, vvp_code_t cp)
|
|||
// X0 register.
|
||||
long index = thr->words[0].w_int;
|
||||
|
||||
vvp_fun_signal_vec*sig = dynamic_cast<vvp_fun_signal_vec*> (net->fun);
|
||||
vvp_signal_value*sig = dynamic_cast<vvp_signal_value*> (net->fun);
|
||||
|
||||
if (index < 0 && (wid <= (unsigned)-index))
|
||||
return true;
|
||||
|
||||
if (index >= (long)sig->size())
|
||||
if (index >= (long)sig->value_size())
|
||||
return true;
|
||||
|
||||
if (index < 0) {
|
||||
|
|
@ -1320,13 +1320,13 @@ bool of_CASSIGN_X0(vthread_t thr, vvp_code_t cp)
|
|||
index = 0;
|
||||
}
|
||||
|
||||
if (index+wid > sig->size())
|
||||
wid = sig->size() - index;
|
||||
if (index+wid > sig->value_size())
|
||||
wid = sig->value_size() - index;
|
||||
|
||||
vvp_vector4_t vector = vthread_bits_to_vector(thr, base, wid);
|
||||
|
||||
vvp_net_ptr_t ptr (net, 1);
|
||||
vvp_send_vec4_pv(ptr, vector, index, wid, sig->size(), 0);
|
||||
vvp_send_vec4_pv(ptr, vector, index, wid, sig->value_size(), 0);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
|
@ -1738,7 +1738,7 @@ bool of_DEASSIGN(vthread_t thr, vvp_code_t cp)
|
|||
unsigned base = cp->bit_idx[0];
|
||||
unsigned width = cp->bit_idx[1];
|
||||
|
||||
vvp_fun_signal_vec*sig = reinterpret_cast<vvp_fun_signal_vec*>(net->fun);
|
||||
vvp_fun_signal_vec*sig = dynamic_cast<vvp_fun_signal_vec*>(net->fun);
|
||||
assert(sig);
|
||||
|
||||
if (base >= sig->size()) return true;
|
||||
|
|
@ -2341,10 +2341,10 @@ bool of_FORCE_V(vthread_t thr, vvp_code_t cp)
|
|||
/* Send the force value to the filter on the node. */
|
||||
|
||||
assert(net->fil);
|
||||
if (value.size() != net->fil->size())
|
||||
value = coerce_to_width(value, net->fil->size());
|
||||
if (value.size() != net->fil->filter_size())
|
||||
value = coerce_to_width(value, net->fil->filter_size());
|
||||
|
||||
net->force_vec4(value, vvp_vector2_t(vvp_vector2_t::FILL1, net->fil->size()));
|
||||
net->force_vec4(value, vvp_vector2_t(vvp_vector2_t::FILL1, net->fil->filter_size()));
|
||||
|
||||
return true;
|
||||
}
|
||||
|
|
@ -2380,7 +2380,7 @@ bool of_FORCE_X0(vthread_t thr, vvp_code_t cp)
|
|||
index = 0;
|
||||
}
|
||||
|
||||
unsigned use_size = net->fil->size();
|
||||
unsigned use_size = net->fil->filter_size();
|
||||
|
||||
|
||||
if (index >= (long)use_size)
|
||||
|
|
@ -3055,13 +3055,13 @@ bool of_LOAD_X1P(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_vec*sig = dynamic_cast<vvp_fun_signal_vec*> (net->fun);
|
||||
vvp_signal_value*sig = dynamic_cast<vvp_signal_value*> (net->fun);
|
||||
assert(sig);
|
||||
|
||||
for (long idx = 0 ; idx < wid ; idx += 1) {
|
||||
long use_index = index + idx;
|
||||
vvp_bit4_t val;
|
||||
if (use_index < 0 || use_index >= (signed)sig->size())
|
||||
if (use_index < 0 || use_index >= (signed)sig->value_size())
|
||||
val = BIT4_X;
|
||||
else
|
||||
val = sig->value(use_index);
|
||||
|
|
@ -3910,10 +3910,11 @@ static bool do_release_vec(vthread_t thr, vvp_code_t cp, bool net_flag)
|
|||
|
||||
assert(net->fil);
|
||||
|
||||
if (base >= net->fil->size()) return true;
|
||||
if (base+width > net->fil->size()) width = net->fil->size() - base;
|
||||
if (base >= net->fil->filter_size()) return true;
|
||||
if (base+width > net->fil->filter_size())
|
||||
width = net->fil->filter_size() - base;
|
||||
|
||||
bool full_sig = base == 0 && width == net->fil->size();
|
||||
bool full_sig = base == 0 && width == net->fil->filter_size();
|
||||
|
||||
// XXXX Can't really do this if this is a partial release?
|
||||
net->fil->force_unlink();
|
||||
|
|
@ -4049,7 +4050,7 @@ bool of_SET_X0(vthread_t thr, vvp_code_t cp)
|
|||
// X0 register.
|
||||
long index = thr->words[0].w_int;
|
||||
|
||||
vvp_fun_signal_vec*sig = dynamic_cast<vvp_fun_signal_vec*> (net->fun);
|
||||
vvp_signal_value*sig = dynamic_cast<vvp_signal_value*> (net->fun);
|
||||
|
||||
// If the entire part is below the beginning of the vector,
|
||||
// then we are done.
|
||||
|
|
@ -4058,7 +4059,7 @@ bool of_SET_X0(vthread_t thr, vvp_code_t cp)
|
|||
|
||||
// If the entire part is above then end of the vector, then we
|
||||
// are done.
|
||||
if (index >= (long)sig->size())
|
||||
if (index >= (long)sig->value_size())
|
||||
return true;
|
||||
|
||||
// If the part starts below the vector, then skip the first
|
||||
|
|
@ -4071,8 +4072,8 @@ bool of_SET_X0(vthread_t thr, vvp_code_t cp)
|
|||
}
|
||||
|
||||
// Reduce the width to keep the part inside the vector.
|
||||
if (index+wid > sig->size())
|
||||
wid = sig->size() - index;
|
||||
if (index+wid > sig->value_size())
|
||||
wid = sig->value_size() - index;
|
||||
|
||||
vvp_vector4_t bit_vec(wid);
|
||||
for (unsigned idx = 0 ; idx < wid ; idx += 1) {
|
||||
|
|
@ -4083,7 +4084,7 @@ bool of_SET_X0(vthread_t thr, vvp_code_t cp)
|
|||
}
|
||||
|
||||
vvp_net_ptr_t ptr (net, 0);
|
||||
vvp_send_vec4_pv(ptr, bit_vec, index, wid, sig->size(), thr->wt_context);
|
||||
vvp_send_vec4_pv(ptr, bit_vec, index, wid, sig->value_size(), thr->wt_context);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1129,7 +1129,7 @@ class vvp_net_fil_t : public vvp_vpi_callback {
|
|||
void force_link(vvp_net_t*dst, vvp_net_t*src);
|
||||
void force_unlink(void);
|
||||
|
||||
virtual unsigned size() const =0;
|
||||
virtual unsigned filter_size() const =0;
|
||||
|
||||
public:
|
||||
// Suport for force methods
|
||||
|
|
|
|||
|
|
@ -65,6 +65,10 @@ template <class T> bool vvp_net_fil_t::filter_mask_(T&val)
|
|||
return true;
|
||||
}
|
||||
|
||||
vvp_signal_value::~vvp_signal_value()
|
||||
{
|
||||
}
|
||||
|
||||
const vvp_vector4_t* vvp_fun_signal4::filter_vec4(const vvp_vector4_t&val)
|
||||
{
|
||||
return filter_mask_(val, force4_, filter4_);
|
||||
|
|
@ -80,9 +84,14 @@ bool vvp_fun_signal_real::filter_real(double&val)
|
|||
return filter_mask_(val);
|
||||
}
|
||||
|
||||
unsigned vvp_fun_signal_real::size() const
|
||||
unsigned vvp_fun_signal_real::filter_size() const
|
||||
{
|
||||
return 1;
|
||||
return size();
|
||||
}
|
||||
|
||||
unsigned vvp_fun_signal4::filter_size() const
|
||||
{
|
||||
return value_size();
|
||||
}
|
||||
|
||||
void vvp_fun_signal4::force_fil_vec4(const vvp_vector4_t&val, vvp_vector2_t mask)
|
||||
|
|
@ -378,17 +387,11 @@ void vvp_fun_signal_base::deassign_pv(unsigned base, unsigned wid)
|
|||
void vvp_fun_signal4_sa::release(vvp_net_ptr_t ptr, bool net)
|
||||
{
|
||||
vvp_vector2_t mask (vvp_vector2_t::FILL1, bits4_.size());
|
||||
assert(!net);
|
||||
|
||||
if (net) {
|
||||
// If releasing a net, then the output should revert to
|
||||
// the un-forced value.
|
||||
release_mask(mask);
|
||||
ptr.ptr()->send_vec4(bits4_, 0);
|
||||
} else {
|
||||
// Variables keep their forced value after the release.
|
||||
bits4_ = filtered_vec4(bits4_);
|
||||
release_mask(mask);
|
||||
}
|
||||
// Variables keep their forced value after the release.
|
||||
bits4_ = filtered_vec4(bits4_);
|
||||
release_mask(mask);
|
||||
}
|
||||
|
||||
void vvp_fun_signal4_sa::release_pv(vvp_net_ptr_t ptr, bool net,
|
||||
|
|
@ -400,17 +403,11 @@ void vvp_fun_signal4_sa::release_pv(vvp_net_ptr_t ptr, bool net,
|
|||
for (unsigned idx = 0 ; idx < wid ; idx += 1)
|
||||
mask.set_bit(base+idx, 1);
|
||||
|
||||
if (net) {
|
||||
release_mask(mask);
|
||||
ptr.ptr()->send_vec4(bits4_,0);
|
||||
} else {
|
||||
bits4_ = filtered_vec4(bits4_);
|
||||
release_mask(mask);
|
||||
}
|
||||
|
||||
bits4_ = filtered_vec4(bits4_);
|
||||
release_mask(mask);
|
||||
}
|
||||
|
||||
unsigned vvp_fun_signal4_sa::size() const
|
||||
unsigned vvp_fun_signal4_sa::value_size() const
|
||||
{
|
||||
return bits4_.size();
|
||||
}
|
||||
|
|
@ -509,7 +506,7 @@ void vvp_fun_signal4_aa::release_pv(vvp_net_ptr_t ptr, bool net,
|
|||
assert(0);
|
||||
}
|
||||
|
||||
unsigned vvp_fun_signal4_aa::size() const
|
||||
unsigned vvp_fun_signal4_aa::value_size() const
|
||||
{
|
||||
return size_;
|
||||
}
|
||||
|
|
@ -603,19 +600,7 @@ void vvp_fun_signal8::recv_vec8_pv(vvp_net_ptr_t ptr, const vvp_vector8_t&bit,
|
|||
* strength aware. */
|
||||
assert(0);
|
||||
break;
|
||||
#if 0
|
||||
case 2: // Force value
|
||||
{ vvp_vector2_t mask (vvp_vector2_t::FILL0, vwid);
|
||||
vvp_vector8_t vec (vvp_vector4_t(vwid, BIT4_Z),6,6);
|
||||
for (unsigned idx = 0 ; idx < wid ; idx += 1) {
|
||||
mask.set_bit(base+idx, 1);
|
||||
vec.set_bit(base+idx, bit.value(idx));
|
||||
}
|
||||
force_vec8(vec, mask);
|
||||
calculate_output_(ptr);
|
||||
break;
|
||||
}
|
||||
#endif
|
||||
|
||||
default:
|
||||
fprintf(stderr, "Unsupported port type %d.\n", ptr.port());
|
||||
assert(0);
|
||||
|
|
@ -657,7 +642,12 @@ void vvp_fun_signal8::release_pv(vvp_net_ptr_t ptr, bool net,
|
|||
}
|
||||
}
|
||||
|
||||
unsigned vvp_fun_signal8::size() const
|
||||
unsigned vvp_fun_signal8::filter_size() const
|
||||
{
|
||||
return value_size();
|
||||
}
|
||||
|
||||
unsigned vvp_fun_signal8::value_size() const
|
||||
{
|
||||
return bits8_.size();
|
||||
}
|
||||
|
|
@ -828,7 +818,7 @@ void vvp_fun_force::recv_vec4(vvp_net_ptr_t ptr, const vvp_vector4_t&bit,
|
|||
vvp_net_t*dst = net->port[3].ptr();
|
||||
assert(dst->fil);
|
||||
|
||||
dst->force_vec4(coerce_to_width(bit, dst->fil->size()), vvp_vector2_t(vvp_vector2_t::FILL1, dst->fil->size()));
|
||||
dst->force_vec4(coerce_to_width(bit, dst->fil->filter_size()), vvp_vector2_t(vvp_vector2_t::FILL1, dst->fil->filter_size()));
|
||||
}
|
||||
|
||||
void vvp_fun_force::recv_real(vvp_net_ptr_t ptr, double bit, vvp_context_t)
|
||||
|
|
@ -838,3 +828,191 @@ void vvp_fun_force::recv_real(vvp_net_ptr_t ptr, double bit, vvp_context_t)
|
|||
vvp_net_t*dst = net->port[3].ptr();
|
||||
dst->force_real(bit, vvp_vector2_t(vvp_vector2_t::FILL1, 1));
|
||||
}
|
||||
|
||||
vvp_wire_base::vvp_wire_base()
|
||||
{
|
||||
}
|
||||
|
||||
vvp_wire_base::~vvp_wire_base()
|
||||
{
|
||||
}
|
||||
|
||||
vvp_wire_vec4::vvp_wire_vec4(unsigned wid, vvp_bit4_t init)
|
||||
: width_(wid)
|
||||
{
|
||||
}
|
||||
|
||||
const vvp_vector4_t* vvp_wire_vec4::filter_vec4(const vvp_vector4_t&bit)
|
||||
{
|
||||
return filter_mask_(bit, force4_, filter4_);
|
||||
}
|
||||
|
||||
const vvp_vector8_t* vvp_wire_vec4::filter_vec8(const vvp_vector8_t&bit)
|
||||
{
|
||||
assert(0);
|
||||
return 0;
|
||||
}
|
||||
|
||||
unsigned vvp_wire_vec4::filter_size() const
|
||||
{
|
||||
return width_;
|
||||
}
|
||||
|
||||
void vvp_wire_vec4::force_fil_vec4(const vvp_vector4_t&val, vvp_vector2_t mask)
|
||||
{
|
||||
force_mask(mask);
|
||||
|
||||
if (force4_.size() == 0) {
|
||||
force4_ = val;
|
||||
} else {
|
||||
for (unsigned idx = 0; idx < mask.size() ; idx += 1) {
|
||||
if (mask.value(idx) == 0)
|
||||
continue;
|
||||
|
||||
force4_.set_bit(idx, val.value(idx));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void vvp_wire_vec4::force_fil_vec8(const vvp_vector8_t&val, vvp_vector2_t mask)
|
||||
{
|
||||
assert(0);
|
||||
}
|
||||
|
||||
void vvp_wire_vec4::force_fil_real(double val, vvp_vector2_t mask)
|
||||
{
|
||||
assert(0);
|
||||
}
|
||||
|
||||
void vvp_wire_vec4::release(vvp_net_ptr_t ptr, bool net)
|
||||
{
|
||||
assert(net);
|
||||
|
||||
// Wires revert to their unforced value after release.
|
||||
vvp_vector2_t mask (vvp_vector2_t::FILL1, width_);
|
||||
release_mask(mask);
|
||||
ptr.ptr()->send_vec4(bits4_, 0);
|
||||
}
|
||||
|
||||
void vvp_wire_vec4::release_pv(vvp_net_ptr_t ptr, bool net,
|
||||
unsigned base, unsigned wid)
|
||||
{
|
||||
assert(bits4_.size() >= base + wid);
|
||||
assert(net);
|
||||
|
||||
vvp_vector2_t mask (vvp_vector2_t::FILL0, bits4_.size());
|
||||
for (unsigned idx = 0 ; idx < wid ; idx += 1)
|
||||
mask.set_bit(base+idx, 1);
|
||||
|
||||
release_mask(mask);
|
||||
ptr.ptr()->send_vec4(bits4_,0);
|
||||
}
|
||||
|
||||
unsigned vvp_wire_vec4::value_size() const
|
||||
{
|
||||
return width_;
|
||||
}
|
||||
|
||||
vvp_bit4_t vvp_wire_vec4::filtered_value_(const vvp_vector4_t&val, unsigned idx) const
|
||||
{
|
||||
if (test_force_mask(idx))
|
||||
return force4_.value(idx);
|
||||
else
|
||||
return val.value(idx);
|
||||
}
|
||||
|
||||
vvp_bit4_t vvp_wire_vec4::value(unsigned idx) const
|
||||
{
|
||||
return filtered_value_(bits4_, idx);
|
||||
}
|
||||
|
||||
vvp_scalar_t vvp_wire_vec4::scalar_value(unsigned idx) const
|
||||
{
|
||||
assert(0);
|
||||
}
|
||||
|
||||
vvp_vector4_t vvp_wire_vec4::vec4_value() const
|
||||
{
|
||||
assert(0);
|
||||
}
|
||||
|
||||
vvp_wire_vec8::vvp_wire_vec8(unsigned wid)
|
||||
: width_(wid)
|
||||
{
|
||||
}
|
||||
|
||||
const vvp_vector4_t* vvp_wire_vec8::filter_vec4(const vvp_vector4_t&bit)
|
||||
{
|
||||
assert(0);
|
||||
return 0;
|
||||
}
|
||||
|
||||
const vvp_vector8_t* vvp_wire_vec8::filter_vec8(const vvp_vector8_t&bit)
|
||||
{
|
||||
assert(0);
|
||||
return 0;
|
||||
}
|
||||
|
||||
unsigned vvp_wire_vec8::filter_size() const
|
||||
{
|
||||
return width_;
|
||||
}
|
||||
|
||||
void vvp_wire_vec8::force_fil_vec4(const vvp_vector4_t&val, vvp_vector2_t mask)
|
||||
{
|
||||
assert(0);
|
||||
}
|
||||
|
||||
void vvp_wire_vec8::force_fil_vec8(const vvp_vector8_t&val, vvp_vector2_t mask)
|
||||
{
|
||||
assert(0);
|
||||
}
|
||||
|
||||
void vvp_wire_vec8::force_fil_real(double val, vvp_vector2_t mask)
|
||||
{
|
||||
assert(0);
|
||||
}
|
||||
|
||||
void vvp_wire_vec8::release(vvp_net_ptr_t ptr, bool net)
|
||||
{
|
||||
assert(net);
|
||||
|
||||
// Wires revert to their unforced value after release.
|
||||
vvp_vector2_t mask (vvp_vector2_t::FILL1, width_);
|
||||
release_mask(mask);
|
||||
ptr.ptr()->send_vec8(bits8_);
|
||||
}
|
||||
|
||||
void vvp_wire_vec8::release_pv(vvp_net_ptr_t ptr, bool net,
|
||||
unsigned base, unsigned wid)
|
||||
{
|
||||
assert(width_ >= base + wid);
|
||||
assert(net);
|
||||
|
||||
vvp_vector2_t mask (vvp_vector2_t::FILL0, width_);
|
||||
for (unsigned idx = 0 ; idx < wid ; idx += 1)
|
||||
mask.set_bit(base+idx, 1);
|
||||
|
||||
release_mask(mask);
|
||||
ptr.ptr()->send_vec8(bits8_);
|
||||
}
|
||||
|
||||
unsigned vvp_wire_vec8::value_size() const
|
||||
{
|
||||
return width_;
|
||||
}
|
||||
|
||||
vvp_bit4_t vvp_wire_vec8::value(unsigned idx) const
|
||||
{
|
||||
assert(0);
|
||||
}
|
||||
|
||||
vvp_scalar_t vvp_wire_vec8::scalar_value(unsigned idx) const
|
||||
{
|
||||
assert(0);
|
||||
}
|
||||
|
||||
vvp_vector4_t vvp_wire_vec8::vec4_value() const
|
||||
{
|
||||
assert(0);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -62,32 +62,6 @@ using namespace std;
|
|||
* off again. Writing into this port can be done in behavioral code
|
||||
* using the %cassign/v instruction, or can be done by the network by
|
||||
* hooking the output of a vvp_net_t to this port.
|
||||
*
|
||||
* Force assignments are made through port-2. When a value is written
|
||||
* here, force mode is activated. In force mode, port-0 data (or
|
||||
* port-1 data if in continuous assign mode) is tracked but not
|
||||
* propagated. The force value is propagated and is what is readable
|
||||
* through the value method.
|
||||
*
|
||||
* Port-3 is a command port, intended for use by procedural
|
||||
* instructions. The client must write long values to this port to
|
||||
* invoke the command of interest. The command values are:
|
||||
*
|
||||
* 1 -- deassign
|
||||
* The deassign command takes the node out of continuous
|
||||
* assignment mode. The output value is unchanged, and force
|
||||
* mode, if active, remains in effect.
|
||||
*
|
||||
* 2 -- release/net
|
||||
* The release/net command takes the node out of force mode,
|
||||
* and propagates the tracked port-0 value to the signal
|
||||
* output. This acts like a release of a net signal.
|
||||
*
|
||||
* 3 -- release/reg
|
||||
* The release/reg command is similar to the release/net
|
||||
* command, but the port-0 value is not propagated. Changes
|
||||
* to port-0 (or port-1 if continuous assign is active) will
|
||||
* propagate starting at the next input change.
|
||||
*/
|
||||
|
||||
|
||||
|
|
@ -117,17 +91,27 @@ class vvp_fun_signal_base : public vvp_net_fun_t, public vvp_net_fil_t {
|
|||
};
|
||||
|
||||
/*
|
||||
* This abstract class is a little more specific than the signal_base
|
||||
* class, in that it adds vector access methods.
|
||||
* Variables and wires can have their values accessed, so this base
|
||||
* class offers the unified concept of an acessible value.
|
||||
*/
|
||||
class vvp_fun_signal_vec : public vvp_fun_signal_base {
|
||||
|
||||
class vvp_signal_value {
|
||||
public:
|
||||
// For vector signal types, this returns the vector count.
|
||||
virtual unsigned size() const =0;
|
||||
virtual ~vvp_signal_value() =0;
|
||||
virtual unsigned value_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;
|
||||
|
||||
virtual void get_signal_value(struct t_vpi_value*vp);
|
||||
};
|
||||
|
||||
/*
|
||||
* This abstract class is a little more specific than the signal_base
|
||||
* class, in that it adds vector access methods.
|
||||
*/
|
||||
class vvp_fun_signal_vec : public vvp_fun_signal_base, public vvp_signal_value {
|
||||
public:
|
||||
unsigned size() const { return value_size(); }
|
||||
};
|
||||
|
||||
class vvp_fun_signal4 : public vvp_fun_signal_vec {
|
||||
|
|
@ -146,6 +130,7 @@ class vvp_fun_signal4 : public vvp_fun_signal_vec {
|
|||
// Test the value against the filter.
|
||||
vvp_bit4_t filtered_value(const vvp_vector4_t&val, unsigned idx) const;
|
||||
const vvp_vector4_t& filtered_vec4(const vvp_vector4_t&val) const;
|
||||
unsigned filter_size() const;
|
||||
|
||||
private:
|
||||
vvp_vector4_t force4_;
|
||||
|
|
@ -172,7 +157,7 @@ class vvp_fun_signal4_sa : public vvp_fun_signal4 {
|
|||
unsigned base, unsigned wid, unsigned vwid);
|
||||
|
||||
// Get information about the vector value.
|
||||
unsigned size() const;
|
||||
unsigned value_size() const;
|
||||
vvp_bit4_t value(unsigned idx) const;
|
||||
vvp_scalar_t scalar_value(unsigned idx) const;
|
||||
vvp_vector4_t vec4_value() const;
|
||||
|
|
@ -209,7 +194,7 @@ class vvp_fun_signal4_aa : public vvp_fun_signal4, public automatic_hooks_s {
|
|||
vvp_context_t);
|
||||
|
||||
// Get information about the vector value.
|
||||
unsigned size() const;
|
||||
unsigned value_size() const;
|
||||
vvp_bit4_t value(unsigned idx) const;
|
||||
vvp_scalar_t scalar_value(unsigned idx) const;
|
||||
vvp_vector4_t vec4_value() const;
|
||||
|
|
@ -241,7 +226,7 @@ class vvp_fun_signal8 : public vvp_fun_signal_vec {
|
|||
unsigned base, unsigned wid, unsigned vwid);
|
||||
|
||||
// Get information about the vector value.
|
||||
unsigned size() const;
|
||||
unsigned value_size() const;
|
||||
vvp_bit4_t value(unsigned idx) const;
|
||||
vvp_scalar_t scalar_value(unsigned idx) const;
|
||||
vvp_vector4_t vec4_value() const;
|
||||
|
|
@ -263,6 +248,7 @@ class vvp_fun_signal8 : public vvp_fun_signal_vec {
|
|||
// Test the value against the filter.
|
||||
vvp_scalar_t filtered_value(const vvp_vector8_t&val, unsigned idx) const;
|
||||
const vvp_vector8_t& filtered_vec8(const vvp_vector8_t&val) const;
|
||||
unsigned filter_size() const;
|
||||
|
||||
private:
|
||||
vvp_vector8_t bits8_;
|
||||
|
|
@ -290,7 +276,8 @@ class vvp_fun_signal_real : public vvp_fun_signal_base {
|
|||
// Test the value against the filter.
|
||||
double filtered_real(double val) const;
|
||||
|
||||
virtual unsigned size() const;
|
||||
unsigned size() const { return 1; }
|
||||
virtual unsigned filter_size() const;
|
||||
|
||||
private:
|
||||
double force_real_;
|
||||
|
|
@ -350,4 +337,90 @@ class vvp_fun_signal_real_aa : public vvp_fun_signal_real, public automatic_hook
|
|||
};
|
||||
|
||||
|
||||
/* vvp_wire
|
||||
* The vvp_wire is different from vvp_variable objects in that it
|
||||
* exists only as a filter. The vvp_wire class tree is for
|
||||
* implementing verilog wires/nets (as opposed to regs/variables).
|
||||
*/
|
||||
|
||||
class vvp_wire_base : public vvp_net_fil_t, public vvp_signal_value {
|
||||
|
||||
public:
|
||||
vvp_wire_base();
|
||||
~vvp_wire_base();
|
||||
|
||||
// The main filter behavior for this class
|
||||
const vvp_vector4_t* filter_vec4(const vvp_vector4_t&bit) =0;
|
||||
const vvp_vector8_t* filter_vec8(const vvp_vector8_t&val) =0;
|
||||
|
||||
};
|
||||
|
||||
class vvp_wire_vec4 : public vvp_wire_base {
|
||||
|
||||
public:
|
||||
vvp_wire_vec4(unsigned wid, vvp_bit4_t init=BIT4_X);
|
||||
|
||||
// The main filter behavior for this class. These methods take
|
||||
// the value that the node is driven to, and applies the firce
|
||||
// filters. In wires, this also saves the driven value, so
|
||||
// that when a force is released, we can revert to the driven value.
|
||||
const vvp_vector4_t* filter_vec4(const vvp_vector4_t&bit);
|
||||
const vvp_vector8_t* filter_vec8(const vvp_vector8_t&val);
|
||||
|
||||
// Abstract methods from vvp_vpi_callback
|
||||
void get_value(struct t_vpi_value*value);
|
||||
// Abstract methods from vvp_net_fit_t
|
||||
unsigned filter_size() const;
|
||||
void force_fil_vec4(const vvp_vector4_t&val, vvp_vector2_t mask);
|
||||
void force_fil_vec8(const vvp_vector8_t&val, vvp_vector2_t mask);
|
||||
void force_fil_real(double val, vvp_vector2_t mask);
|
||||
void release(vvp_net_ptr_t ptr, bool net);
|
||||
void release_pv(vvp_net_ptr_t ptr, bool net, unsigned base, unsigned wid);
|
||||
|
||||
// Implementation of vvp_signal_value methods
|
||||
unsigned value_size() const;
|
||||
vvp_bit4_t value(unsigned idx) const;
|
||||
vvp_scalar_t scalar_value(unsigned idx) const;
|
||||
vvp_vector4_t vec4_value() const;
|
||||
|
||||
private:
|
||||
vvp_bit4_t filtered_value_(const vvp_vector4_t&val, unsigned idx) const;
|
||||
|
||||
private:
|
||||
unsigned width_;
|
||||
vvp_vector4_t bits4_; // The tracked driven value
|
||||
vvp_vector4_t force4_; // the value being forced
|
||||
vvp_vector4_t filter4_; // scratch space for filter_mask_ function.
|
||||
};
|
||||
|
||||
class vvp_wire_vec8 : public vvp_wire_base {
|
||||
|
||||
public:
|
||||
vvp_wire_vec8(unsigned wid);
|
||||
|
||||
// The main filter behavior for this class
|
||||
const vvp_vector4_t* filter_vec4(const vvp_vector4_t&bit);
|
||||
const vvp_vector8_t* filter_vec8(const vvp_vector8_t&val);
|
||||
|
||||
// Abstract methods from vvp_vpi_callback
|
||||
void get_value(struct t_vpi_value*value);
|
||||
// Abstract methods from vvp_net_fit_t
|
||||
unsigned filter_size() const;
|
||||
void force_fil_vec4(const vvp_vector4_t&val, vvp_vector2_t mask);
|
||||
void force_fil_vec8(const vvp_vector8_t&val, vvp_vector2_t mask);
|
||||
void force_fil_real(double val, vvp_vector2_t mask);
|
||||
void release(vvp_net_ptr_t ptr, bool net);
|
||||
void release_pv(vvp_net_ptr_t ptr, bool net, unsigned base, unsigned wid);
|
||||
|
||||
// Implementation of vvp_signal_value methods
|
||||
unsigned value_size() const;
|
||||
vvp_bit4_t value(unsigned idx) const;
|
||||
vvp_scalar_t scalar_value(unsigned idx) const;
|
||||
vvp_vector4_t vec4_value() const;
|
||||
|
||||
private:
|
||||
unsigned width_;
|
||||
vvp_vector8_t bits8_;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
|
|
|||
48
vvp/words.cc
48
vvp/words.cc
|
|
@ -148,40 +148,36 @@ void compile_variablew(char*label, vvp_array_t array,
|
|||
/*
|
||||
* Here we handle .net records from the vvp source:
|
||||
*
|
||||
* <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> ;
|
||||
* .net <name>, <msb>, <lsb>, <input> ;
|
||||
* .net/s <name>, <msb>, <lsb>, <input> ;
|
||||
* .net8 <name>, <msb>, <lsb>, <input> ;
|
||||
* .net8/s <name>, <msb>, <lsb>, <input> ;
|
||||
*
|
||||
* Create a VPI handle to represent it, and fill that handle in with
|
||||
* references into the net.
|
||||
*/
|
||||
static void __compile_net(char*label, char*name,
|
||||
char*array_label, unsigned long array_addr,
|
||||
static void __compile_net(char*label,
|
||||
char*name, char*array_label, unsigned long array_addr,
|
||||
int msb, int lsb,
|
||||
bool signed_flag, bool net8_flag, bool local_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_array_t array = array_label ? array_find(array_label) : 0;
|
||||
assert(array_label ? array!=0 : true);
|
||||
|
||||
vvp_fun_signal_base*vsig = net8_flag
|
||||
? dynamic_cast<vvp_fun_signal_base*>(new vvp_fun_signal8(wid))
|
||||
: dynamic_cast<vvp_fun_signal_base*>(new vvp_fun_signal4_sa(wid,BIT4_Z));
|
||||
node->fun = vsig;
|
||||
node->fil = vsig;
|
||||
|
||||
/* Add the label into the functor symbol table. */
|
||||
define_functor_symbol(label, node);
|
||||
// XXXX Forgot how to implement net arrays...
|
||||
assert(array_label == 0);
|
||||
|
||||
assert(argc == 1);
|
||||
vvp_net_t*node = vvp_net_lookup(argv[0].text);
|
||||
assert(node);
|
||||
|
||||
/* Connect the source to my input. */
|
||||
inputs_connect(node, 1, argv);
|
||||
vvp_wire_base*vsig = net8_flag
|
||||
? dynamic_cast<vvp_wire_base*>(new vvp_wire_vec8(wid))
|
||||
: dynamic_cast<vvp_wire_base*>(new vvp_wire_vec4(wid,BIT4_Z));
|
||||
|
||||
// Assume (for now) that there is only 1 filter per node.
|
||||
assert(node->fil == 0);
|
||||
node->fil = vsig;
|
||||
|
||||
vpiHandle obj = 0;
|
||||
if (! local_flag) {
|
||||
|
|
@ -190,11 +186,8 @@ static void __compile_net(char*label, char*name,
|
|||
/* This attaches the label to the vpiHandle */
|
||||
compile_vpi_symbol(label, obj);
|
||||
}
|
||||
/* If this is an array word, then attach it to the
|
||||
array. Otherwise, attach it to the current scope. */
|
||||
if (array)
|
||||
array_attach_word(array, array_addr, obj);
|
||||
else if (obj)
|
||||
|
||||
if (obj)
|
||||
vpip_attach_to_current_scope(obj);
|
||||
|
||||
free(label);
|
||||
|
|
@ -203,8 +196,7 @@ static void __compile_net(char*label, char*name,
|
|||
free(argv);
|
||||
}
|
||||
|
||||
void compile_net(char*label, char*name,
|
||||
int msb, int lsb,
|
||||
void compile_net(char*label, char*name, int msb, int lsb,
|
||||
bool signed_flag, bool net8_flag, bool local_flag,
|
||||
unsigned argc, struct symb_s*argv)
|
||||
{
|
||||
|
|
|
|||
Loading…
Reference in New Issue