From 7bfb7f3a43f382eb49853f47b140bfd6caad0fb8 Mon Sep 17 00:00:00 2001 From: Gabe Black Date: Thu, 16 Aug 2018 14:42:24 -0700 Subject: [PATCH] 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 Maintainer: Gabe Black --- src/systemc/core/sc_main.cc | 8 ++++++-- src/systemc/core/scheduler.cc | 17 ++++++++++++++++- src/systemc/core/scheduler.hh | 2 ++ 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(); } @@ -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() { 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; -- 2.30.2