Implement cbAtStartOfSimTime callback.
(cherry picked from commit 1b7a42ffcd)
This commit is contained in:
parent
70f15b472f
commit
23ea74a126
|
|
@ -56,9 +56,18 @@ struct event_s {
|
|||
};
|
||||
|
||||
struct event_time_s {
|
||||
event_time_s() { count_time_events += 1; }
|
||||
event_time_s() {
|
||||
count_time_events += 1;
|
||||
start = 0;
|
||||
active = 0;
|
||||
nbassign = 0;
|
||||
rwsync = 0;
|
||||
rosync = 0;
|
||||
del_thr = 0;
|
||||
}
|
||||
vvp_time64_t delay;
|
||||
|
||||
struct event_s*start;
|
||||
struct event_s*active;
|
||||
struct event_s*nbassign;
|
||||
struct event_s*rwsync;
|
||||
|
|
@ -383,8 +392,8 @@ static void signals_revert(void)
|
|||
* itself, and the structure is placed in the right place in the
|
||||
* queue.
|
||||
*/
|
||||
typedef enum event_queue_e { SEQ_ACTIVE, SEQ_NBASSIGN, SEQ_RWSYNC, SEQ_ROSYNC,
|
||||
DEL_THREAD } event_queue_t;
|
||||
typedef enum event_queue_e { SEQ_START, SEQ_ACTIVE, SEQ_NBASSIGN,
|
||||
SEQ_RWSYNC, SEQ_ROSYNC, DEL_THREAD } event_queue_t;
|
||||
|
||||
static void schedule_event_(struct event_s*cur, vvp_time64_t delay,
|
||||
event_queue_t select_queue)
|
||||
|
|
@ -397,11 +406,6 @@ static void schedule_event_(struct event_s*cur, vvp_time64_t delay,
|
|||
/* Is the event_time list completely empty? Create the
|
||||
first event_time object. */
|
||||
ctim = new struct event_time_s;
|
||||
ctim->active = 0;
|
||||
ctim->nbassign = 0;
|
||||
ctim->rwsync = 0;
|
||||
ctim->rosync = 0;
|
||||
ctim->del_thr = 0;
|
||||
ctim->delay = delay;
|
||||
ctim->next = 0;
|
||||
sched_list = ctim;
|
||||
|
|
@ -411,11 +415,6 @@ static void schedule_event_(struct event_s*cur, vvp_time64_t delay,
|
|||
/* Am I looking for an event before the first event_time?
|
||||
If so, create a new event_time to go in front. */
|
||||
struct event_time_s*tmp = new struct event_time_s;
|
||||
tmp->active = 0;
|
||||
tmp->nbassign = 0;
|
||||
tmp->rwsync = 0;
|
||||
tmp->rosync = 0;
|
||||
tmp->del_thr = 0;
|
||||
tmp->delay = delay;
|
||||
tmp->next = ctim;
|
||||
ctim->delay -= delay;
|
||||
|
|
@ -433,11 +432,6 @@ static void schedule_event_(struct event_s*cur, vvp_time64_t delay,
|
|||
|
||||
if (ctim->delay > delay) {
|
||||
struct event_time_s*tmp = new struct event_time_s;
|
||||
tmp->active = 0;
|
||||
tmp->nbassign = 0;
|
||||
tmp->rwsync = 0;
|
||||
tmp->rosync = 0;
|
||||
tmp->del_thr = 0;
|
||||
tmp->delay = delay;
|
||||
tmp->next = prev->next;
|
||||
prev->next = tmp;
|
||||
|
|
@ -450,11 +444,6 @@ static void schedule_event_(struct event_s*cur, vvp_time64_t delay,
|
|||
} else {
|
||||
assert(ctim->next == 0);
|
||||
struct event_time_s*tmp = new struct event_time_s;
|
||||
tmp->active = 0;
|
||||
tmp->nbassign = 0;
|
||||
tmp->rwsync = 0;
|
||||
tmp->rosync = 0;
|
||||
tmp->del_thr = 0;
|
||||
tmp->delay = delay - ctim->delay;
|
||||
tmp->next = 0;
|
||||
ctim->next = tmp;
|
||||
|
|
@ -469,6 +458,16 @@ static void schedule_event_(struct event_s*cur, vvp_time64_t delay,
|
|||
|
||||
switch (select_queue) {
|
||||
|
||||
case SEQ_START:
|
||||
if (ctim->start == 0) {
|
||||
ctim->start = cur;
|
||||
} else {
|
||||
cur->next = ctim->active->next;
|
||||
ctim->active->next = cur;
|
||||
ctim->active = cur;
|
||||
}
|
||||
break;
|
||||
|
||||
case SEQ_ACTIVE:
|
||||
if (ctim->active == 0) {
|
||||
ctim->active = cur;
|
||||
|
|
@ -550,7 +549,6 @@ static void schedule_event_push_(struct event_s*cur)
|
|||
ctim->active->next = cur;
|
||||
}
|
||||
|
||||
|
||||
void schedule_vthread(vthread_t thr, vvp_time64_t delay, bool push_flag)
|
||||
{
|
||||
struct vthread_event_s*cur = new vthread_event_s;
|
||||
|
|
@ -673,6 +671,15 @@ void schedule_generic(vvp_gen_event_t obj, vvp_time64_t delay,
|
|||
sync_flag? (ro_flag?SEQ_ROSYNC:SEQ_RWSYNC) : SEQ_ACTIVE);
|
||||
}
|
||||
|
||||
void schedule_at_start_of_simtime(vvp_gen_event_t obj, vvp_time64_t delay)
|
||||
{
|
||||
struct generic_event_s*cur = new generic_event_s;
|
||||
|
||||
cur->obj = obj;
|
||||
cur->delete_obj_when_done = false;
|
||||
schedule_event_(cur, delay, SEQ_START);
|
||||
}
|
||||
|
||||
static vvp_time64_t schedule_time;
|
||||
vvp_time64_t schedule_simtime(void)
|
||||
{ return schedule_time; }
|
||||
|
|
@ -767,6 +774,17 @@ void schedule_simulate(void)
|
|||
ctim->delay = 0;
|
||||
|
||||
vpiNextSimTime();
|
||||
// Process the cbAtStartOfSimTime callbacks.
|
||||
while (ctim->start) {
|
||||
struct event_s*cur = ctim->start->next;
|
||||
if (cur->next == cur) {
|
||||
ctim->start = 0;
|
||||
} else {
|
||||
ctim->start->next = cur->next;
|
||||
}
|
||||
cur->run_run();
|
||||
delete (cur);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -103,6 +103,8 @@ extern void schedule_generic(vvp_gen_event_t obj, vvp_time64_t delay,
|
|||
bool sync_flag, bool ro_flag =true,
|
||||
bool delete_obj_when_done =false);
|
||||
|
||||
extern void schedule_at_start_of_simtime(vvp_gen_event_t obj, vvp_time64_t delay);
|
||||
|
||||
/* Use this is schedule thread deletion (after rosync). */
|
||||
extern void schedule_del_thr(vthread_t thr);
|
||||
|
||||
|
|
|
|||
|
|
@ -266,7 +266,7 @@ static struct __vpiCallback* make_sync(p_cb_data data, bool readonly_flag)
|
|||
return obj;
|
||||
}
|
||||
|
||||
static struct __vpiCallback* make_afterdelay(p_cb_data data)
|
||||
static struct __vpiCallback* make_afterdelay(p_cb_data data, bool simtime_flag)
|
||||
{
|
||||
struct __vpiCallback*obj = new_vpi_callback();
|
||||
obj->cb_data = *data;
|
||||
|
|
@ -281,19 +281,34 @@ static struct __vpiCallback* make_afterdelay(p_cb_data data)
|
|||
cb->handle = obj;
|
||||
obj->cb_sync = cb;
|
||||
|
||||
vvp_time64_t tv;
|
||||
switch (obj->cb_time.type) {
|
||||
case vpiSimTime: {
|
||||
vvp_time64_t tv = vpip_timestruct_to_time(&obj->cb_time);
|
||||
schedule_generic(cb, tv, false);
|
||||
break;
|
||||
}
|
||||
case vpiSimTime:
|
||||
tv = vpip_timestruct_to_time(&obj->cb_time);
|
||||
break;
|
||||
|
||||
default:
|
||||
fprintf(stderr, "Unsupported time type %d.\n", obj->cb_time.type);
|
||||
assert(0);
|
||||
tv = 0;
|
||||
break;
|
||||
}
|
||||
|
||||
if (simtime_flag) {
|
||||
vvp_time64_t cur = schedule_simtime();
|
||||
if (cur > tv) {
|
||||
tv = 0;
|
||||
assert(0);
|
||||
} else if (cur == tv) {
|
||||
tv = 0;
|
||||
} else {
|
||||
tv -= cur;
|
||||
}
|
||||
schedule_at_start_of_simtime(cb, tv);
|
||||
} else {
|
||||
schedule_generic(cb, tv, false);
|
||||
}
|
||||
|
||||
return obj;
|
||||
}
|
||||
|
||||
|
|
@ -432,8 +447,12 @@ vpiHandle vpi_register_cb(p_cb_data data)
|
|||
obj = make_sync(data, false);
|
||||
break;
|
||||
|
||||
case cbAtStartOfSimTime:
|
||||
obj = make_afterdelay(data, true);
|
||||
break;
|
||||
|
||||
case cbAfterDelay:
|
||||
obj = make_afterdelay(data);
|
||||
obj = make_afterdelay(data, false);
|
||||
break;
|
||||
|
||||
case cbEndOfCompile:
|
||||
|
|
|
|||
Loading…
Reference in New Issue