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 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*/ */
#if !defined(WINNT) #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 #endif
# include "arith.h" # 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) void vvp_arith_sum::set(vvp_ipoint_t i, functor_t f, bool push)
{ {
assert(wid_ <= 8*sizeof(unsigned long));
unsigned page = 0; unsigned page = 0;
unsigned pbit = 0; unsigned pbit = 0;
unsigned long carry = 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 $ * $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 * Revision 1.9 2001/07/07 02:57:33 steve
* Add the .shift/r functor. * Add the .shift/r functor.
* *

View File

@ -18,7 +18,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: 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 #endif
#include "memory.h" #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)); cur = (struct mem_assign_s*) malloc(sizeof(struct mem_assign_s));
else else
ma_free_list = cur->next; ma_free_list = cur->next;
cur->sync_flag = false;
return cur; return cur;
} }

View File

@ -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: 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 #endif
# include "schedule.h" # include "schedule.h"
@ -27,6 +27,7 @@
# include <malloc.h> # include <malloc.h>
# include <assert.h> # include <assert.h>
# include <stdio.h>
/* /*
* The event queue is arranged as a skip list, with the simulation * 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 * 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 * 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 /* If the list is completely empty, then start the list with
this the only event. */ this the only event. */
if (list == 0) { if (sched_list == 0) {
list = cur; sched_list = cur;
cur->next = 0; cur->next = 0;
return; return;
} }
struct event_s*idx = list; struct event_s*idx = sched_list;
if (cur->delay < idx->delay) { if (cur->delay < idx->delay) {
/* If this new event is earlier then even the first /* If this new event is earlier then even the first
event, then insert it in front. Adjust the delay of event, then insert it in front. Adjust the delay of
the next event, and set the start to me. */ the next event, and set the start to me. */
idx->delay -= cur->delay; idx->delay -= cur->delay;
cur->next = idx; cur->next = idx;
list = cur; sched_list = cur;
} else { } 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) void schedule_vthread(vthread_t thr, unsigned delay)
{ {
struct event_s*cur = e_alloc(); struct event_s*cur = e_alloc();
@ -228,30 +277,47 @@ void schedule_simulate(void)
{ {
schedule_time = 0; schedule_time = 0;
while (schedule_runnable && list) { while (schedule_runnable && sched_list) {
/* Pull the first item off the list. Fixup the last /* Pull the first item off the list. Fixup the last
pointer in the next cell, if necessary. */ pointer in the next cell, if necessary. */
struct event_s*cur = list; struct event_s*cur = sched_list;
list = cur->next; sched_list = cur->next;
if (cur->last != cur) { if (cur->last != cur) {
assert(list); assert(sched_list);
assert(list->delay == 0); assert(sched_list->delay == 0);
list->last = cur->last; sched_list->last = cur->last;
} }
schedule_time += cur->delay; /* If the time is advancing, then first run the
//printf("TIME: %u\n", schedule_time); 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) { switch (cur->type) {
case TYPE_THREAD: case TYPE_THREAD:
vthread_run(cur->thr); vthread_run(cur->thr);
e_free(cur);
break; break;
case TYPE_PROP: case TYPE_PROP:
//printf("Propagate %p\n", cur->fun); //printf("Propagate %p\n", cur->fun);
functor_propagate(cur->fun); functor_propagate(cur->fun);
e_free(cur);
break; break;
case TYPE_ASSIGN: case TYPE_ASSIGN:
@ -269,21 +335,31 @@ void schedule_simulate(void)
functor_set(cur->fun, cur->val, HiZ, false); functor_set(cur->fun, cur->val, HiZ, false);
break; break;
} }
e_free(cur);
break; break;
case TYPE_GEN: case TYPE_GEN:
if (cur->obj && cur->obj->run) if (cur->obj && cur->obj->run) {
cur->obj->run(cur->obj, cur->val); if (cur->obj->sync_flag == false) {
cur->obj->run(cur->obj, cur->val);
e_free(cur);
} else {
postpone_sync_event(cur);
}
}
break; break;
} }
e_free(cur);
} }
} }
/* /*
* $Log: schedule.cc,v $ * $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 * Revision 1.10 2001/05/30 03:02:35 steve
* Propagate strength-values instead of drive strengths. * 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 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*/ */
#if !defined(WINNT) #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 #endif
# include "vthread.h" # include "vthread.h"
@ -63,7 +63,8 @@ extern void schedule_generic(vvp_gen_event_t obj, unsigned char val,
struct vvp_gen_event_s struct vvp_gen_event_s
{ {
void (*run)(vvp_gen_event_t obj, unsigned char val); 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 $ * $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 * Revision 1.6 2001/05/02 01:38:13 steve
* Describe a generic event a bit. * Describe a generic event a bit.
* *

View File

@ -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_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 #endif
/* /*
@ -58,7 +58,11 @@ static struct __vpiCallback* make_value_change(p_cb_data data)
struct __vpiCallback*obj = new __vpiCallback; struct __vpiCallback*obj = new __vpiCallback;
obj->base.vpi_type = &callback_rt; obj->base.vpi_type = &callback_rt;
obj->cb_data = *data; 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) assert((data->obj->vpi_type->type_code == vpiReg)
|| (data->obj->vpi_type->type_code == vpiNet)); || (data->obj->vpi_type->type_code == vpiNet));
struct __vpiSignal*sig = reinterpret_cast<__vpiSignal*>(data->obj); struct __vpiSignal*sig = reinterpret_cast<__vpiSignal*>(data->obj);
@ -81,6 +85,45 @@ static struct __vpiCallback* make_value_change(p_cb_data data)
return obj; 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) vpiHandle vpi_register_cb(p_cb_data data)
{ {
struct __vpiCallback*obj = 0; struct __vpiCallback*obj = 0;
@ -91,6 +134,10 @@ vpiHandle vpi_register_cb(p_cb_data data)
obj = make_value_change(data); obj = make_value_change(data);
break; break;
case cbReadOnlySynch:
obj = make_sync(data);
break;
default: default:
fprintf(stderr, "vpi error: vpi_register_cb invalid or " fprintf(stderr, "vpi error: vpi_register_cb invalid or "
"unsupported callback reason: %d\n", "unsupported callback reason: %d\n",
@ -104,6 +151,8 @@ vpiHandle vpi_register_cb(p_cb_data data)
int vpi_remove_cb(vpiHandle ref) int vpi_remove_cb(vpiHandle ref)
{ {
assert(ref);
assert(ref->vpi_type);
assert(ref->vpi_type->type_code == vpiCallback); assert(ref->vpi_type->type_code == vpiCallback);
struct __vpiCallback*obj = reinterpret_cast<__vpiCallback*>(ref); struct __vpiCallback*obj = reinterpret_cast<__vpiCallback*>(ref);
@ -150,6 +199,9 @@ void vpip_trip_monitor_callbacks(void)
/* /*
* $Log: vpi_callback.cc,v $ * $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 * Revision 1.2 2001/06/21 23:05:08 steve
* Some documentation of callback behavior. * Some documentation of callback behavior.
* *

View File

@ -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_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 #endif
# include "vpi_priv.h" # include "vpi_priv.h"
@ -55,12 +55,12 @@ static int vpip_get_global(int property)
int vpi_get(int property, vpiHandle ref) int vpi_get(int property, vpiHandle ref)
{ {
if (property == vpiType)
return ref->vpi_type->type_code;
if (ref == 0) if (ref == 0)
return vpip_get_global(property); return vpip_get_global(property);
if (property == vpiType)
return ref->vpi_type->type_code;
if (ref->vpi_type->vpi_get_ == 0) if (ref->vpi_type->vpi_get_ == 0)
return -1; return -1;
@ -151,6 +151,9 @@ extern "C" void vpi_sim_vcontrol(int operation, va_list ap)
/* /*
* $Log: vpi_priv.cc,v $ * $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 * Revision 1.7 2001/06/30 23:03:17 steve
* support fast programming by only writing the bits * support fast programming by only writing the bits
* that are listed in the input file. * 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 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*/ */
#if !defined(WINNT) #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 #endif
# include "vpi_user.h" # 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 * callback. The handle is stored by the run time, and it triggered
* when the run-time thing that it is waiting for happens. * when the run-time thing that it is waiting for happens.
*/ */
struct sync_cb;
struct __vpiCallback { struct __vpiCallback {
struct __vpiHandle base; struct __vpiHandle base;
struct t_cb_data cb_data; struct t_cb_data cb_data;
struct t_vpi_time cb_time;
struct sync_cb* cb_sync;
struct __vpiCallback*next; struct __vpiCallback*next;
}; };
@ -254,6 +259,9 @@ extern void vpip_set_time_precision(int pres);
/* /*
* $Log: vpi_priv.h,v $ * $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 * Revision 1.18 2001/06/30 23:03:17 steve
* support fast programming by only writing the bits * support fast programming by only writing the bits
* that are listed in the input file. * that are listed in the input file.