From 6521ceaf929e2db13a5df9a770a8b2e91352f271 Mon Sep 17 00:00:00 2001 From: Stephen Williams Date: Sat, 14 Jun 2008 16:17:25 -0700 Subject: [PATCH] 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. --- vvp/array.cc | 3 ++- vvp/vpi_priv.cc | 18 ++++++++++++++---- vvp/vpi_priv.h | 14 +++++++++----- vvp/vpi_signal.cc | 36 ++++++++++++++++++++---------------- 4 files changed, 45 insertions(+), 26 deletions(-) diff --git a/vvp/array.cc b/vvp/array.cc index a256acafe..75bb22f44 100644 --- a/vvp/array.cc +++ b/vvp/array.cc @@ -834,7 +834,8 @@ void array_attach_word(vvp_array_t array, unsigned long addr, vpiHandle word) vvp_fun_signal_base*fun = dynamic_cast(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); } } diff --git a/vvp/vpi_priv.cc b/vvp/vpi_priv.cc index dc0e82a0b..0c004d2a9 100644 --- a/vvp/vpi_priv.cc +++ b/vvp/vpi_priv.cc @@ -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 " diff --git a/vvp/vpi_priv.h b/vvp/vpi_priv.h index 3da88728c..25a5282b8 100644 --- a/vvp/vpi_priv.h +++ b/vvp/vpi_priv.h @@ -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, diff --git a/vvp/vpi_signal.cc b/vvp/vpi_signal.cc index 1796fad5d..54ef5dd47 100644 --- a/vvp/vpi_signal.cc +++ b/vvp/vpi_signal.cc @@ -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;