Make a pass at implementing cbAtEndOfSimTime.
In Icarus Verilog, AtEndOfSimTime is practically the same as cbReadWriteSync, since the latter is after non-blocking events in Icarus Verilog.
This commit is contained in:
parent
b25df08c99
commit
7f95abc6ab
|
|
@ -495,6 +495,7 @@ typedef struct t_cb_data {
|
|||
#define cbExitInteractive 22
|
||||
#define cbInteractiveScopeChange 23
|
||||
#define cbUnresolvedSystf 24
|
||||
#define cbAtEndOfSimTime 31
|
||||
|
||||
extern vpiHandle vpi_register_cb(p_cb_data data);
|
||||
extern PLI_INT32 vpi_remove_cb(vpiHandle ref);
|
||||
|
|
|
|||
|
|
@ -1029,6 +1029,20 @@ void schedule_at_start_of_simtime(vvp_gen_event_t obj, vvp_time64_t delay)
|
|||
schedule_event_(cur, delay, SEQ_START);
|
||||
}
|
||||
|
||||
/*
|
||||
* In the vvp runtime of Icarus Verilog, the SEQ_RWSYNC time step is
|
||||
* after all of the non-blocking assignments, so is effectively the
|
||||
* same as the ReadWriteSync time.
|
||||
*/
|
||||
void schedule_at_end_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_RWSYNC);
|
||||
}
|
||||
|
||||
static vvp_time64_t schedule_time;
|
||||
vvp_time64_t schedule_simtime(void)
|
||||
{ return schedule_time; }
|
||||
|
|
|
|||
|
|
@ -148,6 +148,7 @@ extern void schedule_generic(vvp_gen_event_t obj, vvp_time64_t delay,
|
|||
extern void schedule_functor(vvp_gen_event_t obj);
|
||||
|
||||
extern void schedule_at_start_of_simtime(vvp_gen_event_t obj, vvp_time64_t delay);
|
||||
extern void schedule_at_end_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);
|
||||
|
|
|
|||
|
|
@ -357,7 +357,7 @@ static sync_callback* make_sync(p_cb_data data, bool readonly_flag)
|
|||
return obj;
|
||||
}
|
||||
|
||||
static struct __vpiCallback* make_afterdelay(p_cb_data data, bool simtime_flag)
|
||||
static struct __vpiCallback* make_afterdelay(p_cb_data data)
|
||||
{
|
||||
sync_callback*obj = new sync_callback(data);
|
||||
struct sync_cb*cb = new sync_cb;
|
||||
|
|
@ -378,21 +378,78 @@ static struct __vpiCallback* make_afterdelay(p_cb_data data, bool simtime_flag)
|
|||
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);
|
||||
schedule_generic(cb, tv, false);
|
||||
|
||||
return obj;
|
||||
}
|
||||
|
||||
static struct __vpiCallback* make_at_start_of_sim_time(p_cb_data data)
|
||||
{
|
||||
sync_callback*obj = new sync_callback(data);
|
||||
struct sync_cb*cb = new sync_cb;
|
||||
cb->sync_flag = false;
|
||||
cb->handle = obj;
|
||||
obj->cb_sync = cb;
|
||||
|
||||
vvp_time64_t tv = 0;
|
||||
switch (obj->cb_time.type) {
|
||||
case vpiSimTime:
|
||||
tv = vpip_timestruct_to_time(&obj->cb_time);
|
||||
break;
|
||||
|
||||
default:
|
||||
fprintf(stderr, "Unsupported time type %d.\n",
|
||||
(int)obj->cb_time.type);
|
||||
assert(0);
|
||||
break;
|
||||
}
|
||||
|
||||
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);
|
||||
|
||||
return obj;
|
||||
}
|
||||
|
||||
static struct __vpiCallback* make_at_end_of_sim_time(p_cb_data data)
|
||||
{
|
||||
sync_callback*obj = new sync_callback(data);
|
||||
struct sync_cb*cb = new sync_cb;
|
||||
cb->sync_flag = false;
|
||||
cb->handle = obj;
|
||||
obj->cb_sync = cb;
|
||||
|
||||
vvp_time64_t tv = 0;
|
||||
switch (obj->cb_time.type) {
|
||||
case vpiSimTime:
|
||||
tv = vpip_timestruct_to_time(&obj->cb_time);
|
||||
break;
|
||||
|
||||
default:
|
||||
fprintf(stderr, "Unsupported time type %d.\n",
|
||||
(int)obj->cb_time.type);
|
||||
assert(0);
|
||||
break;
|
||||
}
|
||||
|
||||
vvp_time64_t cur = schedule_simtime();
|
||||
if (cur > tv) {
|
||||
tv = 0;
|
||||
assert(0);
|
||||
} else if (cur == tv) {
|
||||
tv = 0;
|
||||
} else {
|
||||
tv -= cur;
|
||||
}
|
||||
schedule_at_end_of_simtime(cb, tv);
|
||||
|
||||
return obj;
|
||||
}
|
||||
|
||||
|
|
@ -573,11 +630,15 @@ vpiHandle vpi_register_cb(p_cb_data data)
|
|||
break;
|
||||
|
||||
case cbAtStartOfSimTime:
|
||||
obj = make_afterdelay(data, true);
|
||||
obj = make_at_start_of_sim_time(data);
|
||||
break;
|
||||
|
||||
case cbAtEndOfSimTime:
|
||||
obj = make_at_end_of_sim_time(data);
|
||||
break;
|
||||
|
||||
case cbAfterDelay:
|
||||
obj = make_afterdelay(data, false);
|
||||
obj = make_afterdelay(data);
|
||||
break;
|
||||
|
||||
case cbEndOfCompile:
|
||||
|
|
|
|||
Loading…
Reference in New Issue