diff options
Diffstat (limited to 'src/cpu/inorder')
-rw-r--r-- | src/cpu/inorder/first_stage.cc | 39 | ||||
-rw-r--r-- | src/cpu/inorder/first_stage.hh | 5 | ||||
-rw-r--r-- | src/cpu/inorder/pipeline_stage.cc | 92 | ||||
-rw-r--r-- | src/cpu/inorder/pipeline_stage.hh | 5 |
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(); |