summaryrefslogtreecommitdiff
path: root/src/cpu/inorder
diff options
context:
space:
mode:
Diffstat (limited to 'src/cpu/inorder')
-rw-r--r--src/cpu/inorder/first_stage.cc39
-rw-r--r--src/cpu/inorder/first_stage.hh5
-rw-r--r--src/cpu/inorder/pipeline_stage.cc92
-rw-r--r--src/cpu/inorder/pipeline_stage.hh5
4 files changed, 57 insertions, 84 deletions
diff --git a/src/cpu/inorder/first_stage.cc b/src/cpu/inorder/first_stage.cc
index 424d6b6a4..71c6ec3e0 100644
--- a/src/cpu/inorder/first_stage.cc
+++ b/src/cpu/inorder/first_stage.cc
@@ -69,24 +69,24 @@ FirstStage::squash(InstSeqNum squash_seq_num, ThreadID tid)
// insts in them.
DPRINTF(InOrderStage, "Removing instructions from stage instruction "
"list.\n");
- while (!insts[tid].empty()) {
- if (insts[tid].front()->seqNum <= squash_seq_num) {
+ while (!skidBuffer[tid].empty()) {
+ if (skidBuffer[tid].front()->seqNum <= squash_seq_num) {
DPRINTF(InOrderStage,"[tid:%i]: Cannot remove [sn:%i] because "
"it's <= squashing seqNum %i.\n",
tid,
- insts[tid].front()->seqNum,
+ skidBuffer[tid].front()->seqNum,
squash_seq_num);
DPRINTF(InOrderStage, "[tid:%i]: Cannot remove incoming "
"instructions before delay slot [sn:%i]. %i insts"
"left.\n", tid, squash_seq_num,
- insts[tid].size());
+ skidBuffer[tid].size());
break;
}
DPRINTF(InOrderStage, "[tid:%i]: Removing instruction, [sn:%i] "
- "PC %s.\n", tid, insts[tid].front()->seqNum,
- insts[tid].front()->pc);
- insts[tid].pop();
+ "PC %s.\n", tid, skidBuffer[tid].front()->seqNum,
+ skidBuffer[tid].front()->pc);
+ skidBuffer[tid].pop_front();
}
// Now that squash has propagated to the first stage,
@@ -118,9 +118,7 @@ FirstStage::processStage(bool &status_change)
status_change = checkSignalsAndUpdate(tid) || status_change;
}
- for (int insts_fetched = 0;
- insts_fetched < stageWidth && canSendInstToStage(1);
- insts_fetched++) {
+ while (instsProcessed < stageWidth) {
ThreadID tid = getFetchingThread(fetchPolicy);
if (tid >= 0) {
@@ -151,14 +149,14 @@ FirstStage::processInsts(ThreadID tid)
bool all_reqs_completed = true;
for (int insts_fetched = instsProcessed;
- insts_fetched < stageWidth && canSendInstToStage(1);
+ insts_fetched < stageWidth;
insts_fetched++) {
DynInstPtr inst;
bool new_inst = false;
- if (!insts[tid].empty()) {
- inst = insts[tid].front();
+ if (!skidBuffer[tid].empty()) {
+ inst = skidBuffer[tid].front();
} else {
// Get new instruction.
new_inst = true;
@@ -195,22 +193,21 @@ FirstStage::processInsts(ThreadID tid)
if (reqs_processed > 0)
instsProcessed++;
- if (!all_reqs_completed) {
+ if (!all_reqs_completed || !sendInstToNextStage(inst)) {
if (new_inst) {
DPRINTF(InOrderStage, "[tid:%u]: [sn:%u] Did not finish all "
"requests for this stage. Keep in stage inst. "
"list.\n", tid, inst->seqNum);
- insts[tid].push(inst);
+ skidBuffer[tid].push_back(inst);
}
block(tid);
break;
- } else if (!insts[tid].empty()){
+ } else if (!skidBuffer[tid].empty()){
DPRINTF(InOrderStage, "[tid:%u]: [sn:%u] Finished all "
"requests for this stage.\n", tid, inst->seqNum);
- insts[tid].pop();
+ skidBuffer[tid].pop_front();
}
- sendInstToNextStage(inst);
}
// Record that stage has written to the time buffer for activity
@@ -240,7 +237,8 @@ FirstStage::getFetchingThread(FetchPriority &fetch_priority)
ThreadID tid = *activeThreads->begin();
if (stageStatus[tid] == Running ||
- stageStatus[tid] == Idle) {
+ stageStatus[tid] == Idle ||
+ stageStatus[tid] == Unblocking) {
return tid;
} else {
return InvalidThreadID;
@@ -264,7 +262,8 @@ FirstStage::roundRobin()
assert(high_pri <= numThreads);
if (stageStatus[high_pri] == Running ||
- stageStatus[high_pri] == Idle) {
+ stageStatus[high_pri] == Idle ||
+ stageStatus[high_pri] == Unblocking){
fetchPriorityList->erase(pri_iter);
fetchPriorityList->push_back(high_pri);
diff --git a/src/cpu/inorder/first_stage.hh b/src/cpu/inorder/first_stage.hh
index 3a3d550a0..26151075c 100644
--- a/src/cpu/inorder/first_stage.hh
+++ b/src/cpu/inorder/first_stage.hh
@@ -68,11 +68,6 @@ class FirstStage : public PipelineStage {
*/
void sortInsts() {}
- /** There are no skidBuffers for the first stage. So
- * just use an empty function.
- */
- void skidInsert(ThreadID tid) { }
-
/** The number of fetching threads in the CPU */
int numFetchingThreads;
diff --git a/src/cpu/inorder/pipeline_stage.cc b/src/cpu/inorder/pipeline_stage.cc
index d77059717..b4b9e497f 100644
--- a/src/cpu/inorder/pipeline_stage.cc
+++ b/src/cpu/inorder/pipeline_stage.cc
@@ -272,10 +272,6 @@ PipelineStage::block(ThreadID tid)
DPRINTF(InOrderStage, "[tid:%d]: Blocking, sending block signal back to "
"previous stages.\n", tid);
- // Add the current inputs to the skid buffer so they can be
- // reprocessed when this stage unblocks.
- // skidInsert(tid);
-
// If the stage status is blocked or unblocking then stage has not yet
// signalled fetch to unblock. In that case, there is no need to tell
// fetch to block.
@@ -412,19 +408,26 @@ PipelineStage::squash(InstSeqNum squash_seq_num, ThreadID tid)
DPRINTF(InOrderStage, "[tid:%i]: Removing instructions from incoming stage"
" skidbuffer.\n", tid);
- while (!skidBuffer[tid].empty()) {
- if (skidBuffer[tid].front()->seqNum <= squash_seq_num) {
+ //@TODO: Walk Through List Using iterator and remove
+ // all instructions over the value
+ std::list<DynInstPtr>::iterator cur_it = skidBuffer[tid].begin();
+ std::list<DynInstPtr>::iterator end_it = skidBuffer[tid].end();
+
+ while (cur_it != end_it) {
+ if ((*cur_it)->seqNum <= squash_seq_num) {
DPRINTF(InOrderStage, "[tid:%i]: Cannot remove skidBuffer "
"instructions (starting w/[sn:%i]) before delay slot "
"[sn:%i]. %i insts left.\n", tid,
- skidBuffer[tid].front()->seqNum, squash_seq_num,
+ (*cur_it)->seqNum, squash_seq_num,
skidBuffer[tid].size());
- break;
+ cur_it++;
+ } else {
+ DPRINTF(InOrderStage, "[tid:%i]: Removing instruction, [sn:%i] "
+ " PC %s.\n", tid, (*cur_it)->seqNum, (*cur_it)->pc);
+ (*cur_it)->setSquashed();
+ cur_it = skidBuffer[tid].erase(cur_it);
}
- DPRINTF(InOrderStage, "[tid:%i]: Removing instruction, [sn:%i] "
- " PC %s.\n", tid, skidBuffer[tid].front()->seqNum,
- skidBuffer[tid].front()->pc);
- skidBuffer[tid].pop_front();
+
}
}
@@ -442,7 +445,7 @@ PipelineStage::stageBufferAvail()
cpu->pipelineStage[stageNum]->prevStage->size :
0;
- int avail = stageBufferMax - total -0;// incoming_insts;
+ int avail = stageBufferMax - total;
if (avail < 0)
fatal("stageNum %i:stageBufferAvail() < 0..."
@@ -458,7 +461,8 @@ PipelineStage::canSendInstToStage(unsigned stage_num)
bool buffer_avail = false;
if (cpu->pipelineStage[stage_num]->prevStageValid) {
- buffer_avail = cpu->pipelineStage[stage_num]->stageBufferAvail() >= 1;
+ buffer_avail = cpu->pipelineStage[stage_num]->stageBufferAvail() -
+ cpu->pipelineStage[stage_num-1]->nextStage->size >= 1;
}
if (!buffer_avail && nextStageQueueValid(stage_num)) {
@@ -469,27 +473,6 @@ PipelineStage::canSendInstToStage(unsigned stage_num)
return buffer_avail;
}
-void
-PipelineStage::skidInsert(ThreadID tid)
-{
- DynInstPtr inst = NULL;
-
- while (!insts[tid].empty()) {
- inst = insts[tid].front();
-
- insts[tid].pop();
-
- assert(tid == inst->threadNumber);
-
- DPRINTF(InOrderStage,"[tid:%i]: Inserting [sn:%lli] PC:%s into stage "
- "skidBuffer %i\n", tid, inst->seqNum, inst->pcState(),
- inst->threadNumber);
-
- skidBuffer[tid].push_back(inst);
- }
-}
-
-
int
PipelineStage::skidSize()
{
@@ -601,13 +584,8 @@ PipelineStage::sortInsts()
insts_from_cur_stage);
int inserted_insts = 0;
- for (int i = 0; i < insts_from_prev_stage; ++i) {
- if (inserted_insts + insts_from_cur_stage == stageWidth) {
- DPRINTF(InOrderStage, "Stage %i has accepted all insts "
- "possible for this tick.\n");
- break;
- }
+ for (int i = 0; i < insts_from_prev_stage; i++) {
if (prevStage->insts[i]->isSquashed()) {
DPRINTF(InOrderStage, "[tid:%i]: Ignoring squashed [sn:%i], "
"not inserting into stage buffer.\n",
@@ -617,15 +595,27 @@ PipelineStage::sortInsts()
continue;
}
- DPRINTF(InOrderStage, "[tid:%i]: Inserting [sn:%i] into stage "
- "buffer.\n", prevStage->insts[i]->readTid(),
- prevStage->insts[i]->seqNum);
-
ThreadID tid = prevStage->insts[i]->threadNumber;
- DynInstPtr inst = prevStage->insts[i];
+ if (inserted_insts + insts_from_cur_stage == stageWidth) {
+ DPRINTF(InOrderStage, "Stage %i has accepted all insts "
+ "possible for this tick. Placing [sn:%i] in stage %i skidBuffer\n",
+ stageNum, prevStage->insts[i]->seqNum, stageNum - 1);
+ cpu->pipelineStage[stageNum - 1]->
+ skidBuffer[tid].push_front(prevStage->insts[i]);
+
+ int prev_stage = stageNum - 1;
+ if (cpu->pipelineStage[prev_stage]->stageStatus[tid] == Running ||
+ cpu->pipelineStage[prev_stage]->stageStatus[tid] == Idle) {
+ cpu->pipelineStage[prev_stage]->stageStatus[tid] = Unblocking;
+ }
+ } else {
+ DPRINTF(InOrderStage, "[tid:%i]: Inserting [sn:%i] into stage "
+ "buffer.\n", prevStage->insts[i]->readTid(),
+ prevStage->insts[i]->seqNum);
- skidBuffer[tid].push_back(prevStage->insts[i]);
+ skidBuffer[tid].push_back(prevStage->insts[i]);
+ }
prevStage->insts[i] = cpu->dummyBufferInst;
@@ -633,6 +623,7 @@ PipelineStage::sortInsts()
inserted_insts++;
}
+
assert(prevStage->size == 0);
}
}
@@ -862,12 +853,6 @@ PipelineStage::processThread(bool &status_change, ThreadID tid)
// the rest of unblocking.
processInsts(tid);
- if (prevStageValid && prevStageInstsValid()) {
- // Add the current inputs to the skid buffer so they can be
- // reprocessed when this stage unblocks.
- skidInsert(tid);
- }
-
status_change = unblock(tid) || status_change;
}
}
@@ -893,7 +878,6 @@ PipelineStage::processInsts(ThreadID tid)
while (insts_available > 0 &&
instsProcessed < stageWidth &&
- (!nextStageValid || canSendInstToStage(stageNum+1)) &&
last_req_completed) {
assert(!insts_to_stage.empty());
diff --git a/src/cpu/inorder/pipeline_stage.hh b/src/cpu/inorder/pipeline_stage.hh
index fb8ec593e..dfa88de87 100644
--- a/src/cpu/inorder/pipeline_stage.hh
+++ b/src/cpu/inorder/pipeline_stage.hh
@@ -184,11 +184,6 @@ class PipelineStage
/** Send an instruction to the next stage buffer */
bool sendInstToNextStage(DynInstPtr inst);
- /** Inserts a thread's instructions into the skid buffer, to be staged
- * once stage unblocks.
- */
- virtual void skidInsert(ThreadID tid);
-
/** Total size of all skid buffers */
int skidSize();