Go to the documentation of this file.
48 #include "debug/Activity.hh"
49 #include "debug/Decode.hh"
50 #include "debug/O3PipeView.hh"
51 #include "params/BaseO3CPU.hh"
66 renameToDecodeDelay(params.renameToDecodeDelay),
67 iewToDecodeDelay(params.iewToDecodeDelay),
68 commitToDecodeDelay(params.commitToDecodeDelay),
69 fetchToDecodeDelay(params.fetchToDecodeDelay),
70 decodeWidth(params.decodeWidth),
71 numThreads(params.numThreads),
75 fatal(
"decodeWidth (%d) is larger than compiled limit (%d),\n"
76 "\tincrease MaxWidth in src/cpu/o3/limits.hh\n",
119 return cpu->
name() +
".decode";
123 : statistics::
Group(cpu,
"decode"),
124 ADD_STAT(idleCycles, statistics::units::Cycle::get(),
125 "Number of cycles decode is idle"),
126 ADD_STAT(blockedCycles, statistics::units::Cycle::get(),
127 "Number of cycles decode is blocked"),
128 ADD_STAT(runCycles, statistics::units::Cycle::get(),
129 "Number of cycles decode is running"),
130 ADD_STAT(unblockCycles, statistics::units::Cycle::get(),
131 "Number of cycles decode is unblocking"),
132 ADD_STAT(squashCycles, statistics::units::Cycle::get(),
133 "Number of cycles decode is squashing"),
135 "Number of times decode resolved a branch"),
137 "Number of times decode detected a branch misprediction"),
139 "Number of times decode detected an instruction incorrectly "
140 "predicted as a control"),
142 "Number of instructions handled by decode"),
144 "Number of squashed instructions handled by decode")
200 assert(
insts[tid].empty());
219 bool ret_val =
false;
222 DPRINTF(
Decode,
"[tid:%i] Stall fom Rename stage detected.\n", tid);
251 if (
toFetch->decodeUnblock[tid]) {
252 toFetch->decodeUnblock[tid] =
false;
254 toFetch->decodeBlock[tid] =
true;
270 toFetch->decodeUnblock[tid] =
true;
285 DPRINTF(
Decode,
"[tid:%i] [sn:%llu] Squashing due to incorrect branch "
286 "prediction detected at decode.\n", tid, inst->seqNum);
289 toFetch->decodeInfo[tid].branchMispredict =
true;
290 toFetch->decodeInfo[tid].predIncorrect =
true;
291 toFetch->decodeInfo[tid].mispredictInst = inst;
292 toFetch->decodeInfo[tid].squash =
true;
293 toFetch->decodeInfo[tid].doneSeqNum = inst->seqNum;
294 set(
toFetch->decodeInfo[tid].nextPC, *inst->branchTarget());
303 toFetch->decodeInfo[tid].branchTaken = inst->readPredTaken() ||
304 inst->isUncondCtrl();
306 toFetch->decodeInfo[tid].squashInst = inst;
313 toFetch->decodeUnblock[tid] = 1;
320 if (
fromFetch->insts[
i]->threadNumber == tid &&
321 fromFetch->insts[
i]->seqNum > squash_seq_num) {
328 while (!
insts[tid].empty()) {
348 toFetch->decodeUnblock[tid] = 1;
357 toFetch->decodeUnblock[tid] = 1;
365 unsigned squash_count = 0;
368 if (
fromFetch->insts[
i]->threadNumber == tid) {
376 while (!
insts[tid].empty()) {
392 while (!
insts[tid].empty()) {
393 inst =
insts[tid].front();
397 assert(tid == inst->threadNumber);
401 DPRINTF(
Decode,
"Inserting [tid:%d][sn:%lli] PC: %s into decode "
402 "skidBuffer %i\n", inst->threadNumber, inst->seqNum,
417 while (threads != end) {
429 bool any_unblocking =
false;
434 while (threads != end) {
438 any_unblocking =
true;
444 if (any_unblocking) {
448 DPRINTF(Activity,
"Activating stage.\n");
457 DPRINTF(Activity,
"Deactivating stage.\n");
468 for (
int i = 0;
i < insts_from_fetch; ++
i) {
481 assert(
stalls[tid].rename);
503 DPRINTF(
Decode,
"[tid:%i] Squashing instructions due to squash "
504 "from commit.\n", tid);
516 DPRINTF(
Decode,
"[tid:%i] Done blocking, switching to unblocking.\n",
529 DPRINTF(
Decode,
"[tid:%i] Done squashing, switching to running.\n",
547 bool status_change =
false;
557 while (threads != end) {
563 decode(status_change, tid);
571 DPRINTF(Activity,
"Activity this cycle.\n");
597 DPRINTF(
Decode,
"[tid:%i] Not blocked, so attempting to run "
617 status_change =
unblock(tid) || status_change;
629 if (insts_available == 0) {
636 DPRINTF(
Decode,
"[tid:%i] Unblocking, removing insts from skid "
643 std::queue<DynInstPtr>
647 DPRINTF(
Decode,
"[tid:%i] Sending instruction to rename.\n",tid);
650 assert(!insts_to_decode.empty());
652 DynInstPtr inst = std::move(insts_to_decode.front());
654 insts_to_decode.pop();
656 DPRINTF(
Decode,
"[tid:%i] Processing instruction [sn:%lli] with "
657 "PC %s\n", tid, inst->seqNum, inst->pcState());
659 if (inst->isSquashed()) {
661 "squashed, skipping.\n",
662 tid, inst->seqNum, inst->pcState());
675 if (inst->numSrcRegs() == 0) {
690 if (debug::O3PipeView) {
691 inst->decodeTick =
curTick() - inst->fetchTick;
697 if (inst->readPredTaken() && !inst->isControl()) {
698 panic(
"Instruction predicted as a branch!");
704 squash(inst, inst->threadNumber);
712 if (inst->isDirectCtrl() &&
713 (inst->isUncondCtrl() || inst->readPredTaken()))
717 std::unique_ptr<PCStateBase> target = inst->branchTarget();
718 if (*target != inst->readPredTarg()) {
723 squash(inst, inst->threadNumber);
726 "[tid:%i] [sn:%llu] "
727 "Updating predictions: Wrong predicted target: %s \
729 tid, inst->seqNum, inst->readPredTarg(), *target);
731 inst->setPredTarg(*target);
739 if (!insts_to_decode.empty()) {
Tick curTick()
The universal simulation clock.
#define fatal(...)
This implements a cprintf based fatal() function.
unsigned skidBufferMax
Maximum size of the skid buffer.
void updateStatus()
Updates overall decode status based on all of the threads' statuses.
void sortInsts()
Separates instructions from fetch into individual lists of instructions sorted by thread.
Cycles commitToDecodeDelay
Commit to decode delay.
void removeInstsUntil(const InstSeqNum &seq_num, ThreadID tid)
Remove all instructions younger than the given sequence number.
void setActiveThreads(std::list< ThreadID > *at_ptr)
Sets pointer to list of active threads.
bool block(ThreadID tid)
Switches decode to blocking, and signals back that decode has become blocked.
std::list< ThreadID > * activeThreads
List of active thread ids.
bool squashAfterDelaySlot[MaxThreads]
Tells when their is a pending delay slot inst.
statistics::Scalar branchResolved
Stat for number of times a branch is resolved at decode.
void clearStates(ThreadID tid)
Clear all thread-specific states.
std::queue< DynInstPtr > skidBuffer[MaxThreads]
Skid buffer between fetch and decode.
bool fetchInstsValid()
Returns if there any instructions from fetch on this cycle.
statistics::Scalar runCycles
Stat for total number of normal running cycles.
static scfx_rep_node * list
gem5::o3::Decode::DecodeStats stats
statistics::Scalar controlMispred
Stat for number of times decode detected a non-control instruction incorrectly predicted as a branch.
TimeBuffer< TimeStruct >::wire fromRename
Wire to get rename's output from backwards time buffer.
statistics::Scalar branchMispred
Stat for number of times a branch mispredict is detected.
TimeBuffer< TimeStruct > * timeBuffer
Time buffer interface.
bool wroteToTimeBuffer
Variable that tracks if decode has written to the time buffer this cycle.
void decode(bool &status_change, ThreadID tid)
Determines what to do based on decode's current status.
void deactivateStage(const StageIdx idx)
Changes a stage's status to inactive within the activity recorder.
ThreadID numThreads
number of Active Threads
bool skidsEmpty()
Returns if all of the skid buffers are empty.
void tick()
Ticks decode, processing all input signals and decoding as many instructions as possible.
TimeBuffer< TimeStruct >::wire fromCommit
Wire to get commit's information from backwards time buffer.
O3CPU class, has each of the stages (fetch through commit) within it, as well as all of the time buff...
virtual std::string name() const
bool checkSignalsAndUpdate(ThreadID tid)
Checks all input signals and updates decode's status appropriately.
statistics::Scalar unblockCycles
Stat for total number of unblocking cycles.
#define ADD_STAT(n,...)
Convenience macro to add a stat to a statistics group.
void squash(const DynInstPtr &inst, ThreadID tid)
Squashes if there is a PC-relative branch that was predicted incorrectly.
statistics::Scalar decodedInsts
Stat for total number of decoded instructions.
statistics::Scalar blockedCycles
Stat for total number of blocked cycles.
bool isDrained() const
Has the stage drained?
statistics::Scalar idleCycles
Stat for total number of idle cycles.
unsigned toRenameIndex
Index of instructions being sent to rename.
void activateStage(const StageIdx idx)
Changes a stage's status to active within the activity recorder.
TimeBuffer< DecodeStruct >::wire toRename
Wire used to write any information heading to rename.
Decode(CPU *_cpu, const BaseO3CPUParams ¶ms)
Decode constructor.
TimeBuffer< TimeStruct >::wire fromIEW
Wire to get iew's information from backwards time buffer.
Stalls stalls[MaxThreads]
Tracks which stages are telling decode to stall.
std::queue< DynInstPtr > insts[MaxThreads]
Queue of all instructions coming from fetch this cycle.
Addr bdelayDoneSeqNum[MaxThreads]
SeqNum of Squashing Branch Delay Instruction (used for MIPS)
void skidInsert(ThreadID tid)
Inserts a thread's instructions into the skid buffer, to be decoded once decode unblocks.
static constexpr int MaxWidth
bool unblock(ThreadID tid)
Switches decode to unblocking if the skid buffer is empty, and signals back that decode has unblocked...
statistics::Scalar squashCycles
Stat for total number of squashing cycles.
bool checkStall(ThreadID tid) const
Checks all stall signals, and returns if any are true.
statistics::Scalar squashedInsts
Stat for total number of squashed instructions.
TimeBuffer< TimeStruct >::wire toFetch
Wire to write information heading to previous stages.
TimeBuffer< DecodeStruct > * decodeQueue
Decode instruction queue.
bool FullSystem
The FullSystem variable can be used to determine the current mode of simulation.
static constexpr int MaxThreads
void setTimeBuffer(TimeBuffer< TimeStruct > *tb_ptr)
Sets the main backwards communication time buffer pointer.
DecodeStatus _status
Decode status.
void activityThisCycle()
Records that there was time buffer activity this cycle.
ThreadStatus decodeStatus[MaxThreads]
Per-thread status.
Derived & prereq(const Stat &prereq)
Set the prerequisite stat and marks this stat to print at the end of simulation.
Decode class handles both single threaded and SMT decode.
TimeBuffer< FetchStruct > * fetchQueue
Fetch instruction queue interface.
void setDecodeQueue(TimeBuffer< DecodeStruct > *dq_ptr)
Sets pointer to time buffer used to communicate to the next stage.
TimeBuffer< FetchStruct >::wire fromFetch
Wire to get fetch's output from fetch queue.
void drainSanityCheck() const
Perform sanity checks after a drain.
void readStallSignals(ThreadID tid)
Reads all stall signals from the backwards communication timebuffer.
void decodeInsts(ThreadID tid)
Processes instructions from fetch and passes them on to rename.
Cycles renameToDecodeDelay
Rename to decode delay.
DynInstPtr squashInst[MaxThreads]
Instruction used for squashing branch (used for MIPS)
unsigned decodeWidth
The width of decode, in instructions.
void setFetchQueue(TimeBuffer< FetchStruct > *fq_ptr)
Sets pointer to time buffer coming from fetch.
Cycles fetchToDecodeDelay
Fetch to decode delay.
Reference material can be found at the JEDEC website: UFS standard http://www.jedec....
std::string name() const
Returns the name of decode.
Cycles iewToDecodeDelay
IEW to decode delay.
int16_t ThreadID
Thread index/ID type.
#define panic(...)
This implements a cprintf based panic() function.
Generated on Sun Jul 30 2023 01:56:52 for gem5 by doxygen 1.8.17