summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGabe Black <gabeblack@google.com>2018-08-16 14:42:24 -0700
committerGabe Black <gabeblack@google.com>2018-09-20 01:51:29 +0000
commit7bfb7f3a43f382eb49853f47b140bfd6caad0fb8 (patch)
tree9f6dc20f5cafc65c6b4a0088c7d1b2a1f0051749
parente1128dc8eb4afefcf4dad5eb5f863e0da921960a (diff)
downloadgem5-7bfb7f3a43f382eb49853f47b140bfd6caad0fb8.tar.xz
systemc: When sc_start is told to run zero time, do one delta cycle.
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>
-rw-r--r--src/systemc/core/sc_main.cc8
-rw-r--r--src/systemc/core/scheduler.cc17
-rw-r--r--src/systemc/core/scheduler.hh2
3 files changed, 24 insertions, 3 deletions
diff --git a/src/systemc/core/sc_main.cc b/src/systemc/core/sc_main.cc
index 641e0d066..7e107af86 100644
--- a/src/systemc/core/sc_main.cc
+++ b/src/systemc/core/sc_main.cc
@@ -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
diff --git a/src/systemc/core/scheduler.cc b/src/systemc/core/scheduler.cc
index d2e87f25d..7e5272d0e 100644
--- a/src/systemc/core/scheduler.cc
+++ b/src/systemc/core/scheduler.cc
@@ -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();
}
@@ -264,6 +272,13 @@ Scheduler::start(Tick max_tick, bool run_to_time)
}
void
+Scheduler::oneCycle()
+{
+ runOnce = true;
+ start(::MaxTick, false);
+}
+
+void
Scheduler::schedulePause()
{
if (pauseEvent.scheduled())
diff --git a/src/systemc/core/scheduler.hh b/src/systemc/core/scheduler.hh
index 983c53fde..661a36b78 100644
--- a/src/systemc/core/scheduler.hh
+++ b/src/systemc/core/scheduler.hh
@@ -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;