Add support for REadOnlySync and monitors.

This commit is contained in:
steve 2001-07-11 02:27:21 +00:00
parent 13ef84bc35
commit da828a218f
7 changed files with 176 additions and 30 deletions

View File

@ -17,7 +17,7 @@
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*/
#if !defined(WINNT)
#ident "$Id: arith.cc,v 1.9 2001/07/07 02:57:33 steve Exp $"
#ident "$Id: arith.cc,v 1.10 2001/07/11 02:27:21 steve Exp $"
#endif
# include "arith.h"
@ -110,8 +110,6 @@ vvp_arith_sum::~vvp_arith_sum()
void vvp_arith_sum::set(vvp_ipoint_t i, functor_t f, bool push)
{
assert(wid_ <= 8*sizeof(unsigned long));
unsigned page = 0;
unsigned pbit = 0;
unsigned long carry = 0;
@ -468,6 +466,9 @@ void vvp_shiftr::set(vvp_ipoint_t i, functor_t f, bool push)
/*
* $Log: arith.cc,v $
* Revision 1.10 2001/07/11 02:27:21 steve
* Add support for REadOnlySync and monitors.
*
* Revision 1.9 2001/07/07 02:57:33 steve
* Add the .shift/r functor.
*

View File

@ -18,7 +18,7 @@
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*/
#if !defined(WINNT)
#ident "$Id: memory.cc,v 1.4 2001/06/15 03:28:31 steve Exp $"
#ident "$Id: memory.cc,v 1.5 2001/07/11 02:27:21 steve Exp $"
#endif
#include "memory.h"
@ -437,6 +437,8 @@ inline static struct mem_assign_s* ma_alloc()
cur = (struct mem_assign_s*) malloc(sizeof(struct mem_assign_s));
else
ma_free_list = cur->next;
cur->sync_flag = false;
return cur;
}

View File

@ -17,7 +17,7 @@
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*/
#if !defined(WINNT)
#ident "$Id: schedule.cc,v 1.10 2001/05/30 03:02:35 steve Exp $"
#ident "$Id: schedule.cc,v 1.11 2001/07/11 02:27:21 steve Exp $"
#endif
# include "schedule.h"
@ -27,6 +27,7 @@
# include <malloc.h>
# include <assert.h>
# include <stdio.h>
/*
* The event queue is arranged as a skip list, with the simulation
* time the key to the list. The simulation time is stored in each
@ -90,9 +91,20 @@ inline static void e_free(struct event_s* cur)
}
/*
* This is the head of the list of pending events.
* This is the head of the list of pending events. This includes all
* the events that have not been executed yet, and reaches into the
* future.
*/
static struct event_s* list = 0;
static struct event_s* sched_list = 0;
/*
* At the current time, events that are marked as synch events are put
* into this list and held off until the time step is about to
* advance. Then the events in this list are run and the clock is
* allowed to advance.
*/
static struct event_s* synch_list = 0;
/*
* This flag is true until a VPI task or function finishes the
@ -122,20 +134,20 @@ static void schedule_event_(struct event_s*cur)
/* If the list is completely empty, then start the list with
this the only event. */
if (list == 0) {
list = cur;
if (sched_list == 0) {
sched_list = cur;
cur->next = 0;
return;
}
struct event_s*idx = list;
struct event_s*idx = sched_list;
if (cur->delay < idx->delay) {
/* If this new event is earlier then even the first
event, then insert it in front. Adjust the delay of
the next event, and set the start to me. */
idx->delay -= cur->delay;
cur->next = idx;
list = cur;
sched_list = cur;
} else {
@ -173,6 +185,43 @@ static void schedule_event_(struct event_s*cur)
}
}
/*
* The synch_list is managed as a doubly-linked circular list. There is
* no need for the skip capabilities, so use the "last" member as a
* prev pointer. This function appends the event to the synch_list.
*/
static void postpone_sync_event(struct event_s*cur)
{
if (synch_list == 0) {
synch_list = cur;
cur->next = cur;
cur->last = cur;
return;
}
cur->next = synch_list;
cur->last = synch_list->last;
cur->next->last = cur;
cur->last->next = cur;
}
static struct event_s* pull_sync_event(void)
{
if (synch_list == 0)
return 0;
struct event_s*cur = synch_list;
synch_list = cur->next;
if (cur == synch_list) {
synch_list = 0;
} else {
cur->next->last = cur->last;
cur->last->next = cur->next;
}
return cur;
}
void schedule_vthread(vthread_t thr, unsigned delay)
{
struct event_s*cur = e_alloc();
@ -228,30 +277,47 @@ void schedule_simulate(void)
{
schedule_time = 0;
while (schedule_runnable && list) {
while (schedule_runnable && sched_list) {
/* Pull the first item off the list. Fixup the last
pointer in the next cell, if necessary. */
struct event_s*cur = list;
list = cur->next;
struct event_s*cur = sched_list;
sched_list = cur->next;
if (cur->last != cur) {
assert(list);
assert(list->delay == 0);
list->last = cur->last;
assert(sched_list);
assert(sched_list->delay == 0);
sched_list->last = cur->last;
}
/* If the time is advancing, then first run the
postponed sync events. Run them all. */
if (cur->delay > 0) {
struct event_s*sync_cur;
while ( (sync_cur = pull_sync_event()) ) {
assert(sync_cur->type == TYPE_GEN);
if (sync_cur->obj && sync_cur->obj->run) {
assert(sync_cur->obj->sync_flag);
sync_cur->obj->run(sync_cur->obj, sync_cur->val);
}
e_free(sync_cur);
}
schedule_time += cur->delay;
//printf("TIME: %u\n", schedule_time);
}
switch (cur->type) {
case TYPE_THREAD:
vthread_run(cur->thr);
e_free(cur);
break;
case TYPE_PROP:
//printf("Propagate %p\n", cur->fun);
functor_propagate(cur->fun);
e_free(cur);
break;
case TYPE_ASSIGN:
@ -269,21 +335,31 @@ void schedule_simulate(void)
functor_set(cur->fun, cur->val, HiZ, false);
break;
}
e_free(cur);
break;
case TYPE_GEN:
if (cur->obj && cur->obj->run)
if (cur->obj && cur->obj->run) {
if (cur->obj->sync_flag == false) {
cur->obj->run(cur->obj, cur->val);
e_free(cur);
} else {
postpone_sync_event(cur);
}
}
break;
}
e_free(cur);
}
}
/*
* $Log: schedule.cc,v $
* Revision 1.11 2001/07/11 02:27:21 steve
* Add support for REadOnlySync and monitors.
*
* Revision 1.10 2001/05/30 03:02:35 steve
* Propagate strength-values instead of drive strengths.
*

View File

@ -19,7 +19,7 @@
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*/
#if !defined(WINNT)
#ident "$Id: schedule.h,v 1.6 2001/05/02 01:38:13 steve Exp $"
#ident "$Id: schedule.h,v 1.7 2001/07/11 02:27:21 steve Exp $"
#endif
# include "vthread.h"
@ -64,6 +64,7 @@ extern void schedule_generic(vvp_gen_event_t obj, unsigned char val,
struct vvp_gen_event_s
{
void (*run)(vvp_gen_event_t obj, unsigned char val);
bool sync_flag;
};
/*
@ -94,6 +95,9 @@ extern bool schedule_finished(void);
/*
* $Log: schedule.h,v $
* Revision 1.7 2001/07/11 02:27:21 steve
* Add support for REadOnlySync and monitors.
*
* Revision 1.6 2001/05/02 01:38:13 steve
* Describe a generic event a bit.
*

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.2 2001/06/21 23:05:08 steve Exp $"
#ident "$Id: vpi_callback.cc,v 1.3 2001/07/11 02:27:21 steve Exp $"
#endif
/*
@ -58,7 +58,11 @@ static struct __vpiCallback* make_value_change(p_cb_data data)
struct __vpiCallback*obj = new __vpiCallback;
obj->base.vpi_type = &callback_rt;
obj->cb_data = *data;
obj->cb_time = *(data->time);
obj->cb_data.time = &obj->cb_time;
assert(data->obj);
assert(data->obj->vpi_type);
assert((data->obj->vpi_type->type_code == vpiReg)
|| (data->obj->vpi_type->type_code == vpiNet));
struct __vpiSignal*sig = reinterpret_cast<__vpiSignal*>(data->obj);
@ -81,6 +85,45 @@ static struct __vpiCallback* make_value_change(p_cb_data data)
return obj;
}
struct sync_cb : public vvp_gen_event_s {
struct __vpiCallback*handle;
};
static void make_sync_run(vvp_gen_event_t obj, unsigned char)
{
struct sync_cb*cb = (struct sync_cb*)obj;
if (cb->handle == 0)
return;
struct __vpiCallback*cur = cb->handle;
cur->cb_data.time->type = vpiSimTime;
cur->cb_data.time->low = schedule_simtime();
cur->cb_data.time->high = 0;
(cur->cb_data.cb_rtn)(&cur->cb_data);
delete cur;
}
static struct __vpiCallback* make_sync(p_cb_data data)
{
struct __vpiCallback*obj = new __vpiCallback;
obj->base.vpi_type = &callback_rt;
obj->cb_data = *data;
obj->cb_time = *(data->time);
obj->cb_data.time = &obj->cb_time;
obj->next = 0;
struct sync_cb*cb = new sync_cb;
cb->sync_flag = true;
cb->run = &make_sync_run;
cb->handle = obj;
obj->cb_sync = cb;
schedule_generic(cb, 0, 0);
return obj;
}
vpiHandle vpi_register_cb(p_cb_data data)
{
struct __vpiCallback*obj = 0;
@ -91,6 +134,10 @@ vpiHandle vpi_register_cb(p_cb_data data)
obj = make_value_change(data);
break;
case cbReadOnlySynch:
obj = make_sync(data);
break;
default:
fprintf(stderr, "vpi error: vpi_register_cb invalid or "
"unsupported callback reason: %d\n",
@ -104,6 +151,8 @@ vpiHandle vpi_register_cb(p_cb_data data)
int vpi_remove_cb(vpiHandle ref)
{
assert(ref);
assert(ref->vpi_type);
assert(ref->vpi_type->type_code == vpiCallback);
struct __vpiCallback*obj = reinterpret_cast<__vpiCallback*>(ref);
@ -150,6 +199,9 @@ void vpip_trip_monitor_callbacks(void)
/*
* $Log: vpi_callback.cc,v $
* Revision 1.3 2001/07/11 02:27:21 steve
* Add support for REadOnlySync and monitors.
*
* Revision 1.2 2001/06/21 23:05:08 steve
* Some documentation of callback behavior.
*

View File

@ -17,7 +17,7 @@
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*/
#if !defined(WINNT)
#ident "$Id: vpi_priv.cc,v 1.7 2001/06/30 23:03:17 steve Exp $"
#ident "$Id: vpi_priv.cc,v 1.8 2001/07/11 02:27:21 steve Exp $"
#endif
# include "vpi_priv.h"
@ -55,12 +55,12 @@ static int vpip_get_global(int property)
int vpi_get(int property, vpiHandle ref)
{
if (property == vpiType)
return ref->vpi_type->type_code;
if (ref == 0)
return vpip_get_global(property);
if (property == vpiType)
return ref->vpi_type->type_code;
if (ref->vpi_type->vpi_get_ == 0)
return -1;
@ -151,6 +151,9 @@ extern "C" void vpi_sim_vcontrol(int operation, va_list ap)
/*
* $Log: vpi_priv.cc,v $
* Revision 1.8 2001/07/11 02:27:21 steve
* Add support for REadOnlySync and monitors.
*
* Revision 1.7 2001/06/30 23:03:17 steve
* support fast programming by only writing the bits
* that are listed in the input file.

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.18 2001/06/30 23:03:17 steve Exp $"
#ident "$Id: vpi_priv.h,v 1.19 2001/07/11 02:27:21 steve Exp $"
#endif
# include "vpi_user.h"
@ -125,10 +125,15 @@ extern struct __vpiSignal*vpip_sig_from_ptr(vvp_ipoint_t ptr);
* callback. The handle is stored by the run time, and it triggered
* when the run-time thing that it is waiting for happens.
*/
struct sync_cb;
struct __vpiCallback {
struct __vpiHandle base;
struct t_cb_data cb_data;
struct t_vpi_time cb_time;
struct sync_cb* cb_sync;
struct __vpiCallback*next;
};
@ -254,6 +259,9 @@ extern void vpip_set_time_precision(int pres);
/*
* $Log: vpi_priv.h,v $
* Revision 1.19 2001/07/11 02:27:21 steve
* Add support for REadOnlySync and monitors.
*
* Revision 1.18 2001/06/30 23:03:17 steve
* support fast programming by only writing the bits
* that are listed in the input file.