changeset 02562dac0416 in /z/repo/m5
details: http://repo.m5sim.org/m5?cmd=changeset;node=02562dac0416
description:
inorder: switch out buffer
add buffer for instructions to switch out to in a pipeline stage
can't squash the instruction and remove the pipeline so we kind of need
to 'suspend' an instruction at the stage while the memory stall resolves
for the switch on cache miss model
diffstat:
2 files changed, 95 insertions(+), 61 deletions(-)
src/cpu/inorder/pipeline_stage.cc | 137 +++++++++++++++++++++----------------
src/cpu/inorder/pipeline_stage.hh | 19 ++++-
diffs (truncated from 378 to 300 lines):
diff -r 9b37243a6568 -r 02562dac0416 src/cpu/inorder/pipeline_stage.cc
--- a/src/cpu/inorder/pipeline_stage.cc Sun Jan 31 18:25:27 2010 -0500
+++ b/src/cpu/inorder/pipeline_stage.cc Sun Jan 31 18:25:48 2010 -0500
@@ -44,6 +44,9 @@
stageBufferMax(ThePipeline::interStageBuffSize[stage_num]),
prevStageValid(false), nextStageValid(false)
{
+ switchedOutBuffer.resize(ThePipeline::MaxThreads);
+ switchedOutValid.resize(ThePipeline::MaxThreads);
+
init(params);
}
@@ -267,7 +270,8 @@
bool
PipelineStage::block(ThreadID tid)
{
- DPRINTF(InOrderStage, "[tid:%d]: Blocking, sending block signal back to
previous stages.\n", 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.
@@ -296,7 +300,8 @@
void
PipelineStage::blockDueToBuffer(ThreadID tid)
{
- DPRINTF(InOrderStage, "[tid:%d]: Blocking instructions from passing to
next stage.\n", tid);
+ DPRINTF(InOrderStage, "[tid:%d]: Blocking instructions from passing to "
+ "next stage.\n", tid);
if (stageStatus[tid] != Blocked) {
// Set the status to Blocked.
@@ -334,8 +339,9 @@
{
if (cpu->squashSeqNum[tid] < inst->seqNum &&
cpu->lastSquashCycle[tid] == curTick){
- DPRINTF(Resource, "Ignoring [sn:%i] squash signal due to another
stage's squash "
- "signal for after [sn:%i].\n", inst->seqNum,
cpu->squashSeqNum[tid]);
+ DPRINTF(Resource, "Ignoring [sn:%i] squash signal due to another "
+ "stage's squash signal for after [sn:%i].\n", inst->seqNum,
+ cpu->squashSeqNum[tid]);
} else {
// Send back mispredict information.
toPrevStages->stageInfo[stageNum][tid].branchMispredict = true;
@@ -346,20 +352,28 @@
#if ISA_HAS_DELAY_SLOT
- toPrevStages->stageInfo[stageNum][tid].branchTaken =
inst->readNextNPC() !=
+ toPrevStages->stageInfo[stageNum][tid].branchTaken =
+ inst->readNextNPC() !=
(inst->readNextPC() + sizeof(TheISA::MachInst));
- toPrevStages->stageInfo[stageNum][tid].bdelayDoneSeqNum =
inst->bdelaySeqNum;
+
+ toPrevStages->stageInfo[stageNum][tid].bdelayDoneSeqNum =
+ inst->bdelaySeqNum;
+
InstSeqNum squash_seq_num = inst->bdelaySeqNum;
#else
- toPrevStages->stageInfo[stageNum][tid].branchTaken =
inst->readNextPC() !=
+ toPrevStages->stageInfo[stageNum][tid].branchTaken =
+ inst->readNextPC() !=
(inst->readPC() + sizeof(TheISA::MachInst));
+
toPrevStages->stageInfo[stageNum][tid].bdelayDoneSeqNum = inst->seqNum;
InstSeqNum squash_seq_num = inst->seqNum;
#endif
- DPRINTF(InOrderStage, "Target being re-set to %08p\n",
inst->readPredTarg());
- DPRINTF(InOrderStage, "[tid:%i]: Squashing after [sn:%i], due to
[sn:%i] "
- "branch.\n", tid, squash_seq_num, inst->seqNum);
+ DPRINTF(InOrderStage, "Target being re-set to %08p\n",
+ inst->readPredTarg());
+ DPRINTF(InOrderStage, "[tid:%i]: Squashing after [sn:%i], "
+ "due to [sn:%i] branch.\n", tid, squash_seq_num,
+ inst->seqNum);
// Save squash num for later stage use
cpu->squashSeqNum[tid] = squash_seq_num;
@@ -394,8 +408,8 @@
squashPrevStageInsts(squash_seq_num, tid);
- DPRINTF(InOrderStage, "[tid:%i]: Removing instructions from incoming stage
skidbuffer.\n",
- 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) {
DPRINTF(InOrderStage, "[tid:%i]: Cannot remove skidBuffer "
@@ -404,8 +418,9 @@
skidBuffer[tid].size());
break;
}
- DPRINTF(InOrderStage, "[tid:%i]: Removing instruction, [sn:%i] PC
%08p.\n",
- tid, skidBuffer[tid].front()->seqNum,
skidBuffer[tid].front()->PC);
+ DPRINTF(InOrderStage, "[tid:%i]: Removing instruction, [sn:%i] "
+ " PC %08p.\n", tid, skidBuffer[tid].front()->seqNum,
+ skidBuffer[tid].front()->PC);
skidBuffer[tid].pop();
}
@@ -427,7 +442,8 @@
int avail = stageBufferMax - total -0;// incoming_insts;
if (avail < 0)
- fatal("stageNum %i:stageBufferAvail() <
0...stBMax=%i,total=%i,incoming=%i=>%i",
+ fatal("stageNum %i:stageBufferAvail() < 0..."
+ "stBMax=%i,total=%i,incoming=%i=>%i",
stageNum, stageBufferMax, total, incoming_insts, avail);
return avail;
@@ -443,7 +459,8 @@
}
if (!buffer_avail && nextStageQueueValid(stage_num)) {
- DPRINTF(InOrderStall, "STALL: No room in stage %i buffer.\n", stageNum
+ 1);
+ DPRINTF(InOrderStall, "STALL: No room in stage %i buffer.\n",
+ stageNum + 1);
}
return buffer_avail;
@@ -461,8 +478,9 @@
assert(tid == inst->threadNumber);
- DPRINTF(InOrderStage,"[tid:%i]: Inserting [sn:%lli] PC:%#x into stage
skidBuffer %i\n",
- tid, inst->seqNum, inst->readPC(), inst->threadNumber);
+ DPRINTF(InOrderStage,"[tid:%i]: Inserting [sn:%lli] PC:%#x into stage "
+ "skidBuffer %i\n", tid, inst->seqNum, inst->readPC(),
+ inst->threadNumber);
skidBuffer[tid].push(inst);
}
@@ -547,16 +565,16 @@
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",
+ DPRINTF(InOrderStage, "[tid:%i]: Ignoring squashed [sn:%i], "
+ "not inserting into stage buffer.\n",
prevStage->insts[i]->readTid(),
prevStage->insts[i]->seqNum);
continue;
}
- DPRINTF(InOrderStage, "[tid:%i]: Inserting [sn:%i] into stage
buffer.\n",
- prevStage->insts[i]->readTid(),
+ 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;
@@ -611,8 +629,8 @@
// Check for squash from later pipeline stages
for (int stage_idx=stageNum; stage_idx < NumStages; stage_idx++) {
if (fromNextStages->stageInfo[stage_idx][tid].squash) {
- DPRINTF(InOrderStage, "[tid:%u]: Squashing instructions due to
squash "
- "from stage %u.\n", tid, stage_idx);
+ DPRINTF(InOrderStage, "[tid:%u]: Squashing instructions due to "
+ "squash from stage %u.\n", tid, stage_idx);
InstSeqNum squash_seq_num = fromNextStages->
stageInfo[stage_idx][tid].bdelayDoneSeqNum;
squash(squash_seq_num, tid);
@@ -625,8 +643,8 @@
}
if (stageStatus[tid] == Blocked) {
- DPRINTF(InOrderStage, "[tid:%u]: Done blocking, switching to
unblocking.\n",
- tid);
+ DPRINTF(InOrderStage, "[tid:%u]: Done blocking, switching to "
+ "unblocking.\n", tid);
stageStatus[tid] = Unblocking;
@@ -637,15 +655,15 @@
if (stageStatus[tid] == Squashing) {
if (!skidBuffer[tid].empty()) {
- DPRINTF(InOrderStage, "[tid:%u]: Done squashing, switching to
unblocking.\n",
- tid);
+ DPRINTF(InOrderStage, "[tid:%u]: Done squashing, switching to "
+ "unblocking.\n", tid);
stageStatus[tid] = Unblocking;
} else {
// Switch status to running if stage isn't being told to block or
// squash this cycle.
- DPRINTF(InOrderStage, "[tid:%u]: Done squashing, switching to
running.\n",
- tid);
+ DPRINTF(InOrderStage, "[tid:%u]: Done squashing, switching to "
+ "running.\n", tid);
stageStatus[tid] = Running;
}
@@ -717,13 +735,13 @@
}
if (stalls[tid].resources.size() == 0) {
- DPRINTF(InOrderStage, "[tid:%u]: There are no remaining resource
stalls.\n",
- tid);
+ DPRINTF(InOrderStage, "[tid:%u]: There are no remaining resource"
+ "stalls.\n", tid);
}
}
-// @TODO: Update How we handled threads in CPU. Maybe threads shouldnt be
handled
-// one at a time, but instead first come first serve by instruction?
+// @TODO: Update How we handled threads in CPU. Maybe threads shouldnt be
+// handled one at a time, but instead first come first serve by instruction?
// Questions are how should a pipeline stage handle thread-specific stalls &
// pipeline squashes
void
@@ -749,8 +767,8 @@
DPRINTF(InOrderStage, "%i left in stage %i incoming buffer.\n", skidSize(),
stageNum);
- DPRINTF(InOrderStage, "%i available in stage %i incoming buffer.\n",
stageBufferAvail(),
- stageNum);
+ DPRINTF(InOrderStage, "%i available in stage %i incoming buffer.\n",
+ stageBufferAvail(), stageNum);
}
void
@@ -828,8 +846,8 @@
inst = insts_to_stage.front();
- DPRINTF(InOrderStage, "[tid:%u]: Processing instruction [sn:%lli] with
"
- "PC %#x\n",
+ DPRINTF(InOrderStage, "[tid:%u]: Processing instruction [sn:%lli] "
+ "with PC %#x\n",
tid, inst->seqNum, inst->readPC());
if (inst->isSquashed()) {
@@ -856,8 +874,8 @@
// Send to Next Stage or Break Loop
if (nextStageValid && !sendInstToNextStage(inst)) {
- DPRINTF(InOrderStage, "[tid:%i] [sn:%i] unable to proceed to stage
%i.\n",
- tid, inst->seqNum,inst->nextStage);
+ DPRINTF(InOrderStage, "[tid:%i] [sn:%i] unable to proceed to stage"
+ " %i.\n", tid, inst->seqNum,inst->nextStage);
break;
}
@@ -897,14 +915,15 @@
int res_num = inst->nextResource();
- DPRINTF(InOrderStage, "[tid:%i]: [sn:%i]: sending request to
%s.\n",
- tid, inst->seqNum, cpu->resPool->name(res_num));
+ DPRINTF(InOrderStage, "[tid:%i]: [sn:%i]: sending request to %s."
+ "\n", tid, inst->seqNum, cpu->resPool->name(res_num));
ResReqPtr req = cpu->resPool->request(res_num, inst);
if (req->isCompleted()) {
- DPRINTF(InOrderStage, "[tid:%i]: [sn:%i] request to %s
completed.\n",
- tid, inst->seqNum, cpu->resPool->name(res_num));
+ DPRINTF(InOrderStage, "[tid:%i]: [sn:%i] request to %s "
+ "completed.\n", tid, inst->seqNum,
+ cpu->resPool->name(res_num));
if (req->fault == NoFault) {
inst->popSchedEntry();
@@ -913,8 +932,8 @@
curTick, req->fault->name());
}
} else {
- DPRINTF(InOrderStage, "[tid:%i]: [sn:%i] request to %s
failed.\n",
- tid, inst->seqNum, cpu->resPool->name(res_num));
+ DPRINTF(InOrderStage, "[tid:%i]: [sn:%i] request to %s failed."
+ "\n", tid, inst->seqNum, cpu->resPool->name(res_num));
last_req_completed = false;
@@ -956,12 +975,12 @@
assert(next_stage >= 1);
assert(prev_stage >= 0);
- DPRINTF(InOrderStage, "[tid:%u]: Attempting to send instructions to stage
%u.\n", tid,
- stageNum+1);
+ DPRINTF(InOrderStage, "[tid:%u]: Attempting to send instructions to "
+ "stage %u.\n", tid, stageNum+1);
if (!canSendInstToStage(inst->nextStage)) {
- DPRINTF(InOrderStage, "[tid:%u]: Could not send instruction to stage
%u.\n", tid,
- stageNum+1);
+ DPRINTF(InOrderStage, "[tid:%u]: Could not send instruction to "
+ "stage %u.\n", tid, stageNum+1);
return false;
}
@@ -969,12 +988,14 @@
if (nextStageQueueValid(inst->nextStage - 1)) {
if (inst->seqNum > cpu->squashSeqNum[tid] &&
_______________________________________________
m5-dev mailing list
[email protected]
http://m5sim.org/mailman/listinfo/m5-dev