From 7f937e11e2779628002d063a368ee3101a32471d Mon Sep 17 00:00:00 2001 From: Korey Sewell Date: Fri, 4 Feb 2011 00:08:13 -0500 Subject: inorder: activity tracking bug Previous code was marking CPU activity on almost every cycle due to a bug in tracking the status of pipeline stages. This disables the CPU from sleeping on long latency stalls and increases simulation time --- src/cpu/inorder/first_stage.cc | 9 +++++++-- src/cpu/inorder/pipeline_stage.cc | 38 +++++++++++++++++++++++++------------- 2 files changed, 32 insertions(+), 15 deletions(-) diff --git a/src/cpu/inorder/first_stage.cc b/src/cpu/inorder/first_stage.cc index ae458c604..424d6b6a4 100644 --- a/src/cpu/inorder/first_stage.cc +++ b/src/cpu/inorder/first_stage.cc @@ -126,8 +126,10 @@ FirstStage::processStage(bool &status_change) if (tid >= 0) { DPRINTF(InOrderStage, "Processing [tid:%i]\n",tid); processThread(status_change, tid); + DPRINTF(InOrderStage, "Done Processing [tid:%i]\n",tid); } else { DPRINTF(InOrderStage, "No more threads to fetch from.\n"); + break; } } @@ -148,7 +150,7 @@ FirstStage::processInsts(ThreadID tid) { bool all_reqs_completed = true; - for (int insts_fetched = 0; + for (int insts_fetched = instsProcessed; insts_fetched < stageWidth && canSendInstToStage(1); insts_fetched++) { @@ -200,8 +202,11 @@ FirstStage::processInsts(ThreadID tid) "list.\n", tid, inst->seqNum); insts[tid].push(inst); } + block(tid); break; } else if (!insts[tid].empty()){ + DPRINTF(InOrderStage, "[tid:%u]: [sn:%u] Finished all " + "requests for this stage.\n", tid, inst->seqNum); insts[tid].pop(); } @@ -210,7 +215,7 @@ FirstStage::processInsts(ThreadID tid) // Record that stage has written to the time buffer for activity // tracking. - if (toNextStageIndex) { + if (instsProcessed) { wroteToTimeBuffer = true; } } diff --git a/src/cpu/inorder/pipeline_stage.cc b/src/cpu/inorder/pipeline_stage.cc index 2ac402fae..710af5332 100644 --- a/src/cpu/inorder/pipeline_stage.cc +++ b/src/cpu/inorder/pipeline_stage.cc @@ -281,15 +281,15 @@ PipelineStage::block(ThreadID tid) // signalled fetch to unblock. In that case, there is no need to tell // fetch to block. if (stageStatus[tid] != Blocked) { - // Set the status to Blocked. - stageStatus[tid] = Blocked; - if (stageStatus[tid] != Unblocking) { - if (prevStageValid) - toPrevStages->stageBlock[stageNum][tid] = true; wroteToTimeBuffer = true; } + stageStatus[tid] = Blocked; + + if (prevStageValid) + toPrevStages->stageBlock[stageNum][tid] = true; + return true; } @@ -304,12 +304,12 @@ PipelineStage::blockDueToBuffer(ThreadID tid) "next stage.\n", tid); if (stageStatus[tid] != Blocked) { - // Set the status to Blocked. - stageStatus[tid] = Blocked; - if (stageStatus[tid] != Unblocking) { wroteToTimeBuffer = true; } + + // Set the status to Blocked. + stageStatus[tid] = Blocked; } } @@ -595,18 +595,26 @@ PipelineStage::sortInsts() { if (prevStageValid) { int insts_from_prev_stage = prevStage->size; + int insts_from_cur_stage = skidSize(); + DPRINTF(InOrderStage, "%i insts available from stage buffer %i. Stage " + "currently has %i insts from last cycle.\n", + insts_from_prev_stage, prevStageQueue->id(), + insts_from_cur_stage); - DPRINTF(InOrderStage, "%i insts available from stage buffer %i.\n", - insts_from_prev_stage, prevStageQueue->id()); - + 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; + } if (prevStage->insts[i]->isSquashed()) { DPRINTF(InOrderStage, "[tid:%i]: Ignoring squashed [sn:%i], " "not inserting into stage buffer.\n", prevStage->insts[i]->readTid(), prevStage->insts[i]->seqNum); - + prevStage->size--; continue; } @@ -622,7 +630,11 @@ PipelineStage::sortInsts() prevStage->insts[i] = cpu->dummyBufferInst; + prevStage->size--; + + inserted_insts++; } + assert(prevStage->size == 0); } } @@ -937,7 +949,7 @@ PipelineStage::processInsts(ThreadID tid) // Record that stage has written to the time buffer for activity // tracking. - if (toNextStageIndex) { + if (instsProcessed) { wroteToTimeBuffer = true; } } -- cgit v1.2.3