Add regression tests for VPI value change callback with time reporting.

This commit is contained in:
Martin Whitaker 2024-02-05 22:04:29 +00:00
parent bb0502a827
commit 0c61923636
9 changed files with 211 additions and 0 deletions

124
ivtest/vpi/value_change.c Normal file
View File

@ -0,0 +1,124 @@
#ifdef TEST_SCALED_TIME
#define TIME_TYPE vpiScaledRealTime
#else
#define TIME_TYPE vpiSimTime
#endif
# include <sv_vpi_user.h>
# include <assert.h>
# include <string.h>
static PLI_INT32 report_change(p_cb_data cb)
{
vpiHandle handle = (vpiHandle)(cb->user_data);
assert(cb->time && (cb->time->type == TIME_TYPE));
assert(cb->value);
switch (cb->value->format) {
case vpiIntVal:
#ifdef TEST_SCALED_TIME
vpi_printf("At time %f %s = %d\n", cb->time->real, vpi_get_str(vpiName, handle), cb->value->value.integer);
#else
vpi_printf("At time %d %s = %d\n", cb->time->low, vpi_get_str(vpiName, handle), cb->value->value.integer);
#endif
break;
case vpiRealVal:
#ifdef TEST_SCALED_TIME
vpi_printf("At time %f %s = %f\n", cb->time->real, vpi_get_str(vpiName, handle), cb->value->value.real);
#else
vpi_printf("At time %d %s = %f\n", cb->time->low, vpi_get_str(vpiName, handle), cb->value->value.real);
#endif
break;
case vpiSuppressVal:
#ifdef TEST_SCALED_TIME
vpi_printf("At time %f %s changed\n", cb->time->real, vpi_get_str(vpiName, handle));
#else
vpi_printf("At time %d %s changed\n", cb->time->low, vpi_get_str(vpiName, handle));
#endif
break;
default:
vpi_printf("ERROR: unexpected value format %d\n", cb->value->format);
break;
}
return 0;
}
static s_cb_data cb;
static s_vpi_time time;
static s_vpi_value value;
static PLI_INT32 my_monitor_calltf(PLI_BYTE8 *xx)
{
(void)xx; /* Parameter is not used. */
vpiHandle sys = vpi_handle(vpiSysTfCall, 0);
vpiHandle argv = vpi_iterate(vpiArgument, sys);
vpiHandle handle;
memset(&cb, 0, sizeof(cb));
memset(&time, 0, sizeof(time));
memset(&value, 0, sizeof(value));
time.type = TIME_TYPE;
cb.reason = cbValueChange;
cb.cb_rtn = report_change;
cb.time = &time;
cb.value = &value;
while ((handle = vpi_scan(argv))) {
PLI_INT32 type = vpi_get(vpiType, handle);
cb.obj = handle;
cb.user_data = (char *)handle;
switch (type) {
case vpiNet:
case vpiReg:
case vpiIntegerVar:
case vpiBitVar:
case vpiByteVar:
case vpiShortIntVar:
case vpiIntVar:
case vpiLongIntVar:
case vpiPartSelect:
case vpiMemoryWord:
case vpiMemory:
value.format = vpiIntVal;
break;
case vpiRealVar:
value.format = vpiRealVal;
break;
case vpiNamedEvent:
value.format = vpiSuppressVal;
break;
default:
vpi_printf("ERROR: unexpected object type %d\n", type);
break;
}
vpi_register_cb(&cb);
}
memset(&cb, 0, sizeof(cb));
memset(&time, 0, sizeof(time));
memset(&value, 0, sizeof(value));
return 0;
}
static void my_monitor_register(void)
{
s_vpi_systf_data tf_data;
tf_data.type = vpiSysTask;
tf_data.tfname = "$my_monitor";
tf_data.calltf = my_monitor_calltf;
tf_data.compiletf = 0;
tf_data.sizetf = 0;
vpi_register_systf(&tf_data);
}
void (*vlog_startup_routines[])(void) = {
my_monitor_register,
0
};

47
ivtest/vpi/value_change.v Normal file
View File

@ -0,0 +1,47 @@
`timescale 1s/1ms
module test;
logic [3:0] v4;
wire [3:0] w4;
integer i4;
bit [3:0] v2;
byte b2;
shortint s2;
int i2;
longint l2;
real r;
event e;
logic [3:0] p4;
logic [3:0] a4[3:0];
// this causes a segfault - to be investigated
//bit [3:0] a2[3:0];
logic [3:0] a2[3:0];
assign w4 = v4;
initial begin
$my_monitor(v4, w4, i4, v2, b2, s2, i2, l2, r, e, p4[1:0], a4, a2[1]);
#1 v4 = 4'd1;
#1 i4 = 2;
#1 v2 = 4'd3;
#1 b2 = 4;
#1 s2 = 5;
#1 i2 = 6;
#1 l2 = 7;
#1 r = 8.0;
#1 ->e;
// NOTE: the value change callback on a part select returns the value of the entire variable.
#1 p4 = 4'd10;
#1 a4[0] = 4'd11;
#1 a4[1] = 4'd12;
#1 a2[0] = 4'd13;
#1 a2[1] = 4'd14;
end
endmodule

View File

@ -0,0 +1,2 @@
#define TEST_SIM_TIME
#include "value_change.c"

View File

@ -0,0 +1 @@
`include "vpi/value_change.v"

View File

@ -0,0 +1,2 @@
#define TEST_SCALED_TIME
#include "value_change.c"

View File

@ -0,0 +1 @@
`include "vpi/value_change.v"

View File

@ -0,0 +1,16 @@
Compiling vpi/value_change1.c...
Making value_change1.vpi from value_change1.o...
At time 1000 v4 = 1
At time 1000 w4 = 1
At time 2000 i4 = 2
At time 3000 v2 = 3
At time 4000 b2 = 4
At time 5000 s2 = 5
At time 6000 i2 = 6
At time 7000 l2 = 7
At time 8000 r = 8.000000
At time 9000 e changed
At time 10000 p4[1:0] = 10
At time 11000 a4 = 11
At time 12000 a4 = 12
At time 14000 a2[1] = 14

View File

@ -0,0 +1,16 @@
Compiling vpi/value_change2.c...
Making value_change2.vpi from value_change2.o...
At time 1.000000 v4 = 1
At time 1.000000 w4 = 1
At time 2.000000 i4 = 2
At time 3.000000 v2 = 3
At time 4.000000 b2 = 4
At time 5.000000 s2 = 5
At time 6.000000 i2 = 6
At time 7.000000 l2 = 7
At time 8.000000 r = 8.000000
At time 9.000000 e changed
At time 10.000000 p4[1:0] = 10
At time 11.000000 a4 = 11
At time 12.000000 a4 = 12
At time 14.000000 a2[1] = 14

View File

@ -135,6 +135,8 @@ scopes normal scopes.c scopes.log
spec_delays normal,-gspecify spec_delays.c spec_delays.log
start_of_simtime1 normal start_of_simtime1.c start_of_simtime1.log
timescale normal timescale.c timescale.log
value_change1 normal,-g2009 value_change1.c value_change1.gold
value_change2 normal,-g2009 value_change2.c value_change2.gold
# Add new tests in alphabetic/numeric order. If the test needs
# a compile option or a different log file to run with an older