Add the $monitor implementation.
This commit is contained in:
parent
2d1ace1dbc
commit
43ff33cd79
|
|
@ -17,7 +17,7 @@
|
||||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
||||||
*/
|
*/
|
||||||
#if !defined(WINNT)
|
#if !defined(WINNT)
|
||||||
#ident "$Id: sys_display.c,v 1.8 1999/11/06 23:32:14 steve Exp $"
|
#ident "$Id: sys_display.c,v 1.9 1999/11/07 02:25:07 steve Exp $"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
# include "vpi_user.h"
|
# include "vpi_user.h"
|
||||||
|
|
@ -110,8 +110,8 @@ static int format_str(char*fmt, int argc, vpiHandle*argv)
|
||||||
cp += 1;
|
cp += 1;
|
||||||
break;
|
break;
|
||||||
case 'm':
|
case 'm':
|
||||||
vpi_printf("%s",
|
vpi_printf("%s", vpi_get_str(vpiFullName, argv[idx]));
|
||||||
vpi_get_str(vpiFullName, argv[idx++]));
|
idx += 1;
|
||||||
cp += 1;
|
cp += 1;
|
||||||
break;
|
break;
|
||||||
case 'o':
|
case 'o':
|
||||||
|
|
@ -178,7 +178,7 @@ static void do_display(struct strobe_cb_info*info)
|
||||||
vpi_get_value(item, &value);
|
vpi_get_value(item, &value);
|
||||||
idx += format_str(value.value.str,
|
idx += format_str(value.value.str,
|
||||||
info->nitems-idx-1,
|
info->nitems-idx-1,
|
||||||
info->items+1);
|
info->items+idx+1);
|
||||||
} else {
|
} else {
|
||||||
value.format = vpiBinStrVal;
|
value.format = vpiBinStrVal;
|
||||||
vpi_get_value(item, &value);
|
vpi_get_value(item, &value);
|
||||||
|
|
@ -275,16 +275,99 @@ static int sys_strobe_calltf(char*name)
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* The $monitor system task works by managing these static variables,
|
||||||
|
* and the cbValueChange callbacks associated with registers and
|
||||||
|
* nets. Note that it is proper to keep the state in static variables
|
||||||
|
* because there can only be one monitor at a time pending (even
|
||||||
|
* though that monitor may be watching many variables).
|
||||||
|
*/
|
||||||
|
|
||||||
|
static struct strobe_cb_info monitor_info = { 0, 0, 0 };
|
||||||
|
static int monitor_scheduled = 0;
|
||||||
|
static vpiHandle *monitor_callbacks = 0;
|
||||||
|
|
||||||
|
static int monitor_cb_2(p_cb_data cb)
|
||||||
|
{
|
||||||
|
do_display(&monitor_info);
|
||||||
|
vpi_printf("\n");
|
||||||
|
monitor_scheduled = 0;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int monitor_cb_1(p_cb_data cause)
|
||||||
|
{
|
||||||
|
struct t_cb_data cb;
|
||||||
|
struct t_vpi_time time;
|
||||||
|
|
||||||
|
/* Reschedule this event so that it happens for the next
|
||||||
|
trigger on this variable. */
|
||||||
|
cb = *cause;
|
||||||
|
vpi_register_cb(&cb);
|
||||||
|
|
||||||
|
if (monitor_scheduled) return 0;
|
||||||
|
|
||||||
|
/* This this action caused the first trigger, then schedule
|
||||||
|
the monitor to happen at the end of the time slice and mark
|
||||||
|
it as scheduled. */
|
||||||
|
monitor_scheduled += 1;
|
||||||
|
time.type = vpiSimTime;
|
||||||
|
time.low = 0;
|
||||||
|
time.high = 0;
|
||||||
|
|
||||||
|
cb.reason = cbReadOnlySynch;
|
||||||
|
cb.cb_rtn = monitor_cb_2;
|
||||||
|
cb.time = &time;
|
||||||
|
cb.obj = 0;
|
||||||
|
vpi_register_cb(&cb);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
static int sys_monitor_calltf(char*name)
|
static int sys_monitor_calltf(char*name)
|
||||||
{
|
{
|
||||||
|
unsigned idx;
|
||||||
struct t_cb_data cb;
|
struct t_cb_data cb;
|
||||||
struct t_vpi_time time;
|
struct t_vpi_time time;
|
||||||
|
|
||||||
vpiHandle sys = vpi_handle(vpiSysTfCall, 0);
|
vpiHandle sys = vpi_handle(vpiSysTfCall, 0);
|
||||||
vpiHandle argv = vpi_iterate(vpiArgument, sys);
|
vpiHandle argv = vpi_iterate(vpiArgument, sys);
|
||||||
vpiHandle item;
|
|
||||||
|
if (monitor_callbacks) {
|
||||||
|
for (idx = 0 ; idx < monitor_info.nitems ; idx += 1)
|
||||||
|
if (monitor_callbacks[idx])
|
||||||
|
vpi_remove_cb(monitor_callbacks[idx]);
|
||||||
|
|
||||||
|
free(monitor_callbacks);
|
||||||
|
monitor_callbacks = 0;
|
||||||
|
|
||||||
|
free(monitor_info.items);
|
||||||
|
free(monitor_info.name);
|
||||||
|
monitor_info.items = 0;
|
||||||
|
monitor_info.nitems = 0;
|
||||||
|
monitor_info.name = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
array_from_iterator(&monitor_info, argv);
|
||||||
|
monitor_info.name = strdup(name);
|
||||||
|
|
||||||
|
monitor_callbacks = calloc(monitor_info.nitems, sizeof(vpiHandle));
|
||||||
|
|
||||||
time.type = vpiSuppressTime;
|
time.type = vpiSuppressTime;
|
||||||
|
cb.reason = cbValueChange;
|
||||||
|
cb.cb_rtn = monitor_cb_1;
|
||||||
|
cb.time = &time;
|
||||||
|
for (idx = 0 ; idx < monitor_info.nitems ; idx += 1) {
|
||||||
|
|
||||||
|
switch (vpi_get(vpiType, monitor_info.items[idx])) {
|
||||||
|
case vpiNet:
|
||||||
|
case vpiReg:
|
||||||
|
cb.obj = monitor_info.items[idx];
|
||||||
|
monitor_callbacks[idx] = vpi_register_cb(&cb);
|
||||||
|
break;
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
@ -329,6 +412,9 @@ void sys_display_register()
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* $Log: sys_display.c,v $
|
* $Log: sys_display.c,v $
|
||||||
|
* Revision 1.9 1999/11/07 02:25:07 steve
|
||||||
|
* Add the $monitor implementation.
|
||||||
|
*
|
||||||
* Revision 1.8 1999/11/06 23:32:14 steve
|
* Revision 1.8 1999/11/06 23:32:14 steve
|
||||||
* Unify display and strobe format routines.
|
* Unify display and strobe format routines.
|
||||||
*
|
*
|
||||||
|
|
|
||||||
|
|
@ -19,7 +19,7 @@
|
||||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
||||||
*/
|
*/
|
||||||
#if !defined(WINNT)
|
#if !defined(WINNT)
|
||||||
#ident "$Id: vpi_user.h,v 1.4 1999/10/28 00:47:25 steve Exp $"
|
#ident "$Id: vpi_user.h,v 1.5 1999/11/07 02:25:08 steve Exp $"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
|
|
@ -161,6 +161,7 @@ typedef struct t_cb_data {
|
||||||
#define cbUnresolvedSystf 24
|
#define cbUnresolvedSystf 24
|
||||||
|
|
||||||
extern vpiHandle vpi_register_cb(p_cb_data data);
|
extern vpiHandle vpi_register_cb(p_cb_data data);
|
||||||
|
extern int vpi_remove_cb(vpiHandle ref);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* This function allows a vpi application to control the simulation
|
* This function allows a vpi application to control the simulation
|
||||||
|
|
@ -203,6 +204,9 @@ extern void (*vlog_startup_routines[])();
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* $Log: vpi_user.h,v $
|
* $Log: vpi_user.h,v $
|
||||||
|
* Revision 1.5 1999/11/07 02:25:08 steve
|
||||||
|
* Add the $monitor implementation.
|
||||||
|
*
|
||||||
* Revision 1.4 1999/10/28 00:47:25 steve
|
* Revision 1.4 1999/10/28 00:47:25 steve
|
||||||
* Rewrite vvm VPI support to make objects more
|
* Rewrite vvm VPI support to make objects more
|
||||||
* persistent, rewrite the simulation scheduler
|
* persistent, rewrite the simulation scheduler
|
||||||
|
|
|
||||||
|
|
@ -17,7 +17,7 @@
|
||||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
||||||
*/
|
*/
|
||||||
#if !defined(WINNT)
|
#if !defined(WINNT)
|
||||||
#ident "$Id: vpi_signal.c,v 1.3 1999/11/06 16:52:16 steve Exp $"
|
#ident "$Id: vpi_signal.c,v 1.4 1999/11/07 02:25:08 steve Exp $"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
# include "vpi_priv.h"
|
# include "vpi_priv.h"
|
||||||
|
|
@ -28,6 +28,9 @@ static char* signal_get_str(int code, vpiHandle ref)
|
||||||
{
|
{
|
||||||
struct __vpiSignal*rfp = (struct __vpiSignal*)ref;
|
struct __vpiSignal*rfp = (struct __vpiSignal*)ref;
|
||||||
|
|
||||||
|
assert((ref->vpi_type->type_code==vpiNet)
|
||||||
|
|| (ref->vpi_type->type_code==vpiReg));
|
||||||
|
|
||||||
switch (code) {
|
switch (code) {
|
||||||
|
|
||||||
case vpiFullName:
|
case vpiFullName:
|
||||||
|
|
@ -40,6 +43,9 @@ static char* signal_get_str(int code, vpiHandle ref)
|
||||||
static void signal_get_value(vpiHandle ref, s_vpi_value*vp)
|
static void signal_get_value(vpiHandle ref, s_vpi_value*vp)
|
||||||
{
|
{
|
||||||
struct __vpiSignal*rfp = (struct __vpiSignal*)ref;
|
struct __vpiSignal*rfp = (struct __vpiSignal*)ref;
|
||||||
|
assert((ref->vpi_type->type_code==vpiNet)
|
||||||
|
|| (ref->vpi_type->type_code==vpiReg));
|
||||||
|
|
||||||
vpip_bits_get_value(rfp->bits, rfp->nbits, vp);
|
vpip_bits_get_value(rfp->bits, rfp->nbits, vp);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -79,6 +85,9 @@ vpiHandle vpip_make_reg(struct __vpiSignal*ref, const char*name)
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* $Log: vpi_signal.c,v $
|
* $Log: vpi_signal.c,v $
|
||||||
|
* Revision 1.4 1999/11/07 02:25:08 steve
|
||||||
|
* Add the $monitor implementation.
|
||||||
|
*
|
||||||
* Revision 1.3 1999/11/06 16:52:16 steve
|
* Revision 1.3 1999/11/06 16:52:16 steve
|
||||||
* complete value retrieval for number constants.
|
* complete value retrieval for number constants.
|
||||||
*
|
*
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue