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 cbExitInteractive 22
|
||||||
#define cbInteractiveScopeChange 23
|
#define cbInteractiveScopeChange 23
|
||||||
#define cbUnresolvedSystf 24
|
#define cbUnresolvedSystf 24
|
||||||
|
#define cbAtEndOfSimTime 31
|
||||||
|
|
||||||
extern vpiHandle vpi_register_cb(p_cb_data data);
|
extern vpiHandle vpi_register_cb(p_cb_data data);
|
||||||
extern PLI_INT32 vpi_remove_cb(vpiHandle ref);
|
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);
|
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;
|
static vvp_time64_t schedule_time;
|
||||||
vvp_time64_t schedule_simtime(void)
|
vvp_time64_t schedule_simtime(void)
|
||||||
{ return schedule_time; }
|
{ 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_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_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). */
|
/* Use this is schedule thread deletion (after rosync). */
|
||||||
extern void schedule_del_thr(vthread_t thr);
|
extern void schedule_del_thr(vthread_t thr);
|
||||||
|
|
|
||||||
|
|
@ -357,7 +357,33 @@ static sync_callback* make_sync(p_cb_data data, bool readonly_flag)
|
||||||
return obj;
|
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;
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
|
||||||
|
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);
|
sync_callback*obj = new sync_callback(data);
|
||||||
struct sync_cb*cb = new sync_cb;
|
struct sync_cb*cb = new sync_cb;
|
||||||
|
|
@ -378,7 +404,6 @@ static struct __vpiCallback* make_afterdelay(p_cb_data data, bool simtime_flag)
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (simtime_flag) {
|
|
||||||
vvp_time64_t cur = schedule_simtime();
|
vvp_time64_t cur = schedule_simtime();
|
||||||
if (cur > tv) {
|
if (cur > tv) {
|
||||||
tv = 0;
|
tv = 0;
|
||||||
|
|
@ -389,10 +414,42 @@ static struct __vpiCallback* make_afterdelay(p_cb_data data, bool simtime_flag)
|
||||||
tv -= cur;
|
tv -= cur;
|
||||||
}
|
}
|
||||||
schedule_at_start_of_simtime(cb, tv);
|
schedule_at_start_of_simtime(cb, tv);
|
||||||
} else {
|
|
||||||
schedule_generic(cb, tv, false);
|
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;
|
return obj;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -573,11 +630,15 @@ vpiHandle vpi_register_cb(p_cb_data data)
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case cbAtStartOfSimTime:
|
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;
|
break;
|
||||||
|
|
||||||
case cbAfterDelay:
|
case cbAfterDelay:
|
||||||
obj = make_afterdelay(data, false);
|
obj = make_afterdelay(data);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case cbEndOfCompile:
|
case cbEndOfCompile:
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue