49#include "debug/Activity.hh"
50#include "debug/Decode.hh"
51#include "params/BaseO3CPU.hh"
75 "Number of cycles decode is running",
76 "Number of cycles decode is idle",
78 "Number of cycles decode is squashing",
79 "Number of cycles decode is blocking",
80 "Number of cycles decode is unblocking",
95 fatal(
"decodeWidth (%d) is larger than compiled limit (%d),\n"
96 "\tincrease MaxWidth in src/cpu/o3/limits.hh\n",
120 stalls[tid].rename =
false;
123 for (
int i = -
cpu->decodeQueue.getPast();
130 for (
int i = -
cpu->timeBuffer.getPast();
148 stalls[tid].rename =
false;
155 return cpu->name() +
".decode";
161 "Number of cycles decode is idle"),
163 "Number of times decode resolved a branch"),
165 "Number of times decode detected a branch misprediction"),
167 "Number of times decode detected an instruction incorrectly "
168 "predicted as a control"),
170 "Number of instructions handled by decode"),
172 "Number of squashed instructions handled by decode")
228 assert(
insts[tid].empty());
247 bool ret_val =
false;
250 DPRINTF(
Decode,
"[tid:%i] Stall fom Rename stage detected.\n", tid);
279 if (
toFetch->decodeUnblock[tid]) {
280 toFetch->decodeUnblock[tid] =
false;
282 toFetch->decodeBlock[tid] =
true;
298 toFetch->decodeUnblock[tid] =
true;
313 DPRINTF(
Decode,
"[tid:%i] [sn:%llu] Squashing due to incorrect branch "
314 "prediction detected at decode.\n", tid, inst->seqNum);
317 toFetch->decodeInfo[tid].branchMispredict =
true;
318 toFetch->decodeInfo[tid].controlMispredict = control_miss;
319 toFetch->decodeInfo[tid].mispredictInst = inst;
320 toFetch->decodeInfo[tid].squash =
true;
321 toFetch->decodeInfo[tid].doneSeqNum = inst->seqNum;
322 set(
toFetch->decodeInfo[tid].nextPC, *inst->branchTarget());
331 toFetch->decodeInfo[tid].branchTaken = inst->readPredTaken() ||
332 inst->isUncondCtrl();
334 toFetch->decodeInfo[tid].squashInst = inst;
341 toFetch->decodeUnblock[tid] = 1;
348 if (
fromFetch->insts[
i]->threadNumber == tid &&
349 fromFetch->insts[
i]->seqNum > squash_seq_num) {
356 while (!
insts[tid].empty()) {
365 cpu->removeInstsUntil(squash_seq_num, tid);
376 toFetch->decodeUnblock[tid] = 1;
385 toFetch->decodeUnblock[tid] = 1;
393 unsigned squash_count = 0;
396 if (
fromFetch->insts[
i]->threadNumber == tid) {
404 while (!
insts[tid].empty()) {
420 while (!
insts[tid].empty()) {
421 inst =
insts[tid].front();
425 assert(tid == inst->threadNumber);
429 DPRINTF(
Decode,
"Inserting [tid:%d][sn:%lli] PC: %s into decode "
430 "skidBuffer %i\n", inst->threadNumber, inst->seqNum,
453 bool any_unblocking =
false;
457 any_unblocking =
true;
463 if (any_unblocking) {
467 DPRINTF(Activity,
"Activating stage.\n");
476 DPRINTF(Activity,
"Deactivating stage.\n");
487 for (
int i = 0;
i < insts_from_fetch; ++
i) {
496 stalls[tid].rename =
true;
500 assert(
stalls[tid].rename);
501 stalls[tid].rename =
false;
522 DPRINTF(
Decode,
"[tid:%i] Squashing instructions due to squash "
523 "from commit.\n", tid);
535 DPRINTF(
Decode,
"[tid:%i] Done blocking, switching to unblocking.\n",
548 DPRINTF(
Decode,
"[tid:%i] Done squashing, switching to running.\n",
566 bool status_change =
false;
577 decode(status_change, tid);
585 DPRINTF(Activity,
"Activity this cycle.\n");
587 cpu->activityThisCycle();
611 DPRINTF(
Decode,
"[tid:%i] Not blocked, so attempting to run "
631 status_change =
unblock(tid) || status_change;
643 if (insts_available == 0) {
650 DPRINTF(
Decode,
"[tid:%i] Unblocking, removing insts from skid "
657 std::queue<DynInstPtr>
661 DPRINTF(
Decode,
"[tid:%i] Sending instruction to rename.\n",tid);
664 assert(!insts_to_decode.empty());
666 DynInstPtr inst = std::move(insts_to_decode.front());
668 insts_to_decode.pop();
670 DPRINTF(
Decode,
"[tid:%i] Processing instruction [sn:%lli] with "
671 "PC %s\n", tid, inst->seqNum, inst->pcState());
673 if (inst->isSquashed()) {
675 "squashed, skipping.\n",
676 tid, inst->seqNum, inst->pcState());
678 ++
stats.squashedInsts;
689 if (inst->numSrcRegs() == 0) {
700 ++
stats.decodedInsts;
703 inst->decodeTick =
curTick() - inst->fetchTick;
707 if (inst->readPredTaken() && !inst->isControl()) {
708 panic(
"Instruction predicted as a branch!");
710 ++
stats.controlMispred;
714 squash(inst,
true, inst->threadNumber);
722 if (inst->isDirectCtrl() &&
723 (inst->isUncondCtrl() || inst->readPredTaken()))
725 ++
stats.branchResolved;
727 std::unique_ptr<PCStateBase> target = inst->branchTarget();
728 if (*target != inst->readPredTarg()) {
729 ++
stats.branchMispred;
733 squash(inst,
false, inst->threadNumber);
736 "[tid:%i] [sn:%llu] "
737 "Updating predictions: Wrong predicted target: %s \
739 tid, inst->seqNum, inst->readPredTarg(), *target);
741 inst->setPredTarg(*target);
749 if (!insts_to_decode.empty()) {
O3CPU class, has each of the stages (fetch through commit) within it, as well as all of the time buff...
DecodeStatus _status
Decode status.
std::queue< DynInstPtr > skidBuffer[MaxThreads]
Skid buffer between fetch and decode.
bool wroteToTimeBuffer
Variable that tracks if decode has written to the time buffer this cycle.
bool unblock(ThreadID tid)
Switches decode to unblocking if the skid buffer is empty, and signals back that decode has unblocked...
bool squashAfterDelaySlot[MaxThreads]
Tells when their is a pending delay slot inst.
void readStallSignals(ThreadID tid)
Reads all stall signals from the backwards communication timebuffer.
gem5::o3::Decode::DecodeStats stats
DynInstPtr squashInst[MaxThreads]
Instruction used for squashing branch (used for MIPS)
Cycles iewToDecodeDelay
IEW to decode delay.
void decodeInsts(ThreadID tid)
Processes instructions from fetch and passes them on to rename.
Stalls stalls[MaxThreads]
Tracks which stages are telling decode to stall.
TimeBuffer< TimeStruct >::wire toFetch
Wire to write information heading to previous stages.
unsigned skidBufferMax
Maximum size of the skid buffer.
Cycles commitToDecodeDelay
Commit to decode delay.
void decode(bool &status_change, ThreadID tid)
Determines what to do based on decode's current status.
bool fetchInstsValid()
Returns if there any instructions from fetch on this cycle.
void squash(const DynInstPtr &inst, bool control_miss, ThreadID tid)
Squashes if there is a PC-relative branch that was predicted incorrectly.
bool checkSignalsAndUpdate(ThreadID tid)
Checks all input signals and updates decode's status appropriately.
TimeBuffer< DecodeStruct >::wire toRename
Wire used to write any information heading to rename.
Cycles renameToDecodeDelay
Rename to decode delay.
Cycles fetchToDecodeDelay
Fetch to decode delay.
std::queue< DynInstPtr > insts[MaxThreads]
Queue of all instructions coming from fetch this cycle.
void setFetchQueue(TimeBuffer< FetchStruct > *fq_ptr)
Sets pointer to time buffer coming from fetch.
void setTimeBuffer(TimeBuffer< TimeStruct > *tb_ptr)
Sets the main backwards communication time buffer pointer.
ThreadStatus decodeStatus[MaxThreads]
Per-thread status.
void sortInsts()
Separates instructions from fetch into individual lists of instructions sorted by thread.
unsigned toRenameIndex
Index of instructions being sent to rename.
void setDecodeQueue(TimeBuffer< DecodeStruct > *dq_ptr)
Sets pointer to time buffer used to communicate to the next stage.
TimeBuffer< DecodeStruct > * decodeQueue
Decode instruction queue.
void updateStatus()
Updates overall decode status based on all of the threads' statuses.
bool skidsEmpty()
Returns if all of the skid buffers are empty.
unsigned decodeWidth
The width of decode, in instructions.
bool isDrained() const
Has the stage drained?
TimeBuffer< TimeStruct >::wire fromCommit
Wire to get commit's information from backwards time buffer.
ThreadID numThreads
number of Active Threads
TimeBuffer< TimeStruct > * timeBuffer
Time buffer interface.
void setActiveThreads(std::list< ThreadID > *at_ptr)
Sets pointer to list of active threads.
TimeBuffer< FetchStruct >::wire fromFetch
Wire to get fetch's output from fetch queue.
TimeBuffer< TimeStruct >::wire fromRename
Wire to get rename's output from backwards time buffer.
Addr bdelayDoneSeqNum[MaxThreads]
SeqNum of Squashing Branch Delay Instruction (used for MIPS)
TimeBuffer< TimeStruct >::wire fromIEW
Wire to get iew's information from backwards time buffer.
void clearStates(ThreadID tid)
Clear all thread-specific states.
void drainSanityCheck() const
Perform sanity checks after a drain.
std::list< ThreadID > * activeThreads
List of active thread ids.
void tick()
Ticks decode, processing all input signals and decoding as many instructions as possible.
Decode(CPU *_cpu, const BaseO3CPUParams ¶ms)
Decode constructor.
bool block(ThreadID tid)
Switches decode to blocking, and signals back that decode has become blocked.
std::string name() const
Returns the name of decode.
void skidInsert(ThreadID tid)
Inserts a thread's instructions into the skid buffer, to be decoded once decode unblocks.
TimeBuffer< FetchStruct > * fetchQueue
Fetch instruction queue interface.
bool checkStall(ThreadID tid) const
Checks all stall signals, and returns if any are true.
#define ADD_STAT(n,...)
Convenience macro to add a stat to a statistics group.
#define panic(...)
This implements a cprintf based panic() function.
#define fatal(...)
This implements a cprintf based fatal() function.
static constexpr int MaxThreads
void removeCommThreadInsts(ThreadID tid, CommStruct &comm_struct)
Remove instructions belonging to given thread from the given comm struct's instruction array.
RefCountingPtr< DynInst > DynInstPtr
static constexpr int MaxWidth
const FlagsType pdf
Print the percent of the total that this entry represents.
const FlagsType nozero
Don't print if this is zero.
Copyright (c) 2024 Arm Limited All rights reserved.
int16_t ThreadID
Thread index/ID type.
Tick curTick()
The universal simulation clock.
bool FullSystem
The FullSystem variable can be used to determine the current mode of simulation.
Struct that defines the information passed from decode to rename.
static std::string statusStrings[ThreadStatusMax]
statistics::Scalar branchResolved
Stat for number of times a branch is resolved at decode.
static std::string statusDefinitions[ThreadStatusMax]
statistics::Vector status
Stat for total number of cycles spent in each decode state.
statistics::Scalar squashedInsts
Stat for total number of squashed instructions.
statistics::Scalar branchMispred
Stat for number of times a branch mispredict is detected.
statistics::Scalar decodedInsts
Stat for total number of decoded instructions.
statistics::Scalar controlMispred
Stat for number of times decode detected a non-control instruction incorrectly predicted as a branch.
Struct that defines all backwards communication.
bool decodeBlock[MaxThreads]
DecodeComm decodeInfo[MaxThreads]
bool decodeUnblock[MaxThreads]