Allow &PV<> to reference a VPI object (signal) for the base.
This patch adds code to allow &PV<> to access a VPI object (signal) for the base of an indexed part select. This mirrors the code added to &A<>.
This commit is contained in:
parent
50a8c17cf8
commit
f78994b66c
|
|
@ -212,9 +212,10 @@ static void draw_vpi_taskfunc_args(const char*call_string,
|
|||
if (word_ex && ivl_expr_type(word_ex)==IVL_EX_SIGNAL) {
|
||||
/* Special case: the index is a signal. */
|
||||
snprintf(buffer, sizeof buffer,
|
||||
"&A<v%p, v%p_0 >", sig, ivl_expr_signal(word_ex));
|
||||
"&A<v%p, v%p_0 >", sig,
|
||||
ivl_expr_signal(word_ex));
|
||||
} else if (word_ex) {
|
||||
/* fallback case: evaluate expression. */
|
||||
/* Fallback case: evaluate expression. */
|
||||
struct vector_info av;
|
||||
av = draw_eval_expr(word_ex, STUFF_OK_XZ);
|
||||
snprintf(buffer, sizeof buffer,
|
||||
|
|
@ -250,7 +251,14 @@ static void draw_vpi_taskfunc_args(const char*call_string,
|
|||
get_number_immediate(bexpr),
|
||||
ivl_expr_width(expr));
|
||||
/* This is an indexed bit/part select. */
|
||||
} else if (ivl_expr_type(bexpr) == IVL_EX_SIGNAL) {
|
||||
/* Sepcial case: the base is a signal. */
|
||||
snprintf(buffer, sizeof buffer, "&PV<v%p_0, v%p_0, %u>",
|
||||
ivl_expr_signal(vexpr),
|
||||
ivl_expr_signal(bexpr),
|
||||
ivl_expr_width(expr));
|
||||
} else {
|
||||
/* Fallback case: evaluate the expression. */
|
||||
struct vector_info rv;
|
||||
rv = draw_eval_expr(bexpr, STUFF_OK_XZ);
|
||||
snprintf(buffer, sizeof buffer, "&PV<v%p_0, %u %u, %u>",
|
||||
|
|
|
|||
|
|
@ -825,6 +825,8 @@ argument
|
|||
{ $$ = vpip_make_PV($3, $5, $7); }
|
||||
| K_PV '<' T_SYMBOL ',' '-' T_NUMBER ',' T_NUMBER '>'
|
||||
{ $$ = vpip_make_PV($3, -$6, $8); }
|
||||
| K_PV '<' T_SYMBOL ',' T_SYMBOL ',' 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); }
|
||||
;
|
||||
|
|
|
|||
|
|
@ -228,10 +228,12 @@ struct __vpiPV {
|
|||
struct __vpiHandle base;
|
||||
vpiHandle parent;
|
||||
vvp_net_t*net;
|
||||
vpiHandle sbase;
|
||||
int tbase;
|
||||
unsigned twid, width;
|
||||
};
|
||||
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, int tbase, int twid, int width);
|
||||
|
||||
extern struct __vpiPV* vpip_PV_from_handle(vpiHandle obj);
|
||||
|
|
|
|||
|
|
@ -946,12 +946,21 @@ vpiHandle vpip_make_net(const char*name, int msb, int lsb,
|
|||
|
||||
static int PV_get_base(struct __vpiPV*rfp)
|
||||
{
|
||||
/* We return from the symbol base if it is defined. */
|
||||
if (rfp->sbase != 0) {
|
||||
s_vpi_value val;
|
||||
val.format = vpiIntVal;
|
||||
vpi_get_value(rfp->sbase, &val);
|
||||
return val.value.integer;
|
||||
}
|
||||
|
||||
/* If the width is zero then tbase is the constant. */
|
||||
if (rfp->twid == 0) return rfp->tbase;
|
||||
|
||||
int tval = 0;
|
||||
for (unsigned idx = 0 ; idx < rfp->twid ; idx += 1) {
|
||||
vvp_bit4_t bit = vthread_get_bit(vpip_current_vthread,
|
||||
rfp->tbase + idx);
|
||||
rfp->tbase + idx);
|
||||
if (bit == BIT4_1) {
|
||||
tval |= 1<<idx;
|
||||
}
|
||||
|
|
@ -1156,10 +1165,10 @@ struct __vpiPV* vpip_PV_from_handle(vpiHandle obj)
|
|||
|
||||
vpiHandle vpip_make_PV(char*var, int base, int width)
|
||||
{
|
||||
|
||||
struct __vpiPV*obj = (struct __vpiPV*) malloc(sizeof(struct __vpiPV));
|
||||
obj->base.vpi_type = &vpip_PV_rt;
|
||||
obj->parent = vvp_lookup_handle(var);
|
||||
obj->sbase = 0;
|
||||
obj->tbase = base;
|
||||
obj->twid = 0;
|
||||
obj->width = (unsigned) width;
|
||||
|
|
@ -1169,11 +1178,27 @@ vpiHandle vpip_make_PV(char*var, int base, int width)
|
|||
return &obj->base;
|
||||
}
|
||||
|
||||
vpiHandle vpip_make_PV(char*var, char*symbol, int width)
|
||||
{
|
||||
struct __vpiPV*obj = (struct __vpiPV*) malloc(sizeof(struct __vpiPV));
|
||||
obj->base.vpi_type = &vpip_PV_rt;
|
||||
obj->parent = vvp_lookup_handle(var);
|
||||
compile_vpi_lookup(&obj->sbase, symbol);
|
||||
obj->tbase = 0;
|
||||
obj->twid = 0;
|
||||
obj->width = (unsigned) width;
|
||||
obj->net = (vvp_net_t*) malloc(sizeof(vvp_net_t));
|
||||
functor_ref_lookup(&obj->net, var);
|
||||
|
||||
return &obj->base;
|
||||
}
|
||||
|
||||
vpiHandle vpip_make_PV(char*var, int tbase, int twid, int width)
|
||||
{
|
||||
struct __vpiPV*obj = (struct __vpiPV*) malloc(sizeof(struct __vpiPV));
|
||||
obj->base.vpi_type = &vpip_PV_rt;
|
||||
obj->parent = vvp_lookup_handle(var);
|
||||
obj->sbase = 0;
|
||||
obj->tbase = tbase;
|
||||
obj->twid = (unsigned) twid;
|
||||
obj->width = (unsigned) width;
|
||||
|
|
|
|||
Loading…
Reference in New Issue