Support vpiValueChance callbacks.

This commit is contained in:
steve 1999-10-29 03:37:22 +00:00
parent 0721615345
commit 5a2015ee67
5 changed files with 151 additions and 14 deletions

View File

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

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

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

View File

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

View File

@ -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 <vector>
@ -242,6 +242,7 @@ template <unsigned WIDTH> 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<WIDTH>&val)
@ -252,6 +253,9 @@ template <unsigned WIDTH> 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.
*