Fix for GitHub issue #106 - prevent VPI writes during read-only synch.
This commit is contained in:
parent
332170d36b
commit
8234f1845d
|
|
@ -1038,6 +1038,10 @@ extern void vpiStartOfSim();
|
|||
extern void vpiPostsim();
|
||||
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
|
||||
* current time. The ctim object is still in the event queue, because
|
||||
|
|
@ -1050,6 +1054,7 @@ extern void vpiNextSimTime(void);
|
|||
*/
|
||||
static void run_rosync(struct event_time_s*ctim)
|
||||
{
|
||||
sim_at_rosync = true;
|
||||
while (ctim->rosync) {
|
||||
struct event_s*cur = ctim->rosync->next;
|
||||
if (cur->next == cur) {
|
||||
|
|
@ -1061,6 +1066,7 @@ static void run_rosync(struct event_time_s*ctim)
|
|||
cur->run_run();
|
||||
delete cur;
|
||||
}
|
||||
sim_at_rosync = false;
|
||||
|
||||
while (ctim->del_thr) {
|
||||
struct event_s*cur = ctim->del_thr->next;
|
||||
|
|
|
|||
|
|
@ -164,6 +164,13 @@ extern void schedule_simulate(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
|
||||
* 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
|
||||
* 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;
|
||||
int scale;
|
||||
|
||||
if (vpi_get(vpiAutomatic, obj)) {
|
||||
fprintf(stderr, "vpi error: cannot put a value with "
|
||||
"a delay on automatically allocated "
|
||||
"variable '%s'\n",
|
||||
vpi_get_str(vpiName, obj));
|
||||
return 0;
|
||||
}
|
||||
if (vpi_get(vpiAutomatic, obj)) {
|
||||
fprintf(stderr, "VPI error: cannot put a value with "
|
||||
"a delay on automatically allocated "
|
||||
"variable '%s'.\n",
|
||||
vpi_get_str(vpiName, obj));
|
||||
return 0;
|
||||
}
|
||||
|
||||
assert(when != 0);
|
||||
|
||||
|
|
@ -1095,6 +1095,13 @@ vpiHandle vpi_put_value(vpiHandle obj, s_vpi_value*vp,
|
|||
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;
|
||||
put->handle = obj;
|
||||
put->value = *vp;
|
||||
|
|
@ -1132,6 +1139,13 @@ vpiHandle vpi_put_value(vpiHandle obj, s_vpi_value*vp,
|
|||
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);
|
||||
|
||||
return 0;
|
||||
|
|
|
|||
Loading…
Reference in New Issue