systemc: Centralize module callbacks and report new warnings.
authorGabe Black <gabeblack@google.com>
Sat, 8 Sep 2018 01:25:10 +0000 (18:25 -0700)
committerGabe Black <gabeblack@google.com>
Tue, 9 Oct 2018 21:44:00 +0000 (21:44 +0000)
By centralizing module callbacks, the gem5 module class knows when
different stages of the simulation are happening and can do it's own
extra checks. It also compartmentalizes modules more since the kernel
object doesn't have to reach into them to enumerate ports and exports.

Change-Id: I55887284af9c05150fe9d054f5b6147cad6092a1
Reviewed-on: https://gem5-review.googlesource.com/c/12610
Reviewed-by: Gabe Black <gabeblack@google.com>
Maintainer: Gabe Black <gabeblack@google.com>

src/systemc/core/kernel.cc
src/systemc/core/module.cc
src/systemc/core/module.hh
src/systemc/core/sc_module.cc
src/systemc/ext/core/sc_export.hh
src/systemc/ext/core/sc_module.hh
src/systemc/tests/verify.py

index dc5a861484f946a782f80c4d1fa960f8a07e9c0c..ca99e19320d302f1659ef84faa77cda2451fd518 100644 (file)
@@ -75,15 +75,8 @@ Kernel::init()
         fatal("Simulation called sc_stop during elaboration.\n");
 
     status(::sc_core::SC_BEFORE_END_OF_ELABORATION);
-    for (auto m: sc_gem5::allModules) {
-        callbackModule(m);
-        m->sc_mod()->before_end_of_elaboration();
-        for (auto p: m->ports)
-            p->before_end_of_elaboration();
-        for (auto e: m->exports)
-            e->before_end_of_elaboration();
-    }
-    callbackModule(nullptr);
+    for (auto m: sc_gem5::allModules)
+        m->beforeEndOfElaboration();
     for (auto c: sc_gem5::allChannels)
         c->sc_chan()->before_end_of_elaboration();
 }
@@ -100,15 +93,8 @@ Kernel::regStats()
                 p->_gem5Finalize();
 
         status(::sc_core::SC_END_OF_ELABORATION);
