summaryrefslogtreecommitdiff
path: root/cpu/o3/inst_queue_impl.hh
diff options
context:
space:
mode:
Diffstat (limited to 'cpu/o3/inst_queue_impl.hh')
-rw-r--r--cpu/o3/inst_queue_impl.hh160
1 files changed, 104 insertions, 56 deletions
diff --git a/cpu/o3/inst_queue_impl.hh b/cpu/o3/inst_queue_impl.hh
index 804bc2472..0d9cc09f3 100644
--- a/cpu/o3/inst_queue_impl.hh
+++ b/cpu/o3/inst_queue_impl.hh
@@ -82,15 +82,9 @@ InstructionQueue<Impl>::InstructionQueue(Params *params)
{
assert(fuPool);
- numThreads = params->numberOfThreads;
+ switchedOut = false;
- //Initialize thread IQ counts
- for (int i = 0; i <numThreads; i++) {
- count[i] = 0;
- }
-
- // Initialize the number of free IQ entries.
- freeEntries = numEntries;
+ numThreads = params->numberOfThreads;
// Set the number of physical registers as the number of int + float
numPhysRegs = numPhysIntRegs + numPhysFloatRegs;
@@ -101,37 +95,24 @@ InstructionQueue<Impl>::InstructionQueue(Params *params)
//dependency graph.
dependGraph = new DependencyEntry[numPhysRegs];
- // Resize the register scoreboard.
- regScoreboard.resize(numPhysRegs);
-
- //Initialize Mem Dependence Units
- for (int i = 0; i < numThreads; i++) {
- memDepUnit[i].init(params,i);
- memDepUnit[i].setIQ(this);
- }
-
// Initialize all the head pointers to point to NULL, and all the
// entries as unready.
- // Note that in actuality, the registers corresponding to the logical
- // registers start off as ready. However this doesn't matter for the
- // IQ as the instruction should have been correctly told if those
- // registers are ready in rename. Thus it can all be initialized as
- // unready.
for (int i = 0; i < numPhysRegs; ++i) {
dependGraph[i].next = NULL;
dependGraph[i].inst = NULL;
- regScoreboard[i] = false;
}
- for (int i = 0; i < numThreads; ++i) {
- squashedSeqNum[i] = 0;
- }
+ // Resize the register scoreboard.
+ regScoreboard.resize(numPhysRegs);
- for (int i = 0; i < Num_OpClasses; ++i) {
- queueOnList[i] = false;
- readyIt[i] = listOrder.end();
+ //Initialize Mem Dependence Units
+ for (int i = 0; i < numThreads; i++) {
+ memDepUnit[i].init(params,i);
+ memDepUnit[i].setIQ(this);
}
+ resetState();
+
string policy = params->smtIQPolicy;
//Convert string to lowercase
@@ -184,30 +165,7 @@ InstructionQueue<Impl>::InstructionQueue(Params *params)
template <class Impl>
InstructionQueue<Impl>::~InstructionQueue()
{
- // Clear the dependency graph
- DependencyEntry *curr;
- DependencyEntry *prev;
-
- for (int i = 0; i < numPhysRegs; ++i) {
- curr = dependGraph[i].next;
-
- while (curr) {
- DependencyEntry::mem_alloc_counter--;
-
- prev = curr;
- curr = prev->next;
- prev->inst = NULL;
-
- delete prev;
- }
-
- if (dependGraph[i].inst) {
- dependGraph[i].inst = NULL;
- }
-
- dependGraph[i].next = NULL;
- }
-
+ resetDependencyGraph();
assert(DependencyEntry::mem_alloc_counter == 0);
delete [] dependGraph;
@@ -307,10 +265,10 @@ InstructionQueue<Impl>::regStats()
queue_res_dist.subname(i, opClassStrings[i]);
}
n_issued_dist
- .init(totalWidth + 1)
+ .init(0,totalWidth,1)
.name(name() + ".ISSUE:issued_per_cycle")
.desc("Number of insts issued each cycle")
- .flags(total | pdf | dist)
+ .flags(pdf)
;
/*
dist_unissued
@@ -402,6 +360,71 @@ InstructionQueue<Impl>::regStats()
template <class Impl>
void
+InstructionQueue<Impl>::resetState()
+{
+ //Initialize thread IQ counts
+ for (int i = 0; i <numThreads; i++) {
+ count[i] = 0;
+ instList[i].clear();
+ }
+
+ // Initialize the number of free IQ entries.
+ freeEntries = numEntries;
+
+ // Note that in actuality, the registers corresponding to the logical
+ // registers start off as ready. However this doesn't matter for the
+ // IQ as the instruction should have been correctly told if those
+ // registers are ready in rename. Thus it can all be initialized as
+ // unready.
+ for (int i = 0; i < numPhysRegs; ++i) {
+ regScoreboard[i] = false;
+ }
+
+ for (int i = 0; i < numThreads; ++i) {
+ squashedSeqNum[i] = 0;
+ }
+
+ for (int i = 0; i < Num_OpClasses; ++i) {
+ while (!readyInsts[i].empty())
+ readyInsts[i].pop();
+ queueOnList[i] = false;
+ readyIt[i] = listOrder.end();
+ }
+ nonSpecInsts.clear();
+ listOrder.clear();
+}
+
+template <class Impl>
+void
+InstructionQueue<Impl>::resetDependencyGraph()
+{
+ // Clear the dependency graph
+ DependencyEntry *curr;
+ DependencyEntry *prev;
+
+ for (int i = 0; i < numPhysRegs; ++i) {
+ curr = dependGraph[i].next;
+
+ while (curr) {
+ DependencyEntry::mem_alloc_counter--;
+
+ prev = curr;
+ curr = prev->next;
+ prev->inst = NULL;
+
+ delete prev;
+ }
+
+ if (dependGraph[i].inst) {
+ dependGraph[i].inst = NULL;
+ }
+
+ dependGraph[i].next = NULL;
+ }
+}
+
+template <class Impl>
+void
InstructionQueue<Impl>::setActiveThreads(list<unsigned> *at_ptr)
{
DPRINTF(IQ, "Setting active threads list pointer.\n");
@@ -427,6 +450,25 @@ InstructionQueue<Impl>::setTimeBuffer(TimeBuffer<TimeStruct> *tb_ptr)
}
template <class Impl>
+void
+InstructionQueue<Impl>::switchOut()
+{
+ resetState();
+ resetDependencyGraph();
+ switchedOut = true;
+ for (int i = 0; i < numThreads; ++i) {
+ memDepUnit[i].switchOut();
+ }
+}
+
+template <class Impl>
+void
+InstructionQueue<Impl>::takeOverFrom()
+{
+ switchedOut = false;
+}
+
+template <class Impl>
int
InstructionQueue<Impl>::entryAmount(int num_threads)
{
@@ -685,6 +727,10 @@ InstructionQueue<Impl>::processFUCompletion(DynInstPtr &inst, int fu_idx)
{
// The CPU could have been sleeping until this op completed (*extremely*
// long latency op). Wake it if it was. This may be overkill.
+ if (isSwitchedOut()) {
+ return;
+ }
+
iewStage->wakeCPU();
fuPool->freeUnit(fu_idx);
@@ -816,7 +862,7 @@ InstructionQueue<Impl>::scheduleReadyInsts()
FUCompletion *execution = new FUCompletion(issuing_inst,
idx, this);
- execution->schedule(curTick + issue_latency - 1);
+ execution->schedule(curTick + cpu->cycles(issue_latency - 1));
} else {
i2e_info->insts[exec_queue_slot++] = issuing_inst;
i2e_info->size++;
@@ -862,6 +908,8 @@ InstructionQueue<Impl>::scheduleReadyInsts()
}
}
+ n_issued_dist.sample(total_issued);
+
if (total_issued) {
cpu->activityThisCycle();
} else {