bool renameUnblock[Impl::MaxThreads];
bool iewBlock[Impl::MaxThreads];
bool iewUnblock[Impl::MaxThreads];
- bool commitBlock[Impl::MaxThreads];
- bool commitUnblock[Impl::MaxThreads];
};
#endif //__CPU_O3_COMM_HH__
/** Sets the pointer to the IEW stage. */
void setIEWStage(IEW *iew_stage);
- /** Skid buffer between rename and commit. */
- std::queue<DynInstPtr> skidBuffer;
-
/** The pointer to the IEW stage. Used solely to ensure that
* various events (traps, interrupts, syscalls) do not occur until
* all stores have written back.
*/
void setNextStatus();
- /** Checks if the ROB is completed with squashing. This is for the case
- * where the ROB can take multiple cycles to complete squashing.
- */
- bool robDoneSquashing();
-
/** Returns if any of the threads have the number of ROB entries changed
* on this cycle. Used to determine if the number of free ROB entries needs
* to be sent back to previous stages.
/** Gets instructions from rename and inserts them into the ROB. */
void getInsts();
- /** Insert all instructions from rename into skidBuffer */
- void skidInsert();
-
/** Marks completed instructions using information sent from IEW. */
void markCompletedInsts();
}
}
-template <class Impl>
-void
-DefaultCommit<Impl>::skidInsert()
-{
- DPRINTF(Commit, "Attempting to any instructions from rename into "
- "skidBuffer.\n");
-
- for (int inst_num = 0; inst_num < fromRename->size; ++inst_num) {
- DynInstPtr inst = fromRename->insts[inst_num];
-
- if (!inst->isSquashed()) {
- DPRINTF(Commit, "Inserting PC %s [sn:%i] [tid:%i] into ",
- "skidBuffer.\n", inst->pcState(), inst->seqNum,
- inst->threadNumber);
- skidBuffer.push(inst);
- } else {
- DPRINTF(Commit, "Instruction PC %s [sn:%i] [tid:%i] was "
- "squashed, skipping.\n",
- inst->pcState(), inst->seqNum, inst->threadNumber);
- }
- }
-}
-
template <class Impl>
void
DefaultCommit<Impl>::markCompletedInsts()
}
}
-template <class Impl>
-bool
-DefaultCommit<Impl>::robDoneSquashing()
-{
- list<ThreadID>::iterator threads = activeThreads->begin();
- list<ThreadID>::iterator end = activeThreads->end();
-
- while (threads != end) {
- ThreadID tid = *threads++;
-
- if (!rob->isDoneSquashing(tid))
- return false;
- }
-
- return true;
-}
-
template <class Impl>
void
DefaultCommit<Impl>::updateComInstStats(DynInstPtr &inst)
void drainSanityCheck() const;
/** Has the stage drained? */
- bool isDrained() const { return true; }
+ bool isDrained() const;
/** Takes over from another CPU's thread. */
void takeOverFrom() { resetStage(); }
/** Source of possible stalls. */
struct Stalls {
bool rename;
- bool iew;
- bool commit;
};
/** Tracks which stages are telling decode to stall. */
/*
- * Copyright (c) 2012 ARM Limited
+ * Copyright (c) 2012, 2014 ARM Limited
* All rights reserved
*
* The license below extends only to copyright in the software and shall
decodeStatus[tid] = Idle;
stalls[tid].rename = false;
- stalls[tid].iew = false;
- stalls[tid].commit = false;
}
}
}
}
+template <class Impl>
+bool
+DefaultDecode<Impl>::isDrained() const
+{
+ for (ThreadID tid = 0; tid < numThreads; ++tid) {
+ if (!insts[tid].empty() || !skidBuffer[tid].empty())
+ return false;
+ }
+ return true;
+}
+
template<class Impl>
bool
DefaultDecode<Impl>::checkStall(ThreadID tid) const
if (stalls[tid].rename) {
DPRINTF(Decode,"[tid:%i]: Stall fom Rename stage detected.\n", tid);
ret_val = true;
- } else if (stalls[tid].iew) {
- DPRINTF(Decode,"[tid:%i]: Stall fom IEW stage detected.\n", tid);
- ret_val = true;
- } else if (stalls[tid].commit) {
- DPRINTF(Decode,"[tid:%i]: Stall fom Commit stage detected.\n", tid);
- ret_val = true;
}
return ret_val;
assert(tid == inst->threadNumber);
- DPRINTF(Decode,"Inserting [sn:%lli] PC: %s into decode skidBuffer %i\n",
- inst->seqNum, inst->pcState(), inst->threadNumber);
-
skidBuffer[tid].push(inst);
+
+ DPRINTF(Decode,"Inserting [tid:%d][sn:%lli] PC: %s into decode skidBuffer %i\n",
+ inst->threadNumber, inst->seqNum, inst->pcState(), skidBuffer[tid].size());
}
// @todo: Eventually need to enforce this by not letting a thread
assert(stalls[tid].rename);
stalls[tid].rename = false;
}
-
- if (fromIEW->iewBlock[tid]) {
- stalls[tid].iew = true;
- }
-
- if (fromIEW->iewUnblock[tid]) {
- assert(stalls[tid].iew);
- stalls[tid].iew = false;
- }
-
- if (fromCommit->commitBlock[tid]) {
- stalls[tid].commit = true;
- }
-
- if (fromCommit->commitUnblock[tid]) {
- assert(stalls[tid].commit);
- stalls[tid].commit = false;
- }
}
template <class Impl>
return true;
}
- // Check ROB squash signals from commit.
- if (fromCommit->commitInfo[tid].robSquashing) {
- DPRINTF(Decode, "[tid:%u]: ROB is still squashing.\n", tid);
-
- // Continue to squash.
- decodeStatus[tid] = Squashing;
-
- return true;
- }
-
if (checkStall(tid)) {
return block(tid);
}
/** Source of possible stalls. */
struct Stalls {
bool decode;
- bool rename;
- bool iew;
- bool commit;
bool drain;
};
/*
- * Copyright (c) 2010-2013 ARM Limited
+ * Copyright (c) 2010-2014 ARM Limited
* All rights reserved.
*
* The license below extends only to copyright in the software and shall
memReq[tid] = NULL;
stalls[tid].decode = false;
- stalls[tid].rename = false;
- stalls[tid].iew = false;
- stalls[tid].commit = false;
stalls[tid].drain = false;
fetchBufferPC[tid] = 0;
for (ThreadID i = 0; i < numThreads; ++i) {
assert(!memReq[i]);
- assert(!stalls[i].decode);
- assert(!stalls[i].rename);
- assert(!stalls[i].iew);
- assert(!stalls[i].commit);
assert(fetchStatus[i] == Idle || stalls[i].drain);
}
fetchStatus[tid] = IcacheWaitResponse;
}
} else {
- if (!(numInst < fetchWidth)) {
+ // Don't send an instruction to decode if it can't handle it.
+ // Asynchronous nature of this function's calling means we have to
+ // check 2 signals to see if decode is stalled.
+ if (!(numInst < fetchWidth) || stalls[tid].decode ||
+ fromDecode->decodeBlock[tid]) {
assert(!finishTranslationEvent.scheduled());
finishTranslationEvent.setFault(fault);
finishTranslationEvent.setReq(mem_req);
} else if (stalls[tid].decode) {
DPRINTF(Fetch,"[tid:%i]: Stall from Decode stage detected.\n",tid);
ret_val = true;
- } else if (stalls[tid].rename) {
- DPRINTF(Fetch,"[tid:%i]: Stall from Rename stage detected.\n",tid);
- ret_val = true;
- } else if (stalls[tid].iew) {
- DPRINTF(Fetch,"[tid:%i]: Stall from IEW stage detected.\n",tid);
- ret_val = true;
- } else if (stalls[tid].commit) {
- DPRINTF(Fetch,"[tid:%i]: Stall from Commit stage detected.\n",tid);
- ret_val = true;
}
return ret_val;
stalls[tid].decode = false;
}
- if (fromRename->renameBlock[tid]) {
- stalls[tid].rename = true;
- }
-
- if (fromRename->renameUnblock[tid]) {
- assert(stalls[tid].rename);
- assert(!fromRename->renameBlock[tid]);
- stalls[tid].rename = false;
- }
-
- if (fromIEW->iewBlock[tid]) {
- stalls[tid].iew = true;
- }
-
- if (fromIEW->iewUnblock[tid]) {
- assert(stalls[tid].iew);
- assert(!fromIEW->iewBlock[tid]);
- stalls[tid].iew = false;
- }
-
- if (fromCommit->commitBlock[tid]) {
- stalls[tid].commit = true;
- }
-
- if (fromCommit->commitUnblock[tid]) {
- assert(stalls[tid].commit);
- assert(!fromCommit->commitBlock[tid]);
- stalls[tid].commit = false;
- }
-
// Check squash signals from commit.
if (fromCommit->commitInfo[tid].squash) {
branchPred->update(fromCommit->commitInfo[tid].doneSeqNum, tid);
}
- // Check ROB squash signals from commit.
- if (fromCommit->commitInfo[tid].robSquashing) {
- DPRINTF(Fetch, "[tid:%u]: ROB is still squashing.\n", tid);
-
- // Continue to squash.
- fetchStatus[tid] = Squashing;
-
- return true;
- }
-
// Check squash signals from decode.
if (fromDecode->decodeInfo[tid].squash) {
DPRINTF(Fetch, "[tid:%u]: Squashing instructions due to squash "
*/
unsigned validInstsFromRename();
- /** Reads the stall signals. */
- void readStallSignals(ThreadID tid);
-
/** Checks if any of the stall conditions are currently true. */
bool checkStall(ThreadID tid);
*/
bool wroteToTimeBuffer;
- /** Source of possible stalls. */
- struct Stalls {
- bool commit;
- };
-
- /** Stages that are telling IEW to stall. */
- Stalls stalls[Impl::MaxThreads];
-
/** Debug function to print instructions that are issued this cycle. */
void printAvailableInsts();
for (ThreadID tid = 0; tid < numThreads; tid++) {
dispatchStatus[tid] = Running;
- stalls[tid].commit = false;
fetchRedirect[tid] = false;
}
updateLSQNextCycle = false;
- skidBufferMax = (3 * (renameToIEWDelay * params->renameWidth)) + issueWidth;
+ skidBufferMax = (renameToIEWDelay + 1) * params->renameWidth;
}
template <class Impl>
for (ThreadID tid = 0; tid < numThreads; tid++) {
dispatchStatus[tid] = Running;
- stalls[tid].commit = false;
fetchRedirect[tid] = false;
}
ldstQueue.resetEntries();
}
-template <class Impl>
-void
-DefaultIEW<Impl>::readStallSignals(ThreadID tid)
-{
- if (fromCommit->commitBlock[tid]) {
- stalls[tid].commit = true;
- }
-
- if (fromCommit->commitUnblock[tid]) {
- assert(stalls[tid].commit);
- stalls[tid].commit = false;
- }
-}
-
template <class Impl>
bool
DefaultIEW<Impl>::checkStall(ThreadID tid)
{
bool ret_val(false);
- if (stalls[tid].commit) {
+ if (fromCommit->commitInfo[tid].robSquashing) {
DPRINTF(IEW,"[tid:%i]: Stall from Commit stage detected.\n",tid);
ret_val = true;
} else if (instQueue.isFull(tid)) {
// If status was Squashing
// check if squashing is not high. Switch to running this cycle.
- readStallSignals(tid);
-
if (fromCommit->commitInfo[tid].squash) {
squash(tid);
dispatchStatus[tid] = Squashing;
emptyRenameInsts(tid);
wroteToTimeBuffer = true;
- return;
}
if (checkStall(tid)) {
/*
- * Copyright (c) 2010-2012 ARM Limited
+ * Copyright (c) 2010-2012, 2014 ARM Limited
* Copyright (c) 2013 Advanced Micro Devices, Inc.
* All rights reserved.
*
renameWidth, static_cast<int>(Impl::MaxWidth));
// @todo: Make into a parameter.
- skidBufferMax = (2 * (decodeToRenameDelay * params->decodeWidth)) + renameWidth;
+ skidBufferMax = (decodeToRenameDelay + 1) * params->decodeWidth;
}
template <class Impl>
emptyROB[tid] = true;
stalls[tid].iew = false;
- stalls[tid].commit = false;
serializeInst[tid] = NULL;
instsInProgress[tid] = 0;
assert(stalls[tid].iew);
stalls[tid].iew = false;
}
-
- if (fromCommit->commitBlock[tid]) {
- stalls[tid].commit = true;
- }
-
- if (fromCommit->commitUnblock[tid]) {
- assert(stalls[tid].commit);
- stalls[tid].commit = false;
- }
}
template <class Impl>
if (stalls[tid].iew) {
DPRINTF(Rename,"[tid:%i]: Stall from IEW stage detected.\n", tid);
ret_val = true;
- } else if (stalls[tid].commit) {
- DPRINTF(Rename,"[tid:%i]: Stall from Commit stage detected.\n", tid);
- ret_val = true;
} else if (calcFreeROBEntries(tid) <= 0) {
DPRINTF(Rename,"[tid:%i]: Stall: ROB has 0 free entries.\n", tid);
ret_val = true;
return true;
}
- if (fromCommit->commitInfo[tid].robSquashing) {
- DPRINTF(Rename, "[tid:%u]: ROB is still squashing.\n", tid);
-
- renameStatus[tid] = Squashing;
-
- return true;
- }
-
if (checkStall(tid)) {
return block(tid);
}