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. */
|
/* 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 {
|
||||||
|
|
|
||||||
|
|
@ -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
|
||||||
|
|
||||||
|
|
|
||||||
44
vvp/array.cc
44
vvp/array.cc
|
|
@ -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);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -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 '>'
|
||||||
|
|
|
||||||
|
|
@ -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);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue