Add regression tests for VPI simulation time callbacks with both time types.

This commit is contained in:
Martin Whitaker 2024-02-06 23:42:12 +00:00
parent 8e754d180e
commit 3433c92742
8 changed files with 251 additions and 0 deletions

171
ivtest/vpi/sim_time_cb.c Normal file
View File

@ -0,0 +1,171 @@
#ifdef TEST_SCALED_TIME
#define TIME_TYPE vpiScaledRealTime
#else
#define TIME_TYPE vpiSimTime
#endif
#include <vpi_user.h>
#include <stdlib.h>
#include <assert.h>
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
};

View File

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

27
ivtest/vpi/sim_time_cb1.v Normal file
View File

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

View File

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

27
ivtest/vpi/sim_time_cb2.v Normal file
View File

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

View File

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

View File

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

View File

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