systemc: Make sc_main run in its own fiber.
authorGabe Black <gabeblack@google.com>
Thu, 31 May 2018 21:50:41 +0000 (14:50 -0700)
committerGabe Black <gabeblack@google.com>
Wed, 15 Aug 2018 01:26:16 +0000 (01:26 +0000)
The fiber will run until either sc_main returns, or until sc_start is
called. If sc_start is called, then the fiber will only be paused and
waiting for simulation cycles to be run by gem5. Once sc_pause and
sc_stop are implemented, if those are called the sc_main fiber will
be re-entered and allowed to run further towards completion.

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

src/systemc/core/sc_main.cc

index a7a77a4c410beab4b6cf3e4b15308f92812180e7..2ca5ed494b2ddd749fd8e9129d352ef931d1da86 100644 (file)
 
 #include <cstring>
 
+#include "base/fiber.hh"
 #include "base/logging.hh"
+#include "base/types.hh"
 #include "python/pybind11/pybind.hh"
+#include "sim/eventq.hh"
 #include "sim/init.hh"
 #include "systemc/ext/core/sc_main.hh"
 #include "systemc/ext/utils/sc_report_handler.hh"
@@ -57,6 +60,17 @@ bool scMainCalled = false;
 int _argc = 0;
 char **_argv = NULL;
 
+class ScMainFiber : public Fiber
+{
+    void
+    main()
+    {
+        ::sc_main(_argc, _argv);
+    }
+};
+
+ScMainFiber scMainFiber;
+
 // This wrapper adapts the python version of sc_main to the c++ version.
 void
 sc_main(pybind11::args args)
@@ -94,8 +108,7 @@ sc_main(pybind11::args args)
     // again later.
     scMainCalled = true;
 
-    //TODO Start a new fiber to call sc_main from.
-    ::sc_main(_argc, _argv);
+    scMainFiber.run();
 }
 
 // Make our sc_main wrapper available in the internal _m5 python module under
@@ -111,6 +124,9 @@ EmbeddedPyBind embed_("systemc", &systemc_pybind);
 sc_stop_mode _stop_mode = SC_STOP_FINISH_DELTA;
 sc_status _status = SC_ELABORATION;
 
+Tick _max_tick = MaxTick;
+sc_starvation_policy _starvation = SC_EXIT_ON_STARVATION;
+
 uint64_t _deltaCycles = 0;
 
 } // anonymous namespace
@@ -130,7 +146,11 @@ sc_argv()
 void
 sc_start()
 {
-    warn("%s not implemented.\n", __PRETTY_FUNCTION__);
+    _max_tick = MaxTick;
+    _starvation = SC_EXIT_ON_STARVATION;
+
+    // Switch back gem5.
+    Fiber::primaryFiber()->run();
 }
 
 void
@@ -142,7 +162,12 @@ sc_pause()
 void
 sc_start(const sc_time &time, sc_starvation_policy p)
 {
-    warn("%s not implemented.\n", __PRETTY_FUNCTION__);
+    Tick now = curEventQueue() ? curEventQueue()->getCurTick() : 0;
+    _max_tick = now + time.value();
+    _starvation = p;
+
+    // Switch back to gem5.
+    Fiber::primaryFiber()->run();
 }
 
 void