Union scope and parent pointers for signals.
If a signal is part of an array, then it can get its scope from its parent, so the scope and parent pointers can go into a union.
This commit is contained in:
parent
f497dbf01e
commit
6521ceaf92
|
|
@ -834,7 +834,8 @@ void array_attach_word(vvp_array_t array, unsigned long addr, vpiHandle word)
|
|||
vvp_fun_signal_base*fun = dynamic_cast<vvp_fun_signal_base*>(net->fun);
|
||||
assert(fun);
|
||||
fun->attach_as_word(array, addr);
|
||||
sig->parent = &array->base;
|
||||
sig->is_netarray = 1;
|
||||
sig->within.parent = &array->base;
|
||||
sig->id.index = vpip_make_dec_const(addr + array->first_addr.value);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -50,6 +50,14 @@ unsigned vpip_size(__vpiSignal *sig)
|
|||
return abs(sig->msb - sig->lsb) + 1;
|
||||
}
|
||||
|
||||
struct __vpiScope* vpip_scope(__vpiSignal*sig)
|
||||
{
|
||||
if (sig->is_netarray)
|
||||
return (struct __vpiScope*) vpi_handle(vpiScope, sig->within.parent);
|
||||
else
|
||||
return sig->within.scope;
|
||||
}
|
||||
|
||||
const char *vpip_string(const char*str)
|
||||
{
|
||||
static vpip_string_chunk first_chunk = {0, {0}};
|
||||
|
|
@ -320,8 +328,9 @@ int vpip_time_units_from_handle(vpiHandle obj)
|
|||
|
||||
case vpiNet:
|
||||
case vpiReg:
|
||||
signal = (struct __vpiSignal*)obj;
|
||||
return signal->scope->time_units;
|
||||
signal = vpip_signal_from_handle(obj);
|
||||
scope = vpip_scope(signal);
|
||||
return scope->time_units;
|
||||
|
||||
default:
|
||||
fprintf(stderr, "ERROR: vpip_time_units_from_handle called with "
|
||||
|
|
@ -351,8 +360,9 @@ int vpip_time_precision_from_handle(vpiHandle obj)
|
|||
|
||||
case vpiNet:
|
||||
case vpiReg:
|
||||
signal = (struct __vpiSignal*)obj;
|
||||
return signal->scope->time_precision;
|
||||
signal = vpip_signal_from_handle(obj);
|
||||
scope = vpip_scope(signal);
|
||||
return scope->time_precision;
|
||||
|
||||
default:
|
||||
fprintf(stderr, "ERROR: vpip_time_precision_from_handle called "
|
||||
|
|
|
|||
|
|
@ -197,10 +197,11 @@ extern void vpip_make_root_iterator(struct __vpiHandle**&table,
|
|||
*/
|
||||
struct __vpiSignal {
|
||||
struct __vpiHandle base;
|
||||
vpiHandle parent;
|
||||
struct __vpiScope* scope;
|
||||
/* The name of this reg/net, or the index for array words. */
|
||||
union {
|
||||
union { // The scope or parent array that contains me.
|
||||
vpiHandle parent;
|
||||
struct __vpiScope* scope;
|
||||
} within;
|
||||
union { // The name of this reg/net, or the index for array words.
|
||||
const char*name;
|
||||
vpiHandle index;
|
||||
} id;
|
||||
|
|
@ -208,11 +209,14 @@ struct __vpiSignal {
|
|||
int msb, lsb;
|
||||
/* Flags */
|
||||
unsigned signed_flag : 1;
|
||||
unsigned isint_ : 1; // original type was integer
|
||||
unsigned isint_ : 1; // original type was integer
|
||||
unsigned is_netarray : 1; // This is word of a net array
|
||||
/* The represented value is here. */
|
||||
vvp_net_t*node;
|
||||
};
|
||||
extern unsigned vpip_size(__vpiSignal *sig);
|
||||
extern struct __vpiScope* vpip_scope(__vpiSignal*sig);
|
||||
|
||||
extern vpiHandle vpip_make_int(const char*name, int msb, int lsb,
|
||||
vvp_net_t*vec);
|
||||
extern vpiHandle vpip_make_reg(const char*name, int msb, int lsb,
|
||||
|
|
|
|||
|
|
@ -505,16 +505,17 @@ static int signal_get(int code, vpiHandle ref)
|
|||
return rfp->signed_flag != 0;
|
||||
|
||||
case vpiArray:
|
||||
return rfp->parent != 0;
|
||||
return rfp->is_netarray != 0;
|
||||
|
||||
case vpiIndex: // This only works while we have a single index.
|
||||
if (rfp->parent) {
|
||||
if (rfp->is_netarray) {
|
||||
s_vpi_value vp;
|
||||
vp.format = vpiIntVal;
|
||||
vpi_get_value(rfp->id.index, &vp);
|
||||
return vp.value.integer;
|
||||
} else
|
||||
} else {
|
||||
return 0;
|
||||
}
|
||||
|
||||
case vpiSize:
|
||||
if (rfp->msb >= rfp->lsb)
|
||||
|
|
@ -555,8 +556,8 @@ static char* signal_get_str(int code, vpiHandle ref)
|
|||
}
|
||||
|
||||
char *nm, *ixs;
|
||||
if (rfp->parent) {
|
||||
nm = strdup(vpi_get_str(vpiName, rfp->parent));
|
||||
if (rfp->is_netarray) {
|
||||
nm = strdup(vpi_get_str(vpiName, rfp->within.parent));
|
||||
s_vpi_value vp;
|
||||
vp.format = vpiDecStrVal;
|
||||
vpi_get_value(rfp->id.index, &vp);
|
||||
|
|
@ -566,7 +567,7 @@ static char* signal_get_str(int code, vpiHandle ref)
|
|||
ixs = NULL;
|
||||
}
|
||||
|
||||
char *rbuf = generic_get_str(code, &rfp->scope->base, nm, ixs);
|
||||
char *rbuf = generic_get_str(code, &(vpip_scope(rfp)->base), nm, ixs);
|
||||
free(nm);
|
||||
return rbuf;
|
||||
}
|
||||
|
|
@ -576,21 +577,21 @@ static vpiHandle signal_get_handle(int code, vpiHandle ref)
|
|||
assert((ref->vpi_type->type_code==vpiNet)
|
||||
|| (ref->vpi_type->type_code==vpiReg));
|
||||
|
||||
struct __vpiSignal*rfp = (struct __vpiSignal*)ref;
|
||||
struct __vpiSignal*rfp = vpip_signal_from_handle(ref);
|
||||
|
||||
switch (code) {
|
||||
|
||||
case vpiParent:
|
||||
return rfp->parent;
|
||||
return rfp->is_netarray? rfp->within.parent : 0;
|
||||
|
||||
case vpiIndex:
|
||||
return rfp->parent ? rfp->id.index : 0;
|
||||
return rfp->is_netarray? rfp->id.index : 0;
|
||||
|
||||
case vpiScope:
|
||||
return &rfp->scope->base;
|
||||
return &(vpip_scope(rfp)->base);
|
||||
|
||||
case vpiModule:
|
||||
{ struct __vpiScope*scope = rfp->scope;
|
||||
{ struct __vpiScope*scope = vpip_scope(rfp);
|
||||
while (scope && scope->base.vpi_type->type_code != vpiModule)
|
||||
scope = scope->scope;
|
||||
|
||||
|
|
@ -610,7 +611,7 @@ static vpiHandle signal_iterate(int code, vpiHandle ref)
|
|||
struct __vpiSignal*rfp = (struct __vpiSignal*)ref;
|
||||
|
||||
if (code == vpiIndex) {
|
||||
return rfp->parent ? array_index_iterate(code, rfp->id.index) : 0;
|
||||
return rfp->is_netarray? array_index_iterate(code, rfp->id.index) : 0;
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
|
@ -690,7 +691,7 @@ static void signal_get_value(vpiHandle ref, s_vpi_value*vp)
|
|||
fprintf(stderr, "vvp internal error: get_value: "
|
||||
"value type %u not implemented."
|
||||
" Signal is %s in scope %s\n",
|
||||
vp->format, vpi_get_str(vpiName, ref), rfp->scope->name);
|
||||
vp->format, vpi_get_str(vpiName, ref), vpip_scope(rfp)->name);
|
||||
assert(0);
|
||||
}
|
||||
}
|
||||
|
|
@ -921,15 +922,18 @@ vpiHandle vpip_make_net(const char*name, int msb, int lsb,
|
|||
{
|
||||
struct __vpiSignal*obj = allocate_vpiSignal();
|
||||
obj->base.vpi_type = &vpip_net_rt;
|
||||
obj->parent = 0;
|
||||
obj->id.name = name? vpip_name_string(name) : 0;
|
||||
obj->msb = msb;
|
||||
obj->lsb = lsb;
|
||||
obj->signed_flag = signed_flag? 1 : 0;
|
||||
obj->isint_ = false;
|
||||
obj->isint_ = 0;
|
||||
obj->is_netarray = 0;
|
||||
obj->node = node;
|
||||
|
||||
obj->scope = vpip_peek_current_scope();
|
||||
// Place this object within a scope. If this object is
|
||||
// attached to an array, then this value will be replaced with
|
||||
// the handle to the parent.
|
||||
obj->within.scope = vpip_peek_current_scope();
|
||||
|
||||
count_vpi_nets += 1;
|
||||
|
||||
|
|
|
|||
Loading…
Reference in New Issue