From 608bad26cff599e739da6e0893b5abf3a596b212 Mon Sep 17 00:00:00 2001 From: Stephen Williams Date: Tue, 10 Jun 2008 20:36:31 -0700 Subject: [PATCH] Allow &A<> argument syntax to take a reference to a VPI object. This allows the array index to be evaluated when the word is accessed, and that in turn allows access in the ROSYNC scheduler phase to work properly. --- tgt-vvp/draw_vpi.c | 7 ++++++- vvp/array.cc | 31 +++++++++++++++++++++++++++++++ vvp/lexor.lex | 2 +- vvp/parse.y | 2 ++ 4 files changed, 40 insertions(+), 2 deletions(-) diff --git a/tgt-vvp/draw_vpi.c b/tgt-vvp/draw_vpi.c index b1b1928f9..7edee56ba 100644 --- a/tgt-vvp/draw_vpi.c +++ b/tgt-vvp/draw_vpi.c @@ -285,7 +285,12 @@ static void draw_vpi_taskfunc_args(const char*call_string, word_ex = 0; } } - if (word_ex) { + 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)); + } else if (word_ex) { + /* fallback case: evaluate expression. */ struct vector_info av; av = draw_eval_expr(word_ex, STUFF_OK_XZ); snprintf(buffer, sizeof buffer, diff --git a/vvp/array.cc b/vvp/array.cc index f78c4c988..e0e4ec306 100644 --- a/vvp/array.cc +++ b/vvp/array.cc @@ -83,6 +83,8 @@ struct __vpiArrayIndex { struct __vpiArrayVthrA { struct __vpiHandle base; struct __vpiArray*array; + // If this is set, then use it to get the index value. + vpiHandle address_handle; // If wid==0, then address is the address into the array. unsigned address; // If wid >0, then the address is the base and wid the vector @@ -91,8 +93,16 @@ struct __vpiArrayVthrA { unsigned get_address() const { + if (address_handle) { + s_vpi_value vp; + vp.format = vpiIntVal; + vpi_get_value(address_handle, &vp); + return vp.value.integer; + } + if (wid == 0) return address; + vvp_vector4_t tmp (wid); for (unsigned idx = 0 ; idx < wid ; idx += 1) { vvp_bit4_t bit = vthread_get_bit(vpip_current_vthread, address+idx); @@ -1064,6 +1074,7 @@ vpiHandle vpip_make_vthr_A(char*label, unsigned addr) assert(obj->array); free(label); + obj->address_handle = 0; obj->address = addr; obj->wid = 0; assert(addr < obj->array->array_count); @@ -1082,12 +1093,32 @@ vpiHandle vpip_make_vthr_A(char*label, unsigned tbase, unsigned twid) assert(obj->array); free(label); + obj->address_handle = 0; obj->address = tbase; obj->wid = twid; return &(obj->base); } +vpiHandle vpip_make_vthr_A(char*label, char*symbol) +{ + struct __vpiArrayVthrA*obj = (struct __vpiArrayVthrA*) + malloc(sizeof (struct __vpiArrayVthrA)); + + obj->base.vpi_type = &vpip_array_vthr_A_rt; + + obj->array = array_find(label); + assert(obj->array); + free(label); + + obj->address_handle = 0; + compile_vpi_lookup(&obj->address_handle, symbol); + obj->address = 0; + obj->wid = 0; + + return &(obj->base); +} + void compile_array_cleanup(void) { if (array_table) { diff --git a/vvp/lexor.lex b/vvp/lexor.lex index c948a12a4..0e21eb087 100644 --- a/vvp/lexor.lex +++ b/vvp/lexor.lex @@ -228,7 +228,7 @@ /* Symbols are pretty much what is left. They are used to refer to labels so the rule must match a string that a label would match. */ -[.$_a-zA-Z\\][.$_a-zA-Z\\0-9<>/]* { +[.$_a-zA-Z\\]([.$_a-zA-Z\\0-9/]|(\\.))* { yylval.text = strdup(yytext); assert(yylval.text); return T_SYMBOL; } diff --git a/vvp/parse.y b/vvp/parse.y index fea306277..7d0a06560 100644 --- a/vvp/parse.y +++ b/vvp/parse.y @@ -819,6 +819,8 @@ argument { $$ = vpip_make_vthr_A($3, $5); } | K_A '<' T_SYMBOL ',' T_NUMBER T_NUMBER '>' { $$ = vpip_make_vthr_A($3, $5, $6); } + | K_A '<' T_SYMBOL ',' T_SYMBOL '>' + { $$ = vpip_make_vthr_A($3, $5); } | K_PV '<' T_SYMBOL ',' T_NUMBER ',' T_NUMBER '>' { $$ = vpip_make_PV($3, $5, $7); } | K_PV '<' T_SYMBOL ',' '-' T_NUMBER ',' T_NUMBER '>'