Gabe Black has uploaded this change for review. ( https://gem5-review.googlesource.com/c/public/gem5/+/12033

Change subject: systemc: Implement the various sc_module stage callbacks.
......................................................................

systemc: Implement the various sc_module stage callbacks.

This change also gets rid of the SystemC namespace which was
deprecated in favor of sc_gem5.

A few utility functions which check whether certain callbacks have
finished were also implemented. status tracking moved from a global
variable in sc_main.cc to a member of the kernel simobject.

Change-Id: I50967fae9c576fbe45b1faff587aaa824857a289
---
M src/systemc/core/SystemC.py
M src/systemc/core/kernel.cc
M src/systemc/core/kernel.hh
M src/systemc/core/module.cc
M src/systemc/core/module.hh
M src/systemc/core/sc_main.cc
M src/systemc/core/sc_module.cc
M src/systemc/core/scheduler.cc
M src/systemc/ext/core/sc_module.hh
9 files changed, 131 insertions(+), 27 deletions(-)



diff --git a/src/systemc/core/SystemC.py b/src/systemc/core/SystemC.py
index 41fecb2..dff72e2 100644
--- a/src/systemc/core/SystemC.py
+++ b/src/systemc/core/SystemC.py
@@ -33,7 +33,7 @@
# It also acts as a collecting point for systemc related control functionality.
 class SystemC_Kernel(SimObject):
     type = 'SystemC_Kernel'
-    cxx_class = 'SystemC::Kernel'
+    cxx_class = 'sc_gem5::Kernel'
     cxx_header = 'systemc/core/kernel.hh'

     def sc_main(self, *args):
diff --git a/src/systemc/core/kernel.cc b/src/systemc/core/kernel.cc
index 3b75c2f..dac2229 100644
--- a/src/systemc/core/kernel.cc
+++ b/src/systemc/core/kernel.cc
@@ -28,17 +28,56 @@
  */

 #include "systemc/core/kernel.hh"
+
+#include "base/logging.hh"
+#include "systemc/core/module.hh"
 #include "systemc/core/scheduler.hh"

-namespace SystemC
+namespace sc_gem5
 {

 Kernel::Kernel(Params *params) :
-    SimObject(params), t0Event(this, false, EventBase::Default_Pri - 1) {}
+    SimObject(params), _stopAfterCallbacks(false),
+    _startComplete(false), _endComplete(false),
+    _status(sc_core::SC_ELABORATION),
+    t0Event(this, false, EventBase::Default_Pri - 1) {}
+
+void
+Kernel::init()
+{
+    kernel->status(::sc_core::SC_BEFORE_END_OF_ELABORATION);
+    for (auto m: sc_gem5::allModules)
+        m->sc_mod()->before_end_of_elaboration();
+
+    if (_stopAfterCallbacks)
+        stopWork();
+}
+
+void
+Kernel::regStats()
+{
+    kernel->status(::sc_core::SC_END_OF_ELABORATION);
+    for (auto m: sc_gem5::allModules)
+        m->sc_mod()->end_of_elaboration();
+
+    if (_stopAfterCallbacks)
+        stopWork();
+}

 void
 Kernel::startup()
 {
+    kernel->status(::sc_core::SC_START_OF_SIMULATION);
+    for (auto m: sc_gem5::allModules)
+        m->sc_mod()->start_of_simulation();
+
+    _startComplete = true;
+
+    if (_stopAfterCallbacks)
+        stopWork();
+
+    kernel->status(::sc_core::SC_RUNNING);
+
     schedule(t0Event, curTick());
     // Install ourselves as the scheduler's event manager.
     ::sc_gem5::scheduler.setEventQueue(eventQueue());
@@ -47,6 +86,30 @@
 }

 void
+Kernel::stop()
+{
+    if (status() < ::sc_core::SC_RUNNING)
+        _stopAfterCallbacks = true;
+    else
+        stopWork();
+}
+
+void
+Kernel::stopWork()
+{
+    kernel->status(::sc_core::SC_END_OF_SIMULATION);
+    for (auto m: sc_gem5::allModules)
+        m->sc_mod()->end_of_simulation();
+
+    _endComplete = true;
+
+    kernel->status(::sc_core::SC_STOPPED);
+
+    if (_stopAfterCallbacks)
+        fatal("Simulation called sc_stop during elaboration.\n");
+}
+
+void
 Kernel::t0Handler()
 {
     // Now that the event queue has started, mark all the processes that
@@ -57,12 +120,19 @@
// in the spec. The delta phase will happen at normal priority, and then
     // the event which runs the processes which is at a lower priority.
     ::sc_gem5::scheduler.prepareForInit();
+
+    status(::sc_core::SC_RUNNING);
 }

-} // namespace SystemC
+Kernel *kernel;

-SystemC::Kernel *
+} // namespace sc_gem5
+
+sc_gem5::Kernel *
 SystemC_KernelParams::create()
 {
-    return new SystemC::Kernel(this);
+    panic_if(sc_gem5::kernel,
+            "Only one systemc kernel object may be defined.\n");
+    sc_gem5::kernel = new sc_gem5::Kernel(this);
+    return sc_gem5::kernel;
 }
