gem5 [DEVELOP-FOR-25.0]
Loading...
Searching...
No Matches
decode.cc
Go to the documentation of this file.
1/*
2 * Copyright (c) 2012, 2014 ARM Limited
3 * All rights reserved
4 *
5 * The license below extends only to copyright in the software and shall
6 * not be construed as granting a license to any other intellectual
7 * property including but not limited to intellectual property relating
8 * to a hardware implementation of the functionality of the software
9 * licensed hereunder. You may use the software subject to the license
10 * terms below provided that you ensure that this notice is replicated
11 * unmodified and in its entirety in all distributions of the software,
12 * modified or unmodified, in source code or in binary form.
13 *
14 * Copyright (c) 2004-2006 The Regents of The University of Michigan
15 * All rights reserved.
16 *
17 * Redistribution and use in source and binary forms, with or without
18 * modification, are permitted provided that the following conditions are
19 * met: redistributions of source code must retain the above copyright
20 * notice, this list of conditions and the following disclaimer;
21 * redistributions in binary form must reproduce the above copyright
22 * notice, this list of conditions and the following disclaimer in the
23 * documentation and/or other materials provided with the distribution;
24 * neither the name of the copyright holders nor the names of its
25 * contributors may be used to endorse or promote products derived from
26 * this software without specific prior written permission.
27 *
28 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
29 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
30 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
31 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
32 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
33 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
34 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
35 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
36 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
37 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
38 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
39 */
40
41#include "cpu/o3/decode.hh"
42
44#include "base/trace.hh"
45#include "cpu/inst_seq.hh"
46#include "cpu/o3/dyn_inst.hh"
47#include "cpu/o3/limits.hh"
48#include "debug/Activity.hh"
49#include "debug/Decode.hh"
50#include "debug/O3PipeView.hh"
51#include "params/BaseO3CPU.hh"
52#include "sim/full_system.hh"
53
54// clang complains about std::set being overloaded with Packet::set if
55// we open up the entire namespace std
56using std::list;
57
58namespace gem5
59{
60
61namespace o3
62{
63
64Decode::Decode(CPU *_cpu, const BaseO3CPUParams &params)
65 : cpu(_cpu),
71 numThreads(params.numThreads),
72 stats(_cpu)
73{
75 fatal("decodeWidth (%d) is larger than compiled limit (%d),\n"
76 "\tincrease MaxWidth in src/cpu/o3/limits.hh\n",
77 decodeWidth, static_cast<int>(MaxWidth));
78
79 // @todo: Make into a parameter
80 skidBufferMax = (fetchToDecodeDelay + 1) * params.decodeWidth;
81 for (int tid = 0; tid < MaxThreads; tid++) {
82 stalls[tid] = {false};
83 decodeStatus[tid] = Idle;
84 bdelayDoneSeqNum[tid] = 0;
85 squashInst[tid] = nullptr;
86 squashAfterDelaySlot[tid] = 0;
87 }
88}
89
90void
95
96void
98{
99 decodeStatus[tid] = Idle;
100 stalls[tid].rename = false;
101
102 // Clear out any of this thread's instructions being sent to rename.
103 for (int i = -cpu->decodeQueue.getPast();
104 i <= cpu->decodeQueue.getFuture(); ++i) {
105 DecodeStruct& decode_struct = cpu->decodeQueue[i];
106 removeCommThreadInsts(tid, decode_struct);
107 }
108
109 // Clear out any of this thread's instructions being sent to fetch.
110 for (int i = -cpu->timeBuffer.getPast();
111 i <= cpu->timeBuffer.getFuture(); ++i) {
112 TimeStruct& time_struct = cpu->timeBuffer[i];
113 time_struct.decodeInfo[tid] = {};
114 time_struct.decodeBlock[tid] = false;
115 time_struct.decodeUnblock[tid] = false;
116 }
117}
118
119void
121{
123
124 // Setup status, make sure stall signals are clear.
125 for (ThreadID tid = 0; tid < numThreads; ++tid) {
126 decodeStatus[tid] = Idle;
127
128 stalls[tid].rename = false;
129 }
130}
131
132std::string
134{
135 return cpu->name() + ".decode";
136}
137
139 : statistics::Group(cpu, "decode"),
140 ADD_STAT(idleCycles, statistics::units::Cycle::get(),
141 "Number of cycles decode is idle"),
142 ADD_STAT(blockedCycles, statistics::units::Cycle::get(),
143 "Number of cycles decode is blocked"),
144 ADD_STAT(runCycles, statistics::units::Cycle::get(),
145 "Number of cycles decode is running"),
146 ADD_STAT(unblockCycles, statistics::units::Cycle::get(),
147 "Number of cycles decode is unblocking"),
148 ADD_STAT(squashCycles, statistics::units::Cycle::get(),
149 "Number of cycles decode is squashing"),
150 ADD_STAT(branchResolved, statistics::units::Count::get(),
151 "Number of times decode resolved a branch"),
152 ADD_STAT(branchMispred, statistics::units::Count::get(),
153 "Number of times decode detected a branch misprediction"),
154 ADD_STAT(controlMispred, statistics::units::Count::get(),
155 "Number of times decode detected an instruction incorrectly "
156 "predicted as a control"),
157 ADD_STAT(decodedInsts, statistics::units::Count::get(),
158 "Number of instructions handled by decode"),
159 ADD_STAT(squashedInsts, statistics::units::Count::get(),
160 "Number of squashed instructions handled by decode")
161{
162 idleCycles.prereq(idleCycles);
164 runCycles.prereq(runCycles);
172}
173
174void
176{
177 timeBuffer = tb_ptr;
178
179 // Setup wire to write information back to fetch.
180 toFetch = timeBuffer->getWire(0);
181
182 // Create wires to get information from proper places in time buffer.
186}
187
188void
190{
191 decodeQueue = dq_ptr;
192
193 // Setup wire to write information to proper place in decode queue.
194 toRename = decodeQueue->getWire(0);
195}
196
197void
199{
200 fetchQueue = fq_ptr;
201
202 // Setup wire to read information from fetch queue.
204}
205
206void
211
212void
214{
215 for (ThreadID tid = 0; tid < numThreads; ++tid) {
216 assert(insts[tid].empty());
217 assert(skidBuffer[tid].empty());
218 }
219}
220
221bool
223{
224 for (ThreadID tid = 0; tid < numThreads; ++tid) {
225 if (!insts[tid].empty() || !skidBuffer[tid].empty() ||
226 (decodeStatus[tid] != Running && decodeStatus[tid] != Idle))
227 return false;
228 }
229 return true;
230}
231
232bool
234{
235 bool ret_val = false;
236
237 if (stalls[tid].rename) {
238 DPRINTF(Decode,"[tid:%i] Stall fom Rename stage detected.\n", tid);
239 ret_val = true;
240 }
241
242 return ret_val;
243}
244
245bool
247{
248 return fromFetch->size > 0;
249}
250
251bool
253{
254 DPRINTF(Decode, "[tid:%i] Blocking.\n", tid);
255
256 // Add the current inputs to the skid buffer so they can be
257 // reprocessed when this stage unblocks.
258 skidInsert(tid);
259
260 // If the decode status is blocked or unblocking then decode has not yet
261 // signalled fetch to unblock. In that case, there is no need to tell
262 // fetch to block.
263 if (decodeStatus[tid] != Blocked) {
264 // Set the status to Blocked.
265 decodeStatus[tid] = Blocked;
266
267 if (toFetch->decodeUnblock[tid]) {
268 toFetch->decodeUnblock[tid] = false;
269 } else {
270 toFetch->decodeBlock[tid] = true;
271 wroteToTimeBuffer = true;
272 }
273
274 return true;
275 }
276
277 return false;
278}
279
280bool
282{
283 // Decode is done unblocking only if the skid buffer is empty.
284 if (skidBuffer[tid].empty()) {
285 DPRINTF(Decode, "[tid:%i] Done unblocking.\n", tid);
286 toFetch->decodeUnblock[tid] = true;
287 wroteToTimeBuffer = true;
288
289 decodeStatus[tid] = Running;
290 return true;
291 }
292
293 DPRINTF(Decode, "[tid:%i] Currently unblocking.\n", tid);
294
295 return false;
296}
297
298void
300{
301 DPRINTF(Decode, "[tid:%i] [sn:%llu] Squashing due to incorrect branch "
302 "prediction detected at decode.\n", tid, inst->seqNum);
303
304 // Send back mispredict information.
305 toFetch->decodeInfo[tid].branchMispredict = true;
306 toFetch->decodeInfo[tid].predIncorrect = true;
307 toFetch->decodeInfo[tid].mispredictInst = inst;
308 toFetch->decodeInfo[tid].squash = true;
309 toFetch->decodeInfo[tid].doneSeqNum = inst->seqNum;
310 set(toFetch->decodeInfo[tid].nextPC, *inst->branchTarget());
311
312 // Looking at inst->pcState().branching()
313 // may yield unexpected results if the branch
314 // was predicted taken but aliased in the BTB
315 // with a branch jumping to the next instruction (mistarget)
316 // Using PCState::branching() will send execution on the
317 // fallthrough and this will not be caught at execution (since
318 // branch was correctly predicted taken)
319 toFetch->decodeInfo[tid].branchTaken = inst->readPredTaken() ||
320 inst->isUncondCtrl();
321
322 toFetch->decodeInfo[tid].squashInst = inst;
323
324 InstSeqNum squash_seq_num = inst->seqNum;
325
326 // Might have to tell fetch to unblock.
327 if (decodeStatus[tid] == Blocked ||
328 decodeStatus[tid] == Unblocking) {
329 toFetch->decodeUnblock[tid] = 1;
330 }
331
332 // Set status to squashing.
333 decodeStatus[tid] = Squashing;
334
335 for (int i=0; i<fromFetch->size; i++) {
336 if (fromFetch->insts[i]->threadNumber == tid &&
337 fromFetch->insts[i]->seqNum > squash_seq_num) {
338 fromFetch->insts[i]->setSquashed();
339 }
340 }
341
342 // Clear the instruction list and skid buffer in case they have any
343 // insts in them.
344 while (!insts[tid].empty()) {
345 insts[tid].pop();
346 }
347
348 while (!skidBuffer[tid].empty()) {
349 skidBuffer[tid].pop();
350 }
351
352 // Squash instructions up until this one
353 cpu->removeInstsUntil(squash_seq_num, tid);
354}
355
356unsigned
358{
359 DPRINTF(Decode, "[tid:%i] Squashing.\n",tid);
360
361 if (decodeStatus[tid] == Blocked ||
362 decodeStatus[tid] == Unblocking) {
363 if (FullSystem) {
364 toFetch->decodeUnblock[tid] = 1;
365 } else {
366 // In syscall emulation, we can have both a block and a squash due
367 // to a syscall in the same cycle. This would cause both signals
368 // to be high. This shouldn't happen in full system.
369 // @todo: Determine if this still happens.
370 if (toFetch->decodeBlock[tid])
371 toFetch->decodeBlock[tid] = 0;
372 else
373 toFetch->decodeUnblock[tid] = 1;
374 }
375 }
376
377 // Set status to squashing.
378 decodeStatus[tid] = Squashing;
379
380 // Go through incoming instructions from fetch and squash them.
381 unsigned squash_count = 0;
382
383 for (int i=0; i<fromFetch->size; i++) {
384 if (fromFetch->insts[i]->threadNumber == tid) {
385 fromFetch->insts[i]->setSquashed();
386 squash_count++;
387 }
388 }
389
390 // Clear the instruction list and skid buffer in case they have any
391 // insts in them.
392 while (!insts[tid].empty()) {
393 insts[tid].pop();
394 }
395
396 while (!skidBuffer[tid].empty()) {
397 skidBuffer[tid].pop();
398 }
399
400 return squash_count;
401}
402
403void
405{
406 DynInstPtr inst = NULL;
407
408 while (!insts[tid].empty()) {
409 inst = insts[tid].front();
410
411 insts[tid].pop();
412
413 assert(tid == inst->threadNumber);
414
415 skidBuffer[tid].push(inst);
416
417 DPRINTF(Decode, "Inserting [tid:%d][sn:%lli] PC: %s into decode "
418 "skidBuffer %i\n", inst->threadNumber, inst->seqNum,
419 inst->pcState(), skidBuffer[tid].size());
420 }
421
422 // @todo: Eventually need to enforce this by not letting a thread
423 // fetch past its skidbuffer
424 assert(skidBuffer[tid].size() <= skidBufferMax);
425}
426
427bool
429{
430 for (ThreadID tid : *activeThreads) {
431 if (!skidBuffer[tid].empty())
432 return false;
433 }
434
435 return true;
436}
437
438void
440{
441 bool any_unblocking = false;
442
443 for (ThreadID tid : *activeThreads) {
444 if (decodeStatus[tid] == Unblocking) {
445 any_unblocking = true;
446 break;
447 }
448 }
449
450 // Decode will have activity if it's unblocking.
451 if (any_unblocking) {
452 if (_status == Inactive) {
453 _status = Active;
454
455 DPRINTF(Activity, "Activating stage.\n");
456
457 cpu->activateStage(CPU::DecodeIdx);
458 }
459 } else {
460 // If it's not unblocking, then decode will not have any internal
461 // activity. Switch it to inactive.
462 if (_status == Active) {
464 DPRINTF(Activity, "Deactivating stage.\n");
465
466 cpu->deactivateStage(CPU::DecodeIdx);
467 }
468 }
469}
470
471void
473{
474 int insts_from_fetch = fromFetch->size;
475 for (int i = 0; i < insts_from_fetch; ++i) {
476 insts[fromFetch->insts[i]->threadNumber].push(fromFetch->insts[i]);
477 }
478}
479
480void
482{
483 if (fromRename->renameBlock[tid]) {
484 stalls[tid].rename = true;
485 }
486
487 if (fromRename->renameUnblock[tid]) {
488 assert(stalls[tid].rename);
489 stalls[tid].rename = false;
490 }
491}
492
493bool
495{
496 // Check if there's a squash signal, squash if there is.
497 // Check stall signals, block if necessary.
498 // If status was blocked
499 // Check if stall conditions have passed
500 // if so then go to unblocking
501 // If status was Squashing
502 // check if squashing is not high. Switch to running this cycle.
503
504 // Update the per thread stall statuses.
505 readStallSignals(tid);
506
507 // Check squash signals from commit.
508 if (fromCommit->commitInfo[tid].squash) {
509
510 DPRINTF(Decode, "[tid:%i] Squashing instructions due to squash "
511 "from commit.\n", tid);
512
513 squash(tid);
514
515 return true;
516 }
517
518 if (checkStall(tid)) {
519 return block(tid);
520 }
521
522 if (decodeStatus[tid] == Blocked) {
523 DPRINTF(Decode, "[tid:%i] Done blocking, switching to unblocking.\n",
524 tid);
525
527
528 unblock(tid);
529
530 return true;
531 }
532
533 if (decodeStatus[tid] == Squashing) {
534 // Switch status to running if decode isn't being told to block or
535 // squash this cycle.
536 DPRINTF(Decode, "[tid:%i] Done squashing, switching to running.\n",
537 tid);
538
539 decodeStatus[tid] = Running;
540
541 return false;
542 }
543
544 // If we've reached this point, we have not gotten any signals that
545 // cause decode to change its status. Decode remains the same as before.
546 return false;
547}
548
549void
551{
552 wroteToTimeBuffer = false;
553
554 bool status_change = false;
555
556 toRenameIndex = 0;
557
558 sortInsts();
559
560 //Check stall and squash signals.
561 for (ThreadID tid : *activeThreads) {
562 DPRINTF(Decode,"Processing [tid:%i]\n",tid);
563 status_change = checkSignalsAndUpdate(tid) || status_change;
564
565 decode(status_change, tid);
566 }
567
568 if (status_change) {
569 updateStatus();
570 }
571
572 if (wroteToTimeBuffer) {
573 DPRINTF(Activity, "Activity this cycle.\n");
574
575 cpu->activityThisCycle();
576 }
577}
578
579void
580Decode::decode(bool &status_change, ThreadID tid)
581{
582 // If status is Running or idle,
583 // call decodeInsts()
584 // If status is Unblocking,
585 // buffer any instructions coming from fetch
586 // continue trying to empty skid buffer
587 // check if stall conditions have passed
588
589 if (decodeStatus[tid] == Blocked) {
590 ++stats.blockedCycles;
591 } else if (decodeStatus[tid] == Squashing) {
592 ++stats.squashCycles;
593 }
594
595 // Decode should try to decode as many instructions as its bandwidth
596 // will allow, as long as it is not currently blocked.
597 if (decodeStatus[tid] == Running ||
598 decodeStatus[tid] == Idle) {
599 DPRINTF(Decode, "[tid:%i] Not blocked, so attempting to run "
600 "stage.\n",tid);
601
602 decodeInsts(tid);
603 } else if (decodeStatus[tid] == Unblocking) {
604 // Make sure that the skid buffer has something in it if the
605 // status is unblocking.
606 assert(!skidsEmpty());
607
608 // If the status was unblocking, then instructions from the skid
609 // buffer were used. Remove those instructions and handle
610 // the rest of unblocking.
611 decodeInsts(tid);
612
613 if (fetchInstsValid()) {
614 // Add the current inputs to the skid buffer so they can be
615 // reprocessed when this stage unblocks.
616 skidInsert(tid);
617 }
618
619 status_change = unblock(tid) || status_change;
620 }
621}
622
623void
625{
626 // Instructions can come either from the skid buffer or the list of
627 // instructions coming from fetch, depending on decode's status.
628 int insts_available = decodeStatus[tid] == Unblocking ?
629 skidBuffer[tid].size() : insts[tid].size();
630
631 if (insts_available == 0) {
632 DPRINTF(Decode, "[tid:%i] Nothing to do, breaking out"
633 " early.\n",tid);
634 // Should I change the status to idle?
635 ++stats.idleCycles;
636 return;
637 } else if (decodeStatus[tid] == Unblocking) {
638 DPRINTF(Decode, "[tid:%i] Unblocking, removing insts from skid "
639 "buffer.\n",tid);
640 ++stats.unblockCycles;
641 } else if (decodeStatus[tid] == Running) {
642 ++stats.runCycles;
643 }
644
645 std::queue<DynInstPtr>
646 &insts_to_decode = decodeStatus[tid] == Unblocking ?
647 skidBuffer[tid] : insts[tid];
648
649 DPRINTF(Decode, "[tid:%i] Sending instruction to rename.\n",tid);
650
651 while (insts_available > 0 && toRenameIndex < decodeWidth) {
652 assert(!insts_to_decode.empty());
653
654 DynInstPtr inst = std::move(insts_to_decode.front());
655
656 insts_to_decode.pop();
657
658 DPRINTF(Decode, "[tid:%i] Processing instruction [sn:%lli] with "
659 "PC %s\n", tid, inst->seqNum, inst->pcState());
660
661 if (inst->isSquashed()) {
662 DPRINTF(Decode, "[tid:%i] Instruction %i with PC %s is "
663 "squashed, skipping.\n",
664 tid, inst->seqNum, inst->pcState());
665
666 ++stats.squashedInsts;
667
668 --insts_available;
669
670 continue;
671 }
672
673 // Also check if instructions have no source registers. Mark
674 // them as ready to issue at any time. Not sure if this check
675 // should exist here or at a later stage; however it doesn't matter
676 // too much for function correctness.
677 if (inst->numSrcRegs() == 0) {
678 inst->setCanIssue();
679 }
680
681 // This current instruction is valid, so add it into the decode
682 // queue. The next instruction may not be valid, so check to
683 // see if branches were predicted correctly.
684 toRename->insts[toRenameIndex] = inst;
685
686 ++(toRename->size);
688 ++stats.decodedInsts;
689 --insts_available;
690
691#if TRACING_ON
692 if (debug::O3PipeView) {
693 inst->decodeTick = curTick() - inst->fetchTick;
694 }
695#endif
696
697 // Ensure that if it was predicted as a branch, it really is a
698 // branch.
699 if (inst->readPredTaken() && !inst->isControl()) {
700 panic("Instruction predicted as a branch!");
701
702 ++stats.controlMispred;
703
704 // Might want to set some sort of boolean and just do
705 // a check at the end
706 squash(inst, inst->threadNumber);
707
708 break;
709 }
710
711 // Go ahead and compute any PC-relative branches.
712 // This includes direct unconditional control and
713 // direct conditional control that is predicted taken.
714 if (inst->isDirectCtrl() &&
715 (inst->isUncondCtrl() || inst->readPredTaken()))
716 {
717 ++stats.branchResolved;
718
719 std::unique_ptr<PCStateBase> target = inst->branchTarget();
720 if (*target != inst->readPredTarg()) {
721 ++stats.branchMispred;
722
723 // Might want to set some sort of boolean and just do
724 // a check at the end
725 squash(inst, inst->threadNumber);
726
728 "[tid:%i] [sn:%llu] "
729 "Updating predictions: Wrong predicted target: %s \
730 PredPC: %s\n",
731 tid, inst->seqNum, inst->readPredTarg(), *target);
732 //The micro pc after an instruction level branch should be 0
733 inst->setPredTarg(*target);
734 break;
735 }
736 }
737 }
738
739 // If we didn't process all instructions, then we will need to block
740 // and put all those instructions into the skid buffer.
741 if (!insts_to_decode.empty()) {
742 block(tid);
743 }
744
745 // Record that decode has written to the time buffer for activity
746 // tracking.
747 if (toRenameIndex) {
748 wroteToTimeBuffer = true;
749 }
750}
751
752} // namespace o3
753} // namespace gem5
#define DPRINTF(x,...)
Definition trace.hh:209
O3CPU class, has each of the stages (fetch through commit) within it, as well as all of the time buff...
Definition cpu.hh:94
DecodeStatus _status
Decode status.
Definition decode.hh:94
std::queue< DynInstPtr > skidBuffer[MaxThreads]
Skid buffer between fetch and decode.
Definition decode.hh:242
bool wroteToTimeBuffer
Variable that tracks if decode has written to the time buffer this cycle.
Definition decode.hh:247
bool unblock(ThreadID tid)
Switches decode to unblocking if the skid buffer is empty, and signals back that decode has unblocked...
Definition decode.cc:281
bool squashAfterDelaySlot[MaxThreads]
Tells when their is a pending delay slot inst.
Definition decode.hh:295
void readStallSignals(ThreadID tid)
Reads all stall signals from the backwards communication timebuffer.
Definition decode.cc:481
gem5::o3::Decode::DecodeStats stats
DynInstPtr squashInst[MaxThreads]
Instruction used for squashing branch (used for MIPS)
Definition decode.hh:289
CPU * cpu
CPU interface.
Definition decode.hh:208
Cycles iewToDecodeDelay
IEW to decode delay.
Definition decode.hh:262
void decodeInsts(ThreadID tid)
Processes instructions from fetch and passes them on to rename.
Definition decode.cc:624
Stalls stalls[MaxThreads]
Tracks which stages are telling decode to stall.
Definition decode.hh:256
TimeBuffer< TimeStruct >::wire toFetch
Wire to write information heading to previous stages.
Definition decode.hh:224
unsigned skidBufferMax
Maximum size of the skid buffer.
Definition decode.hh:283
Cycles commitToDecodeDelay
Commit to decode delay.
Definition decode.hh:265
void decode(bool &status_change, ThreadID tid)
Determines what to do based on decode's current status.
Definition decode.cc:580
bool fetchInstsValid()
Returns if there any instructions from fetch on this cycle.
Definition decode.cc:246
bool checkSignalsAndUpdate(ThreadID tid)
Checks all input signals and updates decode's status appropriately.
Definition decode.cc:494
void startupStage()
Definition decode.cc:91
TimeBuffer< DecodeStruct >::wire toRename
Wire used to write any information heading to rename.
Definition decode.hh:230
Cycles renameToDecodeDelay
Rename to decode delay.
Definition decode.hh:259
Cycles fetchToDecodeDelay
Fetch to decode delay.
Definition decode.hh:268
std::queue< DynInstPtr > insts[MaxThreads]
Queue of all instructions coming from fetch this cycle.
Definition decode.hh:239
void setFetchQueue(TimeBuffer< FetchStruct > *fq_ptr)
Sets pointer to time buffer coming from fetch.
Definition decode.cc:198
void setTimeBuffer(TimeBuffer< TimeStruct > *tb_ptr)
Sets the main backwards communication time buffer pointer.
Definition decode.cc:175
ThreadStatus decodeStatus[MaxThreads]
Per-thread status.
Definition decode.hh:97
void sortInsts()
Separates instructions from fetch into individual lists of instructions sorted by thread.
Definition decode.cc:472
unsigned toRenameIndex
Index of instructions being sent to rename.
Definition decode.hh:274
void setDecodeQueue(TimeBuffer< DecodeStruct > *dq_ptr)
Sets pointer to time buffer used to communicate to the next stage.
Definition decode.cc:189
TimeBuffer< DecodeStruct > * decodeQueue
Decode instruction queue.
Definition decode.hh:227
void squash(const DynInstPtr &inst, ThreadID tid)
Squashes if there is a PC-relative branch that was predicted incorrectly.
Definition decode.cc:299
void updateStatus()
Updates overall decode status based on all of the threads' statuses.
Definition decode.cc:439
bool skidsEmpty()
Returns if all of the skid buffers are empty.
Definition decode.cc:428
unsigned decodeWidth
The width of decode, in instructions.
Definition decode.hh:271
bool isDrained() const
Has the stage drained?
Definition decode.cc:222
TimeBuffer< TimeStruct >::wire fromCommit
Wire to get commit's information from backwards time buffer.
Definition decode.hh:220
ThreadID numThreads
number of Active Threads
Definition decode.hh:277
TimeBuffer< TimeStruct > * timeBuffer
Time buffer interface.
Definition decode.hh:211
void setActiveThreads(std::list< ThreadID > *at_ptr)
Sets pointer to list of active threads.
Definition decode.cc:207
void resetStage()
Definition decode.cc:120
TimeBuffer< FetchStruct >::wire fromFetch
Wire to get fetch's output from fetch queue.
Definition decode.hh:236
TimeBuffer< TimeStruct >::wire fromRename
Wire to get rename's output from backwards time buffer.
Definition decode.hh:214
Addr bdelayDoneSeqNum[MaxThreads]
SeqNum of Squashing Branch Delay Instruction (used for MIPS)
Definition decode.hh:286
TimeBuffer< TimeStruct >::wire fromIEW
Wire to get iew's information from backwards time buffer.
Definition decode.hh:217
void clearStates(ThreadID tid)
Clear all thread-specific states.
Definition decode.cc:97
void drainSanityCheck() const
Perform sanity checks after a drain.
Definition decode.cc:213
std::list< ThreadID > * activeThreads
List of active thread ids.
Definition decode.hh:280
void tick()
Ticks decode, processing all input signals and decoding as many instructions as possible.
Definition decode.cc:550
Decode(CPU *_cpu, const BaseO3CPUParams &params)
Decode constructor.
Definition decode.cc:64
bool block(ThreadID tid)
Switches decode to blocking, and signals back that decode has become blocked.
Definition decode.cc:252
std::string name() const
Returns the name of decode.
Definition decode.cc:133
void skidInsert(ThreadID tid)
Inserts a thread's instructions into the skid buffer, to be decoded once decode unblocks.
Definition decode.cc:404
TimeBuffer< FetchStruct > * fetchQueue
Fetch instruction queue interface.
Definition decode.hh:233
bool checkStall(ThreadID tid) const
Checks all stall signals, and returns if any are true.
Definition decode.cc:233
STL list class.
Definition stl.hh:51
#define ADD_STAT(n,...)
Convenience macro to add a stat to a statistics group.
Definition group.hh:75
#define panic(...)
This implements a cprintf based panic() function.
Definition logging.hh:220
#define fatal(...)
This implements a cprintf based fatal() function.
Definition logging.hh:232
Bitfield< 7 > i
Definition misc_types.hh:67
Bitfield< 12, 11 > set
static constexpr int MaxThreads
Definition limits.hh:38
void removeCommThreadInsts(ThreadID tid, CommStruct &comm_struct)
Remove instructions belonging to given thread from the given comm struct's instruction array.
Definition comm.hh:235
RefCountingPtr< DynInst > DynInstPtr
static constexpr int MaxWidth
Definition limits.hh:37
Units for Stats.
Definition units.hh:113
Copyright (c) 2024 Arm Limited All rights reserved.
Definition binary32.hh:36
int16_t ThreadID
Thread index/ID type.
Definition types.hh:235
Tick curTick()
The universal simulation clock.
Definition cur_tick.hh:46
bool FullSystem
The FullSystem variable can be used to determine the current mode of simulation.
Definition root.cc:220
uint64_t InstSeqNum
Definition inst_seq.hh:40
Struct that defines the information passed from decode to rename.
Definition comm.hh:73
statistics::Scalar branchResolved
Stat for number of times a branch is resolved at decode.
Definition decode.hh:312
statistics::Scalar squashCycles
Stat for total number of squashing cycles.
Definition decode.hh:310
statistics::Scalar runCycles
Stat for total number of normal running cycles.
Definition decode.hh:306
statistics::Scalar squashedInsts
Stat for total number of squashed instructions.
Definition decode.hh:322
statistics::Scalar idleCycles
Stat for total number of idle cycles.
Definition decode.hh:302
statistics::Scalar branchMispred
Stat for number of times a branch mispredict is detected.
Definition decode.hh:314
statistics::Scalar decodedInsts
Stat for total number of decoded instructions.
Definition decode.hh:320
statistics::Scalar blockedCycles
Stat for total number of blocked cycles.
Definition decode.hh:304
statistics::Scalar controlMispred
Stat for number of times decode detected a non-control instruction incorrectly predicted as a branch.
Definition decode.hh:318
statistics::Scalar unblockCycles
Stat for total number of unblocking cycles.
Definition decode.hh:308
Struct that defines all backwards communication.
Definition comm.hh:113
bool decodeBlock[MaxThreads]
Definition comm.hh:220
DecodeComm decodeInfo[MaxThreads]
Definition comm.hh:129
bool decodeUnblock[MaxThreads]
Definition comm.hh:221

Generated on Mon May 26 2025 09:19:08 for gem5 by doxygen 1.13.2