systemc: Raise an error when SC_METHOD, etc. is used after starting.

Those mechanisms for creating processes are only allowed before the
end of elaboration, or in other words before sc_start is called.
Technically the check in Accellera's implementation won't trigger if
the simulation is stopped, and we immitate that behavior.

Change-Id: I9b8b5bd32f876781b6e0d5c0ee0e09de19bdabc1
Reviewed-on: https://gem5-review.googlesource.com/c/12447
Reviewed-by: Gabe Black <gabeblack@google.com>
Maintainer: Gabe Black <gabeblack@google.com>
This commit is contained in:
Gabe Black
2018-08-30 01:39:21 -07:00
parent 475e8cd580
commit 1cc084fc7a
3 changed files with 37 additions and 8 deletions

View File

@@ -32,6 +32,7 @@
#include "sim/core.hh"
#include "sim/eventq.hh"
#include "systemc/core/kernel.hh"
#include "systemc/core/process_types.hh"
#include "systemc/core/sched_event.hh"
#include "systemc/core/scheduler.hh"
#include "systemc/ext/channel/sc_clock.hh"
@@ -60,7 +61,8 @@ class ClockTick : public ScEvent
{
_name += (to ? ".up_tick" : ".down_tick");
_procName = _name + ".p";
p = newMethodProcess(_procName.c_str(), &funcWrapper);
p = new Method(_procName.c_str(), &funcWrapper);
scheduler.reg(p);
scheduler.dontInitialize(p);
}

View File

@@ -28,6 +28,7 @@
*/
#include <memory>
#include <string>
#include <vector>
#include "base/logging.hh"
@@ -36,6 +37,7 @@
#include "systemc/core/process_types.hh"
#include "systemc/ext/core/sc_module.hh"
#include "systemc/ext/core/sc_module_name.hh"
#include "systemc/ext/utils/sc_report_handler.hh"
namespace sc_gem5
{
@@ -43,7 +45,14 @@ namespace sc_gem5
Process *
newMethodProcess(const char *name, ProcessFuncWrapper *func)
{
Process *p = new Method(name, func);
Method *p = new Method(name, func);
if (::sc_core::sc_is_running()) {
std::string name = p->name();
delete p;
SC_REPORT_ERROR("(E541) call to SC_METHOD in sc_module while "
"simulation running", name.c_str());
return nullptr;
}
scheduler.reg(p);
return p;
}
@@ -51,7 +60,14 @@ newMethodProcess(const char *name, ProcessFuncWrapper *func)
Process *
newThreadProcess(const char *name, ProcessFuncWrapper *func)
{
Process *p = new Thread(name, func);
Thread *p = new Thread(name, func);
if (::sc_core::sc_is_running()) {
std::string name = p->name();
delete p;
SC_REPORT_ERROR("(E542) call to SC_THREAD in sc_module while "
"simulation running", name.c_str());
return nullptr;
}
scheduler.reg(p);
return p;
}
@@ -59,7 +75,14 @@ newThreadProcess(const char *name, ProcessFuncWrapper *func)
Process *
newCThreadProcess(const char *name, ProcessFuncWrapper *func)
{
Process *p = new CThread(name, func);
CThread *p = new CThread(name, func);
if (::sc_core::sc_is_running()) {
std::string name = p->name();
delete p;
SC_REPORT_ERROR("(E543) call to SC_CTHREAD in sc_module while "
"simulation running", name.c_str());
return nullptr;
}
scheduler.reg(p);
p->dontInitialize();
return p;

View File

@@ -289,7 +289,8 @@ bool timed_out();
#name, new ::sc_gem5::ProcessMemberFuncWrapper< \
SC_CURRENT_USER_MODULE>(this, \
&SC_CURRENT_USER_MODULE::name)); \
this->sensitive << p; \
if (p) \
this->sensitive << p; \
}
#define SC_THREAD(name) \
{ \
@@ -298,7 +299,8 @@ bool timed_out();
#name, new ::sc_gem5::ProcessMemberFuncWrapper< \
SC_CURRENT_USER_MODULE>(this, \
&SC_CURRENT_USER_MODULE::name)); \
this->sensitive << p; \
if (p) \
this->sensitive << p; \
}
#define SC_CTHREAD(name, clk) \
{ \
@@ -307,8 +309,10 @@ bool timed_out();
#name, new ::sc_gem5::ProcessMemberFuncWrapper< \
SC_CURRENT_USER_MODULE>(this, \
&SC_CURRENT_USER_MODULE::name)); \
this->sensitive << p; \
this->sensitive << clk; \
if (p) { \
this->sensitive << p; \
this->sensitive << clk; \
} \
}
// Nonstandard