Add callbacks for vpiNamedEvent objects.
This commit is contained in:
parent
b1c0f7306d
commit
cfab250671
36
vvp/event.cc
36
vvp/event.cc
|
|
@ -17,13 +17,14 @@
|
|||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
||||
*/
|
||||
#if !defined(WINNT)
|
||||
#ident "$Id: event.cc,v 1.6 2002/05/18 02:34:11 steve Exp $"
|
||||
#ident "$Id: event.cc,v 1.7 2002/05/19 05:18:16 steve Exp $"
|
||||
#endif
|
||||
|
||||
# include "event.h"
|
||||
# include "compile.h"
|
||||
# include "vthread.h"
|
||||
# include "schedule.h"
|
||||
# include "vpi_priv.h"
|
||||
|
||||
# include <string.h>
|
||||
# include <assert.h>
|
||||
|
|
@ -33,8 +34,10 @@
|
|||
#endif
|
||||
|
||||
event_functor_s::event_functor_s(edge_t e)
|
||||
: edge(e), threads(0)
|
||||
{}
|
||||
: edge(e)
|
||||
{
|
||||
threads = 0;
|
||||
}
|
||||
|
||||
event_functor_s::~event_functor_s()
|
||||
{}
|
||||
|
|
@ -87,6 +90,24 @@ void event_functor_s::set(vvp_ipoint_t ptr, bool, unsigned val, unsigned)
|
|||
}
|
||||
}
|
||||
|
||||
named_event_functor_s::~named_event_functor_s()
|
||||
{
|
||||
}
|
||||
|
||||
void named_event_functor_s::set(vvp_ipoint_t ptr, bool push,
|
||||
unsigned val, unsigned str)
|
||||
{
|
||||
put(ptr, val);
|
||||
|
||||
if (threads) {
|
||||
vthread_t tmp = threads;
|
||||
threads = 0;
|
||||
vthread_schedule_list(tmp);
|
||||
}
|
||||
|
||||
vpip_run_named_event_callbacks(handle);
|
||||
}
|
||||
|
||||
/*
|
||||
** Create an event functor
|
||||
** edge: compile_event(label, type, argc, argv)
|
||||
|
|
@ -148,20 +169,23 @@ void compile_event(char*label, char*type,
|
|||
*/
|
||||
void compile_named_event(char*label, char*name)
|
||||
{
|
||||
functor_t obj = new event_functor_s(vvp_edge_none);
|
||||
named_event_functor_s* obj = new named_event_functor_s;
|
||||
|
||||
vvp_ipoint_t fdx = functor_allocate(1);
|
||||
functor_define(fdx, obj);
|
||||
define_functor_symbol(label, fdx);
|
||||
|
||||
vpiHandle vpi = vpip_make_named_event(name);
|
||||
vpip_attach_to_current_scope(vpi);
|
||||
obj->handle = vpip_make_named_event(name);
|
||||
vpip_attach_to_current_scope(obj->handle);
|
||||
|
||||
free(label);
|
||||
}
|
||||
|
||||
/*
|
||||
* $Log: event.cc,v $
|
||||
* Revision 1.7 2002/05/19 05:18:16 steve
|
||||
* Add callbacks for vpiNamedEvent objects.
|
||||
*
|
||||
* Revision 1.6 2002/05/18 02:34:11 steve
|
||||
* Add vpi support for named events.
|
||||
*
|
||||
|
|
|
|||
22
vvp/event.h
22
vvp/event.h
|
|
@ -19,7 +19,7 @@
|
|||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
||||
*/
|
||||
#if !defined(WINNT)
|
||||
#ident "$Id: event.h,v 1.1 2001/11/06 03:07:22 steve Exp $"
|
||||
#ident "$Id: event.h,v 1.2 2002/05/19 05:18:16 steve Exp $"
|
||||
#endif
|
||||
|
||||
# include "functor.h"
|
||||
|
|
@ -28,13 +28,12 @@
|
|||
* Event / edge detection functors
|
||||
*/
|
||||
|
||||
struct event_functor_s: public edge_inputs_functor_s {
|
||||
struct event_functor_s: public edge_inputs_functor_s, public waitable_hooks_s {
|
||||
typedef unsigned short edge_t;
|
||||
explicit event_functor_s(edge_t e);
|
||||
virtual ~event_functor_s();
|
||||
virtual void set(vvp_ipoint_t i, bool push, unsigned val, unsigned str);
|
||||
edge_t edge;
|
||||
vthread_t threads;
|
||||
};
|
||||
|
||||
#define VVP_EDGE(a,b) (1<<(((a)<<2)|(b)))
|
||||
|
|
@ -58,6 +57,20 @@ const event_functor_s::edge_t vvp_edge_negedge
|
|||
const event_functor_s::edge_t vvp_edge_anyedge = 0x7bde;
|
||||
const event_functor_s::edge_t vvp_edge_none = 0;
|
||||
|
||||
/*
|
||||
* This is a functor to represent named events. This functor has no
|
||||
* inputs, and no output. It is a functor so that the %wait and %set
|
||||
* instructions can get at it.
|
||||
*/
|
||||
struct named_event_functor_s : public waitable_hooks_s, public functor_s {
|
||||
|
||||
public:
|
||||
~named_event_functor_s();
|
||||
void set(vvp_ipoint_t ipt, bool push, unsigned val, unsigned str =0);
|
||||
|
||||
struct __vpiHandle* handle;
|
||||
};
|
||||
|
||||
/*
|
||||
* Callback functors.
|
||||
*/
|
||||
|
|
@ -66,6 +79,9 @@ struct callback_functor_s *vvp_fvector_make_callback
|
|||
|
||||
/*
|
||||
* $Log: event.h,v $
|
||||
* Revision 1.2 2002/05/19 05:18:16 steve
|
||||
* Add callbacks for vpiNamedEvent objects.
|
||||
*
|
||||
* Revision 1.1 2001/11/06 03:07:22 steve
|
||||
* Code rearrange. (Stephan Boettcher)
|
||||
*
|
||||
|
|
|
|||
|
|
@ -19,7 +19,7 @@
|
|||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
||||
*/
|
||||
#if !defined(WINNT)
|
||||
#ident "$Id: functor.h,v 1.45 2002/03/17 03:23:10 steve Exp $"
|
||||
#ident "$Id: functor.h,v 1.46 2002/05/19 05:18:16 steve Exp $"
|
||||
#endif
|
||||
|
||||
# include "pointers.h"
|
||||
|
|
@ -328,6 +328,14 @@ unsigned functor_get(vvp_ipoint_t ptr)
|
|||
|
||||
// Special infrastructure functor types
|
||||
|
||||
/*
|
||||
* A "waitable" functor is one that the %wait instruction can wait
|
||||
* on. This includes the infrastructure needed to hold threads.
|
||||
*/
|
||||
struct waitable_hooks_s {
|
||||
vthread_t threads;
|
||||
};
|
||||
|
||||
|
||||
// The extra_outputs_functor_s class is for devices that require
|
||||
// multiple inputs and outputs.
|
||||
|
|
@ -386,6 +394,9 @@ extern vvp_fvector_t vvp_fvector_continuous_new(unsigned size, vvp_ipoint_t p);
|
|||
|
||||
/*
|
||||
* $Log: functor.h,v $
|
||||
* Revision 1.46 2002/05/19 05:18:16 steve
|
||||
* Add callbacks for vpiNamedEvent objects.
|
||||
*
|
||||
* Revision 1.45 2002/03/17 03:23:10 steve
|
||||
* Force the push flags to be explicit.
|
||||
*
|
||||
|
|
|
|||
|
|
@ -17,7 +17,7 @@
|
|||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
||||
*/
|
||||
#if !defined(WINNT)
|
||||
#ident "$Id: vpi_callback.cc,v 1.16 2002/05/18 02:34:11 steve Exp $"
|
||||
#ident "$Id: vpi_callback.cc,v 1.17 2002/05/19 05:18:16 steve Exp $"
|
||||
#endif
|
||||
|
||||
/*
|
||||
|
|
@ -78,26 +78,12 @@ const struct __vpirt callback_rt = {
|
|||
* event. This member is only used for things like cbReadOnlySync.
|
||||
*/
|
||||
|
||||
struct __vpiCallback {
|
||||
struct __vpiHandle base;
|
||||
|
||||
// user supplied callback data
|
||||
struct t_cb_data cb_data;
|
||||
struct t_vpi_time cb_time;
|
||||
|
||||
// scheduled event
|
||||
struct sync_cb* cb_sync;
|
||||
|
||||
// Used for listing callbacks.
|
||||
struct __vpiCallback*next;
|
||||
};
|
||||
|
||||
struct sync_cb : public vvp_gen_event_s {
|
||||
struct __vpiCallback*handle;
|
||||
};
|
||||
|
||||
|
||||
inline static struct __vpiCallback* new_vpi_callback()
|
||||
struct __vpiCallback* new_vpi_callback()
|
||||
{
|
||||
struct __vpiCallback* obj;
|
||||
|
||||
|
|
@ -209,22 +195,40 @@ static struct __vpiCallback* make_value_change(p_cb_data data)
|
|||
|
||||
assert(data->obj);
|
||||
assert(data->obj->vpi_type);
|
||||
assert((data->obj->vpi_type->type_code == vpiReg)
|
||||
|| (data->obj->vpi_type->type_code == vpiNet));
|
||||
struct __vpiSignal*sig = reinterpret_cast<__vpiSignal*>(data->obj);
|
||||
|
||||
/* Create callback functors, if necessary, to do the value
|
||||
change detection and carry the callback objects. */
|
||||
if (sig->callback == 0) {
|
||||
sig->callback = vvp_fvector_make_callback(sig->bits);
|
||||
assert(sig->callback);
|
||||
switch (data->obj->vpi_type->type_code) {
|
||||
|
||||
case vpiReg:
|
||||
case vpiNet:
|
||||
struct __vpiSignal*sig;
|
||||
sig = reinterpret_cast<__vpiSignal*>(data->obj);
|
||||
|
||||
/* Create callback functors, if necessary, to do the
|
||||
value change detection and carry the callback
|
||||
objects. */
|
||||
if (sig->callback == 0) {
|
||||
sig->callback = vvp_fvector_make_callback(sig->bits);
|
||||
assert(sig->callback);
|
||||
}
|
||||
|
||||
/* Attach the __vpiCallback object to the signals
|
||||
callback functors. */
|
||||
obj->next = sig->callback->cb_handle;
|
||||
sig->callback->cb_handle = obj;
|
||||
break;
|
||||
|
||||
case vpiNamedEvent:
|
||||
struct __vpiNamedEvent*nev;
|
||||
nev = reinterpret_cast<__vpiNamedEvent*>(data->obj);
|
||||
obj->next = nev->callbacks;
|
||||
nev->callbacks = obj;
|
||||
break;
|
||||
|
||||
default:
|
||||
assert(0);
|
||||
break;
|
||||
}
|
||||
|
||||
/* Attach the __vpiCallback object to the signals callback
|
||||
functors. */
|
||||
obj->next = sig->callback->cb_handle;
|
||||
sig->callback->cb_handle = obj;
|
||||
|
||||
return obj;
|
||||
}
|
||||
|
||||
|
|
@ -410,6 +414,18 @@ int vpi_remove_cb(vpiHandle ref)
|
|||
return 0;
|
||||
}
|
||||
|
||||
void callback_execute(struct __vpiCallback*cur)
|
||||
{
|
||||
assert(vpi_mode_flag == VPI_MODE_NONE);
|
||||
vpi_mode_flag = VPI_MODE_RWSYNC;
|
||||
|
||||
cur->cb_data.time->type = vpiSimTime;
|
||||
vpip_time_to_timestruct(cur->cb_data.time, schedule_simtime());
|
||||
(cur->cb_data.cb_rtn)(&cur->cb_data);
|
||||
|
||||
vpi_mode_flag = VPI_MODE_NONE;
|
||||
}
|
||||
|
||||
/*
|
||||
* A callback_functor_s functor uses its set method to detect value
|
||||
* changes. When a value comes in, the __vpiCallback objects that are
|
||||
|
|
@ -435,14 +451,7 @@ void callback_functor_s::set(vvp_ipoint_t, bool, unsigned val, unsigned)
|
|||
}
|
||||
}
|
||||
|
||||
assert(vpi_mode_flag == VPI_MODE_NONE);
|
||||
vpi_mode_flag = VPI_MODE_RWSYNC;
|
||||
|
||||
cur->cb_data.time->type = vpiSimTime;
|
||||
vpip_time_to_timestruct(cur->cb_data.time, schedule_simtime());
|
||||
(cur->cb_data.cb_rtn)(&cur->cb_data);
|
||||
|
||||
vpi_mode_flag = VPI_MODE_NONE;
|
||||
callback_execute(cur);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -450,6 +459,9 @@ void callback_functor_s::set(vvp_ipoint_t, bool, unsigned val, unsigned)
|
|||
|
||||
/*
|
||||
* $Log: vpi_callback.cc,v $
|
||||
* Revision 1.17 2002/05/19 05:18:16 steve
|
||||
* Add callbacks for vpiNamedEvent objects.
|
||||
*
|
||||
* Revision 1.16 2002/05/18 02:34:11 steve
|
||||
* Add vpi support for named events.
|
||||
*
|
||||
|
|
|
|||
|
|
@ -17,7 +17,7 @@
|
|||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
||||
*/
|
||||
#if !defined(WINNT)
|
||||
#ident "$Id: vpi_event.cc,v 1.1 2002/05/18 02:34:11 steve Exp $"
|
||||
#ident "$Id: vpi_event.cc,v 1.2 2002/05/19 05:18:16 steve Exp $"
|
||||
#endif
|
||||
|
||||
# include "vpi_priv.h"
|
||||
|
|
@ -30,27 +30,59 @@
|
|||
# include <string.h>
|
||||
# include <assert.h>
|
||||
|
||||
struct __vpiNamedEvent {
|
||||
struct __vpiHandle base;
|
||||
/* base name of the event object */
|
||||
char*name;
|
||||
/* Parent scope of this object. */
|
||||
struct __vpiScope*scope;
|
||||
};
|
||||
static char* named_event_str(int code, vpiHandle ref)
|
||||
{
|
||||
assert((ref->vpi_type->type_code==vpiNamedEvent));
|
||||
|
||||
struct __vpiNamedEvent*obj = (struct __vpiNamedEvent*)ref;
|
||||
|
||||
switch (code) {
|
||||
|
||||
case vpiName:
|
||||
return obj->name;
|
||||
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static vpiHandle named_event_get_handle(int code, vpiHandle ref)
|
||||
{
|
||||
assert((ref->vpi_type->type_code==vpiNamedEvent));
|
||||
|
||||
struct __vpiNamedEvent*obj = (struct __vpiNamedEvent*)ref;
|
||||
|
||||
switch (code) {
|
||||
|
||||
case vpiScope:
|
||||
return &obj->scope->base;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* We keep the object around, in case we need it again. It's all we
|
||||
* can do, because it cannot be recreated.
|
||||
*/
|
||||
static int named_event_free_object(vpiHandle)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
static const struct __vpirt vpip_named_event_rt = {
|
||||
vpiNamedEvent,
|
||||
|
||||
0,
|
||||
0,
|
||||
named_event_str,
|
||||
0,
|
||||
0,
|
||||
|
||||
0,
|
||||
named_event_get_handle,
|
||||
0,
|
||||
0,
|
||||
|
||||
0
|
||||
named_event_free_object
|
||||
};
|
||||
|
||||
vpiHandle vpip_make_named_event(char*name)
|
||||
|
|
@ -61,12 +93,30 @@ vpiHandle vpip_make_named_event(char*name)
|
|||
obj->base.vpi_type = &vpip_named_event_rt;
|
||||
obj->name = name;
|
||||
obj->scope = vpip_peek_current_scope();
|
||||
obj->callbacks = 0;
|
||||
|
||||
return &obj->base;
|
||||
}
|
||||
|
||||
void vpip_run_named_event_callbacks(vpiHandle ref)
|
||||
{
|
||||
assert((ref->vpi_type->type_code==vpiNamedEvent));
|
||||
|
||||
struct __vpiNamedEvent*obj = (struct __vpiNamedEvent*)ref;
|
||||
|
||||
struct __vpiCallback*cur = obj->callbacks;
|
||||
while (cur) {
|
||||
struct __vpiCallback*next = cur->next;
|
||||
callback_execute(cur);
|
||||
cur = next;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* $Log: vpi_event.cc,v $
|
||||
* Revision 1.2 2002/05/19 05:18:16 steve
|
||||
* Add callbacks for vpiNamedEvent objects.
|
||||
*
|
||||
* Revision 1.1 2002/05/18 02:34:11 steve
|
||||
* Add vpi support for named events.
|
||||
*
|
||||
|
|
|
|||
|
|
@ -19,7 +19,7 @@
|
|||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
||||
*/
|
||||
#if !defined(WINNT)
|
||||
#ident "$Id: vpi_priv.h,v 1.35 2002/05/18 02:34:11 steve Exp $"
|
||||
#ident "$Id: vpi_priv.h,v 1.36 2002/05/19 05:18:16 steve Exp $"
|
||||
#endif
|
||||
|
||||
# include "vpi_user.h"
|
||||
|
|
@ -107,6 +107,27 @@ struct __vpiIterator {
|
|||
extern vpiHandle vpip_make_iterator(unsigned nargs, vpiHandle*args,
|
||||
bool free_args_flag);
|
||||
|
||||
/*
|
||||
* This represents callback handles. There are some privat types that
|
||||
* are defined and used in vpi_callback.cc.
|
||||
*/
|
||||
struct __vpiCallback {
|
||||
struct __vpiHandle base;
|
||||
|
||||
// user supplied callback data
|
||||
struct t_cb_data cb_data;
|
||||
struct t_vpi_time cb_time;
|
||||
|
||||
// scheduled event
|
||||
struct sync_cb* cb_sync;
|
||||
|
||||
// Used for listing callbacks.
|
||||
struct __vpiCallback*next;
|
||||
};
|
||||
|
||||
extern struct __vpiCallback* new_vpi_callback();
|
||||
extern void callback_execute(struct __vpiCallback*cur);
|
||||
|
||||
/*
|
||||
* Scopes are created by .scope statements in the source.
|
||||
*/
|
||||
|
|
@ -155,7 +176,18 @@ extern vpiHandle vpip_make_net(char*name, int msb, int lsb, bool signed_flag,
|
|||
* passed in will be saved, so the caller must allocate it (or not
|
||||
* free it) after it is handed to this function.
|
||||
*/
|
||||
struct __vpiNamedEvent {
|
||||
struct __vpiHandle base;
|
||||
/* base name of the event object */
|
||||
char*name;
|
||||
/* Parent scope of this object. */
|
||||
struct __vpiScope*scope;
|
||||
/* List of callbacks interested in this event. */
|
||||
struct __vpiCallback*callbacks;
|
||||
};
|
||||
|
||||
extern vpiHandle vpip_make_named_event(char*name);
|
||||
extern void vpip_run_named_event_callbacks(vpiHandle ref);
|
||||
|
||||
/*
|
||||
* Memory is an array of bits that is accessible in N-bit chunks, with
|
||||
|
|
@ -326,6 +358,9 @@ extern void vpip_oct_str_to_bits(unsigned char*bits, unsigned nbits,
|
|||
|
||||
/*
|
||||
* $Log: vpi_priv.h,v $
|
||||
* Revision 1.36 2002/05/19 05:18:16 steve
|
||||
* Add callbacks for vpiNamedEvent objects.
|
||||
*
|
||||
* Revision 1.35 2002/05/18 02:34:11 steve
|
||||
* Add vpi support for named events.
|
||||
*
|
||||
|
|
|
|||
|
|
@ -17,7 +17,7 @@
|
|||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
||||
*/
|
||||
#if !defined(WINNT)
|
||||
#ident "$Id: vthread.cc,v 1.70 2002/05/12 23:44:41 steve Exp $"
|
||||
#ident "$Id: vthread.cc,v 1.71 2002/05/19 05:18:16 steve Exp $"
|
||||
#endif
|
||||
|
||||
# include "vthread.h"
|
||||
|
|
@ -1760,7 +1760,7 @@ bool of_WAIT(vthread_t thr, vvp_code_t cp)
|
|||
{
|
||||
assert(! thr->waiting_for_event);
|
||||
thr->waiting_for_event = 1;
|
||||
vvp_event_t ep = dynamic_cast<vvp_event_t>(functor_index(cp->iptr));
|
||||
waitable_hooks_s* ep = dynamic_cast<waitable_hooks_s*>(functor_index(cp->iptr));
|
||||
assert(ep);
|
||||
thr->wait_next = ep->threads;
|
||||
ep->threads = thr;
|
||||
|
|
@ -1884,6 +1884,9 @@ bool of_CALL_UFUNC(vthread_t thr, vvp_code_t cp)
|
|||
|
||||
/*
|
||||
* $Log: vthread.cc,v $
|
||||
* Revision 1.71 2002/05/19 05:18:16 steve
|
||||
* Add callbacks for vpiNamedEvent objects.
|
||||
*
|
||||
* Revision 1.70 2002/05/12 23:44:41 steve
|
||||
* task calls and forks push the thread event in the queue.
|
||||
*
|
||||
|
|
|
|||
Loading…
Reference in New Issue