From 107a873aa680880e47eacd7558b7877f913ed69d Mon Sep 17 00:00:00 2001 From: Sean Anderson Date: Sat, 17 Jun 2023 16:14:14 -0400 Subject: [PATCH] vhpi: Support EndOfTimeStep callbacks Add support for EndOfTimeStep callbacks, which are the final callbacks to occur in a timestep. --- src/rt/model.c | 2 ++ src/rt/rt.h | 1 + src/vhpi/vhpi-model.c | 4 ++++ src/vhpi/vhpi-util.c | 4 ++++ test/vhpi/vhpi2.c | 24 ++++++++++++++++++++++++ 5 files changed, 35 insertions(+) diff --git a/src/rt/model.c b/src/rt/model.c index 9e5c293e..71243144 100644 --- a/src/rt/model.c +++ b/src/rt/model.c @@ -3040,6 +3040,8 @@ static void model_cycle(rt_model_t *m) workq_start(m->postponedq); workq_drain(m->postponedq); + global_event(m, RT_END_TIME_STEP); + m->can_create_delta = true; } else if (m->stop_delta > 0 && m->iteration == m->stop_delta) diff --git a/src/rt/rt.h b/src/rt/rt.h index ee481878..feab093d 100644 --- a/src/rt/rt.h +++ b/src/rt/rt.h @@ -81,6 +81,7 @@ typedef enum { RT_END_OF_PROCESSES, RT_LAST_KNOWN_DELTA_CYCLE, RT_NEXT_TIME_STEP, + RT_END_TIME_STEP, RT_LAST_EVENT } rt_event_t; diff --git a/src/vhpi/vhpi-model.c b/src/vhpi/vhpi-model.c index 2ce5b76b..3aa427c9 100644 --- a/src/vhpi/vhpi-model.c +++ b/src/vhpi/vhpi-model.c @@ -1045,6 +1045,8 @@ static int enable_cb(c_callback *cb) case vhpiCbEndOfSimulation: case vhpiCbLastKnownDeltaCycle: case vhpiCbNextTimeStep: + case vhpiCbEndOfTimeStep: + case vhpiCbRepEndOfTimeStep: model_set_global_cb(model, vhpi_get_rt_event(cb->Reason), vhpi_global_cb, cb); return 0; @@ -1123,6 +1125,8 @@ static bool disable_cb(c_callback *cb) case vhpiCbEndOfSimulation: case vhpiCbLastKnownDeltaCycle: case vhpiCbNextTimeStep: + case vhpiCbEndOfTimeStep: + case vhpiCbRepEndOfTimeStep: return model_clear_global_cb(model, vhpi_get_rt_event(cb->Reason), vhpi_global_cb, cb); return true; diff --git a/src/vhpi/vhpi-util.c b/src/vhpi/vhpi-util.c index dadd8e27..3875b125 100644 --- a/src/vhpi/vhpi-util.c +++ b/src/vhpi/vhpi-util.c @@ -199,6 +199,9 @@ rt_event_t vhpi_get_rt_event(int reason) case vhpiCbNextTimeStep: case vhpiCbRepNextTimeStep: return RT_NEXT_TIME_STEP; + case vhpiCbEndOfTimeStep: + case vhpiCbRepEndOfTimeStep: + return RT_END_TIME_STEP; case vhpiCbRepEndOfProcesses: case vhpiCbEndOfProcesses: return RT_END_OF_PROCESSES; @@ -294,6 +297,7 @@ bool vhpi_is_repetitive(vhpiEnumT reason) case vhpiCbRepEndOfProcesses: case vhpiCbRepLastKnownDeltaCycle: case vhpiCbRepNextTimeStep: + case vhpiCbRepEndOfTimeStep: return true; default: return false; diff --git a/test/vhpi/vhpi2.c b/test/vhpi/vhpi2.c index 865b95e1..34d74d81 100644 --- a/test/vhpi/vhpi2.c +++ b/test/vhpi/vhpi2.c @@ -8,6 +8,7 @@ static vhpiHandleT handle_x; static vhpiHandleT handle_y; static vhpiHandleT handle_sos; +static vhpiHandleT end_of_timestep_cb; static int sequence = 0; static void end_of_processes(const vhpiCbDataT *cb_data) @@ -36,6 +37,22 @@ static void last_known_delta_cycle(const vhpiCbDataT *cb_data) check_error(); } +static void end_of_timestep(const vhpiCbDataT *cb_data) +{ + vhpi_printf("end_of_timestep"); + + fail_unless(sequence++ == 2); + + vhpiValueT value = { + .format = vhpiIntVal, + .value.intg = 0 + }; + fail_unless(vhpi_put_value(handle_x, &value, vhpiForcePropagate)); + + vhpi_remove_cb(end_of_timestep_cb); + check_error(); +} + static void start_of_sim(const vhpiCbDataT *cb_data) { vhpi_printf("start_of_sim"); @@ -65,6 +82,13 @@ static void start_of_sim(const vhpiCbDataT *cb_data) }; vhpi_register_cb(&cb_data2, 0); check_error(); + + vhpiCbDataT cb_data3 = { + .reason = vhpiCbRepEndOfTimeStep, + .cb_rtn = end_of_timestep, + }; + end_of_timestep_cb = vhpi_register_cb(&cb_data3, vhpiReturnCb); + check_error(); } void vhpi2_startup(void) -- 2.39.2