diff --git a/ivtest/vpi/value_change.c b/ivtest/vpi/value_change.c new file mode 100644 index 000000000..6527637a9 --- /dev/null +++ b/ivtest/vpi/value_change.c @@ -0,0 +1,124 @@ +#ifdef TEST_SCALED_TIME +#define TIME_TYPE vpiScaledRealTime +#else +#define TIME_TYPE vpiSimTime +#endif + +# include +# include +# include + +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 +}; diff --git a/ivtest/vpi/value_change.v b/ivtest/vpi/value_change.v new file mode 100644 index 000000000..f3ec25757 --- /dev/null +++ b/ivtest/vpi/value_change.v @@ -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 diff --git a/ivtest/vpi/value_change1.c b/ivtest/vpi/value_change1.c new file mode 100644 index 000000000..33830de7b --- /dev/null +++ b/ivtest/vpi/value_change1.c @@ -0,0 +1,2 @@ +#define TEST_SIM_TIME +#include "value_change.c" diff --git a/ivtest/vpi/value_change1.v b/ivtest/vpi/value_change1.v new file mode 100644 index 000000000..d1b7ef31b --- /dev/null +++ b/ivtest/vpi/value_change1.v @@ -0,0 +1 @@ +`include "vpi/value_change.v" diff --git a/ivtest/vpi/value_change2.c b/ivtest/vpi/value_change2.c new file mode 100644 index 000000000..ede0c8033 --- /dev/null +++ b/ivtest/vpi/value_change2.c @@ -0,0 +1,2 @@ +#define TEST_SCALED_TIME +#include "value_change.c" diff --git a/ivtest/vpi/value_change2.v b/ivtest/vpi/value_change2.v new file mode 100644 index 000000000..d1b7ef31b --- /dev/null +++ b/ivtest/vpi/value_change2.v @@ -0,0 +1 @@ +`include "vpi/value_change.v" diff --git a/ivtest/vpi_gold/value_change1.gold b/ivtest/vpi_gold/value_change1.gold new file mode 100644 index 000000000..5832d4203 --- /dev/null +++ b/ivtest/vpi_gold/value_change1.gold @@ -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 diff --git a/ivtest/vpi_gold/value_change2.gold b/ivtest/vpi_gold/value_change2.gold new file mode 100644 index 000000000..6e4c177b9 --- /dev/null +++ b/ivtest/vpi_gold/value_change2.gold @@ -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 diff --git a/ivtest/vpi_regress.list b/ivtest/vpi_regress.list index 2945bb4bf..218bb2188 100644 --- a/ivtest/vpi_regress.list +++ b/ivtest/vpi_regress.list @@ -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