Fix for GitHub issue #106 - prevent VPI writes during read-only synch.
(cherry picked from commit 8234f1845d)
This commit is contained in:
parent
27a46f4afe
commit
86968e3752
|
|
@ -949,6 +949,10 @@ extern void vpiStartOfSim();
|
||||||
extern void vpiPostsim();
|
extern void vpiPostsim();
|
||||||
extern void vpiNextSimTime(void);
|
extern void vpiNextSimTime(void);
|
||||||
|
|
||||||
|
static bool sim_at_rosync = false;
|
||||||
|
bool schedule_at_rosync(void)
|
||||||
|
{ return sim_at_rosync; }
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* The scheduler uses this function to drain the rosync events of the
|
* The scheduler uses this function to drain the rosync events of the
|
||||||
* current time. The ctim object is still in the event queue, because
|
* current time. The ctim object is still in the event queue, because
|
||||||
|
|
@ -961,6 +965,7 @@ extern void vpiNextSimTime(void);
|
||||||
*/
|
*/
|
||||||
static void run_rosync(struct event_time_s*ctim)
|
static void run_rosync(struct event_time_s*ctim)
|
||||||
{
|
{
|
||||||
|
sim_at_rosync = true;
|
||||||
while (ctim->rosync) {
|
while (ctim->rosync) {
|
||||||
struct event_s*cur = ctim->rosync->next;
|
struct event_s*cur = ctim->rosync->next;
|
||||||
if (cur->next == cur) {
|
if (cur->next == cur) {
|
||||||
|
|
@ -972,6 +977,7 @@ static void run_rosync(struct event_time_s*ctim)
|
||||||
cur->run_run();
|
cur->run_run();
|
||||||
delete cur;
|
delete cur;
|
||||||
}
|
}
|
||||||
|
sim_at_rosync = false;
|
||||||
|
|
||||||
while (ctim->del_thr) {
|
while (ctim->del_thr) {
|
||||||
struct event_s*cur = ctim->del_thr->next;
|
struct event_s*cur = ctim->del_thr->next;
|
||||||
|
|
|
||||||
|
|
@ -155,6 +155,13 @@ extern void schedule_simulate(void);
|
||||||
*/
|
*/
|
||||||
extern vvp_time64_t schedule_simtime(void);
|
extern vvp_time64_t schedule_simtime(void);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Indicate that the simulator is running the rosync callbacks. This is
|
||||||
|
* used to prevent the callbacks from performing any write operations
|
||||||
|
* in the current simulation time slot.
|
||||||
|
*/
|
||||||
|
extern bool schedule_at_rosync(void);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* This function is the equivalent of the $finish system task. It
|
* This function is the equivalent of the $finish system task. It
|
||||||
* tells the simulator that simulation is done, the current thread
|
* tells the simulator that simulation is done, the current thread
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 2008-2015 Stephen Williams (steve@icarus.com)
|
* Copyright (c) 2008-2016 Stephen Williams (steve@icarus.com)
|
||||||
*
|
*
|
||||||
* This source code is free software; you can redistribute it
|
* This source code is free software; you can redistribute it
|
||||||
* and/or modify it in source code form under the terms of the GNU
|
* and/or modify it in source code form under the terms of the GNU
|
||||||
|
|
@ -1067,13 +1067,13 @@ vpiHandle vpi_put_value(vpiHandle obj, s_vpi_value*vp,
|
||||||
vvp_time64_t dly;
|
vvp_time64_t dly;
|
||||||
int scale;
|
int scale;
|
||||||
|
|
||||||
if (vpi_get(vpiAutomatic, obj)) {
|
if (vpi_get(vpiAutomatic, obj)) {
|
||||||
fprintf(stderr, "vpi error: cannot put a value with "
|
fprintf(stderr, "VPI error: cannot put a value with "
|
||||||
"a delay on automatically allocated "
|
"a delay on automatically allocated "
|
||||||
"variable '%s'\n",
|
"variable '%s'.\n",
|
||||||
vpi_get_str(vpiName, obj));
|
vpi_get_str(vpiName, obj));
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
assert(when != 0);
|
assert(when != 0);
|
||||||
|
|
||||||
|
|
@ -1095,6 +1095,13 @@ vpiHandle vpi_put_value(vpiHandle obj, s_vpi_value*vp,
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if ((dly == 0) && schedule_at_rosync()) {
|
||||||
|
fprintf(stderr, "VPI error: attempted to put a value to "
|
||||||
|
"variable '%s' during a read-only synch "
|
||||||
|
"callback.\n", vpi_get_str(vpiName, obj));
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
vpip_put_value_event*put = new vpip_put_value_event;
|
vpip_put_value_event*put = new vpip_put_value_event;
|
||||||
put->handle = obj;
|
put->handle = obj;
|
||||||
put->value = *vp;
|
put->value = *vp;
|
||||||
|
|
@ -1132,6 +1139,13 @@ vpiHandle vpi_put_value(vpiHandle obj, s_vpi_value*vp,
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (schedule_at_rosync()) {
|
||||||
|
fprintf(stderr, "VPI error: attempted to put a value to "
|
||||||
|
"variable '%s' during a read-only synch "
|
||||||
|
"callback.\n", vpi_get_str(vpiName, obj));
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
obj->vpi_put_value(vp, flags);
|
obj->vpi_put_value(vp, flags);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue