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:
parent
c82baa2793
commit
e54fd4df51
|
|
@ -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 {
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
||||
|
|
|
|||
46
vvp/array.cc
46
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<<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));
|
||||
|
|
@ -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);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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 '>'
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
||||
/*
|
||||
|
|
|
|||
Loading…
Reference in New Issue