Support vpiValueChance callbacks.
This commit is contained in:
parent
0721615345
commit
5a2015ee67
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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.
|
||||
*
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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.
|
||||
*
|
||||
|
|
|
|||
Loading…
Reference in New Issue