diff --git a/tgt-vvp/draw_vpi.c b/tgt-vvp/draw_vpi.c index bac5d3176..02159e839 100644 --- a/tgt-vvp/draw_vpi.c +++ b/tgt-vvp/draw_vpi.c @@ -155,19 +155,9 @@ static int get_vpi_taskfunc_signal_arg(struct args_info *result, /* Fallback case: evaluate expression. */ struct vector_info av; av = draw_eval_expr(word_ex, STUFF_OK_XZ); - /* We need to enhance &A<> to support a signed index. */ - if (ivl_expr_signed(word_ex) && - (ivl_expr_width(word_ex) < 8*sizeof(int))) { - fprintf(stderr, "%s:%u: tgt-vvp warning: V0.9 " - "may give incorrect results for " - "an array select with a signed " - "index less than %zu bits.\n", - ivl_expr_file(expr), - ivl_expr_lineno(expr), - 8*sizeof(int)); - } - snprintf(buffer, sizeof buffer, "&A", - sig, av.base, av.wid); + snprintf(buffer, sizeof buffer, "&A", + sig, av.base, av.wid, + (ivl_expr_signed(word_ex) ? "s" : "u")); result->vec = av; result->vec_flag = 1; } else { diff --git a/vvp/README.txt b/vvp/README.txt index c848c7041..6e9ad1876 100644 --- a/vvp/README.txt +++ b/vvp/README.txt @@ -813,11 +813,14 @@ The &A<> argument is a reference to the word of a variable array. The syntax is: &A '<' , '>' - &A '<' , '>' + &A '<' , '>' + &A '<' , <"s" or "u"> '>' The is the label for a variable array, and the is the canonical word index as an unsigned integer. The second form -retrieves the index from thread space ( bits starting at ). +retrieves the from the given signal or &A<>/&PV<> select. +The third form retrieves the index from thread space ( bits +starting at ). The base value may be signed or unsigned. * The &PV<> argument diff --git a/vvp/array.cc b/vvp/array.cc index 577b8cec5..9b301fbec 100644 --- a/vvp/array.cc +++ b/vvp/array.cc @@ -128,6 +128,7 @@ struct __vpiArrayVthrA { // If wid >0, then the address is the base and wid the vector // width of the index to pull from the thread. unsigned wid; + bool is_signed; unsigned get_address() const { @@ -150,14 +151,37 @@ struct __vpiArrayVthrA { 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); - tmp.set_bit(idx, bit); + /* Get the value from thread space. */ + int tval = 0; + for (unsigned idx = 0 ; (idx < wid) && (idx < 8*sizeof(tval)); + idx += 1) { + vvp_bit4_t bit = vthread_get_bit(vpip_current_vthread, + address + idx); + switch (bit) { + case BIT4_X: + case BIT4_Z: + /* Return UINT_MAX to indicate an X base. */ + return UINT_MAX; + break; + + case BIT4_1: + tval |= 1<base); } -vpiHandle vpip_make_vthr_A(char*label, unsigned tbase, unsigned twid) +vpiHandle vpip_make_vthr_A(char*label, unsigned tbase, unsigned twid, + char*is_signed) { struct __vpiArrayVthrA*obj = (struct __vpiArrayVthrA*) malloc(sizeof (struct __vpiArrayVthrA)); @@ -1562,7 +1587,10 @@ vpiHandle vpip_make_vthr_A(char*label, unsigned tbase, unsigned twid) obj->address_handle = 0; obj->address = tbase; - obj->wid = twid; + obj->wid = twid; + obj->is_signed = strcmp(is_signed, "s") == 0; + + delete [] is_signed; return &(obj->base); } diff --git a/vvp/parse.y b/vvp/parse.y index cd23a7e89..92e7d34c3 100644 --- a/vvp/parse.y +++ b/vvp/parse.y @@ -873,8 +873,8 @@ argument symbol_access : K_A '<' T_SYMBOL ',' T_NUMBER '>' { $$ = 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_NUMBER T_NUMBER T_STRING '>' + { $$ = vpip_make_vthr_A($3, $5, $6, $7); } | K_A '<' T_SYMBOL ',' T_SYMBOL '>' { $$ = vpip_make_vthr_A($3, $5); } | K_A '<' T_SYMBOL ',' symbol_access '>' diff --git a/vvp/vpi_priv.h b/vvp/vpi_priv.h index 4d0eba18c..2a3b538d5 100644 --- a/vvp/vpi_priv.h +++ b/vvp/vpi_priv.h @@ -496,7 +496,8 @@ vpiHandle vpip_make_vthr_word(unsigned base, const char*type); vpiHandle vpip_make_vthr_A(char*label, unsigned index); vpiHandle vpip_make_vthr_A(char*label, char*symbol); -vpiHandle vpip_make_vthr_A(char*label, unsigned tbase, unsigned twid); +vpiHandle vpip_make_vthr_A(char*label, unsigned tbase, unsigned twid, + char*is_signed); vpiHandle vpip_make_vthr_A(char*label, vpiHandle handle); /*