systemc: When sc_start is told to run zero time, do one delta cycle.
authorGabe Black <gabeblack@google.com>
Thu, 16 Aug 2018 21:42:24 +0000 (14:42 -0700)
committerGabe Black <gabeblack@google.com>
Thu, 20 Sep 2018 01:51:29 +0000 (01:51 +0000)
This is a special case which is mentioned in the spec but hadn't yet
been given any special handling in this implementation.

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

src/systemc/core/sc_main.cc
src/systemc/core/scheduler.cc
src/systemc/core/scheduler.hh

index 641e0d0669cb2a96583cf5fa4fca48337f5021b6..7e107af86e5d18abeb97e821bcdef7d3aa40c3f2 100644 (file)
@@ -156,8 +156,12 @@ sc_pause()
 void
 sc_start(const sc_time &time, sc_starvation_policy p)
 {
-    Tick now = ::sc_gem5::scheduler.getCurTick();
-    ::sc_gem5::scheduler.start(now + time.value(), p == SC_RUN_TO_TIME);
+    if (time.value() == 0) {
+        ::sc_gem5::scheduler.oneCycle();
+    } else {
+        Tick now = ::sc_gem5::scheduler.getCurTick();
+        ::sc_gem5::scheduler.start(now + time.value(), p == SC_RUN_TO_TIME);
+    }
 }
 
 void
index d2e87f25d6d4d0a3ba24a837dce890023bdd44e4..7e5272d0e57bb8816d7af330232414c7fb267371 100644 (file)
@@ -46,7 +46,8 @@ Scheduler::Scheduler() :
     starvationEvent(this, false, StarvationPriority),
     _started(false), _paused(false), _stopped(false),
     maxTickEvent(this, false, MaxTickPriority),
-    _numCycles(0), _current(nullptr), initReady(false)
+    _numCycles(0), _current(nullptr), initReady(false),
+    runOnce(false)
 {}
 
 void
@@ -191,6 +192,11 @@ Scheduler::runReady()
         scheduleStarvationEvent();
 
     // The delta phase will happen naturally through the event queue.
+
+    if (runOnce) {
+        eq->reschedule(&maxTickEvent, eq->getCurTick());
+        runOnce = false;
+    }
 }
 
 void
@@ -209,6 +215,7 @@ Scheduler::pause()
 {
     _paused = true;
     kernel->status(::sc_core::SC_PAUSED);
+    runOnce = false;
     scMain->run();
 
     // If the ready event is supposed to run now, run it inline so that it
@@ -225,6 +232,7 @@ Scheduler::stop()
 {
     _stopped = true;
     kernel->stop();
+    runOnce = false;
     scMain->run();
 }
 
@@ -263,6 +271,13 @@ Scheduler::start(Tick max_tick, bool run_to_time)
         eq->deschedule(&starvationEvent);
 }
 
+void
+Scheduler::oneCycle()
+{
+    runOnce = true;
+    start(::MaxTick, false);
+}
+
 void
 Scheduler::schedulePause()
 {
index 983c53fde1c7b4d75414014709d0c5114997c106..661a36b78021e4eb3b829d8d76140bf8a230a76b 100644 (file)
@@ -269,6 +269,7 @@ class Scheduler
     void setScMainFiber(Fiber *sc_main) { scMain = sc_main; }
 
     void start(Tick max_tick, bool run_to_time);
+    void oneCycle();
 
     void schedulePause();
     void scheduleStop(bool finish_delta);
@@ -323,6 +324,7 @@ class Scheduler
 
     bool initReady;
     bool runToTime;
+    bool runOnce;
 
     ProcessList initList;
     ProcessList toFinalize;