From 5a2015ee674e471f01a0dd67227d863e1ab0ec0e Mon Sep 17 00:00:00 2001 From: steve Date: Fri, 29 Oct 1999 03:37:22 +0000 Subject: [PATCH] Support vpiValueChance callbacks. --- vpi/sys_display.c | 47 ++++++++++++++++++++++- vvm/vpi_callback.c | 92 +++++++++++++++++++++++++++++++++++++++++----- vvm/vpi_priv.h | 13 ++++++- vvm/vpi_signal.c | 7 +++- vvm/vvm.h | 6 ++- 5 files changed, 151 insertions(+), 14 deletions(-) diff --git a/vpi/sys_display.c b/vpi/sys_display.c index 891639cde..043f6c01f 100644 --- a/vpi/sys_display.c +++ b/vpi/sys_display.c @@ -17,7 +17,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA */ #if !defined(WINNT) -#ident "$Id: sys_display.c,v 1.5 1999/10/28 00:47:25 steve Exp $" +#ident "$Id: sys_display.c,v 1.6 1999/10/29 03:37:22 steve Exp $" #endif # include "vpi_user.h" @@ -260,6 +260,40 @@ static int sys_strobe_calltf(char*name) return 0; } +static int sys_monitor_calltf(char*name) +{ + struct t_cb_data cb; + struct t_vpi_time time; + + vpiHandle sys = vpi_handle(vpiSysTfCall, 0); + vpiHandle argv = vpi_iterate(vpiArgument, sys); + vpiHandle item; + + time.type = vpiSuppressTime; + + for (item = vpi_scan(argv) ; item ; item = vpi_scan(argv)) { + + switch (vpi_get(vpiType, item)) { + + case vpiNet: + case vpiReg: + cb.reason = cbValueChange; + cb.cb_rtn = strobe_cb; + cb.time = &time; + cb.obj = item; + cb.user_data = name; + vpi_register_cb(&cb); + break; + + default: + break; + } + + } + + return 0; +} + void sys_display_register() { s_vpi_systf_data tf_data; @@ -287,11 +321,22 @@ void sys_display_register() tf_data.sizetf = 0; tf_data.user_data = "$strobe"; vpi_register_systf(&tf_data); + + tf_data.type = vpiSysTask; + tf_data.tfname = "$monitor"; + tf_data.calltf = sys_monitor_calltf; + tf_data.compiletf = 0; + tf_data.sizetf = 0; + tf_data.user_data = "$monitor"; + vpi_register_systf(&tf_data); } /* * $Log: sys_display.c,v $ + * 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 diff --git a/vvm/vpi_callback.c b/vvm/vpi_callback.c index 7be4daddf..1dae8ad0a 100644 --- a/vvm/vpi_callback.c +++ b/vvm/vpi_callback.c @@ -17,7 +17,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA */ #if !defined(WINNT) -#ident "$Id: vpi_callback.c,v 1.2 1999/10/28 04:47:57 steve Exp $" +#ident "$Id: vpi_callback.c,v 1.3 1999/10/29 03:37:22 steve Exp $" #endif # include "vpi_priv.h" @@ -47,22 +47,85 @@ static void vpip_call_callback(void*cp) } /* - * Register callbacks. This supports a variety of callback reasons. + * This function is called by the product when it changes the value of + * a signal. It arranges for all the value chance callbacks to be + * called. + */ +void vpip_run_value_changes(struct __vpiSignal*sig) +{ + struct __vpiCallback*cur; + if (sig->monitor == 0) return; + + while (sig->monitor->next != sig->monitor) { + cur = sig->monitor->next; + sig->monitor->next = cur->next; + + cur->next = 0; + cur->ev = vpip_sim_insert_event(0, cur, vpip_call_callback, 0); + } + + cur = sig->monitor; + sig->monitor = 0; + cur->next = 0; + cur->ev = vpip_sim_insert_event(0, cur, vpip_call_callback, 0); +} + +/* + * Handle read-only synch events. This causes the callback to be + * scheduled for a moment at the end of the time period. This method + * handles scheduling with itme delays. + */ +static void go_readonly_synch(struct __vpiCallback*rfp) +{ + unsigned long tim; + assert(rfp->cb_data.time); + assert(rfp->cb_data.time->type == vpiSimTime); + assert(rfp->cb_data.time->high == 0); + tim = rfp->cb_data.time->low; + rfp->ev = vpip_sim_insert_event(tim, rfp, vpip_call_callback, 1); +} + +/* + * To schedule a value change, attach the callback to the signal to me + * monitored. I'll be inserted as an event later. + */ +static void go_value_change(struct __vpiCallback*rfp) +{ + struct __vpiSignal*sig = (struct __vpiSignal*)rfp->cb_data.obj; + assert((sig->base.vpi_type->type_code == vpiReg) + || (sig->base.vpi_type->type_code == vpiNet)); + + /* If there are no monitor events, start the list. */ + if (sig->monitor == 0) { + rfp->next = rfp; + sig->monitor = rfp; + return; + } + + /* Put me at the end of the list. Remember that the monitor + points to the *last* item in the list. */ + rfp->next = sig->monitor->next; + sig->monitor->next = rfp; + sig->monitor = rfp; +} + +/* + * Register callbacks. This supports a variety of callback reasons, + * mostly by dispatching them to a type specific handler. */ vpiHandle vpi_register_cb(p_cb_data data) { - unsigned long tim; struct __vpiCallback*rfp = calloc(1, sizeof(struct __vpiCallback)); rfp->base.vpi_type = &vpip_callback_rt; rfp->cb_data = *data; switch (data->reason) { case cbReadOnlySynch: - assert(data->time); - assert(data->time->type == vpiSimTime); - assert(data->time->high == 0); - tim = data->time->low; - rfp->ev = vpip_sim_insert_event(tim, rfp, vpip_call_callback, 1); + go_readonly_synch(rfp); + break; + + case cbValueChange: + go_value_change(rfp); break; default: @@ -77,13 +140,24 @@ int vpi_remove_cb(vpiHandle ref) { struct __vpiCallback*rfp = (struct __vpiCallback*)ref; assert(ref->vpi_type->type_code == vpiCallback); - vpip_sim_cancel_event(rfp->ev); + + if (rfp->ev) { + /* callbacks attached to events are easy. */ + vpip_sim_cancel_event(rfp->ev); + + } else { + assert(0); + } + free(rfp); return 0; } /* * $Log: vpi_callback.c,v $ + * Revision 1.3 1999/10/29 03:37:22 steve + * Support vpiValueChance callbacks. + * * Revision 1.2 1999/10/28 04:47:57 steve * Support delay in constSync callback. * diff --git a/vvm/vpi_priv.h b/vvm/vpi_priv.h index c71f207bd..2d059b37a 100644 --- a/vvm/vpi_priv.h +++ b/vvm/vpi_priv.h @@ -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.2 1999/10/28 00:47:25 steve Exp $" +#ident "$Id: vpi_priv.h,v 1.3 1999/10/29 03:37:22 steve Exp $" #endif /* @@ -71,7 +71,9 @@ struct __vpirt { struct __vpiCallback { struct __vpiHandle base; struct t_cb_data cb_data; + struct vpip_event*ev; + struct __vpiCallback*next; }; /* @@ -103,10 +105,13 @@ struct __vpiIterator { */ struct __vpiSignal { struct __vpiHandle base; - + /* The signal has a name (this points to static memory.) */ const char*name; + /* The signal has a value and dimension. */ enum vpip_bit_t*bits; unsigned nbits; + /* monitors are added here. */ + struct __vpiCallback*monitor; }; @@ -162,6 +167,7 @@ extern vpiHandle vpip_make_time_var(struct __vpiTimeVar*ref, /* Use this function to call a registered task. */ extern void vpip_calltask(const char*name, unsigned nparms, vpiHandle*parms); +extern void vpip_run_value_changes(struct __vpiSignal*sig); /* * The simulation object holds the current state of the @@ -220,6 +226,9 @@ extern int vpip_finished(); /* * $Log: vpi_priv.h,v $ + * Revision 1.3 1999/10/29 03:37:22 steve + * Support vpiValueChance callbacks. + * * Revision 1.2 1999/10/28 00:47:25 steve * Rewrite vvm VPI support to make objects more * persistent, rewrite the simulation scheduler diff --git a/vvm/vpi_signal.c b/vvm/vpi_signal.c index 60caaf0ae..b59718382 100644 --- a/vvm/vpi_signal.c +++ b/vvm/vpi_signal.c @@ -17,7 +17,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA */ #if !defined(WINNT) -#ident "$Id: vpi_signal.c,v 1.1 1999/10/28 00:47:25 steve Exp $" +#ident "$Id: vpi_signal.c,v 1.2 1999/10/29 03:37:22 steve Exp $" #endif # include "vpi_priv.h" @@ -255,6 +255,7 @@ vpiHandle vpip_make_net(struct __vpiSignal*ref, const char*name) { ref->base.vpi_type = &vpip_net_rt; ref->name = name; + ref->monitor = 0; return &(ref->base); } @@ -271,11 +272,15 @@ vpiHandle vpip_make_reg(struct __vpiSignal*ref, const char*name) { ref->base.vpi_type = &vpip_reg_rt; ref->name = name; + ref->monitor = 0; return &(ref->base); } /* * $Log: vpi_signal.c,v $ + * Revision 1.2 1999/10/29 03:37:22 steve + * Support vpiValueChance callbacks. + * * Revision 1.1 1999/10/28 00:47:25 steve * Rewrite vvm VPI support to make objects more * persistent, rewrite the simulation scheduler diff --git a/vvm/vvm.h b/vvm/vvm.h index c7aaf3238..dd61f3cc4 100644 --- a/vvm/vvm.h +++ b/vvm/vvm.h @@ -19,7 +19,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA */ #if !defined(WINNT) -#ident "$Id: vvm.h,v 1.17 1999/10/28 21:36:00 steve Exp $" +#ident "$Id: vvm.h,v 1.18 1999/10/29 03:37:22 steve Exp $" #endif # include @@ -242,6 +242,7 @@ template class vvm_signal_t : public __vpiSignal { void set(vvm_simulation*sim, unsigned idx, vpip_bit_t val) { bits[idx] = val; + vpip_run_value_changes(this); } void set(vvm_simulation*sim, const vvm_bitset_t&val) @@ -252,6 +253,9 @@ template class vvm_signal_t : public __vpiSignal { /* * $Log: vvm.h,v $ + * Revision 1.18 1999/10/29 03:37:22 steve + * Support vpiValueChance callbacks. + * * Revision 1.17 1999/10/28 21:36:00 steve * Get rid of monitor_t and fold __vpiSignal into signal. *