@@ -129,7 +129,7 @@ Commit::Commit(CPU *_cpu, branch_prediction::BPredUnit *_bp, const BaseO3CPUPara
129129 " --debug-start=%llu --debug-end=%llu\n " ,
130130 lastCommitCycle, cpu->curCycle (),
131131 cpu->cyclesToTicks (Cycles (lastCommitCycle - 200 )),
132- cpu->cyclesToTicks (Cycles (lastCommitCycle + 50 )));
132+ cpu->cyclesToTicks (Cycles (lastCommitCycle + 200 )));
133133 }
134134 cpu->schedule (this ->stuckCheckEvent , cpu->clockEdge (Cycles (40010 )));
135135 }, " CommitStuckCheckEvent" ),
@@ -165,7 +165,9 @@ Commit::Commit(CPU *_cpu, branch_prediction::BPredUnit *_bp, const BaseO3CPUPara
165165 }
166166 }
167167
168- for (ThreadID tid = 0 ; tid < MaxThreads; tid++) {
168+ assert (renameToROBDelay == 1 );
169+
170+ for (ThreadID tid = 0 ; tid < numThreads; tid++) {
169171 commitStatus[tid] = Idle;
170172 changedROBNumEntries[tid] = false ;
171173 trapSquash[tid] = false ;
@@ -181,6 +183,7 @@ Commit::Commit(CPU *_cpu, branch_prediction::BPredUnit *_bp, const BaseO3CPUPara
181183 htmStarts[tid] = 0 ;
182184 htmStops[tid] = 0 ;
183185 traceCommitIndex[tid] = 0 ;
186+ fixedbuffer[tid] = boost::circular_buffer<DynInstPtr>(renameWidth);
184187 }
185188 interrupt = NoFault;
186189
@@ -461,7 +464,6 @@ Commit::startupStage()
461464 // Broadcast the number of free entries.
462465 for (ThreadID tid = 0 ; tid < numThreads; tid++) {
463466 toIEW->commitInfo [tid].usedROB = true ;
464- toIEW->commitInfo [tid].freeROBEntries = rob->numFreeEntries (tid);
465467 toIEW->commitInfo [tid].emptyROB = true ;
466468 }
467469
@@ -1104,10 +1106,10 @@ Commit::commit()
11041106 _nextStatus = Active;
11051107 }
11061108
1107- if (num_squashing_threads != numThreads) {
1108- // If we're not currently squashing, then get instructions.
1109- getInsts ();
1109+ // If we're not currently squashing, then get instructions.
1110+ moveInstsToBuffer ();
11101111
1112+ if (num_squashing_threads != numThreads) {
11111113 // Try to commit any instructions.
11121114 commitInsts ();
11131115 }
@@ -1120,7 +1122,6 @@ Commit::commit()
11201122
11211123 if (changedROBNumEntries[tid]) {
11221124 toIEW->commitInfo [tid].usedROB = true ;
1123- toIEW->commitInfo [tid].freeROBEntries = rob->numFreeEntries (tid);
11241125
11251126 wroteToTimeBuffer = true ;
11261127 changedROBNumEntries[tid] = false ;
@@ -1142,7 +1143,6 @@ Commit::commit()
11421143 checkEmptyROB[tid] = false ;
11431144 toIEW->commitInfo [tid].usedROB = true ;
11441145 toIEW->commitInfo [tid].emptyROB = true ;
1145- toIEW->commitInfo [tid].freeROBEntries = rob->numFreeEntries (tid);
11461146 wroteToTimeBuffer = true ;
11471147 }
11481148
@@ -1242,7 +1242,9 @@ Commit::commitInsts()
12421242 if (commit_success) {
12431243 cpu->perfCCT ->updateInstPos (head_inst->seqNum , PerfRecord::AtCommit);
12441244 cpu->perfCCT ->commitMeta (head_inst->seqNum );
1245- head_inst->printDisassemblyAndResult (cpu->name ());
1245+
1246+ DPRINTF (CommitTrace, " CT: %s\n " , head_inst->genDisassembly ());
1247+
12461248 if (ismispred) {
12471249 ismispred = false ;
12481250 stats.recovery_bubble += (cpu->curCycle () - lastCommitCycle) * renameWidth;
@@ -1382,7 +1384,11 @@ Commit::commitInsts()
13821384 if (head_inst->isLoad ()) {
13831385 Addr load_pc = head_inst->pcState ().instAddr ();
13841386 Addr load_addr = head_inst->physEffAddr ;
1385- Addr load_value = head_inst->memData ? *((uint64_t *)head_inst->memData ) : 0 ;
1387+ char buffer[8 ] = {0 };
1388+ if (head_inst->memData ) {
1389+ std::memcpy (buffer, head_inst->memData , head_inst->effSize );
1390+ }
1391+ Addr load_value = *((uint64_t *)buffer);
13861392 bool hit = loadTripleCounter.update (load_pc, load_addr, load_value);
13871393 if (hit) {
13881394 // same PC && same addr && same value
@@ -1492,6 +1498,7 @@ Commit::commitInsts()
14921498 for (int tid = 0 ; tid < MaxThreads; tid++) {
14931499 toIEW->commitInfo [tid].doneMemSeqNum =
14941500 std::max (toIEW->commitInfo [tid].doneSeqNum , rob->getHeadGroupLastDoneSeq (tid));
1501+ toIEW->commitInfo [tid].robheadNotReadySeqNum = rob->getHeadGroupLastNotReadySeq (tid);
14951502 }
14961503
14971504 DPRINTF (CommitRate, " %i\n " , num_committed);
@@ -1806,16 +1813,54 @@ Commit::commitHead(const DynInstPtr &head_inst, unsigned inst_num)
18061813}
18071814
18081815void
1809- Commit::getInsts ()
1816+ Commit::moveInstsToBuffer ()
18101817{
18111818 DPRINTF (Commit, " Getting instructions from Rename stage.\n " );
1819+ int insts_from_rename = fromRename->size ;
1820+ if (insts_from_rename != 0 ) {
1821+ // move to buffer
1822+ ThreadID tid = fromRename->insts [0 ]->threadNumber ;
1823+ assert (fixedbuffer[tid].empty ());
1824+ for (int i = 0 ; i < insts_from_rename; ++i) {
1825+ const DynInstPtr &inst = fromRename->insts [i];
1826+ assert (inst->threadNumber == tid);
1827+ if (localSquashVer.largerThan (inst->getVersion ())) {
1828+ inst->setSquashed ();
1829+ }
1830+ fixedbuffer[tid].push_back (inst);
1831+ }
1832+ }
18121833
1813- // Read any renamed instructions and place them into the ROB.
1814- int insts_to_process = std::min ((int )renameWidth, fromRename->size );
1834+ // check threads stall & status
1835+ ThreadID tid = InvalidThreadID;
1836+ for (int i = 0 ; i < numThreads; i++) {
1837+ bool robblock = commitStatus[i] == ROBSquashing || commitStatus[i] == TrapPending;
1838+ bool block = (rob->getMaxEntries (i) - rob->getThreadEntries (i) < fixedbuffer[i].size ()) || robblock;
1839+ bool active = !block && !fixedbuffer[i].empty ();
1840+ DPRINTF (Commit, " Thread %i: block %i robblock %i active %i\n " , i, block, robblock, active);
1841+
1842+ stallSig->blockIEW [i] = block;
1843+ if (active) {
1844+ if (tid == InvalidThreadID) tid = i;
1845+ else {
1846+ // if there are multiple active threads, must exhaust all threads first
1847+ // to avoid starvation of other threads and also avoid resource conflict
1848+ stallSig->blockIEW [tid] = true ;
1849+ stallSig->blockIEW [i] = true ;
1850+ DPRINTF (IEW, " Multiple active threads detected, blocking all threads\n " );
1851+ }
1852+ }
1853+ }
1854+ if (tid == InvalidThreadID) {
1855+ DPRINTF (Commit, " No instructions from Rename stage.\n " );
1856+ return ;
1857+ }
18151858
1859+ // Read any renamed instructions and place them into the ROB.
1860+ int insts_to_process = fixedbuffer[tid].size ();
18161861 for (int inst_num = 0 ; inst_num < insts_to_process; ++inst_num) {
1817- const DynInstPtr &inst = fromRename-> insts [inst_num] ;
1818- ThreadID tid = inst-> threadNumber ;
1862+ const DynInstPtr &inst = fixedbuffer[tid]. front () ;
1863+ fixedbuffer[ tid]. pop_front () ;
18191864
18201865 if (localSquashVer.largerThan (inst->getVersion ())) {
18211866 inst->setSquashed ();
@@ -1840,6 +1885,11 @@ Commit::getInsts()
18401885 tid, inst->seqNum , inst->pcState ());
18411886 }
18421887 }
1888+
1889+ if (!fixedbuffer[tid].empty ()) {
1890+ stallSig->blockIEW [tid] = true ;
1891+ DPRINTF (Commit, " Not all instructions from Rename stage could be processed, blocking thread %i\n " , tid);
1892+ }
18431893}
18441894
18451895
@@ -1873,14 +1923,18 @@ Commit::markCompletedInsts()
18731923 for (int inst_num = 0 ; inst_num < fromIEW->size ; ++inst_num) {
18741924 assert (fromIEW->insts [inst_num]);
18751925 if (!fromIEW->insts [inst_num]->isSquashed ()) {
1876- DPRINTF (Commit, " [tid:%i] Marking PC %s, [sn:%llu] ready "
1926+ DPRINTF (Commit,
1927+ " [tid:%i] Marking PC %s, [sn:%llu] ready "
18771928 " within ROB.\n " ,
1878- fromIEW->insts [inst_num]->threadNumber ,
1879- fromIEW->insts [inst_num]->pcState (),
1929+ fromIEW->insts [inst_num]->threadNumber , fromIEW->insts [inst_num]->pcState (),
18801930 fromIEW->insts [inst_num]->seqNum );
18811931
18821932 // Mark the instruction as ready to commit.
18831933 fromIEW->insts [inst_num]->setCanCommit ();
1934+ auto &inst = fromIEW->insts [inst_num];
1935+
1936+ panic_if (!rob->findInst (0 , inst->seqNum ), " [sn:%llu] Committed instruction not found in ROB" ,
1937+ inst->seqNum );
18841938 }
18851939 }
18861940}
@@ -1901,10 +1955,7 @@ Commit::updateComInstStats(const DynInstPtr &inst)
19011955 cpu->instDone (tid, inst);
19021956 }
19031957
1904- //
19051958 // Control Instructions
1906- //
1907- //
19081959 if (inst->isControl ()) {
19091960 bool mispred = inst->mispredicted ();
19101961 std::unique_ptr<PCStateBase> tmp_next_pc (inst->pcState ().clone ());
0 commit comments