Add support for signed thread base index for &A<>

This patch adds support for getting a signed index for &A<> from
thread space. This mimics what was done for &PV<>.
This commit is contained in:
Cary R 2009-09-17 14:00:28 -07:00 committed by Stephen Williams
parent c82baa2793
commit e54fd4df51
5 changed files with 49 additions and 27 deletions

View File

@ -155,19 +155,9 @@ static int get_vpi_taskfunc_signal_arg(struct args_info *result,
/* Fallback case: evaluate expression. */ /* Fallback case: evaluate expression. */
struct vector_info av; struct vector_info av;
av = draw_eval_expr(word_ex, STUFF_OK_XZ); av = draw_eval_expr(word_ex, STUFF_OK_XZ);
/* We need to enhance &A<> to support a signed index. */ snprintf(buffer, sizeof buffer, "&A<v%p, %u %u \"%s\">",
if (ivl_expr_signed(word_ex) && sig, av.base, av.wid,
(ivl_expr_width(word_ex) < 8*sizeof(int))) { (ivl_expr_signed(word_ex) ? "s" : "u"));
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<v%p, %u %u>",
sig, av.base, av.wid);
result->vec = av; result->vec = av;
result->vec_flag = 1; result->vec_flag = 1;
} else { } else {

View File

@ -813,11 +813,14 @@ The &A<> argument is a reference to the word of a variable array. The
syntax is: syntax is:
&A '<' <symbol> , <number> '>' &A '<' <symbol> , <number> '>'
&A '<' <symbol> , <base> <width> '>' &A '<' <symbol> , <base_symbol> '>'
&A '<' <symbol> , <base> <width> <"s" or "u"> '>'
The <symbol> is the label for a variable array, and the <number> is The <symbol> is the label for a variable array, and the <number> is
the canonical word index as an unsigned integer. The second form the canonical word index as an unsigned integer. The second form
retrieves the index from thread space (<width> bits starting at <base>). retrieves the <base> from the given signal or &A<>/&PV<> select.
The third form retrieves the index from thread space (<width> bits
starting at <base>). The base value may be signed or unsigned.
* The &PV<> argument * The &PV<> argument

View File

@ -128,6 +128,7 @@ struct __vpiArrayVthrA {
// If wid >0, then the address is the base and wid the vector // If wid >0, then the address is the base and wid the vector
// width of the index to pull from the thread. // width of the index to pull from the thread.
unsigned wid; unsigned wid;
bool is_signed;
unsigned get_address() const unsigned get_address() const
{ {
@ -150,14 +151,37 @@ struct __vpiArrayVthrA {
if (wid == 0) if (wid == 0)
return address; return address;
vvp_vector4_t tmp (wid); /* Get the value from thread space. */
for (unsigned idx = 0 ; idx < wid ; idx += 1) { int tval = 0;
vvp_bit4_t bit = vthread_get_bit(vpip_current_vthread, address+idx); for (unsigned idx = 0 ; (idx < wid) && (idx < 8*sizeof(tval));
tmp.set_bit(idx, bit); 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<<idx;
break;
case BIT4_0:
break; // Do nothing!
} }
unsigned long val = ULONG_MAX; }
vector4_to_value(tmp, val);
return val; if (is_signed && (wid < 8*sizeof(tval))) {
vvp_bit4_t msb = vthread_get_bit(vpip_current_vthread,
address + wid - 1);
if (msb == BIT4_1) {
tval |= ~((1 << wid) - 1);
}
}
return tval;
} }
}; };
@ -1547,7 +1571,8 @@ vpiHandle vpip_make_vthr_A(char*label, unsigned addr)
return &(obj->base); return &(obj->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*) struct __vpiArrayVthrA*obj = (struct __vpiArrayVthrA*)
malloc(sizeof (struct __vpiArrayVthrA)); malloc(sizeof (struct __vpiArrayVthrA));
@ -1563,6 +1588,9 @@ vpiHandle vpip_make_vthr_A(char*label, unsigned tbase, unsigned twid)
obj->address_handle = 0; obj->address_handle = 0;
obj->address = tbase; obj->address = tbase;
obj->wid = twid; obj->wid = twid;
obj->is_signed = strcmp(is_signed, "s") == 0;
delete [] is_signed;
return &(obj->base); return &(obj->base);
} }

View File

@ -873,8 +873,8 @@ argument
symbol_access symbol_access
: K_A '<' T_SYMBOL ',' T_NUMBER '>' : K_A '<' T_SYMBOL ',' T_NUMBER '>'
{ $$ = vpip_make_vthr_A($3, $5); } { $$ = vpip_make_vthr_A($3, $5); }
| K_A '<' T_SYMBOL ',' T_NUMBER T_NUMBER '>' | K_A '<' T_SYMBOL ',' T_NUMBER T_NUMBER T_STRING '>'
{ $$ = vpip_make_vthr_A($3, $5, $6); } { $$ = vpip_make_vthr_A($3, $5, $6, $7); }
| K_A '<' T_SYMBOL ',' T_SYMBOL '>' | K_A '<' T_SYMBOL ',' T_SYMBOL '>'
{ $$ = vpip_make_vthr_A($3, $5); } { $$ = vpip_make_vthr_A($3, $5); }
| K_A '<' T_SYMBOL ',' symbol_access '>' | K_A '<' T_SYMBOL ',' symbol_access '>'

View File

@ -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, unsigned index);
vpiHandle vpip_make_vthr_A(char*label, char*symbol); 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); vpiHandle vpip_make_vthr_A(char*label, vpiHandle handle);
/* /*