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:
Cary R 2008-08-13 10:29:44 -07:00 committed by Stephen Williams
parent 2c1426a44d
commit e501bbdd27
3 changed files with 55 additions and 2 deletions

View File

@ -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) {
case vpiSimTime:
vpip_time_to_timestruct(cur->cb_data.time, schedule_simtime()); 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",

View File

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

View File

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