Fix problems in VPI callback time and value formats.
This patch adds support for vpiScaledRealTime and vpiSuppressTime to VPI callbacks. It also fixes a bug where the callback data object was not being copied correctly and adds support for vpiSuppressVal. This requires adding vpiSuppressVal to a few other routines. It adds the ability for a callback to return more than vpiScalarVal (all values supported by the vpip_vec4_get_value() procedure). It also fixes a bug where vpip_vec4_get_value() would incorrectly return vpiZ for a BIT4_X scalar value. It also comments the potentially dangerous vpiScalarVal calculation in the vvp_fun_signal::get_value() procedure.
This commit is contained in:
parent
2c1426a44d
commit
e501bbdd27
|
|
@ -127,6 +127,12 @@ static struct __vpiCallback* make_value_change(p_cb_data data)
|
||||||
obj->cb_time.type = vpiSuppressTime;
|
obj->cb_time.type = vpiSuppressTime;
|
||||||
}
|
}
|
||||||
obj->cb_data.time = &obj->cb_time;
|
obj->cb_data.time = &obj->cb_time;
|
||||||
|
if (data->value) {
|
||||||
|
obj->cb_value = *(data->value);
|
||||||
|
} else {
|
||||||
|
obj->cb_value.format = vpiSuppressVal;
|
||||||
|
}
|
||||||
|
obj->cb_data.value = &obj->cb_value;
|
||||||
|
|
||||||
assert(data->obj);
|
assert(data->obj);
|
||||||
assert(data->obj->vpi_type);
|
assert(data->obj->vpi_type);
|
||||||
|
|
@ -457,8 +463,25 @@ void callback_execute(struct __vpiCallback*cur)
|
||||||
vpi_mode_flag = VPI_MODE_RWSYNC;
|
vpi_mode_flag = VPI_MODE_RWSYNC;
|
||||||
|
|
||||||
assert(cur->cb_data.cb_rtn);
|
assert(cur->cb_data.cb_rtn);
|
||||||
cur->cb_data.time->type = vpiSimTime;
|
switch (cur->cb_data.time->type) {
|
||||||
vpip_time_to_timestruct(cur->cb_data.time, schedule_simtime());
|
case vpiSimTime:
|
||||||
|
vpip_time_to_timestruct(cur->cb_data.time, schedule_simtime());
|
||||||
|
break;
|
||||||
|
case vpiScaledRealTime: {
|
||||||
|
cur->cb_data.time->real =
|
||||||
|
vpip_time_to_scaled_real(schedule_simtime(),
|
||||||
|
(struct __vpiScope *) vpi_handle(vpiScope,
|
||||||
|
cur->cb_data.obj));
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case vpiSuppressTime:
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
fprintf(stderr, "Unsupported time format %d.\n",
|
||||||
|
cur->cb_data.time->type);
|
||||||
|
assert(0);
|
||||||
|
break;
|
||||||
|
}
|
||||||
(cur->cb_data.cb_rtn)(&cur->cb_data);
|
(cur->cb_data.cb_rtn)(&cur->cb_data);
|
||||||
|
|
||||||
vpi_mode_flag = save_mode;
|
vpi_mode_flag = save_mode;
|
||||||
|
|
@ -546,10 +569,32 @@ void vvp_fun_signal::get_value(struct t_vpi_value*vp)
|
||||||
{
|
{
|
||||||
switch (vp->format) {
|
switch (vp->format) {
|
||||||
case vpiScalarVal:
|
case vpiScalarVal:
|
||||||
|
// This works because vvp_bit4_t has the same encoding
|
||||||
|
// as a scalar value! See vpip_vec4_get_value() for a
|
||||||
|
// more robust method.
|
||||||
vp->value.scalar = value(0);
|
vp->value.scalar = value(0);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case vpiBinStrVal:
|
||||||
|
case vpiOctStrVal:
|
||||||
|
case vpiDecStrVal:
|
||||||
|
case vpiHexStrVal:
|
||||||
|
case vpiIntVal:
|
||||||
|
case vpiVectorVal:
|
||||||
|
case vpiStringVal:
|
||||||
|
case vpiRealVal: {
|
||||||
|
unsigned wid = size();
|
||||||
|
vvp_vector4_t vec4(wid);
|
||||||
|
for (unsigned idx = 0; idx < wid; idx += 1) {
|
||||||
|
vec4.set_bit(idx, value(idx));
|
||||||
|
}
|
||||||
|
vpip_vec4_get_value(vec4, wid, false, vp);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
case vpiSuppressVal:
|
case vpiSuppressVal:
|
||||||
break;
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
fprintf(stderr, "vpi_callback: value "
|
fprintf(stderr, "vpi_callback: value "
|
||||||
"format %d not supported (fun_signal)\n",
|
"format %d not supported (fun_signal)\n",
|
||||||
|
|
@ -622,6 +667,9 @@ void vvp_fun_signal_real::get_value(struct t_vpi_value*vp)
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
case vpiSuppressVal:
|
||||||
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
fprintf(stderr, "vpi_callback: value "
|
fprintf(stderr, "vpi_callback: value "
|
||||||
"format %d not supported (fun_signal_real)\n",
|
"format %d not supported (fun_signal_real)\n",
|
||||||
|
|
|
||||||
|
|
@ -456,6 +456,9 @@ void vpip_vec4_get_value(const vvp_vector4_t&word_val, unsigned width,
|
||||||
vp->format);
|
vp->format);
|
||||||
assert(0 && "format not implemented");
|
assert(0 && "format not implemented");
|
||||||
|
|
||||||
|
case vpiSuppressVal:
|
||||||
|
break;
|
||||||
|
|
||||||
case vpiBinStrVal:
|
case vpiBinStrVal:
|
||||||
rbuf = need_result_buf(width+1, RBUF_VAL);
|
rbuf = need_result_buf(width+1, RBUF_VAL);
|
||||||
for (unsigned idx = 0 ; idx < width ; idx += 1) {
|
for (unsigned idx = 0 ; idx < width ; idx += 1) {
|
||||||
|
|
@ -504,6 +507,7 @@ void vpip_vec4_get_value(const vvp_vector4_t&word_val, unsigned width,
|
||||||
break;
|
break;
|
||||||
case BIT4_X:
|
case BIT4_X:
|
||||||
vp->value.scalar = vpiX;
|
vp->value.scalar = vpiX;
|
||||||
|
break;
|
||||||
case BIT4_Z:
|
case BIT4_Z:
|
||||||
vp->value.scalar = vpiZ;
|
vp->value.scalar = vpiZ;
|
||||||
break;
|
break;
|
||||||
|
|
|
||||||
|
|
@ -137,6 +137,7 @@ struct __vpiCallback {
|
||||||
// user supplied callback data
|
// user supplied callback data
|
||||||
struct t_cb_data cb_data;
|
struct t_cb_data cb_data;
|
||||||
struct t_vpi_time cb_time;
|
struct t_vpi_time cb_time;
|
||||||
|
struct t_vpi_value cb_value;
|
||||||
|
|
||||||
// scheduled event
|
// scheduled event
|
||||||
struct sync_cb* cb_sync;
|
struct sync_cb* cb_sync;
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue