From 1cc084fc7a214e6b3ed30910e9cd9a0c81f25b2f Mon Sep 17 00:00:00 2001 From: Gabe Black Date: Thu, 30 Aug 2018 01:39:21 -0700 Subject: [PATCH] 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 Maintainer: Gabe Black --- src/systemc/channel/sc_clock.cc | 4 +++- src/systemc/core/sc_module.cc | 29 ++++++++++++++++++++++++++--- src/systemc/ext/core/sc_module.hh | 12 ++++++++---- 3 files changed, 37 insertions(+), 8 deletions(-) diff --git a/src/systemc/channel/sc_clock.cc b/src/systemc/channel/sc_clock.cc index 6736e57cf..7cdd1c1d1 100644 --- a/src/systemc/channel/sc_clock.cc +++ b/src/systemc/channel/sc_clock.cc @@ -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); } diff --git a/src/systemc/core/sc_module.cc b/src/systemc/core/sc_module.cc index bbb9993be..44e442d00 100644 --- a/src/systemc/core/sc_module.cc +++ b/src/systemc/core/sc_module.cc @@ -28,6 +28,7 @@ */ #include +#include #include #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; diff --git a/src/systemc/ext/core/sc_module.hh b/src/systemc/ext/core/sc_module.hh index 539d275ec..0e5e679c9 100644 --- a/src/systemc/ext/core/sc_module.hh +++ b/src/systemc/ext/core/sc_module.hh @@ -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 -- 2.30.2