From 99f66e2781a81aa0eef67099d450fffd71538ce3 Mon Sep 17 00:00:00 2001 From: Martin Whitaker Date: Tue, 7 Nov 2017 18:48:48 +0000 Subject: [PATCH] Fix for GitHub issue #169: nets can get given wrong scope in VPI. In vvp, the __vpiSignal object holds a pointer to the scope containing the signal. This was getting set to the current scope when the net was finally resolved, rather than to the scope where the net was declared. (cherry picked from commit c622d372f90f721b2750f74d042c597d17744958) --- vvp/vpi_priv.h | 7 +++++-- vvp/vpi_real.cc | 16 ++++++++++++++-- vvp/vpi_signal.cc | 31 +++++++++++++++++++++---------- vvp/words.cc | 6 +++--- 4 files changed, 43 insertions(+), 17 deletions(-) diff --git a/vvp/vpi_priv.h b/vvp/vpi_priv.h index ab8c0cc46..a54ec29b6 100644 --- a/vvp/vpi_priv.h +++ b/vvp/vpi_priv.h @@ -339,7 +339,8 @@ extern vpiHandle vpip_make_int4(const char*name, int msb, int lsb, vvp_net_t*vec); extern vpiHandle vpip_make_var4(const char*name, int msb, int lsb, bool signed_flag, vvp_net_t*net); -extern vpiHandle vpip_make_net4(const char*name, int msb, int lsb, +extern vpiHandle vpip_make_net4(__vpiScope*scope, + const char*name, int msb, int lsb, bool signed_flag, vvp_net_t*node); /* @@ -506,7 +507,9 @@ struct __vpiRealVar : public __vpiHandle { }; extern struct __vpiScope* vpip_scope(__vpiRealVar*sig); -extern vpiHandle vpip_make_real_var(const char*name, vvp_net_t*net, bool is_wire); +extern vpiHandle vpip_make_real_var(const char*name, vvp_net_t*net); +extern vpiHandle vpip_make_real_net(__vpiScope*scope, + const char*name, vvp_net_t*net); class __vpiBaseVar : public __vpiHandle { diff --git a/vvp/vpi_real.cc b/vvp/vpi_real.cc index acc426b68..526ac6113 100644 --- a/vvp/vpi_real.cc +++ b/vvp/vpi_real.cc @@ -178,7 +178,8 @@ vpiHandle __vpiRealVar::vpi_handle(int code) vpiHandle __vpiRealVar::vpi_iterate(int code) { return real_var_iterate(code, this); } -vpiHandle vpip_make_real_var(const char*name, vvp_net_t*net, bool is_wire) +static vpiHandle vpip_make_real_(__vpiScope*scope, const char*name, + vvp_net_t*net, bool is_wire) { struct __vpiRealVar*obj = new __vpiRealVar; @@ -187,11 +188,22 @@ vpiHandle vpip_make_real_var(const char*name, vvp_net_t*net, bool is_wire) obj->is_wire = is_wire; obj->net = net; - obj->within.scope = vpip_peek_current_scope(); + obj->within.scope = scope; return obj; } +vpiHandle vpip_make_real_var(const char*name, vvp_net_t*net) +{ + return vpip_make_real_(vpip_peek_current_scope(), name, net, false); +} + +vpiHandle vpip_make_real_net(__vpiScope*scope, + const char*name, vvp_net_t*net) +{ + return vpip_make_real_(scope, name, net, true); +} + #ifdef CHECK_WITH_VALGRIND void real_delete(vpiHandle item) { diff --git a/vvp/vpi_signal.cc b/vvp/vpi_signal.cc index 243254853..27965db4d 100644 --- a/vvp/vpi_signal.cc +++ b/vvp/vpi_signal.cc @@ -132,9 +132,19 @@ char *generic_get_str(int code, vpiHandle ref, const char *name, const char *ind return res; } -static vpiHandle fill_in_net4(struct __vpiSignal*obj, - const char*name, int msb, int lsb, - bool signed_flag, vvp_net_t*node); +static vpiHandle fill_in_net4(struct __vpiSignal*obj, __vpiScope*scope, + const char*name, int msb, int lsb, + bool signed_flag, vvp_net_t*node); + +static vpiHandle fill_in_var4(struct __vpiSignal*obj, + const char*name, int msb, int lsb, + bool signed_flag, vvp_net_t*node) +{ + // Variable declarations are always resolved immediately, + // so we can assume they belong in the current scope. + return fill_in_net4(obj, vpip_peek_current_scope(), + name, msb, lsb, signed_flag, node); +} /* * The standard formatting/conversion routines. @@ -972,7 +982,7 @@ struct signal_longint : public __vpiSignal { vpiHandle vpip_make_int4(const char*name, int msb, int lsb, vvp_net_t*vec) { __vpiSignal*obj = new signal_integer; - return fill_in_net4(obj, name, msb, lsb, true, vec); + return fill_in_var4(obj, name, msb, lsb, true, vec); } /* @@ -1011,7 +1021,7 @@ vpiHandle vpip_make_int2(const char*name, int msb, int lsb, bool signed_flag, } } - return fill_in_net4(obj, name, msb, lsb, signed_flag, vec); + return fill_in_var4(obj, name, msb, lsb, signed_flag, vec); } /* @@ -1021,7 +1031,7 @@ vpiHandle vpip_make_var4(const char*name, int msb, int lsb, bool signed_flag, vvp_net_t*vec) { __vpiSignal*obj = new signal_reg; - return fill_in_net4(obj, name, msb, lsb, signed_flag, vec); + return fill_in_var4(obj, name, msb, lsb, signed_flag, vec); } #ifdef CHECK_WITH_VALGRIND @@ -1116,7 +1126,7 @@ void signal_pool_delete() * The name is the PLI name for the object. If it is an array it is * []. */ -static vpiHandle fill_in_net4(struct __vpiSignal*obj, +static vpiHandle fill_in_net4(struct __vpiSignal*obj, __vpiScope*scope, const char*name, int msb, int lsb, bool signed_flag, vvp_net_t*node) { @@ -1130,18 +1140,19 @@ static vpiHandle fill_in_net4(struct __vpiSignal*obj, // 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(); + obj->within.scope = scope; count_vpi_nets += 1; return obj; } -vpiHandle vpip_make_net4(const char*name, int msb, int lsb, +vpiHandle vpip_make_net4(__vpiScope*scope, + const char*name, int msb, int lsb, bool signed_flag, vvp_net_t*node) { struct __vpiSignal*obj = new signal_net; - return fill_in_net4(obj, name, msb, lsb, signed_flag, node); + return fill_in_net4(obj, scope, name, msb, lsb, signed_flag, node); } static int PV_get_base(struct __vpiPV*rfp) diff --git a/vvp/words.cc b/vvp/words.cc index 139171032..f88864e5c 100644 --- a/vvp/words.cc +++ b/vvp/words.cc @@ -48,7 +48,7 @@ static void __compile_var_real(char*label, char*name, define_functor_symbol(label, net); - vpiHandle obj = vpip_make_real_var(name, net, false); + vpiHandle obj = vpip_make_real_var(name, net); compile_vpi_symbol(label, obj); if (name) { @@ -350,7 +350,7 @@ static void do_compile_net(vvp_net_t*node, vvp_array_t array, vpiHandle obj = 0; if (! local_flag) { /* Make the vpiHandle for the reg. */ - obj = vpip_make_net4(name, msb, lsb, signed_flag, node); + obj = vpip_make_net4(scope, name, msb, lsb, signed_flag, node); /* This attaches the label to the vpiHandle */ compile_vpi_symbol(my_label, obj); } @@ -481,7 +481,7 @@ static void __compile_real_net2(vvp_net_t*node, vvp_array_t array, vpiHandle obj = 0; if (!local_flag) { - obj = vpip_make_real_var(name, node, true); + obj = vpip_make_real_net(scope, name, node); compile_vpi_symbol(my_label, obj); } #ifdef CHECK_WITH_VALGRIND