-        for (auto m: sc_gem5::allModules) {
-            callbackModule(m);
-            m->sc_mod()->end_of_elaboration();
-            for (auto p: m->ports)
-                p->end_of_elaboration();
-            for (auto e: m->exports)
-                e->end_of_elaboration();
-        }
-        callbackModule(nullptr);
+        for (auto m: sc_gem5::allModules)
+            m->endOfElaboration();
         for (auto c: sc_gem5::allChannels)
             c->sc_chan()->end_of_elaboration();
     } catch (...) {
@@ -131,14 +117,8 @@ Kernel::startup()
 
     try {
         status(::sc_core::SC_START_OF_SIMULATION);
-        for (auto m: sc_gem5::allModules) {
-            m->sc_mod()->start_of_simulation();
-            for (auto p: m->ports)
-                p->start_of_simulation();
-            for (auto e: m->exports)
-                e->start_of_simulation();
-        }
-        callbackModule(nullptr);
+        for (auto m: sc_gem5::allModules)
+            m->startOfSimulation();
         for (auto c: sc_gem5::allChannels)
             c->sc_chan()->start_of_simulation();
     } catch (...) {
@@ -167,14 +147,8 @@ Kernel::stopWork()
 {
     status(::sc_core::SC_END_OF_SIMULATION);
     try {
-        for (auto m: sc_gem5::allModules) {
-            m->sc_mod()->end_of_simulation();
-            for (auto p: m->ports)
-                p->end_of_simulation();
-            for (auto e: m->exports)
-                e->end_of_simulation();
-        }
-        callbackModule(nullptr);
+        for (auto m: sc_gem5::allModules)
+            m->endOfSimulation();
         for (auto c: sc_gem5::allChannels)
             c->sc_chan()->end_of_simulation();
     } catch (...) {
index 78ce2c6fbd14bad7c8aa6ca8a4548ab43c618c58..dcd6faa53aa810706463d9d6c18881018cfda175 100644 (file)
@@ -32,6 +32,7 @@
 #include <cassert>
 
 #include "base/logging.hh"
+#include "systemc/ext/core/sc_export.hh"
 #include "systemc/ext/core/sc_port.hh"
 #include "systemc/ext/utils/sc_report_handler.hh"
 
@@ -48,7 +49,9 @@ Module *_callbackModule = nullptr;
 
 } // anonymous namespace
 
-Module::Module(const char *name) : _name(name), _sc_mod(nullptr), _obj(nullptr)
+Module::Module(const char *name) :
+    _name(name), _sc_mod(nullptr), _obj(nullptr), _ended(false),
+    _deprecatedConstructor(false)
 {
     panic_if(_new_module, "Previous module not finished.\n");
     _new_module = this;
@@ -105,6 +108,60 @@ Module::bindPorts(std::vector<const ::sc_core::sc_bind_proxy *> &proxies)
     }
 }
 
+void
+Module::beforeEndOfElaboration()
+{
+    callbackModule(this);
+    _sc_mod->before_end_of_elaboration();
+    for (auto p: ports)
+        p->before_end_of_elaboration();
+    for (auto e: exports)
+        e->before_end_of_elaboration();
+    callbackModule(nullptr);
+}
+
+void
+Module::endOfElaboration()
+{
+    if (_deprecatedConstructor && !_ended) {
+        std::string msg = csprintf("module '%s'", name());
+        SC_REPORT_WARNING("(W509) module construction not properly completed: "
+                "did you forget to add a sc_module_name parameter to "
+                "your module constructor?", msg.c_str());
+    }
+    callbackModule(this);
+    _sc_mod->end_of_elaboration();
+    for (auto p: ports)
+        p->end_of_elaboration();
+    for (auto e: exports)
+        e->end_of_elaboration();
+    callbackModule(nullptr);
+}
+
+void
+Module::startOfSimulation()
+{
+    callbackModule(this);
+    _sc_mod->start_of_simulation();
+    for (auto p: ports)
+        p->start_of_simulation();
+    for (auto e: exports)
+        e->start_of_simulation();
+    callbackModule(nullptr);
+}
+
+void
+Module::endOfSimulation()
+{
+    callbackModule(this);
+    _sc_mod->end_of_simulation();
+    for (auto p: ports)
+        p->end_of_simulation();
+    for (auto e: exports)
+        e->end_of_simulation();
+    callbackModule(nullptr);
+}
+
 Module *
 currentModule()
 {
index e60018e2b9aae147e33a9b6aa4e304be9b10b034..aa723368a7aece91aec691934fd203957b924028 100644 (file)
@@ -74,6 +74,8 @@ class Module
     const char *_name;
     sc_core::sc_module *_sc_mod;
     Object *_obj;
+    bool _ended;
+    bool _deprecatedConstructor;
 
     UniqueNameGen nameGen;
 
@@ -85,6 +87,8 @@ class Module
     void finish(Object *this_obj);
 
     const char *name() const { return _name; }
+    void endModule() { _ended = true; }
+    void deprecatedConstructor() { _deprecatedConstructor = true; }
 
     sc_core::sc_module *
     sc_mod() const
@@ -115,6 +119,11 @@ class Module
 
     std::vector<::sc_core::sc_port_base *> ports;
     std::vector<::sc_core::sc_export_base *> exports;
+
+    void beforeEndOfElaboration();
+    void endOfElaboration();
+    void startOfSimulation();
+    void endOfSimulation();
 };
 
 Module *currentModule();
index 3cceff119a9537aac34380f9f9025c7d765b21f9..2fc6e8c75c8150bb223a163980ce5d6b1c74d1b0 100644 (file)
@@ -221,10 +221,27 @@ sc_module::sc_module() :
 {}
 
 sc_module::sc_module(const sc_module_name &) : sc_module() {}
-sc_module::sc_module(const char *_name) : sc_module(sc_module_name(_name)) {}
+sc_module::sc_module(const char *_name) : sc_module(sc_module_name(_name))
+{
+    _gem5_module->deprecatedConstructor();
+    SC_REPORT_WARNING("(W569) sc_module(const char*), "
+            "sc_module(const std::string&) have been deprecated, use "
+            "sc_module(const sc_module_name&)", _name);
+}
 sc_module::sc_module(const std::string &_name) :
     sc_module(sc_module_name(_name.c_str()))
-{}
+{
+    _gem5_module->deprecatedConstructor();
+    SC_REPORT_WARNING("(W569) sc_module(const char*), "
+            "sc_module(const std::string&) have been deprecated, use "
+            "sc_module(const sc_module_name&)", _name.c_str());
+}
+
+void
+sc_module::end_module()
+{
+    _gem5_module->endModule();
+}
 
 void
 sc_module::reset_signal_is(const sc_in<bool> &, bool)
index f5ce894b87bc53b8f37f4843155ff97152edf652..e8bf0d911589d623734971a5551d626fd54dab27 100644 (file)
@@ -48,7 +48,7 @@ class sc_export_base : public sc_object
     virtual const sc_interface *get_interface() const = 0;
 
   protected:
-    friend class sc_gem5::Kernel;
+    friend class sc_gem5::Module;
 
     virtual void before_end_of_elaboration() = 0;
     virtual void end_of_elaboration() = 0;
index 0e5e679c9094ee20fccb6ba359675d68c70af464..e5e4c2086160f894aa7411802d40c0ae790c4f14 100644 (file)
@@ -95,6 +95,7 @@ class sc_module : public sc_object
 {
   public:
     friend class ::sc_gem5::Kernel;
+    friend class ::sc_gem5::Module;
 
     virtual ~sc_module();
 
@@ -177,7 +178,7 @@ class sc_module : public sc_object
     sc_module(const std::string &);
 
     /* Deprecated, but used in the regression tests. */
-    void end_module() {}
+    void end_module();
 
     void reset_signal_is(const sc_in<bool> &, bool);
     void reset_signal_is(const sc_inout<bool> &, bool);
index 051d5b5e0271789d6a069e58ad8bf8878093ff93..fe165516ea426a88ca0dfbc03fdac37a2ba7e15f 100755 (executable)
@@ -233,7 +233,6 @@ class LogChecker(Checker):
         r'^\nInfo: \(I804\) /IEEE_Std_1666/deprecated: \n' +
         r'    sc_clock\(const char(.*\n){3}',
         warning_filt(540),
-        warning_filt(569),
         warning_filt(571),
         info_filt(804),
         in_file_filt,