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. */
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<v%p, %u %u>",
sig, av.base, av.wid);
snprintf(buffer, sizeof buffer, "&A<v%p, %u %u \"%s\">",
sig, av.base, av.wid,
(ivl_expr_signed(word_ex) ? "s" : "u"));
result->vec = av;
result->vec_flag = 1;
} else {

View File

@ -813,11 +813,14 @@ The &A<> argument is a reference to the word of a variable array. The
syntax is:
&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 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

View File

@ -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<<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);
}
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));
@ -1563,6 +1588,9 @@ vpiHandle vpip_make_vthr_A(char*label, unsigned tbase, unsigned twid)
obj->address_handle = 0;
obj->address = tbase;
obj->wid = twid;
obj->is_signed = strcmp(is_signed, "s") == 0;
delete [] is_signed;
return &(obj->base);
}

View File

@ -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 '>'

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, 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);
/*