From f78994b66cb804ebd6738d0869777874b8c8b0c0 Mon Sep 17 00:00:00 2001 From: Cary R Date: Fri, 13 Jun 2008 16:22:18 -0700 Subject: [PATCH] Allow &PV<> to reference a VPI object (signal) for the base. This patch adds code to allow &PV<> to access a VPI object (signal) for the base of an indexed part select. This mirrors the code added to &A<>. --- tgt-vvp/draw_vpi.c | 12 ++++++++++-- vvp/parse.y | 2 ++ vvp/vpi_priv.h | 2 ++ vvp/vpi_signal.cc | 29 +++++++++++++++++++++++++++-- 4 files changed, 41 insertions(+), 4 deletions(-) diff --git a/tgt-vvp/draw_vpi.c b/tgt-vvp/draw_vpi.c index e1033b112..1c2271116 100644 --- a/tgt-vvp/draw_vpi.c +++ b/tgt-vvp/draw_vpi.c @@ -212,9 +212,10 @@ static void draw_vpi_taskfunc_args(const char*call_string, if (word_ex && ivl_expr_type(word_ex)==IVL_EX_SIGNAL) { /* Special case: the index is a signal. */ snprintf(buffer, sizeof buffer, - "&A", sig, ivl_expr_signal(word_ex)); + "&A", sig, + ivl_expr_signal(word_ex)); } else if (word_ex) { - /* fallback case: evaluate expression. */ + /* Fallback case: evaluate expression. */ struct vector_info av; av = draw_eval_expr(word_ex, STUFF_OK_XZ); snprintf(buffer, sizeof buffer, @@ -250,7 +251,14 @@ static void draw_vpi_taskfunc_args(const char*call_string, get_number_immediate(bexpr), ivl_expr_width(expr)); /* This is an indexed bit/part select. */ + } else if (ivl_expr_type(bexpr) == IVL_EX_SIGNAL) { + /* Sepcial case: the base is a signal. */ + snprintf(buffer, sizeof buffer, "&PV", + ivl_expr_signal(vexpr), + ivl_expr_signal(bexpr), + ivl_expr_width(expr)); } else { + /* Fallback case: evaluate the expression. */ struct vector_info rv; rv = draw_eval_expr(bexpr, STUFF_OK_XZ); snprintf(buffer, sizeof buffer, "&PV", diff --git a/vvp/parse.y b/vvp/parse.y index 7d0a06560..6947f8996 100644 --- a/vvp/parse.y +++ b/vvp/parse.y @@ -825,6 +825,8 @@ argument { $$ = vpip_make_PV($3, $5, $7); } | K_PV '<' T_SYMBOL ',' '-' T_NUMBER ',' T_NUMBER '>' { $$ = vpip_make_PV($3, -$6, $8); } + | K_PV '<' T_SYMBOL ',' T_SYMBOL ',' T_NUMBER '>' + { $$ = vpip_make_PV($3, $5, $7); } | K_PV '<' T_SYMBOL ',' T_NUMBER T_NUMBER ',' T_NUMBER '>' { $$ = vpip_make_PV($3, $5, $6, $8); } ; diff --git a/vvp/vpi_priv.h b/vvp/vpi_priv.h index af8927417..3da88728c 100644 --- a/vvp/vpi_priv.h +++ b/vvp/vpi_priv.h @@ -228,10 +228,12 @@ struct __vpiPV { struct __vpiHandle base; vpiHandle parent; vvp_net_t*net; + vpiHandle sbase; int tbase; unsigned twid, width; }; extern vpiHandle vpip_make_PV(char*name, int base, int width); +extern vpiHandle vpip_make_PV(char*name, char*symbol, int width); extern vpiHandle vpip_make_PV(char*name, int tbase, int twid, int width); extern struct __vpiPV* vpip_PV_from_handle(vpiHandle obj); diff --git a/vvp/vpi_signal.cc b/vvp/vpi_signal.cc index 539d0f990..8388aa420 100644 --- a/vvp/vpi_signal.cc +++ b/vvp/vpi_signal.cc @@ -946,12 +946,21 @@ vpiHandle vpip_make_net(const char*name, int msb, int lsb, static int PV_get_base(struct __vpiPV*rfp) { + /* We return from the symbol base if it is defined. */ + if (rfp->sbase != 0) { + s_vpi_value val; + val.format = vpiIntVal; + vpi_get_value(rfp->sbase, &val); + return val.value.integer; + } + + /* If the width is zero then tbase is the constant. */ if (rfp->twid == 0) return rfp->tbase; int tval = 0; for (unsigned idx = 0 ; idx < rfp->twid ; idx += 1) { vvp_bit4_t bit = vthread_get_bit(vpip_current_vthread, - rfp->tbase + idx); + rfp->tbase + idx); if (bit == BIT4_1) { tval |= 1<base.vpi_type = &vpip_PV_rt; obj->parent = vvp_lookup_handle(var); + obj->sbase = 0; obj->tbase = base; obj->twid = 0; obj->width = (unsigned) width; @@ -1169,11 +1178,27 @@ vpiHandle vpip_make_PV(char*var, int base, int width) return &obj->base; } +vpiHandle vpip_make_PV(char*var, char*symbol, int width) +{ + struct __vpiPV*obj = (struct __vpiPV*) malloc(sizeof(struct __vpiPV)); + obj->base.vpi_type = &vpip_PV_rt; + obj->parent = vvp_lookup_handle(var); + compile_vpi_lookup(&obj->sbase, symbol); + obj->tbase = 0; + obj->twid = 0; + obj->width = (unsigned) width; + obj->net = (vvp_net_t*) malloc(sizeof(vvp_net_t)); + functor_ref_lookup(&obj->net, var); + + return &obj->base; +} + vpiHandle vpip_make_PV(char*var, int tbase, int twid, int width) { struct __vpiPV*obj = (struct __vpiPV*) malloc(sizeof(struct __vpiPV)); obj->base.vpi_type = &vpip_PV_rt; obj->parent = vvp_lookup_handle(var); + obj->sbase = 0; obj->tbase = tbase; obj->twid = (unsigned) twid; obj->width = (unsigned) width;