// 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,
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) {
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;
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
ThreadID tid = *activeThreads->begin();
if (stageStatus[tid] == Running ||
- stageStatus[tid] == Idle) {
+ stageStatus[tid] == Idle ||
+ stageStatus[tid] == Unblocking) {
return tid;
} else {
return InvalidThreadID;
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);
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.
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();
+
}
}
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..."
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)) {
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()
{
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",
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;
inserted_insts++;
}
+
assert(prevStage->size == 0);
}
}
// 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;
}
}
while (insts_available > 0 &&
instsProcessed < stageWidth &&
- (!nextStageValid || canSendInstToStage(stageNum+1)) &&
last_req_completed) {
assert(!insts_to_stage.empty());