diff --git a/vvp/array.cc b/vvp/array.cc index 4994a3cd6..defaddffb 100644 --- a/vvp/array.cc +++ b/vvp/array.cc @@ -842,6 +842,19 @@ void array_attach_word(vvp_array_t array, unsigned long addr, vpiHandle word) sig->is_netarray = 1; sig->within.parent = &array->base; sig->id.index = vpip_make_dec_const(addr + array->first_addr.value); + return; + } + + if (struct __vpiRealVar*sig = (struct __vpiRealVar*)word) { + vvp_net_t*net = sig->net; + assert(net); + vvp_fun_signal_base*fun = dynamic_cast(net->fun); + assert(fun); + fun->attach_as_word(array, addr); + sig->is_netarray = 1; + sig->within.parent = &array->base; + sig->id.index = vpip_make_dec_const(addr + array->first_addr.value); + return; } } diff --git a/vvp/vpi_priv.cc b/vvp/vpi_priv.cc index f0338e909..27af301cf 100644 --- a/vvp/vpi_priv.cc +++ b/vvp/vpi_priv.cc @@ -58,6 +58,14 @@ struct __vpiScope* vpip_scope(__vpiSignal*sig) return sig->within.scope; } +struct __vpiScope* vpip_scope(__vpiRealVar*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}}; diff --git a/vvp/vpi_priv.h b/vvp/vpi_priv.h index c88197bca..6b053ad72 100644 --- a/vvp/vpi_priv.h +++ b/vvp/vpi_priv.h @@ -354,16 +354,20 @@ extern void vpip_real_value_change(struct __vpiCallback*cbh, */ struct __vpiRealVar { struct __vpiHandle base; - vpiHandle parent; - struct __vpiScope* scope; + union { // The scope or parent array that contains me. + vpiHandle parent; + struct __vpiScope* scope; + } within; /* The name of this variable, or the index for array words. */ union { const char*name; vpiHandle index; } id; + unsigned is_netarray : 1; // This is word of a net array vvp_net_t*net; }; +extern struct __vpiScope* vpip_scope(__vpiRealVar*sig); extern vpiHandle vpip_make_real_var(const char*name, vvp_net_t*net); /* diff --git a/vvp/vpi_real.cc b/vvp/vpi_real.cc index 6965ed145..78b607519 100644 --- a/vvp/vpi_real.cc +++ b/vvp/vpi_real.cc @@ -36,7 +36,7 @@ static int real_var_get(int code, vpiHandle ref) switch (code) { case vpiArray: - return rfp->parent != 0; + return rfp->is_netarray != 0; case vpiSize: return 1; @@ -62,8 +62,8 @@ static char* real_var_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); @@ -73,7 +73,7 @@ static char* real_var_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; } @@ -87,10 +87,13 @@ static vpiHandle real_var_get_handle(int code, vpiHandle 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 &(vpip_scope(rfp)->base); } return 0; @@ -103,8 +106,8 @@ static vpiHandle real_var_iterate(int code, vpiHandle ref) struct __vpiRealVar*rfp = (struct __vpiRealVar*)ref; if (code == vpiIndex) { - return rfp->parent ? (rfp->id.index->vpi_type->iterate_) - (code, rfp->id.index) : 0; + return rfp->is_netarray ? (rfp->id.index->vpi_type->iterate_) + (code, rfp->id.index) : 0; } return 0; @@ -179,22 +182,17 @@ void vpip_real_value_change(struct __vpiCallback*cbh, fun->add_vpi_callback(cbh); } -/* - * Since reals do not currently support arrays none of the array code - * has been tested! Though it should work since it is a copy of the - * signal code. - */ vpiHandle vpip_make_real_var(const char*name, vvp_net_t*net) { struct __vpiRealVar*obj = (struct __vpiRealVar*) malloc(sizeof(struct __vpiRealVar)); obj->base.vpi_type = &vpip_real_var_rt; - obj->parent = 0; obj->id.name = name ? vpip_name_string(name) : 0; + obj->is_netarray = 0; obj->net = net; - obj->scope = vpip_peek_current_scope(); + obj->within.scope = vpip_peek_current_scope(); return &obj->base; }