diff --git a/src/systemc/core/kernel.hh b/src/systemc/core/kernel.hh
index 8cbf4fb..15641c5 100644
--- a/src/systemc/core/kernel.hh
+++ b/src/systemc/core/kernel.hh
@@ -32,8 +32,9 @@

 #include "params/SystemC_Kernel.hh"
 #include "sim/sim_object.hh"
+#include "systemc/ext/core/sc_main.hh"

-namespace SystemC
+namespace sc_gem5
 {

 /*
@@ -49,14 +50,33 @@
     typedef SystemC_KernelParams Params;
     Kernel(Params *params);

+    void init() override;
+    void regStats() override;
     void startup() override;

     void t0Handler();

+    sc_core::sc_status status() { return _status; }
+    void status(sc_core::sc_status s) { _status = s; }
+
+    void stop();
+
+    bool startOfSimulationComplete() { return _startComplete; }
+    bool endOfSimulationComplete() { return _endComplete; }
+
   private:
+    bool _stopAfterCallbacks;
+    void stopWork();
+
+    bool _startComplete;
+    bool _endComplete;
+    sc_core::sc_status _status;
+
     EventWrapper<Kernel, &Kernel::t0Handler> t0Event;
 };

-} // namespace SystemC
+extern Kernel *kernel;
+
+} // namespace sc_gem5

 #endif // __SYSTEMC_KERNEL_H__
diff --git a/src/systemc/core/module.cc b/src/systemc/core/module.cc
index 3b7e922..e41e932 100644
--- a/src/systemc/core/module.cc
+++ b/src/systemc/core/module.cc
@@ -51,6 +51,8 @@
     _new_module = this;
 }

+Module::~Module() { allModules.erase(this); }
+
 void
 Module::finish(Object *this_obj)
 {
@@ -58,6 +60,10 @@
     _obj = this_obj;
     _modules.push_back(this);
     _new_module = nullptr;
+    // This is called from the constructor of this_obj, so it can't use
+    // dynamic cast.
+    sc_mod(static_cast<::sc_core::sc_module *>(this_obj->sc_obj()));
+    allModules.insert(this);
 }

 void
@@ -84,4 +90,6 @@
     return _new_module;
 }

+std::set<Module *> allModules;
+
 } // namespace sc_gem5
diff --git a/src/systemc/core/module.hh b/src/systemc/core/module.hh
index 3734e63..696d8c5 100644
--- a/src/systemc/core/module.hh
+++ b/src/systemc/core/module.hh
@@ -31,6 +31,7 @@
 #define __SYSTEMC_CORE_MODULE_HH__

 #include <cassert>
+#include <set>

 #include "systemc/core/object.hh"
 #include "systemc/ext/core/sc_module.hh"
@@ -48,6 +49,8 @@
   public:

     Module(const char *name);
+    ~Module();
+
     void finish(Object *this_obj);

     const char *name() const { return _name; }
@@ -79,6 +82,8 @@
 Module *currentModule();
 Module *newModule();

+extern std::set<Module *> allModules;
+
 } // namespace sc_gem5

 #endif  //__SYSTEMC_CORE_MODULE_HH__
diff --git a/src/systemc/core/sc_main.cc b/src/systemc/core/sc_main.cc
index 103b303..8e92c94 100644
--- a/src/systemc/core/sc_main.cc
+++ b/src/systemc/core/sc_main.cc
@@ -36,6 +36,7 @@
 #include "sim/core.hh"
 #include "sim/eventq.hh"
 #include "sim/init.hh"
+#include "systemc/core/kernel.hh"
 #include "systemc/core/scheduler.hh"
 #include "systemc/ext/core/sc_main.hh"
 #include "systemc/ext/utils/sc_report_handler.hh"
@@ -121,7 +122,6 @@
 EmbeddedPyBind embed_("systemc", &systemc_pybind);

 sc_stop_mode _stop_mode = SC_STOP_FINISH_DELTA;
-sc_status _status = SC_ELABORATION;

 } // anonymous namespace

@@ -147,22 +147,15 @@
 void
 sc_pause()
 {
-    if (_status == SC_RUNNING)
+    if (::sc_gem5::kernel->status() == SC_RUNNING)
         ::sc_gem5::scheduler.schedulePause();
 }

 void
 sc_start(const sc_time &time, sc_starvation_policy p)
 {
-    _status = SC_RUNNING;
-
     Tick now = ::sc_gem5::scheduler.getCurTick();
     ::sc_gem5::scheduler.start(now + time.value(), p == SC_RUN_TO_TIME);
-
-    if (::sc_gem5::scheduler.paused())
-        _status = SC_PAUSED;
-    else if (::sc_gem5::scheduler.stopped())
-        _status = SC_STOPPED;
 }

 void
@@ -185,14 +178,14 @@
 void
 sc_stop()
 {
-    if (_status == SC_STOPPED)
+    if (::sc_gem5::kernel->status() == SC_STOPPED)
         return;

     if (sc_is_running()) {
         bool finish_delta = (_stop_mode == SC_STOP_FINISH_DELTA);
         ::sc_gem5::scheduler.scheduleStop(finish_delta);
     } else {
-        //XXX Should stop if in one of the various elaboration callbacks.
+        ::sc_gem5::kernel->stop();
     }
 }

@@ -215,7 +208,7 @@
 bool
 sc_is_running()
 {
-    return _status & (SC_RUNNING | SC_PAUSED);
+    return sc_get_status() & (SC_RUNNING | SC_PAUSED);
 }

 bool
@@ -246,7 +239,7 @@
 sc_status
 sc_get_status()
 {
-    return _status;
+ return ::sc_gem5::kernel ? ::sc_gem5::kernel->status() : SC_ELABORATION;
 }

 } // namespace sc_core
diff --git a/src/systemc/core/sc_module.cc b/src/systemc/core/sc_module.cc
index 20cc4d2..499a741 100644
--- a/src/systemc/core/sc_module.cc
+++ b/src/systemc/core/sc_module.cc
@@ -31,6 +31,7 @@
 #include <vector>

 #include "base/logging.hh"
+#include "systemc/core/kernel.hh"
 #include "systemc/core/module.hh"
 #include "systemc/core/process_types.hh"
 #include "systemc/ext/core/sc_module.hh"
@@ -72,7 +73,7 @@

 const sc_bind_proxy SC_BIND_PROXY_NUL(*(const sc_port_base *)nullptr);

-sc_module::~sc_module() {}
+sc_module::~sc_module() { delete _gem5_module; }

 const sc_bind_proxy SC_BIND_PROXY_NIL(*(const sc_port_base *)nullptr);

@@ -652,15 +653,13 @@
 bool
 sc_start_of_simulation_invoked()
 {
-    warn("%s not implemented.\n", __PRETTY_FUNCTION__);
-    return false;
+    return ::sc_gem5::kernel->startOfSimulationComplete();
 }

 bool
 sc_end_of_simulation_invoked()
 {
-    warn("%s not implemented.\n", __PRETTY_FUNCTION__);
-    return false;
+    return ::sc_gem5::kernel->endOfSimulationComplete();
 }

 sc_module *
diff --git a/src/systemc/core/scheduler.cc b/src/systemc/core/scheduler.cc
index eab6f48..6bb67d1 100644
--- a/src/systemc/core/scheduler.cc
+++ b/src/systemc/core/scheduler.cc
@@ -32,6 +32,8 @@
 #include "base/fiber.hh"
 #include "base/logging.hh"
 #include "sim/eventq.hh"
+#include "systemc/core/kernel.hh"
+#include "systemc/ext/core/sc_main.hh"

 namespace sc_gem5
 {
@@ -174,6 +176,7 @@
 Scheduler::pause()
 {
     _paused = true;
+    kernel->status(::sc_core::SC_PAUSED);
     scMain->run();
 }

@@ -181,6 +184,7 @@
 Scheduler::stop()
 {
     _stopped = true;
+    kernel->stop();
     scMain->run();
 }

@@ -197,8 +201,10 @@

     maxTick = max_tick;

-    if (initReady)
+    if (initReady) {
+        kernel->status(::sc_core::SC_RUNNING);
         eq->schedule(&maxTickEvent, maxTick);
+    }

     // Return to gem5 to let it run events, etc.
     Fiber::primaryFiber()->run();
diff --git a/src/systemc/ext/core/sc_module.hh b/src/systemc/ext/core/sc_module.hh
index 746e0c7..7088c4e 100644
--- a/src/systemc/ext/core/sc_module.hh
+++ b/src/systemc/ext/core/sc_module.hh
@@ -46,6 +46,7 @@
 namespace sc_gem5
 {

+class Kernel;
 class Module;
 class Process;
 struct ProcessFuncWrapper;
@@ -91,6 +92,8 @@
 class sc_module : public sc_object
 {
   public:
+    friend class ::sc_gem5::Kernel;
+
     virtual ~sc_module();

     virtual const char *kind() const { return "sc_module"; }

--
To view, visit https://gem5-review.googlesource.com/c/public/gem5/+/12033
To unsubscribe, or for help writing mail filters, visit https://gem5-review.googlesource.com/settings

Gerrit-Project: public/gem5
Gerrit-Branch: master
Gerrit-Change-Id: I50967fae9c576fbe45b1faff587aaa824857a289
Gerrit-Change-Number: 12033
Gerrit-PatchSet: 1
Gerrit-Owner: Gabe Black <[email protected]>
Gerrit-MessageType: newchange
_______________________________________________
gem5-dev mailing list
[email protected]
http://m5sim.org/mailman/listinfo/gem5-dev

Reply via email to