summaryrefslogtreecommitdiff
path: root/src/systemc/core
diff options
context:
space:
mode:
authorGabe Black <gabeblack@google.com>2018-09-20 02:57:54 -0700
committerGabe Black <gabeblack@google.com>2018-10-16 00:26:15 +0000
commit3d29513196e7d59e1b8f9da120089bac17e8771d (patch)
tree600c99d37f34fd7ec07b7221fb41f14848b4938c /src/systemc/core
parenta503a24d97b29ef246330e95dab77669a0a4256c (diff)
downloadgem5-3d29513196e7d59e1b8f9da120089bac17e8771d.tar.xz
systemc: Implement general and VCD trace support.
This doesn't include WIF trace support, but does make allowances for adding it in the future. Change-Id: Ifb62f40a7d8a13e94463930a44ac4b1cf41e3009 Reviewed-on: https://gem5-review.googlesource.com/c/12826 Reviewed-by: Gabe Black <gabeblack@google.com> Maintainer: Gabe Black <gabeblack@google.com>
Diffstat (limited to 'src/systemc/core')
-rw-r--r--src/systemc/core/scheduler.cc22
-rw-r--r--src/systemc/core/scheduler.hh20
2 files changed, 40 insertions, 2 deletions
diff --git a/src/systemc/core/scheduler.cc b/src/systemc/core/scheduler.cc
index ae1aa899f..d79abb251 100644
--- a/src/systemc/core/scheduler.cc
+++ b/src/systemc/core/scheduler.cc
@@ -36,6 +36,7 @@
#include "systemc/ext/core/sc_main.hh"
#include "systemc/ext/utils/sc_report.hh"
#include "systemc/ext/utils/sc_report_handler.hh"
+#include "systemc/utils/tracefile.hh"
namespace sc_gem5
{
@@ -48,8 +49,8 @@ Scheduler::Scheduler() :
starvationEvent(this, false, StarvationPriority),
_elaborationDone(false), _started(false), _stopNow(false),
_status(StatusOther), maxTickEvent(this, false, MaxTickPriority),
- _numCycles(0), _changeStamp(0), _current(nullptr), initDone(false),
- runOnce(false)
+ timeAdvancesEvent(this, false, TimeAdvancesPriority), _numCycles(0),
+ _changeStamp(0), _current(nullptr), initDone(false), runOnce(false)
{}
Scheduler::~Scheduler()
@@ -86,6 +87,8 @@ Scheduler::clear()
deschedule(&starvationEvent);
if (maxTickEvent.scheduled())
deschedule(&maxTickEvent);
+ if (timeAdvancesEvent.scheduled())
+ deschedule(&timeAdvancesEvent);
Process *p;
while ((p = initList.getNext()))
@@ -134,6 +137,8 @@ Scheduler::initPhase()
initDone = true;
status(StatusOther);
+
+ scheduleTimeAdvancesEvent();
}
void
@@ -263,10 +268,13 @@ Scheduler::scheduleStarvationEvent()
void
Scheduler::runReady()
{
+ scheduleTimeAdvancesEvent();
+
bool empty = readyListMethods.empty() && readyListThreads.empty();
lastReadyTick = getCurTick();
// The evaluation phase.
+ status(StatusEvaluate);
do {
yield();
} while (getNextReady());
@@ -282,6 +290,8 @@ Scheduler::runReady()
}
runUpdate();
+ if (!traceFiles.empty())
+ trace(true);
runDelta();
if (!runToTime && starved())
@@ -367,6 +377,7 @@ Scheduler::start(Tick max_tick, bool run_to_time)
}
schedule(&maxTickEvent, maxTick);
+ scheduleTimeAdvancesEvent();
// Return to gem5 to let it run events, etc.
Fiber::primaryFiber()->run();
@@ -429,6 +440,13 @@ Scheduler::scheduleStop(bool finish_delta)
schedule(&stopEvent);
}
+void
+Scheduler::trace(bool delta)
+{
+ for (auto tf: traceFiles)
+ tf->trace(delta);
+}
+
Scheduler scheduler;
namespace {
diff --git a/src/systemc/core/scheduler.hh b/src/systemc/core/scheduler.hh
index 8015260a3..ebe15462c 100644
--- a/src/systemc/core/scheduler.hh
+++ b/src/systemc/core/scheduler.hh
@@ -48,6 +48,8 @@ class Fiber;
namespace sc_gem5
{
+class TraceFile;
+
typedef NodeList<Process> ProcessList;
typedef NodeList<Channel> ChannelList;
@@ -280,6 +282,7 @@ class Scheduler
timeSlots.erase(timeSlots.begin());
if (!runToTime && starved())
scheduleStarvationEvent();
+ scheduleTimeAdvancesEvent();
}
// Pending activity ignores gem5 activity, much like how a systemc
@@ -357,6 +360,9 @@ class Scheduler
Status status() { return _status; }
void status(Status s) { _status = s; }
+ void registerTraceFile(TraceFile *tf) { traceFiles.insert(tf); }
+ void unregisterTraceFile(TraceFile *tf) { traceFiles.erase(tf); }
+
private:
typedef const EventBase::Priority Priority;
static Priority DefaultPriority = EventBase::Default_Pri;
@@ -366,6 +372,7 @@ class Scheduler
static Priority MaxTickPriority = DefaultPriority + 2;
static Priority ReadyPriority = DefaultPriority + 3;
static Priority StarvationPriority = ReadyPriority;
+ static Priority TimeAdvancesPriority = EventBase::Maximum_Pri;
EventQueue *eq;
@@ -440,6 +447,15 @@ class Scheduler
}
EventWrapper<Scheduler, &Scheduler::maxTickFunc> maxTickEvent;
+ void timeAdvances() { trace(false); }
+ EventWrapper<Scheduler, &Scheduler::timeAdvances> timeAdvancesEvent;
+ void
+ scheduleTimeAdvancesEvent()
+ {
+ if (!traceFiles.empty() && !timeAdvancesEvent.scheduled())
+ schedule(&timeAdvancesEvent);
+ }
+
uint64_t _numCycles;
uint64_t _changeStamp;
@@ -457,6 +473,10 @@ class Scheduler
ChannelList updateList;
std::map<::Event *, Tick> eventsToSchedule;
+
+ std::set<TraceFile *> traceFiles;
+
+ void trace(bool delta);
};
extern Scheduler scheduler;