From 53585c9209a435d1b299b27b6d34fd9401ca919d Mon Sep 17 00:00:00 2001 From: Stephen Williams Date: Sun, 29 Jan 2012 17:31:19 -0800 Subject: [PATCH] Derived classes for different callback types. --- vvp/vpi_callback.cc | 131 ++++++++++++++++++++++++++++---------------- vvp/vpi_priv.h | 14 ++--- 2 files changed, 90 insertions(+), 55 deletions(-) diff --git a/vvp/vpi_callback.cc b/vvp/vpi_callback.cc index 5c6a617bb..01cced8c1 100644 --- a/vvp/vpi_callback.cc +++ b/vvp/vpi_callback.cc @@ -50,7 +50,7 @@ */ struct sync_cb : public vvp_gen_event_s { - struct __vpiCallback*handle; + class sync_callback*handle; bool sync_flag; ~sync_cb () { } @@ -60,19 +60,44 @@ struct sync_cb : public vvp_gen_event_s { inline __vpiCallback::__vpiCallback() { - cb_sync = 0; next = 0; } __vpiCallback::~__vpiCallback() { - delete cb_sync; } int __vpiCallback::get_type_code(void) const { return vpiCallback; } +class value_callback : public __vpiCallback { + public: + explicit value_callback(p_cb_data data); + + public: + // user supplied callback data + struct t_vpi_time cb_time; + struct t_vpi_value cb_value; +}; + +inline value_callback::value_callback(p_cb_data data) +{ + cb_data = *data; + if (data->time) { + cb_time = *(data->time); + } else { + cb_time.type = vpiSuppressTime; + } + cb_data.time = &cb_time; + if (data->value) { + cb_value = *(data->value); + } else { + cb_value.format = vpiSuppressVal; + } + cb_data.value = &cb_value; +} + /* * A value change callback is tripped when a bit of a signal * changes. This function creates that value change callback and @@ -80,7 +105,7 @@ int __vpiCallback::get_type_code(void) const * does not already have them, create some callback functors to do the * actual value change detection. */ -static struct __vpiCallback* make_value_change(p_cb_data data) +static value_callback* make_value_change(p_cb_data data) { if (vpi_get(vpiAutomatic, data->obj)) { fprintf(stderr, "vpi error: cannot place value change " @@ -90,23 +115,9 @@ static struct __vpiCallback* make_value_change(p_cb_data data) return 0; } - struct __vpiCallback*obj = new __vpiCallback; - obj->cb_data = *data; - if (data->time) { - obj->cb_time = *(data->time); - } else { - obj->cb_time.type = vpiSuppressTime; - } - obj->cb_data.time = &obj->cb_time; - if (data->value) { - obj->cb_value = *(data->value); - } else { - obj->cb_value.format = vpiSuppressVal; - } - obj->cb_data.value = &obj->cb_value; + value_callback*obj = new value_callback(data); assert(data->obj); - switch (data->obj->get_type_code()) { case vpiReg: @@ -170,12 +181,41 @@ static struct __vpiCallback* make_value_change(p_cb_data data) return obj; } +class sync_callback : public __vpiCallback { + public: + explicit sync_callback(p_cb_data data); + ~sync_callback(); + + public: + // scheduled event + struct sync_cb* cb_sync; + // user supplied callback data + struct t_vpi_time cb_time; + + private: +}; + +inline sync_callback::sync_callback(p_cb_data data) +{ + cb_sync = 0; + + cb_data = *data; + assert(data->time); + cb_time = *(data->time); + cb_data.time = &cb_time; +} + +sync_callback::~sync_callback() +{ + delete cb_sync; +} + void sync_cb::run_run() { if (handle == 0) return; - struct __vpiCallback*cur = handle; + sync_callback*cur = handle; cur->cb_data.time->type = vpiSimTime; vpip_time_to_timestruct(cur->cb_data.time, schedule_simtime()); @@ -192,13 +232,9 @@ void sync_cb::run_run() delete cur; } -static struct __vpiCallback* make_sync(p_cb_data data, bool readonly_flag) +static sync_callback* make_sync(p_cb_data data, bool readonly_flag) { - struct __vpiCallback*obj = new __vpiCallback; - obj->cb_data = *data; - assert(data->time); - obj->cb_time = *(data->time); - obj->cb_data.time = &obj->cb_time; + sync_callback*obj = new sync_callback(data); struct sync_cb*cb = new sync_cb; cb->sync_flag = readonly_flag? true : false; @@ -232,11 +268,7 @@ static struct __vpiCallback* make_sync(p_cb_data data, bool readonly_flag) static struct __vpiCallback* make_afterdelay(p_cb_data data, bool simtime_flag) { - struct __vpiCallback*obj = new __vpiCallback; - obj->cb_data = *data; - assert(data->time); - obj->cb_time = *(data->time); - obj->cb_data.time = &obj->cb_time; + sync_callback*obj = new sync_callback(data); struct sync_cb*cb = new sync_cb; cb->sync_flag = false; cb->handle = obj; @@ -279,13 +311,21 @@ static struct __vpiCallback* make_afterdelay(p_cb_data data, bool simtime_flag) * callbacks. */ -static struct __vpiCallback*NextSimTime = 0; -static struct __vpiCallback*EndOfCompile = NULL; -static struct __vpiCallback*StartOfSimulation = NULL; -static struct __vpiCallback*EndOfSimulation = NULL; +class simulator_callback : public __vpiCallback { + public: + inline explicit simulator_callback(struct t_cb_data*data) + { cb_data = *data; } + + public: +}; + +static simulator_callback*NextSimTime = 0; +static simulator_callback*EndOfCompile = 0; +static simulator_callback*StartOfSimulation = 0; +static simulator_callback*EndOfSimulation = 0; void vpiEndOfCompile(void) { - struct __vpiCallback* cur; + simulator_callback* cur; /* * Walk the list of register callbacks, executing them and @@ -296,7 +336,7 @@ void vpiEndOfCompile(void) { while (EndOfCompile) { cur = EndOfCompile; - EndOfCompile = cur->next; + EndOfCompile = dynamic_cast(cur->next); (cur->cb_data.cb_rtn)(&cur->cb_data); delete cur; } @@ -305,7 +345,7 @@ void vpiEndOfCompile(void) { } void vpiStartOfSim(void) { - struct __vpiCallback* cur; + simulator_callback* cur; /* * Walk the list of register callbacks, executing them and @@ -316,7 +356,7 @@ void vpiStartOfSim(void) { while (StartOfSimulation) { cur = StartOfSimulation; - StartOfSimulation = cur->next; + StartOfSimulation = dynamic_cast(cur->next); (cur->cb_data.cb_rtn)(&cur->cb_data); delete cur; } @@ -325,7 +365,7 @@ void vpiStartOfSim(void) { } void vpiPostsim(void) { - struct __vpiCallback* cur; + simulator_callback* cur; /* * Walk the list of register callbacks @@ -335,7 +375,7 @@ void vpiPostsim(void) { while (EndOfSimulation) { cur = EndOfSimulation; - EndOfSimulation = cur->next; + EndOfSimulation = dynamic_cast(cur->next); /* Only set the time if it is not NULL. */ if (cur->cb_data.time) vpip_time_to_timestruct(cur->cb_data.time, schedule_simtime()); @@ -352,21 +392,20 @@ void vpiPostsim(void) { */ void vpiNextSimTime(void) { - struct __vpiCallback* cur; + simulator_callback* cur; while (NextSimTime) { cur = NextSimTime; - NextSimTime = cur->next; + NextSimTime = dynamic_cast(cur->next); (cur->cb_data.cb_rtn)(&cur->cb_data); delete cur; } } -static struct __vpiCallback* make_prepost(p_cb_data data) +static simulator_callback* make_prepost(p_cb_data data) { - struct __vpiCallback*obj = new __vpiCallback; - obj->cb_data = *data; + simulator_callback*obj = new simulator_callback(data); /* Insert at head of list */ switch (data->reason) { diff --git a/vvp/vpi_priv.h b/vvp/vpi_priv.h index 8981bcbaa..949e092f6 100644 --- a/vvp/vpi_priv.h +++ b/vvp/vpi_priv.h @@ -150,19 +150,14 @@ struct __vpiCallback : public __vpiHandle { ~__vpiCallback(); int get_type_code(void) const; + // Used for listing callbacks. + struct __vpiCallback*next; + // user supplied callback data struct t_cb_data cb_data; - struct t_vpi_time cb_time; - struct t_vpi_value cb_value; - - // scheduled event - struct sync_cb* cb_sync; // The callback holder may use this for various purposes. long extra_data; - - // Used for listing callbacks. - struct __vpiCallback*next; }; extern void callback_execute(struct __vpiCallback*cur); @@ -405,6 +400,7 @@ extern struct __vpiModPath* vpip_make_modpath(vvp_net_t *net) ; * free it) after it is handed to this function. */ class __vpiNamedEvent : public __vpiHandle { + public: __vpiNamedEvent(__vpiScope*scope, const char*name); int get_type_code(void) const; @@ -428,7 +424,7 @@ class __vpiNamedEvent : public __vpiHandle { /* Parent scope of this object. */ struct __vpiScope*scope_; /* List of callbacks interested in this event. */ - struct __vpiCallback*callbacks_; + __vpiCallback*callbacks_; }; extern vpiHandle vpip_make_named_event(const char*name, vvp_net_t*f);