42 #ifndef __CPU_O3_IEW_IMPL_IMPL_HH__
43 #define __CPU_O3_IEW_IMPL_IMPL_HH__
51 #include "arch/utility.hh"
52 #include "config/the_isa.hh"
57 #include "debug/Activity.hh"
58 #include "debug/Drain.hh"
59 #include "debug/IEW.hh"
60 #include "debug/O3PipeView.hh"
61 #include "params/DerivO3CPU.hh"
67 : issueToExecQueue(params->backComSize, params->forwardComSize),
69 instQueue(_cpu, this, params),
70 ldstQueue(_cpu, this, params),
71 fuPool(params->fuPool),
72 commitToIEWDelay(params->commitToIEWDelay),
73 renameToIEWDelay(params->renameToIEWDelay),
74 issueToExecuteDelay(params->issueToExecuteDelay),
75 dispatchWidth(params->dispatchWidth),
76 issueWidth(params->issueWidth),
79 wbWidth(params->wbWidth),
80 numThreads(params->numThreads)
83 fatal(
"dispatchWidth (%d) is larger than compiled limit (%d),\n"
84 "\tincrease MaxWidth in src/cpu/o3/impl.hh\n",
87 fatal(
"issueWidth (%d) is larger than compiled limit (%d),\n"
88 "\tincrease MaxWidth in src/cpu/o3/impl.hh\n",
91 fatal(
"wbWidth (%d) is larger than compiled limit (%d),\n"
92 "\tincrease MaxWidth in src/cpu/o3/impl.hh\n",
93 wbWidth,
static_cast<int>(Impl::MaxWidth));
105 for (
ThreadID tid = 0; tid < Impl::MaxThreads; tid++) {
115 template <
class Impl>
119 return cpu->name() +
".iew";
122 template <
class Impl>
142 template <
class Impl>
146 using namespace Stats;
148 instQueue.regStats();
151 .name(
name() +
".iewIdleCycles")
152 .desc(
"Number of cycles IEW is idle");
155 .name(
name() +
".iewSquashCycles")
156 .desc(
"Number of cycles IEW is squashing");
159 .name(
name() +
".iewBlockCycles")
160 .desc(
"Number of cycles IEW is blocking");
163 .name(
name() +
".iewUnblockCycles")
164 .desc(
"Number of cycles IEW is unblocking");
167 .name(
name() +
".iewDispatchedInsts")
168 .desc(
"Number of instructions dispatched to IQ");
171 .name(
name() +
".iewDispSquashedInsts")
172 .desc(
"Number of squashed instructions skipped by dispatch");
175 .name(
name() +
".iewDispLoadInsts")
176 .desc(
"Number of dispatched load instructions");
179 .name(
name() +
".iewDispStoreInsts")
180 .desc(
"Number of dispatched store instructions");
183 .name(
name() +
".iewDispNonSpecInsts")
184 .desc(
"Number of dispatched non-speculative instructions");
187 .name(
name() +
".iewIQFullEvents")
188 .desc(
"Number of times the IQ has become full, causing a stall");
191 .name(
name() +
".iewLSQFullEvents")
192 .desc(
"Number of times the LSQ has become full, causing a stall");
194 memOrderViolationEvents
195 .name(
name() +
".memOrderViolationEvents")
196 .desc(
"Number of memory order violations");
198 predictedTakenIncorrect
199 .name(
name() +
".predictedTakenIncorrect")
200 .desc(
"Number of branches that were predicted taken incorrectly");
202 predictedNotTakenIncorrect
203 .name(
name() +
".predictedNotTakenIncorrect")
204 .desc(
"Number of branches that were predicted not taken incorrectly");
207 .name(
name() +
".branchMispredicts")
208 .desc(
"Number of branch mispredicts detected at execute");
210 branchMispredicts = predictedTakenIncorrect + predictedNotTakenIncorrect;
213 .name(
name() +
".iewExecutedInsts")
214 .desc(
"Number of executed instructions");
217 .init(cpu->numThreads)
218 .name(
name() +
".iewExecLoadInsts")
219 .desc(
"Number of load instructions executed")
223 .name(
name() +
".iewExecSquashedInsts")
224 .desc(
"Number of squashed instructions skipped in execute");
227 .init(cpu->numThreads)
228 .name(
name() +
".exec_swp")
229 .desc(
"number of swp insts executed")
233 .init(cpu->numThreads)
234 .name(
name() +
".exec_nop")
235 .desc(
"number of nop insts executed")
239 .init(cpu->numThreads)
240 .name(
name() +
".exec_refs")
241 .desc(
"number of memory reference insts executed")
245 .init(cpu->numThreads)
246 .name(
name() +
".exec_branches")
247 .desc(
"Number of branches executed")
251 .name(
name() +
".exec_stores")
252 .desc(
"Number of stores executed")
254 iewExecStoreInsts = iewExecutedRefs - iewExecLoadInsts;
257 .name(
name() +
".exec_rate")
258 .desc(
"Inst execution rate")
261 iewExecRate = iewExecutedInsts / cpu->numCycles;
264 .init(cpu->numThreads)
265 .name(
name() +
".wb_sent")
266 .desc(
"cumulative count of insts sent to commit")
270 .init(cpu->numThreads)
271 .name(
name() +
".wb_count")
272 .desc(
"cumulative count of insts written-back")
276 .init(cpu->numThreads)
277 .name(
name() +
".wb_producers")
278 .desc(
"num instructions producing a value")
282 .init(cpu->numThreads)
283 .name(
name() +
".wb_consumers")
284 .desc(
"num instructions consuming a value")
288 .name(
name() +
".wb_fanout")
289 .desc(
"average fanout of values written-back")
292 wbFanout = producerInst / consumerInst;
295 .name(
name() +
".wb_rate")
296 .desc(
"insts written-back per cycle")
298 wbRate = writebackCount / cpu->numCycles;
305 for (
ThreadID tid = 0; tid < numThreads; tid++) {
306 toRename->iewInfo[tid].usedIQ =
true;
307 toRename->iewInfo[tid].freeIQEntries =
308 instQueue.numFreeEntries(tid);
310 toRename->iewInfo[tid].usedLSQ =
true;
311 toRename->iewInfo[tid].freeLQEntries = ldstQueue.numFreeLoadEntries(tid);
312 toRename->iewInfo[tid].freeSQEntries = ldstQueue.numFreeStoreEntries(tid);
317 cpu->checker->setDcachePort(&ldstQueue.getDataPort());
320 cpu->activateStage(O3CPU::IEWIdx);
327 toRename->iewInfo[tid].usedIQ =
true;
328 toRename->iewInfo[tid].freeIQEntries =
329 instQueue.numFreeEntries(tid);
331 toRename->iewInfo[tid].usedLSQ =
true;
332 toRename->iewInfo[tid].freeLQEntries = ldstQueue.numFreeLoadEntries(tid);
333 toRename->iewInfo[tid].freeSQEntries = ldstQueue.numFreeStoreEntries(tid);
343 fromCommit = timeBuffer->
getWire(-commitToIEWDelay);
346 toRename = timeBuffer->getWire(0);
348 toFetch = timeBuffer->getWire(0);
351 instQueue.setTimeBuffer(tb_ptr);
358 renameQueue = rq_ptr;
361 fromRename = renameQueue->
getWire(-renameToIEWDelay);
371 toCommit = iewQueue->
getWire(0);
378 activeThreads = at_ptr;
380 ldstQueue.setActiveThreads(at_ptr);
381 instQueue.setActiveThreads(at_ptr);
391 template <
class Impl>
395 bool drained = ldstQueue.isDrained() && instQueue.isDrained();
397 for (
ThreadID tid = 0; tid < numThreads; tid++) {
398 if (!insts[tid].empty()) {
399 DPRINTF(Drain,
"%i: Insts not empty.\n", tid);
402 if (!skidBuffer[tid].empty()) {
403 DPRINTF(Drain,
"%i: Skid buffer not empty.\n", tid);
406 drained = drained && dispatchStatus[tid] ==
Running;
412 if (drained && !fuPool->isDrained()) {
413 DPRINTF(Drain,
"FU pool still busy.\n");
420 template <
class Impl>
426 instQueue.drainSanityCheck();
427 ldstQueue.drainSanityCheck();
430 template <
class Impl>
439 instQueue.takeOverFrom();
440 ldstQueue.takeOverFrom();
441 fuPool->takeOverFrom();
444 cpu->activityThisCycle();
446 for (
ThreadID tid = 0; tid < numThreads; tid++) {
448 fetchRedirect[tid] =
false;
451 updateLSQNextCycle =
false;
453 for (
int i = 0;
i < issueToExecQueue.getSize(); ++
i) {
454 issueToExecQueue.advance();
462 DPRINTF(IEW,
"[tid:%i] Squashing all instructions.\n", tid);
465 instQueue.squash(tid);
468 ldstQueue.squash(fromCommit->commitInfo[tid].doneSeqNum, tid);
469 updatedQueues =
true;
473 "Removing skidbuffer instructions until "
474 "[sn:%llu] [tid:%i]\n",
475 fromCommit->commitInfo[tid].doneSeqNum, tid);
477 while (!skidBuffer[tid].empty()) {
478 if (skidBuffer[tid].front()->isLoad()) {
479 toRename->iewInfo[tid].dispatchedToLQ++;
481 if (skidBuffer[tid].front()->isStore() ||
482 skidBuffer[tid].front()->isAtomic()) {
483 toRename->iewInfo[tid].dispatchedToSQ++;
486 toRename->iewInfo[tid].dispatched++;
488 skidBuffer[tid].pop();
491 emptyRenameInsts(tid);
498 DPRINTF(IEW,
"[tid:%i] [sn:%llu] Squashing from a specific instruction,"
500 "\n", tid, inst->seqNum, inst->pcState() );
502 if (!toCommit->squash[tid] ||
503 inst->seqNum < toCommit->squashedSeqNum[tid]) {
504 toCommit->squash[tid] =
true;
505 toCommit->squashedSeqNum[tid] = inst->seqNum;
506 toCommit->branchTaken[tid] = inst->pcState().branching();
511 toCommit->pc[tid] =
pc;
512 toCommit->mispredictInst[tid] = inst;
513 toCommit->includeSquashInst[tid] =
false;
515 wroteToTimeBuffer =
true;
524 DPRINTF(IEW,
"[tid:%i] Memory violation, squashing violator and younger "
525 "insts, PC: %s [sn:%llu].\n", tid, inst->pcState(), inst->seqNum);
532 if (!toCommit->squash[tid] ||
533 inst->seqNum <= toCommit->squashedSeqNum[tid]) {
534 toCommit->squash[tid] =
true;
536 toCommit->squashedSeqNum[tid] = inst->seqNum;
537 toCommit->pc[tid] = inst->pcState();
538 toCommit->mispredictInst[tid] = NULL;
541 toCommit->includeSquashInst[tid] =
true;
543 wroteToTimeBuffer =
true;
551 DPRINTF(IEW,
"[tid:%i] Blocking.\n", tid);
553 if (dispatchStatus[tid] != Blocked &&
554 dispatchStatus[tid] != Unblocking) {
555 toRename->iewBlock[tid] =
true;
556 wroteToTimeBuffer =
true;
563 dispatchStatus[tid] = Blocked;
570 DPRINTF(IEW,
"[tid:%i] Reading instructions out of the skid "
571 "buffer %u.\n",tid, tid);
575 if (skidBuffer[tid].empty()) {
576 toRename->iewUnblock[tid] =
true;
577 wroteToTimeBuffer =
true;
578 DPRINTF(IEW,
"[tid:%i] Done unblocking.\n",tid);
587 instQueue.wakeDependents(inst);
594 instQueue.rescheduleMemInst(inst);
601 instQueue.replayMemInst(inst);
608 instQueue.blockMemInst(inst);
615 instQueue.cacheUnblocked();
632 while ((*iewQueue)[wbCycle].insts[wbNumInst]) {
634 if (wbNumInst == wbWidth) {
640 DPRINTF(IEW,
"Current wb cycle: %i, width: %i, numInst: %i\nwbActual:%i\n",
641 wbCycle, wbWidth, wbNumInst, wbCycle * wbWidth + wbNumInst);
643 (*iewQueue)[wbCycle].insts[wbNumInst] = inst;
644 (*iewQueue)[wbCycle].size++;
647 template <
class Impl>
651 unsigned inst_count = 0;
653 for (
int i=0;
i<fromRename->size;
i++) {
654 if (!fromRename->insts[
i]->isSquashed())
667 while (!insts[tid].empty()) {
668 inst = insts[tid].front();
672 DPRINTF(IEW,
"[tid:%i] Inserting [sn:%lli] PC:%s into "
673 "dispatch skidBuffer %i\n",tid, inst->seqNum,
674 inst->pcState(),tid);
676 skidBuffer[tid].push(inst);
679 assert(skidBuffer[tid].size() <= skidBufferMax &&
680 "Skidbuffer Exceeded Max Size");
692 while (threads != end) {
694 unsigned thread_count = skidBuffer[tid].size();
695 if (max < thread_count)
709 while (threads != end) {
712 if (!skidBuffer[tid].empty())
719 template <
class Impl>
723 bool any_unblocking =
false;
728 while (threads != end) {
731 if (dispatchStatus[tid] == Unblocking) {
732 any_unblocking =
true;
740 instQueue.intInstQueueReads++;
741 if (_status == Active && !instQueue.hasReadyInsts() &&
742 !ldstQueue.willWB() && !any_unblocking) {
743 DPRINTF(IEW,
"IEW switching to idle\n");
748 }
else if (_status == Inactive && (instQueue.hasReadyInsts() ||
749 ldstQueue.willWB() ||
752 DPRINTF(IEW,
"IEW switching to active\n");
760 template <
class Impl>
766 if (fromCommit->commitInfo[tid].robSquashing) {
767 DPRINTF(IEW,
"[tid:%i] Stall from Commit stage detected.\n",tid);
769 }
else if (instQueue.isFull(tid)) {
770 DPRINTF(IEW,
"[tid:%i] Stall: IQ is full.\n",tid);
777 template <
class Impl>
788 if (fromCommit->commitInfo[tid].squash) {
791 if (dispatchStatus[tid] == Blocked ||
792 dispatchStatus[tid] == Unblocking) {
793 toRename->iewUnblock[tid] =
true;
794 wroteToTimeBuffer =
true;
797 dispatchStatus[tid] = Squashing;
798 fetchRedirect[tid] =
false;
802 if (fromCommit->commitInfo[tid].robSquashing) {
803 DPRINTF(IEW,
"[tid:%i] ROB is still squashing.\n", tid);
805 dispatchStatus[tid] = Squashing;
806 emptyRenameInsts(tid);
807 wroteToTimeBuffer =
true;
810 if (checkStall(tid)) {
812 dispatchStatus[tid] = Blocked;
816 if (dispatchStatus[tid] == Blocked) {
819 DPRINTF(IEW,
"[tid:%i] Done blocking, switching to unblocking.\n",
822 dispatchStatus[tid] = Unblocking;
829 if (dispatchStatus[tid] == Squashing) {
832 DPRINTF(IEW,
"[tid:%i] Done squashing, switching to running.\n",
841 template <
class Impl>
845 int insts_from_rename = fromRename->size;
847 for (
ThreadID tid = 0; tid < numThreads; tid++)
848 assert(insts[tid].empty());
850 for (
int i = 0;
i < insts_from_rename; ++
i) {
851 insts[fromRename->insts[
i]->threadNumber].push(fromRename->insts[
i]);
855 template <
class Impl>
859 DPRINTF(IEW,
"[tid:%i] Removing incoming rename instructions\n", tid);
861 while (!insts[tid].empty()) {
863 if (insts[tid].front()->isLoad()) {
864 toRename->iewInfo[tid].dispatchedToLQ++;
866 if (insts[tid].front()->isStore() ||
867 insts[tid].front()->isAtomic()) {
868 toRename->iewInfo[tid].dispatchedToSQ++;
871 toRename->iewInfo[tid].dispatched++;
877 template <
class Impl>
884 template <
class Impl>
888 DPRINTF(Activity,
"Activity this cycle.\n");
889 cpu->activityThisCycle();
892 template <
class Impl>
896 DPRINTF(Activity,
"Activating stage.\n");
897 cpu->activateStage(O3CPU::IEWIdx);
900 template <
class Impl>
904 DPRINTF(Activity,
"Deactivating stage.\n");
905 cpu->deactivateStage(O3CPU::IEWIdx);
919 if (dispatchStatus[tid] == Blocked) {
922 }
else if (dispatchStatus[tid] == Squashing) {
928 if (dispatchStatus[tid] ==
Running ||
929 dispatchStatus[tid] == Idle) {
930 DPRINTF(IEW,
"[tid:%i] Not blocked, so attempting to run "
934 }
else if (dispatchStatus[tid] == Unblocking) {
937 assert(!skidsEmpty());
946 if (validInstsFromRename()) {
956 template <
class Impl>
962 std::queue<DynInstPtr> &insts_to_dispatch =
963 dispatchStatus[tid] == Unblocking ?
964 skidBuffer[tid] : insts[tid];
966 int insts_to_add = insts_to_dispatch.size();
969 bool add_to_iq =
false;
970 int dis_num_inst = 0;
974 for ( ; dis_num_inst < insts_to_add &&
975 dis_num_inst < dispatchWidth;
978 inst = insts_to_dispatch.front();
980 if (dispatchStatus[tid] == Unblocking) {
981 DPRINTF(IEW,
"[tid:%i] Issue: Examining instruction from skid "
988 DPRINTF(IEW,
"[tid:%i] Issue: Adding PC %s [sn:%lli] [tid:%i] to "
990 tid, inst->pcState(), inst->seqNum, inst->threadNumber);
997 if (inst->isSquashed()) {
998 DPRINTF(IEW,
"[tid:%i] Issue: Squashed instruction encountered, "
999 "not adding to IQ.\n", tid);
1001 ++iewDispSquashedInsts;
1003 insts_to_dispatch.pop();
1006 if (inst->isLoad()) {
1007 toRename->iewInfo[tid].dispatchedToLQ++;
1009 if (inst->isStore() || inst->isAtomic()) {
1010 toRename->iewInfo[tid].dispatchedToSQ++;
1013 toRename->iewInfo[tid].dispatched++;
1019 if (instQueue.isFull(tid)) {
1020 DPRINTF(IEW,
"[tid:%i] Issue: IQ has become full.\n", tid);
1028 toRename->iewUnblock[tid] =
false;
1035 if ((inst->isAtomic() && ldstQueue.sqFull(tid)) ||
1036 (inst->isLoad() && ldstQueue.lqFull(tid)) ||
1037 (inst->isStore() && ldstQueue.sqFull(tid))) {
1038 DPRINTF(IEW,
"[tid:%i] Issue: %s has become full.\n",tid,
1039 inst->isLoad() ?
"LQ" :
"SQ");
1047 toRename->iewUnblock[tid] =
false;
1055 const int numHtmStarts = ldstQueue.numHtmStarts(tid);
1056 const int numHtmStops = ldstQueue.numHtmStops(tid);
1057 const int htmDepth = numHtmStarts - numHtmStops;
1060 inst->setHtmTransactionalState(ldstQueue.getLatestHtmUid(tid),
1063 inst->clearHtmTransactionalState();
1068 if (inst->isAtomic()) {
1069 DPRINTF(IEW,
"[tid:%i] Issue: Memory instruction "
1070 "encountered, adding to LSQ.\n", tid);
1072 ldstQueue.insertStore(inst);
1074 ++iewDispStoreInsts;
1079 inst->setCanCommit();
1080 instQueue.insertNonSpec(inst);
1083 ++iewDispNonSpecInsts;
1085 toRename->iewInfo[tid].dispatchedToSQ++;
1086 }
else if (inst->isLoad()) {
1087 DPRINTF(IEW,
"[tid:%i] Issue: Memory instruction "
1088 "encountered, adding to LSQ.\n", tid);
1092 ldstQueue.insertLoad(inst);
1098 toRename->iewInfo[tid].dispatchedToLQ++;
1099 }
else if (inst->isStore()) {
1100 DPRINTF(IEW,
"[tid:%i] Issue: Memory instruction "
1101 "encountered, adding to LSQ.\n", tid);
1103 ldstQueue.insertStore(inst);
1105 ++iewDispStoreInsts;
1107 if (inst->isStoreConditional()) {
1112 inst->setCanCommit();
1113 instQueue.insertNonSpec(inst);
1116 ++iewDispNonSpecInsts;
1121 toRename->iewInfo[tid].dispatchedToSQ++;
1122 }
else if (inst->isMemBarrier() || inst->isWriteBarrier()) {
1124 inst->setCanCommit();
1125 instQueue.insertBarrier(inst);
1127 }
else if (inst->isNop()) {
1128 DPRINTF(IEW,
"[tid:%i] Issue: Nop instruction encountered, "
1129 "skipping.\n", tid);
1132 inst->setExecuted();
1133 inst->setCanCommit();
1135 instQueue.recordProducer(inst);
1137 iewExecutedNop[tid]++;
1141 assert(!inst->isExecuted());
1145 if (add_to_iq && inst->isNonSpeculative()) {
1146 DPRINTF(IEW,
"[tid:%i] Issue: Nonspeculative instruction "
1147 "encountered, skipping.\n", tid);
1150 inst->setCanCommit();
1153 instQueue.insertNonSpec(inst);
1155 ++iewDispNonSpecInsts;
1163 instQueue.insert(inst);
1166 insts_to_dispatch.pop();
1168 toRename->iewInfo[tid].dispatched++;
1170 ++iewDispatchedInsts;
1173 inst->dispatchTick =
curTick() - inst->fetchTick;
1175 ppDispatch->notify(inst);
1178 if (!insts_to_dispatch.empty()) {
1179 DPRINTF(IEW,
"[tid:%i] Issue: Bandwidth Full. Blocking.\n", tid);
1181 toRename->iewUnblock[tid] =
false;
1184 if (dispatchStatus[tid] == Idle && dis_num_inst) {
1185 dispatchStatus[tid] =
Running;
1187 updatedQueues =
true;
1193 template <
class Impl>
1199 std::cout <<
"Available Instructions: ";
1201 while (fromIssue->insts[inst]) {
1203 if (inst%3==0) std::cout <<
"\n\t";
1205 std::cout <<
"PC: " << fromIssue->insts[inst]->pcState()
1206 <<
" TN: " << fromIssue->insts[inst]->threadNumber
1207 <<
" SN: " << fromIssue->insts[inst]->seqNum <<
" | ";
1216 template <
class Impl>
1226 while (threads != end) {
1228 fetchRedirect[tid] =
false;
1236 int insts_to_execute = fromIssue->size;
1238 for (; inst_num < insts_to_execute;
1241 DPRINTF(IEW,
"Execute: Executing instructions from IQ.\n");
1243 DynInstPtr inst = instQueue.getInstToExecute();
1245 DPRINTF(IEW,
"Execute: Processing PC %s, [tid:%i] [sn:%llu].\n",
1246 inst->pcState(), inst->threadNumber,inst->seqNum);
1250 ppExecute->notify(inst);
1253 if (inst->isSquashed()) {
1254 DPRINTF(IEW,
"Execute: Instruction was squashed. PC: %s, [tid:%i]"
1255 " [sn:%llu]\n", inst->pcState(), inst->threadNumber,
1260 inst->setExecuted();
1264 inst->setCanCommit();
1266 ++iewExecSquashedInsts;
1276 if (inst->isMemRef()) {
1277 DPRINTF(IEW,
"Execute: Calculating address for memory "
1281 if (inst->isAtomic()) {
1283 fault = ldstQueue.executeStore(inst);
1285 if (inst->isTranslationDelayed() &&
1289 DPRINTF(IEW,
"Execute: Delayed translation, deferring "
1291 instQueue.deferMemInst(inst);
1294 }
else if (inst->isLoad()) {
1297 fault = ldstQueue.executeLoad(inst);
1299 if (inst->isTranslationDelayed() &&
1303 DPRINTF(IEW,
"Execute: Delayed translation, deferring "
1305 instQueue.deferMemInst(inst);
1309 if (inst->isDataPrefetch() || inst->isInstPrefetch()) {
1312 }
else if (inst->isStore()) {
1313 fault = ldstQueue.executeStore(inst);
1315 if (inst->isTranslationDelayed() &&
1319 DPRINTF(IEW,
"Execute: Delayed translation, deferring "
1321 instQueue.deferMemInst(inst);
1326 if (fault !=
NoFault || !inst->readPredicate() ||
1327 !inst->isStoreConditional()) {
1332 inst->setExecuted();
1334 activityThisCycle();
1341 panic(
"Unexpected memory type!\n");
1349 if (inst->getFault() ==
NoFault) {
1351 if (!inst->readPredicate())
1352 inst->forwardOldRegs();
1355 inst->setExecuted();
1360 updateExeInstStats(inst);
1372 if (!fetchRedirect[tid] ||
1373 !toCommit->squash[tid] ||
1374 toCommit->squashedSeqNum[tid] > inst->seqNum) {
1378 bool loadNotExecuted = !inst->isExecuted() && inst->isLoad();
1380 if (inst->mispredicted() && !loadNotExecuted) {
1381 fetchRedirect[tid] =
true;
1383 DPRINTF(IEW,
"[tid:%i] [sn:%llu] Execute: "
1384 "Branch mispredict detected.\n",
1386 DPRINTF(IEW,
"[tid:%i] [sn:%llu] "
1387 "Predicted target was PC: %s\n",
1388 tid,inst->seqNum,inst->readPredTarg());
1389 DPRINTF(IEW,
"[tid:%i] [sn:%llu] Execute: "
1390 "Redirecting fetch to PC: %s\n",
1391 tid,inst->seqNum,inst->pcState());
1393 squashDueToBranch(inst, tid);
1395 ppMispredict->notify(inst);
1397 if (inst->readPredTaken()) {
1398 predictedTakenIncorrect++;
1400 predictedNotTakenIncorrect++;
1402 }
else if (ldstQueue.violation(tid)) {
1403 assert(inst->isMemRef());
1408 violator = ldstQueue.getMemDepViolator(tid);
1410 DPRINTF(IEW,
"LDSTQ detected a violation. Violator PC: %s "
1411 "[sn:%lli], inst PC: %s [sn:%lli]. Addr is: %#x.\n",
1412 violator->pcState(), violator->seqNum,
1413 inst->pcState(), inst->seqNum, inst->physEffAddr);
1415 fetchRedirect[tid] =
true;
1418 instQueue.violation(inst, violator);
1421 squashDueToMemOrder(violator, tid);
1423 ++memOrderViolationEvents;
1428 if (ldstQueue.violation(tid)) {
1429 assert(inst->isMemRef());
1431 DynInstPtr violator = ldstQueue.getMemDepViolator(tid);
1433 DPRINTF(IEW,
"LDSTQ detected a violation. Violator PC: "
1434 "%s, inst PC: %s. Addr is: %#x.\n",
1435 violator->pcState(), inst->pcState(),
1437 DPRINTF(IEW,
"Violation will not be handled because "
1438 "already squashing\n");
1440 ++memOrderViolationEvents;
1447 if (exeStatus == Idle) {
1451 updatedQueues =
true;
1453 cpu->activityThisCycle();
1463 template <
class Impl>
1472 for (
int inst_num = 0; inst_num < wbWidth &&
1473 toCommit->insts[inst_num]; inst_num++) {
1477 DPRINTF(IEW,
"Sending instructions to commit, [sn:%lli] PC %s.\n",
1478 inst->seqNum, inst->pcState());
1480 iewInstsToCommit[tid]++;
1483 ppToCommit->notify(inst);
1490 if (!inst->isSquashed() && inst->isExecuted() && inst->getFault() ==
NoFault) {
1491 int dependents = instQueue.wakeDependents(inst);
1493 for (
int i = 0;
i < inst->numDestRegs();
i++) {
1495 if (inst->renamedDestRegIdx(
i)->
1496 getNumPinnedWritesToComplete() == 0) {
1497 DPRINTF(IEW,
"Setting Destination Register %i (%s)\n",
1498 inst->renamedDestRegIdx(
i)->index(),
1499 inst->renamedDestRegIdx(
i)->className());
1500 scoreboard->setReg(inst->renamedDestRegIdx(
i));
1505 producerInst[tid]++;
1506 consumerInst[tid]+= dependents;
1508 writebackCount[tid]++;
1513 template<
class Impl>
1520 wroteToTimeBuffer =
false;
1521 updatedQueues =
false;
1528 fuPool->processFreeUnits();
1534 while (threads != end) {
1537 DPRINTF(IEW,
"Issue: Processing [tid:%i]\n",tid);
1539 checkSignalsAndUpdate(tid);
1543 if (exeStatus != Squashing) {
1551 instQueue.scheduleReadyInsts();
1555 issueToExecQueue.advance();
1558 bool broadcast_free_entries =
false;
1560 if (updatedQueues || exeStatus ==
Running || updateLSQNextCycle) {
1562 updateLSQNextCycle =
false;
1564 broadcast_free_entries =
true;
1568 ldstQueue.writebackStores();
1575 threads = activeThreads->begin();
1576 while (threads != end) {
1579 DPRINTF(IEW,
"Processing [tid:%i]\n",tid);
1582 if (fromCommit->commitInfo[tid].doneSeqNum != 0 &&
1583 !fromCommit->commitInfo[tid].squash &&
1584 !fromCommit->commitInfo[tid].robSquashing) {
1586 ldstQueue.commitStores(fromCommit->commitInfo[tid].doneSeqNum,tid);
1588 ldstQueue.commitLoads(fromCommit->commitInfo[tid].doneSeqNum,tid);
1590 updateLSQNextCycle =
true;
1591 instQueue.commit(fromCommit->commitInfo[tid].doneSeqNum,tid);
1594 if (fromCommit->commitInfo[tid].nonSpecSeqNum != 0) {
1597 if (fromCommit->commitInfo[tid].strictlyOrdered) {
1598 instQueue.replayMemInst(
1599 fromCommit->commitInfo[tid].strictlyOrderedLoad);
1600 fromCommit->commitInfo[tid].strictlyOrderedLoad->setAtCommit();
1602 instQueue.scheduleNonSpec(
1603 fromCommit->commitInfo[tid].nonSpecSeqNum);
1607 if (broadcast_free_entries) {
1608 toFetch->iewInfo[tid].iqCount =
1609 instQueue.getCount(tid);
1610 toFetch->iewInfo[tid].ldstqCount =
1611 ldstQueue.getCount(tid);
1613 toRename->iewInfo[tid].usedIQ =
true;
1614 toRename->iewInfo[tid].freeIQEntries =
1615 instQueue.numFreeEntries(tid);
1616 toRename->iewInfo[tid].usedLSQ =
true;
1618 toRename->iewInfo[tid].freeLQEntries =
1619 ldstQueue.numFreeLoadEntries(tid);
1620 toRename->iewInfo[tid].freeSQEntries =
1621 ldstQueue.numFreeStoreEntries(tid);
1623 wroteToTimeBuffer =
true;
1626 DPRINTF(IEW,
"[tid:%i], Dispatch dispatched %i instructions.\n",
1627 tid, toRename->iewInfo[tid].dispatched);
1630 DPRINTF(IEW,
"IQ has %i free entries (Can schedule: %i). "
1631 "LQ has %i free entries. SQ has %i free entries.\n",
1632 instQueue.numFreeEntries(), instQueue.hasReadyInsts(),
1633 ldstQueue.numFreeLoadEntries(), ldstQueue.numFreeStoreEntries());
1637 if (wroteToTimeBuffer) {
1638 DPRINTF(Activity,
"Activity this cycle.\n");
1639 cpu->activityThisCycle();
1643 template <
class Impl>
1652 if (
DTRACE(O3PipeView)) {
1653 inst->completeTick =
curTick() - inst->fetchTick;
1660 if (inst->isControl())
1661 iewExecutedBranches[tid]++;
1666 if (inst->isMemRef()) {
1667 iewExecutedRefs[tid]++;
1669 if (inst->isLoad()) {
1670 iewExecLoadInsts[tid]++;
1675 template <
class Impl>
1681 if (!fetchRedirect[tid] ||
1682 !toCommit->squash[tid] ||
1683 toCommit->squashedSeqNum[tid] > inst->seqNum) {
1685 if (inst->mispredicted()) {
1686 fetchRedirect[tid] =
true;
1688 DPRINTF(IEW,
"[tid:%i] [sn:%llu] Execute: "
1689 "Branch mispredict detected.\n",
1691 DPRINTF(IEW,
"[tid:%i] [sn:%llu] Predicted target "
1692 "was PC:%#x, NPC:%#x\n",
1694 inst->predInstAddr(), inst->predNextInstAddr());
1695 DPRINTF(IEW,
"[tid:%i] [sn:%llu] Execute: "
1696 "Redirecting fetch to PC: %#x, "
1699 inst->nextInstAddr(),
1700 inst->nextInstAddr());
1702 squashDueToBranch(inst, tid);
1704 if (inst->readPredTaken()) {
1705 predictedTakenIncorrect++;
1707 predictedNotTakenIncorrect++;
1713 #endif//__CPU_O3_IEW_IMPL_IMPL_HH__