gem5 v24.0.0.0
Loading...
Searching...
No Matches
iew.cc
Go to the documentation of this file.
1/*
2 * Copyright (c) 2010-2013, 2018-2019 ARM Limited
3 * Copyright (c) 2013 Advanced Micro Devices, Inc.
4 * All rights reserved.
5 *
6 * The license below extends only to copyright in the software and shall
7 * not be construed as granting a license to any other intellectual
8 * property including but not limited to intellectual property relating
9 * to a hardware implementation of the functionality of the software
10 * licensed hereunder. You may use the software subject to the license
11 * terms below provided that you ensure that this notice is replicated
12 * unmodified and in its entirety in all distributions of the software,
13 * modified or unmodified, in source code or in binary form.
14 *
15 * Copyright (c) 2004-2006 The Regents of The University of Michigan
16 * All rights reserved.
17 *
18 * Redistribution and use in source and binary forms, with or without
19 * modification, are permitted provided that the following conditions are
20 * met: redistributions of source code must retain the above copyright
21 * notice, this list of conditions and the following disclaimer;
22 * redistributions in binary form must reproduce the above copyright
23 * notice, this list of conditions and the following disclaimer in the
24 * documentation and/or other materials provided with the distribution;
25 * neither the name of the copyright holders nor the names of its
26 * contributors may be used to endorse or promote products derived from
27 * this software without specific prior written permission.
28 *
29 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
30 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
31 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
32 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
33 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
34 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
35 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
36 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
37 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
38 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
39 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
40 */
41
42// @todo: Fix the instantaneous communication among all the stages within
43// iew. There's a clear delay between issue and execute, yet backwards
44// communication happens simultaneously.
45
46#include "cpu/o3/iew.hh"
47
48#include <queue>
49
50#include "cpu/checker/cpu.hh"
51#include "cpu/o3/dyn_inst.hh"
52#include "cpu/o3/fu_pool.hh"
53#include "cpu/o3/limits.hh"
54#include "cpu/timebuf.hh"
55#include "debug/Activity.hh"
56#include "debug/Drain.hh"
57#include "debug/IEW.hh"
58#include "debug/O3PipeView.hh"
59#include "params/BaseO3CPU.hh"
60
61namespace gem5
62{
63
64namespace o3
65{
66
67IEW::IEW(CPU *_cpu, const BaseO3CPUParams &params)
68 : issueToExecQueue(params.backComSize, params.forwardComSize),
69 cpu(_cpu),
70 instQueue(_cpu, this, params),
71 ldstQueue(_cpu, this, params),
72 fuPool(params.fuPool),
73 commitToIEWDelay(params.commitToIEWDelay),
74 renameToIEWDelay(params.renameToIEWDelay),
75 issueToExecuteDelay(params.issueToExecuteDelay),
76 dispatchWidth(params.dispatchWidth),
77 issueWidth(params.issueWidth),
78 wbNumInst(0),
79 wbCycle(0),
80 wbWidth(params.wbWidth),
81 numThreads(params.numThreads),
82 iewStats(cpu)
83{
85 fatal("dispatchWidth (%d) is larger than compiled limit (%d),\n"
86 "\tincrease MaxWidth in src/cpu/o3/limits.hh\n",
87 dispatchWidth, static_cast<int>(MaxWidth));
88 if (issueWidth > MaxWidth)
89 fatal("issueWidth (%d) is larger than compiled limit (%d),\n"
90 "\tincrease MaxWidth in src/cpu/o3/limits.hh\n",
91 issueWidth, static_cast<int>(MaxWidth));
92 if (wbWidth > MaxWidth)
93 fatal("wbWidth (%d) is larger than compiled limit (%d),\n"
94 "\tincrease MaxWidth in src/cpu/o3/limits.hh\n",
95 wbWidth, static_cast<int>(MaxWidth));
96
99 wbStatus = Idle;
100
101 // Setup wire to read instructions coming from issue.
103
104 // Instruction queue needs the queue between issue and execute.
106
107 for (ThreadID tid = 0; tid < MaxThreads; tid++) {
108 dispatchStatus[tid] = Running;
109 fetchRedirect[tid] = false;
110 }
111
112 updateLSQNextCycle = false;
113
114 skidBufferMax = (renameToIEWDelay + 1) * params.renameWidth;
115}
116
117std::string
119{
120 return cpu->name() + ".iew";
121}
122
123void
125{
127 cpu->getProbeManager(), "Dispatch");
129 cpu->getProbeManager(), "Mispredict");
135 cpu->getProbeManager(), "Execute");
141 cpu->getProbeManager(), "ToCommit");
142}
143
145 : statistics::Group(cpu, "iew"),
146 ADD_STAT(idleCycles, statistics::units::Cycle::get(),
147 "Number of cycles IEW is idle"),
148 ADD_STAT(squashCycles, statistics::units::Cycle::get(),
149 "Number of cycles IEW is squashing"),
150 ADD_STAT(blockCycles, statistics::units::Cycle::get(),
151 "Number of cycles IEW is blocking"),
152 ADD_STAT(unblockCycles, statistics::units::Cycle::get(),
153 "Number of cycles IEW is unblocking"),
154 ADD_STAT(dispatchedInsts, statistics::units::Count::get(),
155 "Number of instructions dispatched to IQ"),
156 ADD_STAT(dispSquashedInsts, statistics::units::Count::get(),
157 "Number of squashed instructions skipped by dispatch"),
158 ADD_STAT(dispLoadInsts, statistics::units::Count::get(),
159 "Number of dispatched load instructions"),
160 ADD_STAT(dispStoreInsts, statistics::units::Count::get(),
161 "Number of dispatched store instructions"),
162 ADD_STAT(dispNonSpecInsts, statistics::units::Count::get(),
163 "Number of dispatched non-speculative instructions"),
164 ADD_STAT(iqFullEvents, statistics::units::Count::get(),
165 "Number of times the IQ has become full, causing a stall"),
166 ADD_STAT(lsqFullEvents, statistics::units::Count::get(),
167 "Number of times the LSQ has become full, causing a stall"),
168 ADD_STAT(memOrderViolationEvents, statistics::units::Count::get(),
169 "Number of memory order violations"),
170 ADD_STAT(predictedTakenIncorrect, statistics::units::Count::get(),
171 "Number of branches that were predicted taken incorrectly"),
172 ADD_STAT(predictedNotTakenIncorrect, statistics::units::Count::get(),
173 "Number of branches that were predicted not taken incorrectly"),
174 ADD_STAT(branchMispredicts, statistics::units::Count::get(),
175 "Number of branch mispredicts detected at execute",
176 predictedTakenIncorrect + predictedNotTakenIncorrect),
177 executedInstStats(cpu),
178 ADD_STAT(instsToCommit, statistics::units::Count::get(),
179 "Cumulative count of insts sent to commit"),
180 ADD_STAT(writebackCount, statistics::units::Count::get(),
181 "Cumulative count of insts written-back"),
182 ADD_STAT(producerInst, statistics::units::Count::get(),
183 "Number of instructions producing a value"),
184 ADD_STAT(consumerInst, statistics::units::Count::get(),
185 "Number of instructions consuming a value"),
186 ADD_STAT(wbRate, statistics::units::Rate<
187 statistics::units::Count, statistics::units::Cycle>::get(),
188 "Insts written-back per cycle"),
189 ADD_STAT(wbFanout, statistics::units::Rate<
190 statistics::units::Count, statistics::units::Count>::get(),
191 "Average fanout of values written-back")
192{
196
200
204
208
209 wbRate
212
216}
217
219 : statistics::Group(cpu),
220 ADD_STAT(numSquashedInsts, statistics::units::Count::get(),
221 "Number of squashed instructions skipped in execute"),
222 ADD_STAT(numSwp, statistics::units::Count::get(),
223 "Number of swp insts executed")
224{
225 numSwp
228}
229
230void
232{
233 for (ThreadID tid = 0; tid < numThreads; tid++) {
234 toRename->iewInfo[tid].usedIQ = true;
235 toRename->iewInfo[tid].freeIQEntries =
237
238 toRename->iewInfo[tid].usedLSQ = true;
239 toRename->iewInfo[tid].freeLQEntries =
241 toRename->iewInfo[tid].freeSQEntries =
243 }
244
245 // Initialize the checker's dcache port here
246 if (cpu->checker) {
248 }
249
251}
252
253void
255{
256 toRename->iewInfo[tid].usedIQ = true;
257 toRename->iewInfo[tid].freeIQEntries =
259
260 toRename->iewInfo[tid].usedLSQ = true;
261 toRename->iewInfo[tid].freeLQEntries = ldstQueue.numFreeLoadEntries(tid);
262 toRename->iewInfo[tid].freeSQEntries = ldstQueue.numFreeStoreEntries(tid);
263}
264
265void
267{
268 timeBuffer = tb_ptr;
269
270 // Setup wire to read information from time buffer, from commit.
272
273 // Setup wire to write information back to previous stages.
274 toRename = timeBuffer->getWire(0);
275
276 toFetch = timeBuffer->getWire(0);
277
278 // Instruction queue also needs main time buffer.
279 instQueue.setTimeBuffer(tb_ptr);
280}
281
282void
284{
285 renameQueue = rq_ptr;
286
287 // Setup wire to read information from rename queue.
289}
290
291void
293{
294 iewQueue = iq_ptr;
295
296 // Setup wire to write instructions to commit.
298}
299
300void
308
309void
311{
312 scoreboard = sb_ptr;
313}
314
315bool
317{
318 bool drained = ldstQueue.isDrained() && instQueue.isDrained();
319
320 for (ThreadID tid = 0; tid < numThreads; tid++) {
321 if (!insts[tid].empty()) {
322 DPRINTF(Drain, "%i: Insts not empty.\n", tid);
323 drained = false;
324 }
325 if (!skidBuffer[tid].empty()) {
326 DPRINTF(Drain, "%i: Skid buffer not empty.\n", tid);
327 drained = false;
328 }
329 drained = drained && dispatchStatus[tid] == Running;
330 }
331
332 // Also check the FU pool as instructions are "stored" in FU
333 // completion events until they are done and not accounted for
334 // above
335 if (drained && !fuPool->isDrained()) {
336 DPRINTF(Drain, "FU pool still busy.\n");
337 drained = false;
338 }
339
340 return drained;
341}
342
343void
345{
346 assert(isDrained());
347
350}
351
352void
354{
355 // Reset all state.
356 _status = Active;
358 wbStatus = Idle;
359
363
364 startupStage();
366
367 for (ThreadID tid = 0; tid < numThreads; tid++) {
368 dispatchStatus[tid] = Running;
369 fetchRedirect[tid] = false;
370 }
371
372 updateLSQNextCycle = false;
373
374 for (int i = 0; i < issueToExecQueue.getSize(); ++i) {
375 issueToExecQueue.advance();
376 }
377}
378
379void
381{
382 DPRINTF(IEW, "[tid:%i] Squashing all instructions.\n", tid);
383
384 // Tell the IQ to start squashing.
385 instQueue.squash(tid);
386
387 // Tell the LDSTQ to start squashing.
388 ldstQueue.squash(fromCommit->commitInfo[tid].doneSeqNum, tid);
389 updatedQueues = true;
390
391 // Clear the skid buffer in case it has any data in it.
392 DPRINTF(IEW,
393 "Removing skidbuffer instructions until "
394 "[sn:%llu] [tid:%i]\n",
395 fromCommit->commitInfo[tid].doneSeqNum, tid);
396
397 while (!skidBuffer[tid].empty()) {
398 if (skidBuffer[tid].front()->isLoad()) {
399 toRename->iewInfo[tid].dispatchedToLQ++;
400 }
401 if (skidBuffer[tid].front()->isStore() ||
402 skidBuffer[tid].front()->isAtomic()) {
403 toRename->iewInfo[tid].dispatchedToSQ++;
404 }
405
406 toRename->iewInfo[tid].dispatched++;
407
408 skidBuffer[tid].pop();
409 }
410
411 emptyRenameInsts(tid);
412}
413
414void
416{
417 DPRINTF(IEW, "[tid:%i] [sn:%llu] Squashing from a specific instruction,"
418 " PC: %s "
419 "\n", tid, inst->seqNum, inst->pcState() );
420
421 if (!toCommit->squash[tid] ||
422 inst->seqNum < toCommit->squashedSeqNum[tid]) {
423 toCommit->squash[tid] = true;
424 toCommit->squashedSeqNum[tid] = inst->seqNum;
425 toCommit->branchTaken[tid] = inst->pcState().branching();
426
427 set(toCommit->pc[tid], inst->pcState());
428 inst->staticInst->advancePC(*toCommit->pc[tid]);
429
430 toCommit->mispredictInst[tid] = inst;
431 toCommit->includeSquashInst[tid] = false;
432
433 wroteToTimeBuffer = true;
434 }
435
436}
437
438void
440{
441 DPRINTF(IEW, "[tid:%i] Memory violation, squashing violator and younger "
442 "insts, PC: %s [sn:%llu].\n", tid, inst->pcState(), inst->seqNum);
443 // Need to include inst->seqNum in the following comparison to cover the
444 // corner case when a branch misprediction and a memory violation for the
445 // same instruction (e.g. load PC) are detected in the same cycle. In this
446 // case the memory violator should take precedence over the branch
447 // misprediction because it requires the violator itself to be included in
448 // the squash.
449 if (!toCommit->squash[tid] ||
450 inst->seqNum <= toCommit->squashedSeqNum[tid]) {
451 toCommit->squash[tid] = true;
452
453 toCommit->squashedSeqNum[tid] = inst->seqNum;
454 set(toCommit->pc[tid], inst->pcState());
455 toCommit->mispredictInst[tid] = NULL;
456
457 // Must include the memory violator in the squash.
458 toCommit->includeSquashInst[tid] = true;
459
460 wroteToTimeBuffer = true;
461 }
462}
463
464void
466{
467 DPRINTF(IEW, "[tid:%i] Blocking.\n", tid);
468
469 if (dispatchStatus[tid] != Blocked &&
470 dispatchStatus[tid] != Unblocking) {
471 toRename->iewBlock[tid] = true;
472 wroteToTimeBuffer = true;
473 }
474
475 // Add the current inputs to the skid buffer so they can be
476 // reprocessed when this stage unblocks.
477 skidInsert(tid);
478
479 dispatchStatus[tid] = Blocked;
480}
481
482void
484{
485 DPRINTF(IEW, "[tid:%i] Reading instructions out of the skid "
486 "buffer %u.\n",tid, tid);
487
488 // If the skid bufffer is empty, signal back to previous stages to unblock.
489 // Also switch status to running.
490 if (skidBuffer[tid].empty()) {
491 toRename->iewUnblock[tid] = true;
492 wroteToTimeBuffer = true;
493 DPRINTF(IEW, "[tid:%i] Done unblocking.\n",tid);
494 dispatchStatus[tid] = Running;
495 }
496}
497
498void
500{
502}
503
504void
509
510void
512{
514}
515
516void
518{
520}
521
522void
527
528void
530{
531 // This function should not be called after writebackInsts in a
532 // single cycle. That will cause problems with an instruction
533 // being added to the queue to commit without being processed by
534 // writebackInsts prior to being sent to commit.
535
536 // First check the time slot that this instruction will write
537 // to. If there are free write ports at the time, then go ahead
538 // and write the instruction to that time. If there are not,
539 // keep looking back to see where's the first time there's a
540 // free slot.
541 while ((*iewQueue)[wbCycle].insts[wbNumInst]) {
542 ++wbNumInst;
543 if (wbNumInst == wbWidth) {
544 ++wbCycle;
545 wbNumInst = 0;
546 }
547 }
548
549 DPRINTF(IEW, "Current wb cycle: %i, width: %i, numInst: %i\nwbActual:%i\n",
551 // Add finished instruction to queue to commit.
552 (*iewQueue)[wbCycle].insts[wbNumInst] = inst;
553 (*iewQueue)[wbCycle].size++;
554}
555
556void
558{
559 DynInstPtr inst = NULL;
560
561 while (!insts[tid].empty()) {
562 inst = insts[tid].front();
563
564 insts[tid].pop();
565
566 DPRINTF(IEW,"[tid:%i] Inserting [sn:%lli] PC:%s into "
567 "dispatch skidBuffer %i\n",tid, inst->seqNum,
568 inst->pcState(),tid);
569
570 skidBuffer[tid].push(inst);
571 }
572
573 assert(skidBuffer[tid].size() <= skidBufferMax &&
574 "Skidbuffer Exceeded Max Size");
575}
576
577int
579{
580 int max=0;
581
584
585 while (threads != end) {
586 ThreadID tid = *threads++;
587 unsigned thread_count = skidBuffer[tid].size();
588 if (max < thread_count)
589 max = thread_count;
590 }
591
592 return max;
593}
594
595bool
597{
600
601 while (threads != end) {
602 ThreadID tid = *threads++;
603
604 if (!skidBuffer[tid].empty())
605 return false;
606 }
607
608 return true;
609}
610
611void
613{
614 bool any_unblocking = false;
615
618
619 while (threads != end) {
620 ThreadID tid = *threads++;
621
622 if (dispatchStatus[tid] == Unblocking) {
623 any_unblocking = true;
624 break;
625 }
626 }
627
628 // If there are no ready instructions waiting to be scheduled by the IQ,
629 // and there's no stores waiting to write back, and dispatch is not
630 // unblocking, then there is no internal activity for the IEW stage.
632 if (_status == Active && !instQueue.hasReadyInsts() &&
633 !ldstQueue.willWB() && !any_unblocking) {
634 DPRINTF(IEW, "IEW switching to idle\n");
635
637
639 } else if (_status == Inactive && (instQueue.hasReadyInsts() ||
640 ldstQueue.willWB() ||
641 any_unblocking)) {
642 // Otherwise there is internal activity. Set to active.
643 DPRINTF(IEW, "IEW switching to active\n");
644
646
647 _status = Active;
648 }
649}
650
651bool
653{
654 bool ret_val(false);
655
656 if (fromCommit->commitInfo[tid].robSquashing) {
657 DPRINTF(IEW,"[tid:%i] Stall from Commit stage detected.\n",tid);
658 ret_val = true;
659 } else if (instQueue.isFull(tid)) {
660 DPRINTF(IEW,"[tid:%i] Stall: IQ is full.\n",tid);
661 ret_val = true;
662 }
663
664 return ret_val;
665}
666
667void
669{
670 // Check if there's a squash signal, squash if there is
671 // Check stall signals, block if there is.
672 // If status was Blocked
673 // if so then go to unblocking
674 // If status was Squashing
675 // check if squashing is not high. Switch to running this cycle.
676
677 if (fromCommit->commitInfo[tid].squash) {
678 squash(tid);
679
680 if (dispatchStatus[tid] == Blocked ||
681 dispatchStatus[tid] == Unblocking) {
682 toRename->iewUnblock[tid] = true;
683 wroteToTimeBuffer = true;
684 }
685
687 fetchRedirect[tid] = false;
688 return;
689 }
690
691 if (fromCommit->commitInfo[tid].robSquashing) {
692 DPRINTF(IEW, "[tid:%i] ROB is still squashing.\n", tid);
693
695 emptyRenameInsts(tid);
696 wroteToTimeBuffer = true;
697 }
698
699 if (checkStall(tid)) {
700 block(tid);
701 dispatchStatus[tid] = Blocked;
702 return;
703 }
704
705 if (dispatchStatus[tid] == Blocked) {
706 // Status from previous cycle was blocked, but there are no more stall
707 // conditions. Switch over to unblocking.
708 DPRINTF(IEW, "[tid:%i] Done blocking, switching to unblocking.\n",
709 tid);
710
712
713 unblock(tid);
714
715 return;
716 }
717
718 if (dispatchStatus[tid] == Squashing) {
719 // Switch status to running if rename isn't being told to block or
720 // squash this cycle.
721 DPRINTF(IEW, "[tid:%i] Done squashing, switching to running.\n",
722 tid);
723
724 dispatchStatus[tid] = Running;
725
726 return;
727 }
728}
729
730void
732{
733 int insts_from_rename = fromRename->size;
734#ifdef GEM5_DEBUG
735 for (ThreadID tid = 0; tid < numThreads; tid++)
736 assert(insts[tid].empty());
737#endif
738 for (int i = 0; i < insts_from_rename; ++i) {
739 insts[fromRename->insts[i]->threadNumber].push(fromRename->insts[i]);
740 }
741}
742
743void
745{
746 DPRINTF(IEW, "[tid:%i] Removing incoming rename instructions\n", tid);
747
748 while (!insts[tid].empty()) {
749
750 if (insts[tid].front()->isLoad()) {
751 toRename->iewInfo[tid].dispatchedToLQ++;
752 }
753 if (insts[tid].front()->isStore() ||
754 insts[tid].front()->isAtomic()) {
755 toRename->iewInfo[tid].dispatchedToSQ++;
756 }
757
758 toRename->iewInfo[tid].dispatched++;
759
760 insts[tid].pop();
761 }
762}
763
764void
766{
767 cpu->wakeCPU();
768}
769
770void
772{
773 DPRINTF(Activity, "Activity this cycle.\n");
775}
776
777void
779{
780 DPRINTF(Activity, "Activating stage.\n");
782}
783
784void
786{
787 DPRINTF(Activity, "Deactivating stage.\n");
789}
790
791void
793{
794 // If status is Running or idle,
795 // call dispatchInsts()
796 // If status is Unblocking,
797 // buffer any instructions coming from rename
798 // continue trying to empty skid buffer
799 // check if stall conditions have passed
800
801 if (dispatchStatus[tid] == Blocked) {
803
804 } else if (dispatchStatus[tid] == Squashing) {
806 }
807
808 // Dispatch should try to dispatch as many instructions as its bandwidth
809 // will allow, as long as it is not currently blocked.
810 if (dispatchStatus[tid] == Running ||
811 dispatchStatus[tid] == Idle) {
812 DPRINTF(IEW, "[tid:%i] Not blocked, so attempting to run "
813 "dispatch.\n", tid);
814
815 dispatchInsts(tid);
816 } else if (dispatchStatus[tid] == Unblocking) {
817 // Make sure that the skid buffer has something in it if the
818 // status is unblocking.
819 assert(!skidsEmpty());
820
821 // If the status was unblocking, then instructions from the skid
822 // buffer were used. Remove those instructions and handle
823 // the rest of unblocking.
824 dispatchInsts(tid);
825
827
828 if (fromRename->size != 0) {
829 // Add the current inputs to the skid buffer so they can be
830 // reprocessed when this stage unblocks.
831 skidInsert(tid);
832 }
833
834 unblock(tid);
835 }
836}
837
838void
840{
841 // Obtain instructions from skid buffer if unblocking, or queue from rename
842 // otherwise.
843 std::queue<DynInstPtr> &insts_to_dispatch =
844 dispatchStatus[tid] == Unblocking ?
845 skidBuffer[tid] : insts[tid];
846
847 int insts_to_add = insts_to_dispatch.size();
848
849 DynInstPtr inst;
850 bool add_to_iq = false;
851 int dis_num_inst = 0;
852
853 // Loop through the instructions, putting them in the instruction
854 // queue.
855 for ( ; dis_num_inst < insts_to_add &&
856 dis_num_inst < dispatchWidth;
857 ++dis_num_inst)
858 {
859 inst = insts_to_dispatch.front();
860
861 if (dispatchStatus[tid] == Unblocking) {
862 DPRINTF(IEW, "[tid:%i] Issue: Examining instruction from skid "
863 "buffer\n", tid);
864 }
865
866 // Make sure there's a valid instruction there.
867 assert(inst);
868
869 DPRINTF(IEW, "[tid:%i] Issue: Adding PC %s [sn:%lli] [tid:%i] to "
870 "IQ.\n",
871 tid, inst->pcState(), inst->seqNum, inst->threadNumber);
872
873 // Be sure to mark these instructions as ready so that the
874 // commit stage can go ahead and execute them, and mark
875 // them as issued so the IQ doesn't reprocess them.
876
877 // Check for squashed instructions.
878 if (inst->isSquashed()) {
879 DPRINTF(IEW, "[tid:%i] Issue: Squashed instruction encountered, "
880 "not adding to IQ.\n", tid);
881
883
884 insts_to_dispatch.pop();
885
886 //Tell Rename That An Instruction has been processed
887 if (inst->isLoad()) {
888 toRename->iewInfo[tid].dispatchedToLQ++;
889 }
890 if (inst->isStore() || inst->isAtomic()) {
891 toRename->iewInfo[tid].dispatchedToSQ++;
892 }
893
894 toRename->iewInfo[tid].dispatched++;
895
896 continue;
897 }
898
899 // Check for full conditions.
900 if (instQueue.isFull(tid)) {
901 DPRINTF(IEW, "[tid:%i] Issue: IQ has become full.\n", tid);
902
903 // Call function to start blocking.
904 block(tid);
905
906 // Set unblock to false. Special case where we are using
907 // skidbuffer (unblocking) instructions but then we still
908 // get full in the IQ.
909 toRename->iewUnblock[tid] = false;
910
912 break;
913 }
914
915 // Check LSQ if inst is LD/ST
916 if ((inst->isAtomic() && ldstQueue.sqFull(tid)) ||
917 (inst->isLoad() && ldstQueue.lqFull(tid)) ||
918 (inst->isStore() && ldstQueue.sqFull(tid))) {
919 DPRINTF(IEW, "[tid:%i] Issue: %s has become full.\n",tid,
920 inst->isLoad() ? "LQ" : "SQ");
921
922 // Call function to start blocking.
923 block(tid);
924
925 // Set unblock to false. Special case where we are using
926 // skidbuffer (unblocking) instructions but then we still
927 // get full in the IQ.
928 toRename->iewUnblock[tid] = false;
929
931 break;
932 }
933
934 // hardware transactional memory
935 // CPU needs to track transactional state in program order.
936 const int numHtmStarts = ldstQueue.numHtmStarts(tid);
937 const int numHtmStops = ldstQueue.numHtmStops(tid);
938 const int htmDepth = numHtmStarts - numHtmStops;
939
940 if (htmDepth > 0) {
941 inst->setHtmTransactionalState(ldstQueue.getLatestHtmUid(tid),
942 htmDepth);
943 } else {
944 inst->clearHtmTransactionalState();
945 }
946
947
948 // Otherwise issue the instruction just fine.
949 if (inst->isAtomic()) {
950 DPRINTF(IEW, "[tid:%i] Issue: Memory instruction "
951 "encountered, adding to LSQ.\n", tid);
952
954
956
957 // AMOs need to be set as "canCommit()"
958 // so that commit can process them when they reach the
959 // head of commit.
960 inst->setCanCommit();
962 add_to_iq = false;
963
965
966 toRename->iewInfo[tid].dispatchedToSQ++;
967 } else if (inst->isLoad()) {
968 DPRINTF(IEW, "[tid:%i] Issue: Memory instruction "
969 "encountered, adding to LSQ.\n", tid);
970
971 // Reserve a spot in the load store queue for this
972 // memory access.
973 ldstQueue.insertLoad(inst);
974
976
977 add_to_iq = true;
978
979 toRename->iewInfo[tid].dispatchedToLQ++;
980 } else if (inst->isStore()) {
981 DPRINTF(IEW, "[tid:%i] Issue: Memory instruction "
982 "encountered, adding to LSQ.\n", tid);
983
985
987
988 if (inst->isStoreConditional()) {
989 // Store conditionals need to be set as "canCommit()"
990 // so that commit can process them when they reach the
991 // head of commit.
992 // @todo: This is somewhat specific to Alpha.
993 inst->setCanCommit();
995 add_to_iq = false;
996
998 } else {
999 add_to_iq = true;
1000 }
1001
1002 toRename->iewInfo[tid].dispatchedToSQ++;
1003 } else if (inst->isReadBarrier() || inst->isWriteBarrier()) {
1004 // Same as non-speculative stores.
1005 inst->setCanCommit();
1007 add_to_iq = false;
1008 } else if (inst->isNop()) {
1009 DPRINTF(IEW, "[tid:%i] Issue: Nop instruction encountered, "
1010 "skipping.\n", tid);
1011
1012 inst->setIssued();
1013 inst->setExecuted();
1014 inst->setCanCommit();
1015
1017
1018 cpu->executeStats[tid]->numNop++;
1019
1020 add_to_iq = false;
1021 } else {
1022 assert(!inst->isExecuted());
1023 add_to_iq = true;
1024 }
1025
1026 if (add_to_iq && inst->isNonSpeculative()) {
1027 DPRINTF(IEW, "[tid:%i] Issue: Nonspeculative instruction "
1028 "encountered, skipping.\n", tid);
1029
1030 // Same as non-speculative stores.
1031 inst->setCanCommit();
1032
1033 // Specifically insert it as nonspeculative.
1035
1037
1038 add_to_iq = false;
1039 }
1040
1041 // If the instruction queue is not full, then add the
1042 // instruction.
1043 if (add_to_iq) {
1044 instQueue.insert(inst);
1045 }
1046
1047 insts_to_dispatch.pop();
1048
1049 toRename->iewInfo[tid].dispatched++;
1050
1052
1053#if TRACING_ON
1054 inst->dispatchTick = curTick() - inst->fetchTick;
1055#endif
1056 ppDispatch->notify(inst);
1057 }
1058
1059 if (!insts_to_dispatch.empty()) {
1060 DPRINTF(IEW,"[tid:%i] Issue: Bandwidth Full. Blocking.\n", tid);
1061 block(tid);
1062 toRename->iewUnblock[tid] = false;
1063 }
1064
1065 if (dispatchStatus[tid] == Idle && dis_num_inst) {
1066 dispatchStatus[tid] = Running;
1067
1068 updatedQueues = true;
1069 }
1070
1071 dis_num_inst = 0;
1072}
1073
1074void
1076{
1077 int inst = 0;
1078
1079 std::cout << "Available Instructions: ";
1080
1081 while (fromIssue->insts[inst]) {
1082
1083 if (inst%3==0) std::cout << "\n\t";
1084
1085 std::cout << "PC: " << fromIssue->insts[inst]->pcState()
1086 << " TN: " << fromIssue->insts[inst]->threadNumber
1087 << " SN: " << fromIssue->insts[inst]->seqNum << " | ";
1088
1089 inst++;
1090
1091 }
1092
1093 std::cout << "\n";
1094}
1095
1096void
1098{
1099 wbNumInst = 0;
1100 wbCycle = 0;
1101
1104
1105 while (threads != end) {
1106 ThreadID tid = *threads++;
1107 fetchRedirect[tid] = false;
1108 }
1109
1110 // Uncomment this if you want to see all available instructions.
1111 // @todo This doesn't actually work anymore, we should fix it.
1112// printAvailableInsts();
1113
1114 // Execute/writeback any instructions that are available.
1115 int insts_to_execute = fromIssue->size;
1116 int inst_num = 0;
1117 for (; inst_num < insts_to_execute;
1118 ++inst_num) {
1119
1120 DPRINTF(IEW, "Execute: Executing instructions from IQ.\n");
1121
1123
1124 DPRINTF(IEW, "Execute: Processing PC %s, [tid:%i] [sn:%llu].\n",
1125 inst->pcState(), inst->threadNumber,inst->seqNum);
1126
1127 // Notify potential listeners that this instruction has started
1128 // executing
1129 ppExecute->notify(inst);
1130
1131 // Check if the instruction is squashed; if so then skip it
1132 if (inst->isSquashed()) {
1133 DPRINTF(IEW, "Execute: Instruction was squashed. PC: %s, [tid:%i]"
1134 " [sn:%llu]\n", inst->pcState(), inst->threadNumber,
1135 inst->seqNum);
1136
1137 // Consider this instruction executed so that commit can go
1138 // ahead and retire the instruction.
1139 inst->setExecuted();
1140
1141 // Not sure if I should set this here or just let commit try to
1142 // commit any squashed instructions. I like the latter a bit more.
1143 inst->setCanCommit();
1144
1146
1147 continue;
1148 }
1149
1150 Fault fault = NoFault;
1151
1152 // Execute instruction.
1153 // Note that if the instruction faults, it will be handled
1154 // at the commit stage.
1155 if (inst->isMemRef()) {
1156 DPRINTF(IEW, "Execute: Calculating address for memory "
1157 "reference.\n");
1158
1159 // Tell the LDSTQ to execute this instruction (if it is a load).
1160 if (inst->isAtomic()) {
1161 // AMOs are treated like store requests
1162 fault = ldstQueue.executeStore(inst);
1163
1164 if (inst->isTranslationDelayed() &&
1165 fault == NoFault) {
1166 // A hw page table walk is currently going on; the
1167 // instruction must be deferred.
1168 DPRINTF(IEW, "Execute: Delayed translation, deferring "
1169 "store.\n");
1170 instQueue.deferMemInst(inst);
1171 continue;
1172 }
1173 } else if (inst->isLoad()) {
1174 // Loads will mark themselves as executed, and their writeback
1175 // event adds the instruction to the queue to commit
1176 fault = ldstQueue.executeLoad(inst);
1177
1178 if (inst->isTranslationDelayed() &&
1179 fault == NoFault) {
1180 // A hw page table walk is currently going on; the
1181 // instruction must be deferred.
1182 DPRINTF(IEW, "Execute: Delayed translation, deferring "
1183 "load.\n");
1184 instQueue.deferMemInst(inst);
1185 continue;
1186 }
1187
1188 if (inst->isDataPrefetch() || inst->isInstPrefetch()) {
1189 inst->fault = NoFault;
1190 }
1191 } else if (inst->isStore()) {
1192 fault = ldstQueue.executeStore(inst);
1193
1194 if (inst->isTranslationDelayed() &&
1195 fault == NoFault) {
1196 // A hw page table walk is currently going on; the
1197 // instruction must be deferred.
1198 DPRINTF(IEW, "Execute: Delayed translation, deferring "
1199 "store.\n");
1200 instQueue.deferMemInst(inst);
1201 continue;
1202 }
1203
1204 // If the store had a fault then it may not have a mem req
1205 if (fault != NoFault || !inst->readPredicate() ||
1206 !inst->isStoreConditional()) {
1207 // If the instruction faulted, then we need to send it
1208 // along to commit without the instruction completing.
1209 // Send this instruction to commit, also make sure iew
1210 // stage realizes there is activity.
1211 inst->setExecuted();
1212 instToCommit(inst);
1214 }
1215
1216 // Store conditionals will mark themselves as
1217 // executed, and their writeback event will add the
1218 // instruction to the queue to commit.
1219 } else {
1220 panic("Unexpected memory type!\n");
1221 }
1222
1223 } else {
1224 // If the instruction has already faulted, then skip executing it.
1225 // Such case can happen when it faulted during ITLB translation.
1226 // If we execute the instruction (even if it's a nop) the fault
1227 // will be replaced and we will lose it.
1228 if (inst->getFault() == NoFault) {
1229 inst->execute();
1230 if (!inst->readPredicate())
1231 inst->forwardOldRegs();
1232 }
1233
1234 inst->setExecuted();
1235
1236 instToCommit(inst);
1237 }
1238
1239 updateExeInstStats(inst);
1240
1241 // Check if branch prediction was correct, if not then we need
1242 // to tell commit to squash in flight instructions. Only
1243 // handle this if there hasn't already been something that
1244 // redirects fetch in this group of instructions.
1245
1246 // This probably needs to prioritize the redirects if a different
1247 // scheduler is used. Currently the scheduler schedules the oldest
1248 // instruction first, so the branch resolution order will be correct.
1249 ThreadID tid = inst->threadNumber;
1250
1251 if (!fetchRedirect[tid] ||
1252 !toCommit->squash[tid] ||
1253 toCommit->squashedSeqNum[tid] > inst->seqNum) {
1254
1255 // Prevent testing for misprediction on load instructions,
1256 // that have not been executed.
1257 bool loadNotExecuted = !inst->isExecuted() && inst->isLoad();
1258
1259 if (inst->mispredicted() && !loadNotExecuted) {
1260 fetchRedirect[tid] = true;
1261
1262 DPRINTF(IEW, "[tid:%i] [sn:%llu] Execute: "
1263 "Branch mispredict detected.\n",
1264 tid, inst->seqNum);
1265 DPRINTF(IEW, "[tid:%i] [sn:%llu] "
1266 "Predicted target was PC: %s\n",
1267 tid, inst->seqNum, inst->readPredTarg());
1268 DPRINTF(IEW, "[tid:%i] [sn:%llu] Execute: "
1269 "Redirecting fetch to PC: %s\n",
1270 tid, inst->seqNum, inst->pcState());
1271 // If incorrect, then signal the ROB that it must be squashed.
1272 squashDueToBranch(inst, tid);
1273
1274 ppMispredict->notify(inst);
1275
1276 if (inst->readPredTaken()) {
1278 } else {
1280 }
1281 } else if (ldstQueue.violation(tid)) {
1282 assert(inst->isMemRef());
1283 // If there was an ordering violation, then get the
1284 // DynInst that caused the violation. Note that this
1285 // clears the violation signal.
1286 DynInstPtr violator;
1287 violator = ldstQueue.getMemDepViolator(tid);
1288
1289 DPRINTF(IEW, "LDSTQ detected a violation. Violator PC: %s "
1290 "[sn:%lli], inst PC: %s [sn:%lli]. Addr is: %#x.\n",
1291 violator->pcState(), violator->seqNum,
1292 inst->pcState(), inst->seqNum, inst->physEffAddr);
1293
1294 fetchRedirect[tid] = true;
1295
1296 // Tell the instruction queue that a violation has occured.
1297 instQueue.violation(inst, violator);
1298
1299 // Squash.
1300 squashDueToMemOrder(violator, tid);
1301
1303 }
1304 } else {
1305 // Reset any state associated with redirects that will not
1306 // be used.
1307 if (ldstQueue.violation(tid)) {
1308 assert(inst->isMemRef());
1309
1310 DynInstPtr violator = ldstQueue.getMemDepViolator(tid);
1311
1312 DPRINTF(IEW, "LDSTQ detected a violation. Violator PC: "
1313 "%s, inst PC: %s. Addr is: %#x.\n",
1314 violator->pcState(), inst->pcState(),
1315 inst->physEffAddr);
1316 DPRINTF(IEW, "Violation will not be handled because "
1317 "already squashing\n");
1318
1320 }
1321 }
1322 }
1323
1324 // Update and record activity if we processed any instructions.
1325 if (inst_num) {
1326 if (exeStatus == Idle) {
1328 }
1329
1330 updatedQueues = true;
1331
1333 }
1334
1335 // Need to reset this in case a writeback event needs to write into the
1336 // iew queue. That way the writeback event will write into the correct
1337 // spot in the queue.
1338 wbNumInst = 0;
1339
1340}
1341
1342void
1344{
1345 // Loop through the head of the time buffer and wake any
1346 // dependents. These instructions are about to write back. Also
1347 // mark scoreboard that this instruction is finally complete.
1348 // Either have IEW have direct access to scoreboard, or have this
1349 // as part of backwards communication.
1350 for (int inst_num = 0; inst_num < wbWidth &&
1351 toCommit->insts[inst_num]; inst_num++) {
1352 DynInstPtr inst = toCommit->insts[inst_num];
1353 ThreadID tid = inst->threadNumber;
1354
1355 DPRINTF(IEW, "Sending instructions to commit, [sn:%lli] PC %s.\n",
1356 inst->seqNum, inst->pcState());
1357
1358 iewStats.instsToCommit[tid]++;
1359 // Notify potential listeners that execution is complete for this
1360 // instruction.
1361 ppToCommit->notify(inst);
1362
1363 // Some instructions will be sent to commit without having
1364 // executed because they need commit to handle them.
1365 // E.g. Strictly ordered loads have not actually executed when they
1366 // are first sent to commit. Instead commit must tell the LSQ
1367 // when it's ready to execute the strictly ordered load.
1368 if (!inst->isSquashed() && inst->isExecuted() &&
1369 inst->getFault() == NoFault) {
1370 int dependents = instQueue.wakeDependents(inst);
1371
1372 for (int i = 0; i < inst->numDestRegs(); i++) {
1373 // Mark register as ready if not pinned
1374 if (inst->renamedDestIdx(i)->
1375 getNumPinnedWritesToComplete() == 0) {
1376 DPRINTF(IEW,"Setting Destination Register %i (%s)\n",
1377 inst->renamedDestIdx(i)->index(),
1378 inst->renamedDestIdx(i)->className());
1379 scoreboard->setReg(inst->renamedDestIdx(i));
1380 }
1381 }
1382
1383 if (dependents) {
1384 iewStats.producerInst[tid]++;
1385 iewStats.consumerInst[tid]+= dependents;
1386 }
1387 iewStats.writebackCount[tid]++;
1388 }
1389 }
1390}
1391
1392void
1394{
1395 wbNumInst = 0;
1396 wbCycle = 0;
1397
1398 wroteToTimeBuffer = false;
1399 updatedQueues = false;
1400
1401 ldstQueue.tick();
1402
1403 sortInsts();
1404
1405 // Free function units marked as being freed this cycle.
1407
1410
1411 // Check stall and squash signals, dispatch any instructions.
1412 while (threads != end) {
1413 ThreadID tid = *threads++;
1414
1415 DPRINTF(IEW,"Issue: Processing [tid:%i]\n",tid);
1416
1418 dispatch(tid);
1419 }
1420
1421 if (exeStatus != Squashing) {
1422 executeInsts();
1423
1425
1426 // Have the instruction queue try to schedule any ready instructions.
1427 // (In actuality, this scheduling is for instructions that will
1428 // be executed next cycle.)
1430
1431 // Also should advance its own time buffers if the stage ran.
1432 // Not the best place for it, but this works (hopefully).
1433 issueToExecQueue.advance();
1434 }
1435
1436 bool broadcast_free_entries = false;
1437
1439 exeStatus = Idle;
1440 updateLSQNextCycle = false;
1441
1442 broadcast_free_entries = true;
1443 }
1444
1445 // Writeback any stores using any leftover bandwidth.
1447
1448 // Check the committed load/store signals to see if there's a load
1449 // or store to commit. Also check if it's being told to execute a
1450 // nonspeculative instruction.
1451 // This is pretty inefficient...
1452
1453 threads = activeThreads->begin();
1454 while (threads != end) {
1455 ThreadID tid = (*threads++);
1456
1457 DPRINTF(IEW,"Processing [tid:%i]\n",tid);
1458
1459 // Update structures based on instructions committed.
1460 if (fromCommit->commitInfo[tid].doneSeqNum != 0 &&
1461 !fromCommit->commitInfo[tid].squash &&
1462 !fromCommit->commitInfo[tid].robSquashing) {
1463
1464 ldstQueue.commitStores(fromCommit->commitInfo[tid].doneSeqNum,tid);
1465
1466 ldstQueue.commitLoads(fromCommit->commitInfo[tid].doneSeqNum,tid);
1467
1468 updateLSQNextCycle = true;
1469 instQueue.commit(fromCommit->commitInfo[tid].doneSeqNum,tid);
1470 }
1471
1472 if (fromCommit->commitInfo[tid].nonSpecSeqNum != 0) {
1473
1474 //DPRINTF(IEW,"NonspecInst from thread %i",tid);
1475 if (fromCommit->commitInfo[tid].strictlyOrdered) {
1477 fromCommit->commitInfo[tid].strictlyOrderedLoad);
1478 fromCommit->commitInfo[tid].strictlyOrderedLoad->setAtCommit();
1479 } else {
1481 fromCommit->commitInfo[tid].nonSpecSeqNum);
1482 }
1483 }
1484
1485 if (broadcast_free_entries) {
1486 toFetch->iewInfo[tid].iqCount =
1487 instQueue.getCount(tid);
1488 toFetch->iewInfo[tid].ldstqCount =
1489 ldstQueue.getCount(tid);
1490
1491 toRename->iewInfo[tid].usedIQ = true;
1492 toRename->iewInfo[tid].freeIQEntries =
1494 toRename->iewInfo[tid].usedLSQ = true;
1495
1496 toRename->iewInfo[tid].freeLQEntries =
1498 toRename->iewInfo[tid].freeSQEntries =
1500
1501 wroteToTimeBuffer = true;
1502 }
1503
1504 DPRINTF(IEW, "[tid:%i], Dispatch dispatched %i instructions.\n",
1505 tid, toRename->iewInfo[tid].dispatched);
1506 }
1507
1508 DPRINTF(IEW, "IQ has %i free entries (Can schedule: %i). "
1509 "LQ has %i free entries. SQ has %i free entries.\n",
1512
1513 updateStatus();
1514
1515 if (wroteToTimeBuffer) {
1516 DPRINTF(Activity, "Activity this cycle.\n");
1518 }
1519}
1520
1521void
1523{
1524 ThreadID tid = inst->threadNumber;
1525
1526 cpu->executeStats[tid]->numInsts++;
1527
1528#if TRACING_ON
1529 if (debug::O3PipeView) {
1530 inst->completeTick = curTick() - inst->fetchTick;
1531 }
1532#endif
1533
1534 //
1535 // Control operations
1536 //
1537 if (inst->isControl()) {
1538 cpu->executeStats[tid]->numBranches++;
1539 }
1540
1541 //
1542 // Memory operations
1543 //
1544 if (inst->isMemRef()) {
1545 cpu->executeStats[tid]->numMemRefs++;
1546
1547 if (inst->isLoad()) {
1548 cpu->executeStats[tid]->numLoadInsts++;
1549 }
1550 }
1551}
1552
1553void
1555{
1556 ThreadID tid = inst->threadNumber;
1557
1558 if (!fetchRedirect[tid] ||
1559 !toCommit->squash[tid] ||
1560 toCommit->squashedSeqNum[tid] > inst->seqNum) {
1561
1562 if (inst->mispredicted()) {
1563 fetchRedirect[tid] = true;
1564
1565 DPRINTF(IEW, "[tid:%i] [sn:%llu] Execute: "
1566 "Branch mispredict detected.\n",
1567 tid, inst->seqNum);
1568 DPRINTF(IEW, "[tid:%i] [sn:%llu] Predicted target was PC: %s\n",
1569 tid, inst->seqNum, inst->readPredTarg());
1570 DPRINTF(IEW, "[tid:%i] [sn:%llu] Execute: "
1571 "Redirecting fetch to PC: %s\n",
1572 tid, inst->seqNum, inst->pcState());
1573 // If incorrect, then signal the ROB that it must be squashed.
1574 squashDueToBranch(inst, tid);
1575
1576 if (inst->readPredTaken()) {
1578 } else {
1580 }
1581 }
1582 }
1583}
1584
1585} // namespace o3
1586} // namespace gem5
#define DPRINTF(x,...)
Definition trace.hh:210
gem5::BaseCPU::BaseCPUStats baseStats
ThreadID numThreads
Number of threads we're actually simulating (<= SMT_MAX_THREADS).
Definition base.hh:390
std::vector< std::unique_ptr< ExecuteCPUStats > > executeStats
Definition base.hh:820
void setDcachePort(RequestPort *dcache_port)
Definition cpu.cc:124
virtual std::string name() const
Definition named.hh:47
ProbePointArg generates a point for the class of Arg.
Definition probe.hh:264
wire getWire(int idx)
Definition timebuf.hh:232
O3CPU class, has each of the stages (fetch through commit) within it, as well as all of the time buff...
Definition cpu.hh:94
gem5::Checker< DynInstPtr > * checker
Pointer to the checker, which can dynamically verify instruction results at run time.
Definition cpu.hh:527
void activityThisCycle()
Records that there was time buffer activity this cycle.
Definition cpu.hh:488
void deactivateStage(const StageIdx idx)
Changes a stage's status to inactive within the activity recorder.
Definition cpu.hh:499
void activateStage(const StageIdx idx)
Changes a stage's status to active within the activity recorder.
Definition cpu.hh:492
void wakeCPU()
Wakes the CPU, rescheduling the CPU if it's not already active.
Definition cpu.cc:1316
void processFreeUnits()
Frees all FUs on the list.
Definition fu_pool.cc:197
bool isDrained() const
Have all the FUs drained?
Definition fu_pool.cc:244
void takeOverFrom()
Takes over from another CPU's thread.
Definition fu_pool.hh:182
IEW handles both single threaded and SMT IEW (issue/execute/writeback).
Definition iew.hh:88
void printAvailableInsts()
Debug function to print instructions that are issued this cycle.
Definition iew.cc:1075
void updateStatus()
Updates overall IEW status based on all of the stages' statuses.
Definition iew.cc:612
void deactivateStage()
Tells CPU that the IEW stage is inactive and idle.
Definition iew.cc:785
TimeBuffer< IEWStruct > * iewQueue
IEW stage time buffer.
Definition iew.hh:327
TimeBuffer< TimeStruct >::wire fromCommit
Wire to get commit's output from backwards time buffer.
Definition iew.hh:306
StageStatus dispatchStatus[MaxThreads]
Dispatch status.
Definition iew.hh:114
std::list< ThreadID > * activeThreads
Pointer to list of active threads.
Definition iew.hh:412
void takeOverFrom()
Takes over from another CPU's thread.
Definition iew.cc:353
void setTimeBuffer(TimeBuffer< TimeStruct > *tb_ptr)
Sets main time buffer used for backwards communication.
Definition iew.cc:266
int skidCount()
Returns the max of the number of entries in all of the skid buffers.
Definition iew.cc:578
void instToCommit(const DynInstPtr &inst)
Sends an instruction to commit through the time buffer.
Definition iew.cc:529
FUPool * fuPool
Pointer to the functional unit pool.
Definition iew.hh:361
void squashDueToBranch(const DynInstPtr &inst, ThreadID tid)
Sends commit proper information for a squash due to a branch mispredict.
Definition iew.cc:415
void squashDueToMemOrder(const DynInstPtr &inst, ThreadID tid)
Sends commit proper information for a squash due to a memory order violation.
Definition iew.cc:439
unsigned wbWidth
Writeback width.
Definition iew.hh:406
std::queue< DynInstPtr > insts[MaxThreads]
Queue of all instructions coming from rename this cycle.
Definition iew.hh:333
void block(ThreadID tid)
Sets Dispatch to blocked, and signals back to other stages to block.
Definition iew.cc:465
StageStatus exeStatus
Execute status.
Definition iew.hh:116
void clearStates(ThreadID tid)
Clear all thread-specific states.
Definition iew.cc:254
void dispatch(ThreadID tid)
Determines proper actions to take given Dispatch's status.
Definition iew.cc:792
void startupStage()
Initializes stage; sends back the number of free IQ and LSQ entries.
Definition iew.cc:231
void blockMemInst(const DynInstPtr &inst)
Moves memory instruction onto the list of cache blocked instructions.
Definition iew.cc:517
void unblock(ThreadID tid)
Unblocks Dispatch if the skid buffer is empty, and signals back to other stages to unblock.
Definition iew.cc:483
void sortInsts()
Sorts instructions coming from rename into lists separated by thread.
Definition iew.cc:731
void wakeDependents(const DynInstPtr &inst)
Wakes all dependents of a completed instruction.
Definition iew.cc:499
unsigned issueWidth
Width of issue, in instructions.
Definition iew.hh:393
void updateExeInstStats(const DynInstPtr &inst)
Updates execution stats based on the instruction.
Definition iew.cc:1522
void dispatchInsts(ThreadID tid)
Dispatches instructions to IQ and LSQ.
Definition iew.cc:839
void drainSanityCheck() const
Perform sanity checks after a drain.
Definition iew.cc:344
TimeBuffer< IssueStruct > issueToExecQueue
Issue stage queue.
Definition iew.hh:318
void checkSignalsAndUpdate(ThreadID tid)
Processes inputs and changes state accordingly.
Definition iew.cc:668
void activateStage()
Tells CPU that the IEW stage is active and running.
Definition iew.cc:778
TimeBuffer< TimeStruct >::wire toRename
Wire to write information heading to previous stages.
Definition iew.hh:309
bool wroteToTimeBuffer
Records if IEW has written to the time buffer this cycle, so that the CPU can deschedule itself if th...
Definition iew.hh:348
CPU * cpu
CPU pointer.
Definition iew.hh:343
void activityThisCycle()
Reports to the CPU that there is activity this cycle.
Definition iew.cc:771
void setScoreboard(Scoreboard *sb_ptr)
Sets pointer to the scoreboard.
Definition iew.cc:310
Scoreboard * scoreboard
Scoreboard pointer.
Definition iew.hh:339
std::queue< DynInstPtr > skidBuffer[MaxThreads]
Skid buffer between rename and IEW.
Definition iew.hh:336
TimeBuffer< IssueStruct >::wire fromIssue
Wire to read information from the issue stage time queue.
Definition iew.hh:321
Cycles renameToIEWDelay
Rename to IEW delay.
Definition iew.hh:380
TimeBuffer< TimeStruct > * timeBuffer
Pointer to main time buffer used for backwards communication.
Definition iew.hh:300
void writebackInsts()
Writebacks instructions.
Definition iew.cc:1343
void wakeCPU()
Tells the CPU to wakeup if it has descheduled itself due to no activity.
Definition iew.cc:765
void squash(ThreadID tid)
Squashes instructions in IEW for a specific thread.
Definition iew.cc:380
void setIEWQueue(TimeBuffer< IEWStruct > *iq_ptr)
Sets time buffer to pass on instructions to commit.
Definition iew.cc:292
ProbePointArg< DynInstPtr > * ppExecute
To probe when instruction execution begins.
Definition iew.hh:124
void rescheduleMemInst(const DynInstPtr &inst)
Tells memory dependence unit that a memory instruction needs to be rescheduled.
Definition iew.cc:505
ThreadID numThreads
Number of active threads.
Definition iew.hh:409
unsigned skidBufferMax
Maximum size of the skid buffer.
Definition iew.hh:415
Status _status
Overall stage status.
Definition iew.hh:112
TimeBuffer< RenameStruct >::wire fromRename
Wire to get rename's output from rename queue.
Definition iew.hh:315
ProbePointArg< DynInstPtr > * ppMispredict
Probe points.
Definition iew.hh:121
TimeBuffer< TimeStruct >::wire toFetch
Wire to write information heading to previous stages.
Definition iew.hh:303
gem5::o3::IEW::IEWStats iewStats
bool isDrained() const
Has the stage drained?
Definition iew.cc:316
InstructionQueue instQueue
Instruction queue.
Definition iew.hh:355
bool fetchRedirect[MaxThreads]
Records if there is a fetch redirect on this cycle for each thread.
Definition iew.hh:369
TimeBuffer< RenameStruct > * renameQueue
Rename instruction queue interface.
Definition iew.hh:312
IEW(CPU *_cpu, const BaseO3CPUParams &params)
Constructs a IEW with the given parameters.
Definition iew.cc:67
unsigned dispatchWidth
Width of dispatch, in instructions.
Definition iew.hh:390
ProbePointArg< DynInstPtr > * ppDispatch
Definition iew.hh:122
std::string name() const
Returns the name of the IEW stage.
Definition iew.cc:118
void tick()
Ticks IEW stage, causing Dispatch, the IQ, the LSQ, Execute, and Writeback to run for one cycle.
Definition iew.cc:1393
ProbePointArg< DynInstPtr > * ppToCommit
To probe when instruction execution is complete.
Definition iew.hh:126
bool updatedQueues
Records if the queues have been changed (inserted or issued insts), so that IEW knows to broadcast th...
Definition iew.hh:374
void checkMisprediction(const DynInstPtr &inst)
Check misprediction
Definition iew.cc:1554
LSQ ldstQueue
Load / store queue.
Definition iew.hh:358
Cycles issueToExecuteDelay
Issue to execute delay.
Definition iew.hh:387
void setActiveThreads(std::list< ThreadID > *at_ptr)
Sets pointer to list of active threads.
Definition iew.cc:301
bool skidsEmpty()
Returns if all of the skid buffers are empty.
Definition iew.cc:596
bool updateLSQNextCycle
Records if the LSQ needs to be updated on the next cycle, so that IEW knows if there will be activity...
Definition iew.hh:365
void emptyRenameInsts(ThreadID tid)
Removes instructions from rename from a thread's instruction list.
Definition iew.cc:744
void replayMemInst(const DynInstPtr &inst)
Re-executes all rescheduled memory instructions.
Definition iew.cc:511
Cycles commitToIEWDelay
Commit to IEW delay.
Definition iew.hh:377
unsigned wbCycle
Cycle number within the queue of instructions being written back.
Definition iew.hh:403
void skidInsert(ThreadID tid)
Inserts unused instructions of a thread into the skid buffer.
Definition iew.cc:557
void cacheUnblocked()
Notifies that the cache has become unblocked.
Definition iew.cc:523
TimeBuffer< IEWStruct >::wire toCommit
Wire to write infromation heading to commit.
Definition iew.hh:330
void regProbePoints()
Registers probes.
Definition iew.cc:124
bool checkStall(ThreadID tid)
Checks if any of the stall conditions are currently true.
Definition iew.cc:652
void executeInsts()
Executes instructions.
Definition iew.cc:1097
unsigned wbNumInst
Index into queue of instructions being written back.
Definition iew.hh:396
void setRenameQueue(TimeBuffer< RenameStruct > *rq_ptr)
Sets time buffer for getting instructions coming from rename.
Definition iew.cc:283
StageStatus wbStatus
Writeback status.
Definition iew.hh:118
void commit(const InstSeqNum &inst, ThreadID tid=0)
Commits all instructions up to and including the given sequence number, for a specific thread.
void deferMemInst(const DynInstPtr &deferred_inst)
Defers a memory instruction when its DTB translation incurs a hw page table walk.
void insertBarrier(const DynInstPtr &barr_inst)
Inserts a memory or write barrier into the IQ to make sure loads and stores are ordered properly.
int wakeDependents(const DynInstPtr &completed_inst)
Wakes all dependents of a completed instruction.
void setTimeBuffer(TimeBuffer< TimeStruct > *tb_ptr)
Sets the global time buffer.
unsigned numFreeEntries()
Returns total number of free entries.
void rescheduleMemInst(const DynInstPtr &resched_inst)
Reschedules a memory instruction.
void insertNonSpec(const DynInstPtr &new_inst)
Inserts a new, non-speculative instruction into the IQ.
unsigned getCount(ThreadID tid)
Returns the number of used entries for a thread.
void replayMemInst(const DynInstPtr &replay_inst)
Replays a memory instruction.
void recordProducer(const DynInstPtr &inst)
Records the instruction as the producer of a register without adding it to the rest of the IQ.
bool isDrained() const
Determine if we are drained.
void cacheUnblocked()
Notify instruction queue that a previous blockage has resolved.
void blockMemInst(const DynInstPtr &blocked_inst)
Defers a memory instruction when it is cache blocked.
void drainSanityCheck() const
Perform sanity checks after a drain.
void takeOverFrom()
Takes over execution from another CPU's thread.
gem5::o3::InstructionQueue::IQIOStats iqIOStats
void violation(const DynInstPtr &store, const DynInstPtr &faulting_load)
Indicates an ordering violation between a store and a load.
bool hasReadyInsts()
Returns if there are any ready instructions in the IQ.
void setActiveThreads(std::list< ThreadID > *at_ptr)
Sets active threads list.
void scheduleNonSpec(const InstSeqNum &inst)
Schedules a single specific non-speculative instruction.
void scheduleReadyInsts()
Schedules ready instructions, adding the ready ones (oldest first) to the queue to execute.
bool isFull()
Returns whether or not the IQ is full.
void squash(ThreadID tid)
Squashes instructions for a thread.
void setIssueToExecuteQueue(TimeBuffer< IssueStruct > *i2eQueue)
Sets the timer buffer between issue and execute.
void insert(const DynInstPtr &new_inst)
Inserts a new instruction into the IQ.
DynInstPtr getInstToExecute()
Returns the oldest scheduled instruction, and removes it from the list of instructions waiting to exe...
bool isDrained() const
Has the LSQ drained?
Definition lsq.cc:146
int numHtmStarts(ThreadID tid) const
Definition lsq.cc:344
void commitStores(InstSeqNum &youngest_inst, ThreadID tid)
Commits stores up until the given sequence number for a specific thread.
Definition lsq.cc:259
void squash(const InstSeqNum &squashed_num, ThreadID tid)
Squash instructions from a thread until the specified sequence number.
Definition lsq.cc:283
unsigned numFreeLoadEntries()
Returns the number of free load entries.
Definition lsq.cc:524
void takeOverFrom()
Takes over execution from another CPU's thread.
Definition lsq.cc:164
DynInstPtr getMemDepViolator(ThreadID tid)
Gets the instruction that caused the memory ordering violation.
Definition lsq.cc:308
void setActiveThreads(std::list< ThreadID > *at_ptr)
Sets the pointer to the list of active threads.
Definition lsq.cc:130
void insertStore(const DynInstPtr &store_inst)
Inserts a store into the LSQ.
Definition lsq.cc:229
void commitLoads(InstSeqNum &youngest_inst, ThreadID tid)
Commits loads up until the given sequence number for a specific thread.
Definition lsq.cc:253
RequestPort & getDataPort()
Definition lsq.hh:892
uint64_t getLatestHtmUid(ThreadID tid) const
Definition lsq.cc:368
bool willWB()
Returns if the LSQ will write back to memory this cycle.
Definition lsq.cc:742
void drainSanityCheck() const
Perform sanity checks after a drain.
Definition lsq.cc:137
int numHtmStops(ThreadID tid) const
Definition lsq.cc:352
void writebackStores()
Attempts to write back stores until all cache ports are used or the interface becomes blocked.
Definition lsq.cc:265
bool lqFull()
Returns if any of the LQs are full.
Definition lsq.cc:635
int getCount()
Returns the number of instructions in all of the queues.
Definition lsq.cc:473
Fault executeStore(const DynInstPtr &inst)
Executes a store.
Definition lsq.cc:245
void tick()
Ticks the LSQ.
Definition lsq.cc:175
void insertLoad(const DynInstPtr &load_inst)
Inserts a load into the LSQ.
Definition lsq.cc:221
Fault executeLoad(const DynInstPtr &inst)
Executes a load.
Definition lsq.cc:237
bool violation()
Returns whether or not there was a memory ordering violation.
Definition lsq.cc:289
unsigned numFreeStoreEntries()
Returns the number of free store entries.
Definition lsq.cc:541
bool sqFull()
Returns if any of the SQs are full.
Definition lsq.cc:662
Implements a simple scoreboard to track which registers are ready.
Definition scoreboard.hh:55
void setReg(PhysRegIdPtr phys_reg)
Sets the register as ready.
Definition scoreboard.hh:97
Derived & flags(Flags _flags)
Set the flags and marks this stat to print at the end of simulation.
Statistics container.
Definition group.hh:93
Derived & init(size_type size)
Set this vector to have the given size.
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:188
#define fatal(...)
This implements a cprintf based fatal() function.
Definition logging.hh:200
ProbeManager * getProbeManager()
Get the probe manager for this object.
Bitfield< 7 > i
Definition misc_types.hh:67
Bitfield< 12, 11 > set
static constexpr int MaxThreads
Definition limits.hh:38
static constexpr int MaxWidth
Definition limits.hh:37
const FlagsType total
Print the total.
Definition info.hh:59
Copyright (c) 2024 - Pranith Kumar Copyright (c) 2020 Inria All rights reserved.
Definition binary32.hh:36
std::shared_ptr< FaultBase > Fault
Definition types.hh:249
int16_t ThreadID
Thread index/ID type.
Definition types.hh:235
Tick curTick()
The universal simulation clock.
Definition cur_tick.hh:46
constexpr decltype(nullptr) NoFault
Definition types.hh:253
statistics::Scalar numCycles
Definition base.hh:640
statistics::Vector numSwp
Number of executed software prefetches.
Definition iew.hh:462
statistics::Scalar numSquashedInsts
Stat for total number of squashed instructions skipped at execute.
Definition iew.hh:460
statistics::Scalar dispatchedInsts
Stat for total number of instructions dispatched.
Definition iew.hh:431
statistics::Formula wbFanout
Average number of woken instructions per writeback.
Definition iew.hh:476
statistics::Scalar squashCycles
Stat for total number of squashing cycles.
Definition iew.hh:425
statistics::Vector consumerInst
Number of instructions that wake up from producers.
Definition iew.hh:472
statistics::Scalar predictedNotTakenIncorrect
Stat for total number of incorrect predicted not taken branches.
Definition iew.hh:449
statistics::Scalar dispLoadInsts
Stat for total number of dispatched load instructions.
Definition iew.hh:435
statistics::Scalar dispNonSpecInsts
Stat for total number of dispatched non speculative insts.
Definition iew.hh:439
statistics::Vector instsToCommit
Number of instructions sent to commit.
Definition iew.hh:466
gem5::o3::IEW::IEWStats::ExecutedInstStats executedInstStats
statistics::Formula wbRate
Number of instructions per cycle written back.
Definition iew.hh:474
statistics::Scalar dispSquashedInsts
Stat for total number of squashed instructions dispatch skips.
Definition iew.hh:433
statistics::Scalar predictedTakenIncorrect
Stat for total number of incorrect predicted taken branches.
Definition iew.hh:447
statistics::Scalar blockCycles
Stat for total number of blocking cycles.
Definition iew.hh:427
statistics::Vector writebackCount
Number of instructions that writeback.
Definition iew.hh:468
statistics::Scalar memOrderViolationEvents
Stat for total number of memory ordering violation events.
Definition iew.hh:445
statistics::Vector producerInst
Number of instructions that wake consumers.
Definition iew.hh:470
IEWStats(CPU *cpu)
Definition iew.cc:144
statistics::Scalar iqFullEvents
Stat for number of times the IQ becomes full.
Definition iew.hh:441
statistics::Scalar unblockCycles
Stat for total number of unblocking cycles.
Definition iew.hh:429
statistics::Scalar lsqFullEvents
Stat for number of times the LSQ becomes full.
Definition iew.hh:443
statistics::Scalar dispStoreInsts
Stat for total number of dispatched store instructions.
Definition iew.hh:437

Generated on Tue Jun 18 2024 16:24:01 for gem5 by doxygen 1.11.0