Add support to &PV<> for signed base values from thread space.
When calculating a value from thread space we need to tell &PV<> if the base value is signed or not. This patch adds support for that functionality.
This commit is contained in:
parent
0b6bd343e8
commit
617897f3bf
|
|
@ -212,19 +212,11 @@ static int get_vpi_taskfunc_signal_arg(struct args_info *result,
|
|||
/* Fallback case: evaluate the expression. */
|
||||
struct vector_info rv;
|
||||
rv = draw_eval_expr(bexpr, STUFF_OK_XZ);
|
||||
/* We need to enhance &PV<> to support a signed index. */
|
||||
if (ivl_expr_signed(bexpr) &&
|
||||
(ivl_expr_width(bexpr) < 8*sizeof(int))) {
|
||||
fprintf(stderr, "%s:%u: tgt-vvp warning: V0.9 may give "
|
||||
"incorrect results for a 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, "&PV<v%p_0, %u %u, %u>",
|
||||
snprintf(buffer, sizeof buffer,
|
||||
"&PV<v%p_0, %u %u \"%s\", %u>",
|
||||
ivl_expr_signal(vexpr),
|
||||
rv.base, rv.wid,
|
||||
(ivl_expr_signed(bexpr) ? "s" : "u"),
|
||||
ivl_expr_width(expr));
|
||||
result->vec = rv;
|
||||
result->vec_flag = 1;
|
||||
|
|
|
|||
|
|
@ -824,12 +824,15 @@ retrieves the index from thread space (<width> bits starting at <base>).
|
|||
The &PV<> argument is a reference to part of a signal. The syntax is:
|
||||
|
||||
&PV '<' <symbol> , <base> , <width> '>'
|
||||
&PV '<' <symbol> , <tbase> <twid> , <width> '>'
|
||||
&PV '<' <symbol> , <base_symbol> , <width> '>'
|
||||
&PV '<' <symbol> , <tbase> <twid> <"s" or "u"> , <width> '>'
|
||||
|
||||
The <symbol> is the label for a signal, the <base> is the canonical
|
||||
starting bit of the part select and <width> is the number of bits in
|
||||
the select. The second form retrieves the <base> from thread space
|
||||
using <twid> bits starting at <tbase>.
|
||||
the select. The second form retrieves the <base> from the given signal
|
||||
or &A<>/&PV<> select. The third form retrieves the <base> from thread
|
||||
space using <twid> bits starting at <tbase>. The base value may be
|
||||
signed or unsigned.
|
||||
|
||||
* The T<> argument
|
||||
|
||||
|
|
|
|||
|
|
@ -887,8 +887,8 @@ symbol_access
|
|||
{ $$ = vpip_make_PV($3, $5, $7); }
|
||||
| K_PV '<' T_SYMBOL ',' symbol_access ',' T_NUMBER '>'
|
||||
{ $$ = vpip_make_PV($3, $5, $7); }
|
||||
| K_PV '<' T_SYMBOL ',' T_NUMBER T_NUMBER ',' T_NUMBER '>'
|
||||
{ $$ = vpip_make_PV($3, $5, $6, $8); }
|
||||
| K_PV '<' T_SYMBOL ',' T_NUMBER T_NUMBER T_STRING ',' T_NUMBER '>'
|
||||
{ $$ = vpip_make_PV($3, $5, $6, $7, $9); }
|
||||
|
||||
/* functor operands can only be a list of symbols. */
|
||||
symbols
|
||||
|
|
|
|||
|
|
@ -264,11 +264,13 @@ struct __vpiPV {
|
|||
vpiHandle sbase;
|
||||
int tbase;
|
||||
unsigned twid, width;
|
||||
bool is_signed;
|
||||
};
|
||||
extern vpiHandle vpip_make_PV(char*name, int base, int width);
|
||||
extern vpiHandle vpip_make_PV(char*name, char*symbol, int width);
|
||||
extern vpiHandle vpip_make_PV(char*name, vpiHandle handle, int width);
|
||||
extern vpiHandle vpip_make_PV(char*name, int tbase, int twid, int width);
|
||||
extern vpiHandle vpip_make_PV(char*name, int tbase, int twid, char*is_signed,
|
||||
int width);
|
||||
|
||||
extern struct __vpiPV* vpip_PV_from_handle(vpiHandle obj);
|
||||
extern void vpip_part_select_value_change(struct __vpiCallback*cbh, vpiHandle obj);
|
||||
|
|
|
|||
|
|
@ -1027,6 +1027,15 @@ static int PV_get_base(struct __vpiPV*rfp)
|
|||
}
|
||||
}
|
||||
|
||||
/* Check to see if we need to sign extend the result. */
|
||||
if (rfp->is_signed && (rfp->twid < 8*sizeof(tval))) {
|
||||
vvp_bit4_t msb = vthread_get_bit(vpip_current_vthread,
|
||||
rfp->tbase + rfp->twid - 1);
|
||||
if (msb == BIT4_1) {
|
||||
tval |= ~((1 << rfp->twid) - 1);
|
||||
}
|
||||
}
|
||||
|
||||
return tval;
|
||||
}
|
||||
|
||||
|
|
@ -1281,7 +1290,7 @@ vpiHandle vpip_make_PV(char*var, vpiHandle handle, int width)
|
|||
return &obj->base;
|
||||
}
|
||||
|
||||
vpiHandle vpip_make_PV(char*var, int tbase, int twid, int width)
|
||||
vpiHandle vpip_make_PV(char*var, int tbase, int twid, char*is_signed, int width)
|
||||
{
|
||||
struct __vpiPV*obj = (struct __vpiPV*) malloc(sizeof(struct __vpiPV));
|
||||
obj->base.vpi_type = &vpip_PV_rt;
|
||||
|
|
@ -1289,10 +1298,13 @@ vpiHandle vpip_make_PV(char*var, int tbase, int twid, int width)
|
|||
obj->sbase = 0;
|
||||
obj->tbase = tbase;
|
||||
obj->twid = (unsigned) twid;
|
||||
obj->is_signed = strcmp(is_signed, "s") == 0;
|
||||
obj->width = (unsigned) width;
|
||||
obj->net = 0;
|
||||
functor_ref_lookup(&obj->net, var);
|
||||
|
||||
delete [] is_signed;
|
||||
|
||||
return &obj->base;
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Reference in New Issue