summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMitch Hayenga <mitch.hayenga@arm.com>2014-10-29 23:18:26 -0500
committerMitch Hayenga <mitch.hayenga@arm.com>2014-10-29 23:18:26 -0500
commit6847bbf7cefcebfeed6ec29fa139efcb3ce20be4 (patch)
tree1c27673aef935e5c52f24b8aa171aa87541d918d
parentb31d9e93e2744b044d7ccc2d9113bc367038e14f (diff)
downloadgem5-6847bbf7cefcebfeed6ec29fa139efcb3ce20be4.tar.xz
cpu: Add drain check functionality to IEW
IEW did not check the instQueue and memDepUnit to ensure they were drained. This caused issues when drainSanityCheck() did check those structures after asserting IEW was drained.
-rw-r--r--src/cpu/o3/iew_impl.hh2
-rw-r--r--src/cpu/o3/inst_queue.hh3
-rw-r--r--src/cpu/o3/inst_queue_impl.hh11
-rw-r--r--src/cpu/o3/mem_dep_unit.hh3
-rw-r--r--src/cpu/o3/mem_dep_unit_impl.hh13
5 files changed, 31 insertions, 1 deletions
diff --git a/src/cpu/o3/iew_impl.hh b/src/cpu/o3/iew_impl.hh
index 448be3a74..bf44fb9f2 100644
--- a/src/cpu/o3/iew_impl.hh
+++ b/src/cpu/o3/iew_impl.hh
@@ -381,7 +381,7 @@ template <class Impl>
bool
DefaultIEW<Impl>::isDrained() const
{
- bool drained(ldstQueue.isDrained());
+ bool drained = ldstQueue.isDrained() && instQueue.isDrained();
for (ThreadID tid = 0; tid < numThreads; tid++) {
if (!insts[tid].empty()) {
diff --git a/src/cpu/o3/inst_queue.hh b/src/cpu/o3/inst_queue.hh
index d59d5281b..c6c55d08a 100644
--- a/src/cpu/o3/inst_queue.hh
+++ b/src/cpu/o3/inst_queue.hh
@@ -145,6 +145,9 @@ class InstructionQueue
/** Sets the global time buffer. */
void setTimeBuffer(TimeBuffer<TimeStruct> *tb_ptr);
+ /** Determine if we are drained. */
+ bool isDrained() const;
+
/** Perform sanity checks after a drain. */
void drainSanityCheck() const;
diff --git a/src/cpu/o3/inst_queue_impl.hh b/src/cpu/o3/inst_queue_impl.hh
index 0caee41ed..6a76b49d0 100644
--- a/src/cpu/o3/inst_queue_impl.hh
+++ b/src/cpu/o3/inst_queue_impl.hh
@@ -441,6 +441,17 @@ InstructionQueue<Impl>::setTimeBuffer(TimeBuffer<TimeStruct> *tb_ptr)
}
template <class Impl>
+bool
+InstructionQueue<Impl>::isDrained() const
+{
+ bool drained = dependGraph.empty() && instsToExecute.empty();
+ for (ThreadID tid = 0; tid < numThreads; ++tid)
+ drained = drained && memDepUnit[tid].isDrained();
+
+ return drained;
+}
+
+template <class Impl>
void
InstructionQueue<Impl>::drainSanityCheck() const
{
diff --git a/src/cpu/o3/mem_dep_unit.hh b/src/cpu/o3/mem_dep_unit.hh
index 3cc1d88fe..c2c411fe4 100644
--- a/src/cpu/o3/mem_dep_unit.hh
+++ b/src/cpu/o3/mem_dep_unit.hh
@@ -104,6 +104,9 @@ class MemDepUnit
/** Registers statistics. */
void regStats();
+ /** Determine if we are drained. */
+ bool isDrained() const;
+
/** Perform sanity checks after a drain. */
void drainSanityCheck() const;
diff --git a/src/cpu/o3/mem_dep_unit_impl.hh b/src/cpu/o3/mem_dep_unit_impl.hh
index 6684e4ff0..376198fc1 100644
--- a/src/cpu/o3/mem_dep_unit_impl.hh
+++ b/src/cpu/o3/mem_dep_unit_impl.hh
@@ -128,6 +128,19 @@ MemDepUnit<MemDepPred, Impl>::regStats()
}
template <class MemDepPred, class Impl>
+bool
+MemDepUnit<MemDepPred, Impl>::isDrained() const
+{
+ bool drained = instsToReplay.empty()
+ && memDepHash.empty()
+ && instsToReplay.empty();
+ for (int i = 0; i < Impl::MaxThreads; ++i)
+ drained = drained && instList[i].empty();
+
+ return drained;
+}
+
+template <class MemDepPred, class Impl>
void
MemDepUnit<MemDepPred, Impl>::drainSanityCheck() const
{