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:
Cary R 2009-09-17 09:47:57 -07:00 committed by Stephen Williams
parent 0b6bd343e8
commit 617897f3bf
5 changed files with 27 additions and 18 deletions

View File

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

View File

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

View File

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

View File

@ -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);

View File

@ -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;
}