diff --git a/ivtest/vpi/sim_time_cb.c b/ivtest/vpi/sim_time_cb.c new file mode 100644 index 000000000..acb829972 --- /dev/null +++ b/ivtest/vpi/sim_time_cb.c @@ -0,0 +1,171 @@ +#ifdef TEST_SCALED_TIME +#define TIME_TYPE vpiScaledRealTime +#else +#define TIME_TYPE vpiSimTime +#endif + +#include +#include +#include + +static PLI_INT32 monitor_cb(p_cb_data cb_data) +{ + vpiHandle*var_list = (vpiHandle*)cb_data->user_data; + + s_vpi_time time; + s_vpi_value value; + PLI_INT32 index; + + time.type = TIME_TYPE; + vpi_get_time(var_list[0], &time); +#ifdef TEST_SCALED_TIME + vpi_printf(" @ %1.1f :", time.real); +#else + vpi_printf(" @ %04d :", time.low); +#endif + + value.format = vpiIntVal; + + index = 0; + while (var_list[index]) { + vpi_get_value(var_list[index], &value); + vpi_printf(" %s = %d", vpi_get_str(vpiName, var_list[index]), value.value.integer); + index++; + } + vpi_printf("\n"); + + return 0; +} + +static PLI_INT32 monitor_cb_start(p_cb_data cb_data) +{ + vpi_printf("cbStartOfSimTime"); + monitor_cb(cb_data); + return 0; +} + +static PLI_INT32 monitor_cb_delay(p_cb_data cb_data) +{ + vpi_printf("cbAfterDelay "); + monitor_cb(cb_data); + return 0; +} + +static PLI_INT32 monitor_cb_synch(p_cb_data cb_data) +{ + vpi_printf("cbReadWriteSynch"); + monitor_cb(cb_data); + return 0; +} + +static PLI_INT32 monitor_cb_end(p_cb_data cb_data) +{ + vpiHandle*var_list = (vpiHandle*)cb_data->user_data; + + vpi_printf("cbEndOfSimTime "); + monitor_cb(cb_data); + free(var_list); + return 0; +} + +static PLI_INT32 monitor_calltf(char*xx) +{ + vpiHandle sys = vpi_handle(vpiSysTfCall, 0); + vpiHandle argv = vpi_iterate(vpiArgument, sys); + + vpiHandle*var_list = 0; + + vpiHandle handle; + PLI_INT32 index; + s_vpi_time time; + s_vpi_time delay; + s_vpi_value value; + s_cb_data cb_data; + + (void)xx; /* Parameter is not used. */ + + delay.type = TIME_TYPE; + delay.low = 0; + delay.high = 0; + delay.real = 0.0; + + assert(argv); + + handle = vpi_scan(argv); + assert(handle && (vpi_get(vpiType, handle) == vpiConstant)); +#ifdef TEST_SCALED_TIME + value.format = vpiRealVal; + vpi_get_value(handle, &value); + delay.real = value.value.real; +#else + value.format = vpiIntVal; + vpi_get_value(handle, &value); + delay.low = value.value.integer; +#endif + + index = 0; + while ((handle = vpi_scan(argv))) { + assert(vpi_get(vpiType, handle) == vpiReg); + var_list = realloc(var_list, (index + 1) * sizeof(vpiHandle)); + var_list[index++] = handle; + } + var_list = realloc(var_list, (index + 1) * sizeof(vpiHandle)); + var_list[index++] = 0; + + assert(index > 0); + + time.type = TIME_TYPE; + vpi_get_time(var_list[0], &time); + // cbAtStartOfSimTime and cbAtEndOfSimTime want an absolute time. + // We know the test is short, so can ignore the high part. +#ifdef TEST_SCALED_TIME + time.real += delay.real; +#else + time.low += delay.low; +#endif + + cb_data.reason = cbAtStartOfSimTime; + cb_data.cb_rtn = monitor_cb_start; + cb_data.user_data = (char*)var_list; + cb_data.time = &time; + vpi_register_cb(&cb_data); + + cb_data.reason = cbAfterDelay; + cb_data.cb_rtn = monitor_cb_delay; + cb_data.user_data = (char*)var_list; + cb_data.time = &delay; + vpi_register_cb(&cb_data); + + // Add cbNBASynch when we support it + + cb_data.reason = cbReadWriteSynch; + cb_data.cb_rtn = monitor_cb_synch; + cb_data.user_data = (char*)var_list; + cb_data.time = &delay; + vpi_register_cb(&cb_data); + + cb_data.reason = cbAtEndOfSimTime; + cb_data.cb_rtn = monitor_cb_end; + cb_data.user_data = (char*)var_list; + cb_data.time = &time; + vpi_register_cb(&cb_data); + + return 0; +} + +static void monitor_register(void) +{ + s_vpi_systf_data tf_data; + + tf_data.type = vpiSysTask; + tf_data.tfname = "$monitor_time_slot"; + tf_data.calltf = monitor_calltf; + tf_data.compiletf = 0; + tf_data.sizetf = 0; + vpi_register_systf(&tf_data); +} + +void (*vlog_startup_routines[])(void) = { + monitor_register, + 0 +}; diff --git a/ivtest/vpi/sim_time_cb1.c b/ivtest/vpi/sim_time_cb1.c new file mode 100644 index 000000000..d93ba2499 --- /dev/null +++ b/ivtest/vpi/sim_time_cb1.c @@ -0,0 +1,2 @@ +#define TEST_SIM_TIME +#include "sim_time_cb.c" diff --git a/ivtest/vpi/sim_time_cb1.v b/ivtest/vpi/sim_time_cb1.v new file mode 100644 index 000000000..e58741bf3 --- /dev/null +++ b/ivtest/vpi/sim_time_cb1.v @@ -0,0 +1,27 @@ +`timescale 1s/1ms + +module test; + +reg [7:0] a, b; + +initial begin + a = 0; b = 0; + $monitor_time_slot(2000, a, b); + $monitor_time_slot(5000, a, b); + #1; + a = 1; b <= 1; + #1; + a = 2; b <= 2; + #1; + a = 3; b <= 3; + #1; + a = 4; b <= 4; + #1; + a = 5; b <= 5; + #1; + a = 6; b <= 6; + #1; + $finish(0); +end + +endmodule diff --git a/ivtest/vpi/sim_time_cb2.c b/ivtest/vpi/sim_time_cb2.c new file mode 100644 index 000000000..dab1047ed --- /dev/null +++ b/ivtest/vpi/sim_time_cb2.c @@ -0,0 +1,2 @@ +#define TEST_SCALED_TIME +#include "sim_time_cb.c" diff --git a/ivtest/vpi/sim_time_cb2.v b/ivtest/vpi/sim_time_cb2.v new file mode 100644 index 000000000..cd547c2da --- /dev/null +++ b/ivtest/vpi/sim_time_cb2.v @@ -0,0 +1,27 @@ +`timescale 1s/1ms + +module test; + +reg [7:0] a, b; + +initial begin + a = 0; b = 0; + $monitor_time_slot(2.0, a, b); + $monitor_time_slot(5.0, a, b); + #1; + a = 1; b <= 1; + #1; + a = 2; b <= 2; + #1; + a = 3; b <= 3; + #1; + a = 4; b <= 4; + #1; + a = 5; b <= 5; + #1; + a = 6; b <= 6; + #1; + $finish(0); +end + +endmodule diff --git a/ivtest/vpi_gold/sim_time_cb1.gold b/ivtest/vpi_gold/sim_time_cb1.gold new file mode 100644 index 000000000..d99e5379b --- /dev/null +++ b/ivtest/vpi_gold/sim_time_cb1.gold @@ -0,0 +1,10 @@ +Compiling vpi/sim_time_cb1.c... +Making sim_time_cb1.vpi from sim_time_cb1.o... +cbStartOfSimTime @ 2000 : a = 1 b = 1 +cbAfterDelay @ 2000 : a = 1 b = 1 +cbReadWriteSynch @ 2000 : a = 2 b = 2 +cbEndOfSimTime @ 2000 : a = 2 b = 2 +cbStartOfSimTime @ 5000 : a = 4 b = 4 +cbAfterDelay @ 5000 : a = 4 b = 4 +cbReadWriteSynch @ 5000 : a = 5 b = 5 +cbEndOfSimTime @ 5000 : a = 5 b = 5 diff --git a/ivtest/vpi_gold/sim_time_cb2.gold b/ivtest/vpi_gold/sim_time_cb2.gold new file mode 100644 index 000000000..0ec0e5ae1 --- /dev/null +++ b/ivtest/vpi_gold/sim_time_cb2.gold @@ -0,0 +1,10 @@ +Compiling vpi/sim_time_cb2.c... +Making sim_time_cb2.vpi from sim_time_cb2.o... +cbStartOfSimTime @ 2.0 : a = 1 b = 1 +cbAfterDelay @ 2.0 : a = 1 b = 1 +cbReadWriteSynch @ 2.0 : a = 2 b = 2 +cbEndOfSimTime @ 2.0 : a = 2 b = 2 +cbStartOfSimTime @ 5.0 : a = 4 b = 4 +cbAfterDelay @ 5.0 : a = 4 b = 4 +cbReadWriteSynch @ 5.0 : a = 5 b = 5 +cbEndOfSimTime @ 5.0 : a = 5 b = 5 diff --git a/ivtest/vpi_regress.list b/ivtest/vpi_regress.list index facced0c6..24c928180 100644 --- a/ivtest/vpi_regress.list +++ b/ivtest/vpi_regress.list @@ -132,6 +132,8 @@ scanmem normal scanmem.cc scanmem.log scanmem2 normal scanmem2.cc scanmem2.log scanmem3 normal scanmem3.cc scanmem3.log scopes normal scopes.c scopes.log +sim_time_cb1 normal sim_time_cb1.c sim_time_cb1.gold +sim_time_cb2 normal sim_time_cb2.c sim_time_cb2.gold 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