@@ -119,6 +119,13 @@ InstructionQueue::MdpAddrReplayLdInst::MdpAddrReplayLdInst(
119119{
120120}
121121
122+ bool
123+ InstructionQueue::PhysicalSQFullReplayOrder::operator ()(
124+ const DynInstPtr &lhs, const DynInstPtr &rhs) const
125+ {
126+ return lhs->seqNum > rhs->seqNum ;
127+ }
128+
122129bool
123130InstructionQueue::hasMdpAddrReplayInsts () const
124131{
@@ -397,6 +404,9 @@ InstructionQueue::resetState()
397404 for (auto &replay_ld_insts : mdpAddrReplayLdInsts) {
398405 replay_ld_insts.clear ();
399406 }
407+ for (auto &replay_q : physicalSQFullReplayQs) {
408+ replay_q = PhysicalSQFullReplayQueue ();
409+ }
400410 blockedMemInsts.clear ();
401411 retryMemInsts.clear ();
402412 wbOutstanding = 0 ;
@@ -434,6 +444,7 @@ InstructionQueue::isDrained() const
434444 bool drained = scheduler->isDrained () &&
435445 instsToExecute.empty () &&
436446 wbOutstanding == 0 ;
447+ drained = drained && !hasPhysicalSQFullReplayInsts ();
437448 for (ThreadID tid = 0 ; tid < numThreads; ++tid)
438449 drained = drained && memDepUnit[tid].isDrained ();
439450
444455InstructionQueue::drainSanityCheck () const
445456{
446457 assert (instsToExecute.empty ());
458+ assert (!hasPhysicalSQFullReplayInsts ());
447459 for (ThreadID tid = 0 ; tid < numThreads; ++tid)
448460 memDepUnit[tid].drainSanityCheck ();
449461}
@@ -472,6 +484,7 @@ InstructionQueue::insert(const DynInstPtr &new_inst, int disp_seq)
472484 }
473485 // Make sure the instruction is valid
474486 assert (new_inst);
487+ new_inst->instQueue = this ;
475488
476489 DPRINTF (IQ , " Adding instruction [sn:%llu] PC %s to the IQ.\n " ,
477490 new_inst->seqNum , new_inst->pcState ());
@@ -495,6 +508,7 @@ InstructionQueue::insertNonSpec(const DynInstPtr &new_inst)
495508 }
496509
497510 assert (new_inst);
511+ new_inst->instQueue = this ;
498512
499513 scheduler->insertNonSpec (new_inst);
500514 nonSpecInsts[new_inst->seqNum ] = new_inst;
@@ -632,6 +646,10 @@ InstructionQueue::scheduleReadyInsts()
632646 mem_inst->issueQue ->retryMem (mem_inst);
633647 }
634648
649+ while ((mem_inst = getPhysicalSQFullReplayInstToExecute ())) {
650+ mem_inst->issueQue ->retryMem (mem_inst);
651+ }
652+
635653 // Have iterator to head of the list
636654 // While I haven't exceeded bandwidth or reached the end of the list,
637655 // Try to get a FU that can do what this op needs.
@@ -1108,6 +1126,68 @@ InstructionQueue::getBlockedMemInstToExecute()
11081126 }
11091127}
11101128
1129+ void
1130+ InstructionQueue::deferPhysicalSQFullReplay (const DynInstPtr &inst)
1131+ {
1132+ assert (inst);
1133+ assert (inst->needPhysicalSQFullReplay ());
1134+ iewStage->ldstQueue .recordStoreQueueReplay (inst);
1135+ physicalSQFullReplayQs[inst->threadNumber ].push (inst);
1136+ DPRINTF (Schedule,
1137+ " Physical SQ replay waits in dedicated IQ queue [sn:%llu] "
1138+ " sqIdx=%llu\n " ,
1139+ inst->seqNum , static_cast <unsigned long long >(inst->sqIdx ));
1140+ }
1141+
1142+ bool
1143+ InstructionQueue::storeQueueWriteReady (const DynInstPtr &inst) const
1144+ {
1145+ return iewStage->ldstQueue .storeQueueWriteReady (inst);
1146+ }
1147+
1148+ void
1149+ InstructionQueue::recordAddrOrDataReady (const DynInstPtr &inst)
1150+ {
1151+ iewStage->ldstQueue .recordAddrOrDataReady (inst);
1152+ }
1153+
1154+ DynInstPtr
1155+ InstructionQueue::getPhysicalSQFullReplayInstToExecute ()
1156+ {
1157+ for (ThreadID tid = 0 ; tid < MaxThreads; ++tid) {
1158+ auto &replay_q = physicalSQFullReplayQs[tid];
1159+ while (!replay_q.empty ()) {
1160+ const auto inst = replay_q.top ();
1161+ if (!inst || inst->isSquashed ()) {
1162+ replay_q.pop ();
1163+ continue ;
1164+ }
1165+ if (!iewStage->ldstQueue .phySQFullReplayReady (inst)) {
1166+ break ;
1167+ }
1168+
1169+ replay_q.pop ();
1170+ DPRINTF (Schedule,
1171+ " Physical SQ replay wakes from IQ queue [sn:%llu] "
1172+ " sqIdx=%llu\n " ,
1173+ inst->seqNum , static_cast <unsigned long long >(inst->sqIdx ));
1174+ return inst;
1175+ }
1176+ }
1177+ return nullptr ;
1178+ }
1179+
1180+ bool
1181+ InstructionQueue::hasPhysicalSQFullReplayInsts () const
1182+ {
1183+ for (const auto &replay_q : physicalSQFullReplayQs) {
1184+ if (!replay_q.empty ()) {
1185+ return true ;
1186+ }
1187+ }
1188+ return false ;
1189+ }
1190+
11111191void
11121192InstructionQueue::violation (const DynInstPtr &store,
11131193 const DynInstPtr &faulting_load)
0 commit comments