cbValueChange automatically replays.

This commit is contained in:
steve 2002-04-06 20:25:45 +00:00
parent 284c6fd85d
commit c98c24b9ff
4 changed files with 61 additions and 141 deletions

View File

@ -17,7 +17,7 @@
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*/
#if !defined(WINNT) && !defined(macintosh)
#ident "$Id: sys_display.c,v 1.35 2002/02/06 04:50:04 steve Exp $"
#ident "$Id: sys_display.c,v 1.36 2002/04/06 20:25:45 steve Exp $"
#endif
# include "config.h"
@ -593,21 +593,7 @@ static int monitor_cb_1(p_cb_data cause)
{
struct t_cb_data cb;
struct t_vpi_time time;
/* The user_data of the callback is a pointer to the callback
handle. I use this to reschedule the callback if needed. */
vpiHandle*cbh = (vpiHandle*) (cause->user_data);
/* Reschedule this event so that it happens for the next
trigger on this variable. */
time.type = vpiSuppressTime;
cb.reason = cbValueChange;
cb.cb_rtn = monitor_cb_1;
cb.time = &time;
cb.obj = cause->obj;
cb.value = 0;
cb.user_data = cause->user_data;
*cbh = vpi_register_cb(&cb);
if (monitor_scheduled) return 0;
/* This this action caused the first trigger, then schedule
@ -1125,6 +1111,9 @@ void sys_display_register()
/*
* $Log: sys_display.c,v $
* Revision 1.36 2002/04/06 20:25:45 steve
* cbValueChange automatically replays.
*
* Revision 1.35 2002/02/06 04:50:04 steve
* Detect and skip suppressed values in display
*
@ -1144,90 +1133,5 @@ void sys_display_register()
*
* Revision 1.30 2001/10/25 04:19:53 steve
* VPI support for callback to return values.
*
* Revision 1.29 2001/08/16 03:26:04 steve
* Add some missing print escape sequences.
*
* Revision 1.28 2001/07/25 03:10:50 steve
* Create a config.h.in file to hold all the config
* junk, and support gcc 3.0. (Stephan Boettcher)
*
* Revision 1.27 2001/07/16 18:40:19 steve
* Add a stdlog output for vvp, and vvp options
* to direct them around. (Stephan Boettcher.)
*
* Revision 1.26 2001/07/11 02:22:17 steve
* Manually create the stage-2 callback structure.
*
* Revision 1.25 2001/06/25 03:11:41 steve
* More robust about incorrect arguments.
*
* Revision 1.24 2001/03/22 02:23:40 steve
* fgetc patch from Peter Monta.
*
* Revision 1.23 2001/03/18 00:31:32 steve
* $display can take 0 arguments.
*
* Revision 1.22 2001/02/10 19:50:33 steve
* Slightly more specific error message.
*
* Revision 1.21 2000/12/02 02:40:56 steve
* Support for %s in $display (PR#62)
*
* Revision 1.20 2000/11/04 05:49:22 steve
* Integrate parameter count changes (PR#34)
*
* Revision 1.19 2000/11/04 01:52:57 steve
* Scope information is needed by all types of display tasks.
*
* Revision 1.18 2000/10/28 00:51:42 steve
* Add scope to threads in vvm, pass that scope
* to vpi sysTaskFunc objects, and add vpi calls
* to access that information.
*
* $display displays scope in %m (PR#1)
*
* Revision 1.17 2000/08/20 17:49:05 steve
* Clean up warnings and portability issues.
*
* Revision 1.16 2000/05/31 02:15:43 steve
* typo: fix vpiReadVal to vpiRealVal
*
* Revision 1.15 2000/05/09 00:02:29 steve
* Remove test print.
*
* Revision 1.14 2000/05/07 18:20:07 steve
* Import MCD support from Stephen Tell, and add
* system function parameter support to the IVL core.
*
* Revision 1.13 2000/04/21 02:00:35 steve
* exit if hex value is missing.
*
* Revision 1.12 2000/03/31 07:08:39 steve
* allow cancelling of cbValueChange events.
*
* Revision 1.11 2000/02/23 02:56:56 steve
* Macintosh compilers do not support ident.
*
* Revision 1.10 2000/02/13 19:18:27 steve
* Accept memory words as parameter to $display.
*
* Revision 1.9 1999/11/07 02:25:07 steve
* Add the $monitor implementation.
*
* Revision 1.8 1999/11/06 23:32:14 steve
* Unify display and strobe format routines.
*
* Revision 1.7 1999/11/06 22:16:50 steve
* Get the $strobe task working.
*
* Revision 1.6 1999/10/29 03:37:22 steve
* Support vpiValueChance callbacks.
*
* Revision 1.5 1999/10/28 00:47:25 steve
* Rewrite vvm VPI support to make objects more
* persistent, rewrite the simulation scheduler
* in C (to interface with VPI) and add VPI support
* for callbacks.
*/

View File

@ -17,7 +17,7 @@
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*/
#if !defined(WINNT) && !defined(macintosh)
#ident "$Id: sys_lxt.c,v 1.1 2002/03/09 21:54:49 steve Exp $"
#ident "$Id: sys_lxt.c,v 1.2 2002/04/06 20:25:45 steve Exp $"
#endif
# include "config.h"
@ -245,14 +245,8 @@ static void vcd_checkpoint_x()
static int variable_cb(p_cb_data cause)
{
unsigned long now = cause->time->low;
struct t_cb_data cb;
struct vcd_info*info = (struct vcd_info*)cause->user_data;
/* Reschedule this event so that it happens for the next
trigger on this variable. */
cb = *cause;
vpi_register_cb(&cb);
if (dump_is_off)
return 0;
@ -778,6 +772,9 @@ void sys_lxt_register()
/*
* $Log: sys_lxt.c,v $
* Revision 1.2 2002/04/06 20:25:45 steve
* cbValueChange automatically replays.
*
* Revision 1.1 2002/03/09 21:54:49 steve
* Add LXT dumper support. (Anthony Bybell)
*

View File

@ -17,7 +17,7 @@
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*/
#if !defined(WINNT) && !defined(macintosh)
#ident "$Id: sys_vcd.c,v 1.26 2001/10/26 02:29:10 steve Exp $"
#ident "$Id: sys_vcd.c,v 1.27 2002/04/06 20:25:45 steve Exp $"
#endif
# include "config.h"
@ -230,14 +230,8 @@ static void vcd_checkpoint_x()
static int variable_cb(p_cb_data cause)
{
unsigned long now = cause->time->low;
struct t_cb_data cb;
struct vcd_info*info = (struct vcd_info*)cause->user_data;
/* Reschedule this event so that it happens for the next
trigger on this variable. */
cb = *cause;
vpi_register_cb(&cb);
if (dump_is_off)
return 0;
@ -782,6 +776,9 @@ void sys_vcd_register()
/*
* $Log: sys_vcd.c,v $
* Revision 1.27 2002/04/06 20:25:45 steve
* cbValueChange automatically replays.
*
* Revision 1.26 2001/10/26 02:29:10 steve
* const/non-const warnings. (Stephan Boettcher)
*

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.10 2001/11/06 03:07:22 steve Exp $"
#ident "$Id: vpi_callback.cc,v 1.11 2002/04/06 20:25:45 steve Exp $"
#endif
/*
@ -56,16 +56,28 @@ const struct __vpirt callback_rt = {
* Callback handles are created when the VPI function registers a
* callback. The handle is stored by the run time, and it triggered
* when the run-time thing that it is waiting for happens.
*
* This is the thing that the VPI code references by the vpiHandle. It
* also points to callback data that the caller attached to the event,
* as well as the time structure to receive data.
*
* The cb_sync is a private member that points to the schedulable
* event that is triggered when the event happens. The sync_cb class
* represents the action to execute when the scheduler gets to this
* 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;
};
@ -73,31 +85,29 @@ struct sync_cb : public vvp_gen_event_s {
struct __vpiCallback*handle;
};
static struct __vpiCallback* free_callback_root = 0x0;
inline static struct __vpiCallback* new_vpi_callback()
{
struct __vpiCallback* obj;
if (!free_callback_root) {
obj = new __vpiCallback;
obj->base.vpi_type = &callback_rt;
} else {
obj = free_callback_root;
free_callback_root = obj->next;
}
obj->next = 0x0;
obj = new __vpiCallback;
obj->base.vpi_type = &callback_rt;
obj->cb_sync = 0;
obj->next = 0;
return obj;
}
inline static void free_vpi_callback(struct __vpiCallback* obj)
{
obj->next = free_callback_root;
free_callback_root = obj;
delete obj;
}
/*
* A signal get equipped with a callback_functor_s to trigger
* callbacks.
* The callback_functor_s functor is used to support cbValueChange
* callbacks. When a value change callback is created, instances of
* this functor are created to receive values and detect changes in
* the functor web at the right spot.
*/
struct callback_functor_s: public functor_s {
@ -105,16 +115,21 @@ struct callback_functor_s: public functor_s {
virtual ~callback_functor_s();
virtual void set(vvp_ipoint_t i, bool push, unsigned val, unsigned str);
struct __vpiCallback *cb_handle;
unsigned permanent : 1;
};
inline callback_functor_s::callback_functor_s()
: permanent(0)
callback_functor_s::callback_functor_s()
{}
callback_functor_s::~callback_functor_s()
{}
/*
* Make the functors necessary to support an edge callback. This is a
* single event functor that is in turn fed by edge detector functors
* attached to all the input bit functors. (Just like an event-or.)
* This function creates the callback_functor and the necessary event
* functors, and attaches the event functors to the net.
*/
struct callback_functor_s *vvp_fvector_make_callback(vvp_fvector_t vec,
event_functor_s::edge_t edge)
{
@ -164,7 +179,6 @@ struct callback_functor_s *vvp_fvector_make_callback(vvp_fvector_t vec,
vfu->out = ipt;
}
obj->permanent = 0;
obj->cb_handle = 0;
return obj;
}
@ -172,8 +186,9 @@ struct callback_functor_s *vvp_fvector_make_callback(vvp_fvector_t vec,
/*
* A value change callback is tripped when a bit of a signal
* changes. This function creates that value change callback and
* attaches it to the relevent vpiSignal object. Also flag the
* functors associated with the signal so that they know to trip.
* attaches it to the relevent vpiSignal object. Also, if the signal
* 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)
{
@ -188,11 +203,15 @@ static struct __vpiCallback* make_value_change(p_cb_data data)
|| (data->obj->vpi_type->type_code == vpiNet));
struct __vpiSignal*sig = reinterpret_cast<__vpiSignal*>(data->obj);
if (!sig->callback) {
/* 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;
@ -270,14 +289,15 @@ int vpi_remove_cb(vpiHandle ref)
}
/*
* A callback event happened.
* A callback_functor_s functor uses its set method to detect value
* changes. When a value comes in, the __vpiCallback objects that are
* associated with this callback functor are all called.
*/
void callback_functor_s::set(vvp_ipoint_t, bool, unsigned val, unsigned)
{
struct __vpiCallback *next = cb_handle;
if (!permanent)
cb_handle = 0;
while (next) {
struct __vpiCallback * cur = next;
next = cur->next;
@ -296,8 +316,7 @@ void callback_functor_s::set(vvp_ipoint_t, bool, unsigned val, unsigned)
cur->cb_data.time->low = schedule_simtime();
cur->cb_data.time->high = 0;
(cur->cb_data.cb_rtn)(&cur->cb_data);
if (!permanent)
free_vpi_callback(cur);
}
}
@ -309,6 +328,9 @@ void vpip_trip_monitor_callbacks(void)
/*
* $Log: vpi_callback.cc,v $
* Revision 1.11 2002/04/06 20:25:45 steve
* cbValueChange automatically replays.
*
* Revision 1.10 2001/11/06 03:07:22 steve
* Code rearrange. (Stephan Boettcher)
*