Cleaner __vpiCallback construction.
This commit is contained in:
parent
bb58ace6d6
commit
d3df962b2a
|
|
@ -1516,13 +1516,13 @@ void array_word_change(vvp_array_t array, unsigned long addr)
|
||||||
|
|
||||||
array->vpi_callbacks = next;
|
array->vpi_callbacks = next;
|
||||||
cur->next = 0;
|
cur->next = 0;
|
||||||
delete_vpi_callback(cur);
|
delete cur;
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
assert(prev->next == cur);
|
assert(prev->next == cur);
|
||||||
prev->next = next;
|
prev->next = next;
|
||||||
cur->next = 0;
|
cur->next = 0;
|
||||||
delete_vpi_callback(cur);
|
delete cur;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -296,17 +296,17 @@ vvp_net_t* vvp_net_lookup(const char*label)
|
||||||
case vpiIntVar:
|
case vpiIntVar:
|
||||||
case vpiLongIntVar:
|
case vpiLongIntVar:
|
||||||
case vpiIntegerVar: {
|
case vpiIntegerVar: {
|
||||||
__vpiSignal*sig = (__vpiSignal*)vpi;
|
__vpiSignal*sig = dynamic_cast<__vpiSignal*>(vpi);
|
||||||
return sig->node;
|
return sig->node;
|
||||||
}
|
}
|
||||||
|
|
||||||
case vpiRealVar: {
|
case vpiRealVar: {
|
||||||
__vpiRealVar*sig = (__vpiRealVar*)vpi;
|
__vpiRealVar*sig = dynamic_cast<__vpiRealVar*>(vpi);
|
||||||
return sig->net;
|
return sig->net;
|
||||||
}
|
}
|
||||||
|
|
||||||
case vpiNamedEvent: {
|
case vpiNamedEvent: {
|
||||||
__vpiNamedEvent*tmp = (__vpiNamedEvent*)vpi;
|
__vpiNamedEvent*tmp = dynamic_cast<__vpiNamedEvent*>(vpi);
|
||||||
return tmp->funct;
|
return tmp->funct;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -688,7 +688,9 @@ void vvp_named_event_sa::recv_vec4(vvp_net_ptr_t port, const vvp_vector4_t&bit,
|
||||||
vvp_net_t*net = port.ptr();
|
vvp_net_t*net = port.ptr();
|
||||||
net->send_vec4(bit, 0);
|
net->send_vec4(bit, 0);
|
||||||
|
|
||||||
vpip_run_named_event_callbacks(handle_);
|
__vpiNamedEvent*obj = dynamic_cast<__vpiNamedEvent*>(handle_);
|
||||||
|
assert(obj);
|
||||||
|
obj->run_vpi_callbacks();
|
||||||
}
|
}
|
||||||
|
|
||||||
vvp_named_event_aa::vvp_named_event_aa(class __vpiHandle*h)
|
vvp_named_event_aa::vvp_named_event_aa(class __vpiHandle*h)
|
||||||
|
|
|
||||||
|
|
@ -34,15 +34,6 @@
|
||||||
# include <cstdio>
|
# include <cstdio>
|
||||||
# include <cassert>
|
# include <cassert>
|
||||||
# include <cstdlib>
|
# include <cstdlib>
|
||||||
|
|
||||||
|
|
||||||
inline __vpiCallback::__vpiCallback()
|
|
||||||
{ }
|
|
||||||
|
|
||||||
int __vpiCallback::get_type_code(void) const
|
|
||||||
{ return vpiCallback; }
|
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Callback handles are created when the VPI function registers a
|
* Callback handles are created when the VPI function registers a
|
||||||
* callback. The handle is stored by the run time, and it triggered
|
* callback. The handle is stored by the run time, and it triggered
|
||||||
|
|
@ -67,24 +58,20 @@ struct sync_cb : public vvp_gen_event_s {
|
||||||
virtual void run_run();
|
virtual void run_run();
|
||||||
};
|
};
|
||||||
|
|
||||||
struct __vpiCallback* new_vpi_callback()
|
inline __vpiCallback::__vpiCallback()
|
||||||
{
|
{
|
||||||
struct __vpiCallback* obj;
|
cb_sync = 0;
|
||||||
|
next = 0;
|
||||||
obj = new __vpiCallback;
|
|
||||||
|
|
||||||
obj->cb_sync = 0;
|
|
||||||
obj->next = 0;
|
|
||||||
return obj;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void delete_vpi_callback(struct __vpiCallback* ref)
|
__vpiCallback::~__vpiCallback()
|
||||||
{
|
{
|
||||||
assert(ref);
|
delete cb_sync;
|
||||||
delete ref->cb_sync;
|
|
||||||
delete ref;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int __vpiCallback::get_type_code(void) const
|
||||||
|
{ return vpiCallback; }
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* A value change callback is tripped when a bit of a signal
|
* A value change callback is tripped when a bit of a signal
|
||||||
|
|
@ -103,7 +90,7 @@ static struct __vpiCallback* make_value_change(p_cb_data data)
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
struct __vpiCallback*obj = new_vpi_callback();
|
struct __vpiCallback*obj = new __vpiCallback;
|
||||||
obj->cb_data = *data;
|
obj->cb_data = *data;
|
||||||
if (data->time) {
|
if (data->time) {
|
||||||
obj->cb_time = *(data->time);
|
obj->cb_time = *(data->time);
|
||||||
|
|
@ -150,8 +137,7 @@ static struct __vpiCallback* make_value_change(p_cb_data data)
|
||||||
case vpiNamedEvent:
|
case vpiNamedEvent:
|
||||||
struct __vpiNamedEvent*nev;
|
struct __vpiNamedEvent*nev;
|
||||||
nev = dynamic_cast<__vpiNamedEvent*>(data->obj);
|
nev = dynamic_cast<__vpiNamedEvent*>(data->obj);
|
||||||
obj->next = nev->callbacks;
|
nev->add_vpi_callback(obj);
|
||||||
nev->callbacks = obj;
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case vpiMemoryWord:
|
case vpiMemoryWord:
|
||||||
|
|
@ -203,19 +189,17 @@ void sync_cb::run_run()
|
||||||
vpi_mode_flag = VPI_MODE_NONE;
|
vpi_mode_flag = VPI_MODE_NONE;
|
||||||
}
|
}
|
||||||
|
|
||||||
delete_vpi_callback(cur);
|
delete cur;
|
||||||
}
|
}
|
||||||
|
|
||||||
static struct __vpiCallback* make_sync(p_cb_data data, bool readonly_flag)
|
static struct __vpiCallback* make_sync(p_cb_data data, bool readonly_flag)
|
||||||
{
|
{
|
||||||
struct __vpiCallback*obj = new_vpi_callback();
|
struct __vpiCallback*obj = new __vpiCallback;
|
||||||
obj->cb_data = *data;
|
obj->cb_data = *data;
|
||||||
assert(data->time);
|
assert(data->time);
|
||||||
obj->cb_time = *(data->time);
|
obj->cb_time = *(data->time);
|
||||||
obj->cb_data.time = &obj->cb_time;
|
obj->cb_data.time = &obj->cb_time;
|
||||||
|
|
||||||
obj->next = 0;
|
|
||||||
|
|
||||||
struct sync_cb*cb = new sync_cb;
|
struct sync_cb*cb = new sync_cb;
|
||||||
cb->sync_flag = readonly_flag? true : false;
|
cb->sync_flag = readonly_flag? true : false;
|
||||||
cb->handle = obj;
|
cb->handle = obj;
|
||||||
|
|
@ -248,14 +232,11 @@ static struct __vpiCallback* make_sync(p_cb_data data, bool readonly_flag)
|
||||||
|
|
||||||
static struct __vpiCallback* make_afterdelay(p_cb_data data, bool simtime_flag)
|
static struct __vpiCallback* make_afterdelay(p_cb_data data, bool simtime_flag)
|
||||||
{
|
{
|
||||||
struct __vpiCallback*obj = new_vpi_callback();
|
struct __vpiCallback*obj = new __vpiCallback;
|
||||||
obj->cb_data = *data;
|
obj->cb_data = *data;
|
||||||
assert(data->time);
|
assert(data->time);
|
||||||
obj->cb_time = *(data->time);
|
obj->cb_time = *(data->time);
|
||||||
obj->cb_data.time = &obj->cb_time;
|
obj->cb_data.time = &obj->cb_time;
|
||||||
|
|
||||||
obj->next = 0;
|
|
||||||
|
|
||||||
struct sync_cb*cb = new sync_cb;
|
struct sync_cb*cb = new sync_cb;
|
||||||
cb->sync_flag = false;
|
cb->sync_flag = false;
|
||||||
cb->handle = obj;
|
cb->handle = obj;
|
||||||
|
|
@ -317,7 +298,7 @@ void vpiEndOfCompile(void) {
|
||||||
cur = EndOfCompile;
|
cur = EndOfCompile;
|
||||||
EndOfCompile = cur->next;
|
EndOfCompile = cur->next;
|
||||||
(cur->cb_data.cb_rtn)(&cur->cb_data);
|
(cur->cb_data.cb_rtn)(&cur->cb_data);
|
||||||
delete_vpi_callback(cur);
|
delete cur;
|
||||||
}
|
}
|
||||||
|
|
||||||
vpi_mode_flag = VPI_MODE_NONE;
|
vpi_mode_flag = VPI_MODE_NONE;
|
||||||
|
|
@ -337,7 +318,7 @@ void vpiStartOfSim(void) {
|
||||||
cur = StartOfSimulation;
|
cur = StartOfSimulation;
|
||||||
StartOfSimulation = cur->next;
|
StartOfSimulation = cur->next;
|
||||||
(cur->cb_data.cb_rtn)(&cur->cb_data);
|
(cur->cb_data.cb_rtn)(&cur->cb_data);
|
||||||
delete_vpi_callback(cur);
|
delete cur;
|
||||||
}
|
}
|
||||||
|
|
||||||
vpi_mode_flag = VPI_MODE_NONE;
|
vpi_mode_flag = VPI_MODE_NONE;
|
||||||
|
|
@ -359,7 +340,7 @@ void vpiPostsim(void) {
|
||||||
if (cur->cb_data.time)
|
if (cur->cb_data.time)
|
||||||
vpip_time_to_timestruct(cur->cb_data.time, schedule_simtime());
|
vpip_time_to_timestruct(cur->cb_data.time, schedule_simtime());
|
||||||
(cur->cb_data.cb_rtn)(&cur->cb_data);
|
(cur->cb_data.cb_rtn)(&cur->cb_data);
|
||||||
delete_vpi_callback(cur);
|
delete cur;
|
||||||
}
|
}
|
||||||
|
|
||||||
vpi_mode_flag = VPI_MODE_NONE;
|
vpi_mode_flag = VPI_MODE_NONE;
|
||||||
|
|
@ -377,14 +358,14 @@ void vpiNextSimTime(void)
|
||||||
cur = NextSimTime;
|
cur = NextSimTime;
|
||||||
NextSimTime = cur->next;
|
NextSimTime = cur->next;
|
||||||
(cur->cb_data.cb_rtn)(&cur->cb_data);
|
(cur->cb_data.cb_rtn)(&cur->cb_data);
|
||||||
delete_vpi_callback(cur);
|
delete cur;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static struct __vpiCallback* make_prepost(p_cb_data data)
|
static struct __vpiCallback* make_prepost(p_cb_data data)
|
||||||
{
|
{
|
||||||
struct __vpiCallback*obj = new_vpi_callback();
|
struct __vpiCallback*obj = new __vpiCallback;
|
||||||
obj->cb_data = *data;
|
obj->cb_data = *data;
|
||||||
|
|
||||||
/* Insert at head of list */
|
/* Insert at head of list */
|
||||||
|
|
@ -562,13 +543,13 @@ void vvp_vpi_callback::run_vpi_callbacks()
|
||||||
|
|
||||||
vpi_callbacks_ = next;
|
vpi_callbacks_ = next;
|
||||||
cur->next = 0;
|
cur->next = 0;
|
||||||
delete_vpi_callback(cur);
|
delete cur;
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
assert(prev->next == cur);
|
assert(prev->next == cur);
|
||||||
prev->next = next;
|
prev->next = next;
|
||||||
cur->next = 0;
|
cur->next = 0;
|
||||||
delete_vpi_callback(cur);
|
delete cur;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -25,8 +25,12 @@
|
||||||
# include <cassert>
|
# include <cassert>
|
||||||
# include "ivl_alloc.h"
|
# include "ivl_alloc.h"
|
||||||
|
|
||||||
inline __vpiNamedEvent::__vpiNamedEvent()
|
inline __vpiNamedEvent::__vpiNamedEvent(__vpiScope*sc, const char*nam)
|
||||||
{ }
|
{
|
||||||
|
scope_ = sc;
|
||||||
|
name_ = vpip_name_string(nam);
|
||||||
|
callbacks_ = 0;
|
||||||
|
}
|
||||||
|
|
||||||
int __vpiNamedEvent::get_type_code(void) const
|
int __vpiNamedEvent::get_type_code(void) const
|
||||||
{ return vpiNamedEvent; }
|
{ return vpiNamedEvent; }
|
||||||
|
|
@ -36,7 +40,7 @@ int __vpiNamedEvent::vpi_get(int code)
|
||||||
switch (code) {
|
switch (code) {
|
||||||
|
|
||||||
case vpiAutomatic:
|
case vpiAutomatic:
|
||||||
return (int) scope->is_automatic;
|
return (int) scope_->is_automatic;
|
||||||
}
|
}
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
|
|
@ -47,7 +51,7 @@ char* __vpiNamedEvent::vpi_get_str(int code)
|
||||||
if (code == vpiFile) { // Not implemented for now!
|
if (code == vpiFile) { // Not implemented for now!
|
||||||
return simple_set_rbuf_str(file_names[0]);
|
return simple_set_rbuf_str(file_names[0]);
|
||||||
}
|
}
|
||||||
return generic_get_str(code, scope, name, NULL);
|
return generic_get_str(code, scope_, name_, NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -55,10 +59,10 @@ vpiHandle __vpiNamedEvent::vpi_handle(int code)
|
||||||
{
|
{
|
||||||
switch (code) {
|
switch (code) {
|
||||||
case vpiScope:
|
case vpiScope:
|
||||||
return scope;
|
return scope_;
|
||||||
|
|
||||||
case vpiModule:
|
case vpiModule:
|
||||||
return vpip_module(scope);
|
return vpip_module(scope_);
|
||||||
}
|
}
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
|
|
@ -67,12 +71,9 @@ vpiHandle __vpiNamedEvent::vpi_handle(int code)
|
||||||
|
|
||||||
vpiHandle vpip_make_named_event(const char*name, vvp_net_t*funct)
|
vpiHandle vpip_make_named_event(const char*name, vvp_net_t*funct)
|
||||||
{
|
{
|
||||||
struct __vpiNamedEvent*obj = new __vpiNamedEvent;
|
struct __vpiNamedEvent*obj = new __vpiNamedEvent(vpip_peek_current_scope(), name);
|
||||||
|
|
||||||
obj->name = vpip_name_string(name);
|
|
||||||
obj->scope = vpip_peek_current_scope();
|
|
||||||
obj->funct = funct;
|
obj->funct = funct;
|
||||||
obj->callbacks = 0;
|
|
||||||
|
|
||||||
return obj;
|
return obj;
|
||||||
}
|
}
|
||||||
|
|
@ -90,11 +91,9 @@ vpiHandle vpip_make_named_event(const char*name, vvp_net_t*funct)
|
||||||
* We can not use vpi_free_object() here since it does not really
|
* We can not use vpi_free_object() here since it does not really
|
||||||
* delete the callback.
|
* delete the callback.
|
||||||
*/
|
*/
|
||||||
void vpip_run_named_event_callbacks(vpiHandle ref)
|
void __vpiNamedEvent::run_vpi_callbacks()
|
||||||
{
|
{
|
||||||
struct __vpiNamedEvent*obj = dynamic_cast<__vpiNamedEvent*>(ref);
|
struct __vpiCallback*next = callbacks_;
|
||||||
|
|
||||||
struct __vpiCallback*next = obj->callbacks;
|
|
||||||
struct __vpiCallback*prev = 0;
|
struct __vpiCallback*prev = 0;
|
||||||
while (next) {
|
while (next) {
|
||||||
struct __vpiCallback*cur = next;
|
struct __vpiCallback*cur = next;
|
||||||
|
|
@ -105,7 +104,7 @@ void vpip_run_named_event_callbacks(vpiHandle ref)
|
||||||
prev = cur;
|
prev = cur;
|
||||||
|
|
||||||
} else if (prev == 0) {
|
} else if (prev == 0) {
|
||||||
obj->callbacks = next;
|
callbacks_ = next;
|
||||||
cur->next = 0;
|
cur->next = 0;
|
||||||
delete cur;
|
delete cur;
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -147,6 +147,7 @@ extern vpiHandle vpip_make_iterator(unsigned nargs, vpiHandle*args,
|
||||||
*/
|
*/
|
||||||
struct __vpiCallback : public __vpiHandle {
|
struct __vpiCallback : public __vpiHandle {
|
||||||
__vpiCallback();
|
__vpiCallback();
|
||||||
|
~__vpiCallback();
|
||||||
int get_type_code(void) const;
|
int get_type_code(void) const;
|
||||||
|
|
||||||
// user supplied callback data
|
// user supplied callback data
|
||||||
|
|
@ -164,8 +165,6 @@ struct __vpiCallback : public __vpiHandle {
|
||||||
struct __vpiCallback*next;
|
struct __vpiCallback*next;
|
||||||
};
|
};
|
||||||
|
|
||||||
extern struct __vpiCallback* new_vpi_callback();
|
|
||||||
extern void delete_vpi_callback(struct __vpiCallback* ref);
|
|
||||||
extern void callback_execute(struct __vpiCallback*cur);
|
extern void callback_execute(struct __vpiCallback*cur);
|
||||||
|
|
||||||
struct __vpiSystemTime : public __vpiHandle {
|
struct __vpiSystemTime : public __vpiHandle {
|
||||||
|
|
@ -405,25 +404,34 @@ extern struct __vpiModPath* vpip_make_modpath(vvp_net_t *net) ;
|
||||||
* passed in will be saved, so the caller must allocate it (or not
|
* passed in will be saved, so the caller must allocate it (or not
|
||||||
* free it) after it is handed to this function.
|
* free it) after it is handed to this function.
|
||||||
*/
|
*/
|
||||||
struct __vpiNamedEvent : public __vpiHandle {
|
class __vpiNamedEvent : public __vpiHandle {
|
||||||
__vpiNamedEvent();
|
public:
|
||||||
|
__vpiNamedEvent(__vpiScope*scope, const char*name);
|
||||||
int get_type_code(void) const;
|
int get_type_code(void) const;
|
||||||
int vpi_get(int code);
|
int vpi_get(int code);
|
||||||
char* vpi_get_str(int code);
|
char* vpi_get_str(int code);
|
||||||
vpiHandle vpi_handle(int code);
|
vpiHandle vpi_handle(int code);
|
||||||
|
|
||||||
/* base name of the event object */
|
inline void add_vpi_callback(__vpiCallback*cb)
|
||||||
const char*name;
|
{ cb->next = callbacks_;
|
||||||
/* Parent scope of this object. */
|
callbacks_ = cb;
|
||||||
struct __vpiScope*scope;
|
}
|
||||||
|
|
||||||
|
void run_vpi_callbacks(void);
|
||||||
|
|
||||||
/* The functor, used for %set operations. */
|
/* The functor, used for %set operations. */
|
||||||
vvp_net_t*funct;
|
vvp_net_t*funct;
|
||||||
|
|
||||||
|
private:
|
||||||
|
/* base name of the event object */
|
||||||
|
const char*name_;
|
||||||
|
/* Parent scope of this object. */
|
||||||
|
struct __vpiScope*scope_;
|
||||||
/* List of callbacks interested in this event. */
|
/* List of callbacks interested in this event. */
|
||||||
struct __vpiCallback*callbacks;
|
struct __vpiCallback*callbacks_;
|
||||||
};
|
};
|
||||||
|
|
||||||
extern vpiHandle vpip_make_named_event(const char*name, vvp_net_t*f);
|
extern vpiHandle vpip_make_named_event(const char*name, vvp_net_t*f);
|
||||||
extern void vpip_run_named_event_callbacks(vpiHandle ref);
|
|
||||||
extern void vpip_real_value_change(struct __vpiCallback*cbh,
|
extern void vpip_real_value_change(struct __vpiCallback*cbh,
|
||||||
vpiHandle ref);
|
vpiHandle ref);
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue