Add callbacks for vpiNamedEvent objects.

This commit is contained in:
steve 2002-05-19 05:18:16 +00:00
parent b1c0f7306d
commit cfab250671
7 changed files with 212 additions and 61 deletions

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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