gem5 v24.0.0.0
Loading...
Searching...
No Matches
cpu.cc
Go to the documentation of this file.
1/*
2 * Copyright (c) 2011-2012, 2014, 2016, 2017, 2019-2020, 2024 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 * Copyright (c) 2011 Regents of the University of California
17 * All rights reserved.
18 *
19 * Redistribution and use in source and binary forms, with or without
20 * modification, are permitted provided that the following conditions are
21 * met: redistributions of source code must retain the above copyright
22 * notice, this list of conditions and the following disclaimer;
23 * redistributions in binary form must reproduce the above copyright
24 * notice, this list of conditions and the following disclaimer in the
25 * documentation and/or other materials provided with the distribution;
26 * neither the name of the copyright holders nor the names of its
27 * contributors may be used to endorse or promote products derived from
28 * this software without specific prior written permission.
29 *
30 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
31 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
32 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
33 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
34 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
35 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
36 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
37 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
38 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
39 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
40 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
41 */
42
43#include "cpu/o3/cpu.hh"
44
45#include "cpu/activity.hh"
46#include "cpu/checker/cpu.hh"
48#include "cpu/o3/dyn_inst.hh"
49#include "cpu/o3/limits.hh"
51#include "cpu/simple_thread.hh"
52#include "cpu/thread_context.hh"
53#include "debug/Activity.hh"
54#include "debug/Drain.hh"
55#include "debug/O3CPU.hh"
56#include "debug/Quiesce.hh"
57#include "enums/MemoryMode.hh"
58#include "sim/cur_tick.hh"
59#include "sim/full_system.hh"
60#include "sim/process.hh"
61#include "sim/stat_control.hh"
62#include "sim/system.hh"
63
64namespace gem5
65{
66
67struct BaseCPUParams;
68
69namespace o3
70{
71
72CPU::CPU(const BaseO3CPUParams &params)
73 : BaseCPU(params),
74 mmu(params.mmu),
75 tickEvent([this]{ tick(); }, "O3CPU tick",
76 false, Event::CPU_Tick_Pri),
77 threadExitEvent([this]{ exitThreads(); }, "O3CPU exit threads",
78 false, Event::CPU_Exit_Pri),
79#ifndef NDEBUG
80 instcount(0),
81#endif
82 removeInstsThisCycle(false),
83 fetch(this, params),
84 decode(this, params),
85 rename(this, params),
86 iew(this, params),
87 commit(this, params),
88
89 regFile(params.numPhysIntRegs,
90 params.numPhysFloatRegs,
91 params.numPhysVecRegs,
92 params.numPhysVecPredRegs,
93 params.numPhysMatRegs,
94 params.numPhysCCRegs,
95 params.isa[0]->regClasses()),
96
97 freeList(name() + ".freelist", &regFile),
98
99 rob(this, params),
100
101 scoreboard(name() + ".scoreboard", regFile.totalNumPhysRegs()),
102
103 isa(numThreads, NULL),
104
105 timeBuffer(params.backComSize, params.forwardComSize),
106 fetchQueue(params.backComSize, params.forwardComSize),
107 decodeQueue(params.backComSize, params.forwardComSize),
108 renameQueue(params.backComSize, params.forwardComSize),
109 iewQueue(params.backComSize, params.forwardComSize),
110 activityRec(name(), NumStages,
111 params.backComSize + params.forwardComSize,
112 params.activity),
113
114 globalSeqNum(1),
115 system(params.system),
116 lastRunningCycle(curCycle()),
117 cpuStats(this)
118{
119 fatal_if(FullSystem && params.numThreads > 1,
120 "SMT is not supported in O3 in full system mode currently.");
121
122 fatal_if(!FullSystem && params.numThreads < params.workload.size(),
123 "More workload items (%d) than threads (%d) on CPU %s.",
124 params.workload.size(), params.numThreads, name());
125
126 if (!params.switched_out) {
127 _status = Running;
128 } else {
129 _status = SwitchedOut;
130 }
131
132 if (params.checker) {
133 BaseCPU *temp_checker = params.checker;
134 checker = dynamic_cast<Checker<DynInstPtr> *>(temp_checker);
135 checker->setIcachePort(&fetch.getInstPort());
136 checker->setSystem(params.system);
137 } else {
138 checker = NULL;
139 }
140
141 if (!FullSystem) {
142 thread.resize(numThreads);
143 tids.resize(numThreads);
144 }
145
146 // The stages also need their CPU pointer setup. However this
147 // must be done at the upper level CPU because they have pointers
148 // to the upper level CPU, and not this CPU.
149
150 // Set up Pointers to the activeThreads list for each stage
151 fetch.setActiveThreads(&activeThreads);
152 decode.setActiveThreads(&activeThreads);
153 rename.setActiveThreads(&activeThreads);
154 iew.setActiveThreads(&activeThreads);
155 commit.setActiveThreads(&activeThreads);
156
157 // Give each of the stages the time buffer they will use.
158 fetch.setTimeBuffer(&timeBuffer);
159 decode.setTimeBuffer(&timeBuffer);
160 rename.setTimeBuffer(&timeBuffer);
161 iew.setTimeBuffer(&timeBuffer);
162 commit.setTimeBuffer(&timeBuffer);
163
164 // Also setup each of the stages' queues.
165 fetch.setFetchQueue(&fetchQueue);
166 decode.setFetchQueue(&fetchQueue);
167 commit.setFetchQueue(&fetchQueue);
168 decode.setDecodeQueue(&decodeQueue);
169 rename.setDecodeQueue(&decodeQueue);
170 rename.setRenameQueue(&renameQueue);
171 iew.setRenameQueue(&renameQueue);
172 iew.setIEWQueue(&iewQueue);
173 commit.setIEWQueue(&iewQueue);
174 commit.setRenameQueue(&renameQueue);
175
176 commit.setIEWStage(&iew);
177 rename.setIEWStage(&iew);
178 rename.setCommitStage(&commit);
179
180 ThreadID active_threads;
181 if (FullSystem) {
182 active_threads = 1;
183 } else {
184 active_threads = params.workload.size();
185
186 if (active_threads > MaxThreads) {
187 panic("Workload Size too large. Increase the 'MaxThreads' "
188 "constant in cpu/o3/limits.hh or edit your workload size.");
189 }
190 }
191
192 // Make Sure That this a Valid Architeture
193 assert(numThreads);
194 const auto &regClasses = params.isa[0]->regClasses();
195
196 panic_if(params.numPhysIntRegs <=
197 numThreads * regClasses.at(IntRegClass)->numRegs() &&
198 regClasses.at(IntRegClass)->numRegs() != 0,
199 "Not enough physical registers, consider increasing "
200 "numPhysIntRegs\n");
201 panic_if(params.numPhysFloatRegs <=
202 numThreads * regClasses.at(FloatRegClass)->numRegs() &&
203 regClasses.at(FloatRegClass)->numRegs() != 0,
204 "Not enough physical registers, consider increasing "
205 "numPhysFloatRegs\n");
206 panic_if(params.numPhysVecRegs <=
207 numThreads * regClasses.at(VecRegClass)->numRegs() &&
208 regClasses.at(VecRegClass)->numRegs() != 0,
209 "Not enough physical registers, consider increasing "
210 "numPhysVecRegs\n");
211 panic_if(params.numPhysVecPredRegs <=
212 numThreads * regClasses.at(VecPredRegClass)->numRegs() &&
213 regClasses.at(VecPredRegClass)->numRegs() != 0,
214 "Not enough physical registers, consider increasing "
215 "numPhysVecPredRegs\n");
216 panic_if(params.numPhysMatRegs <=
217 numThreads * regClasses.at(MatRegClass)->numRegs() &&
218 regClasses.at(MatRegClass)->numRegs() != 0,
219 "Not enough physical registers, consider increasing "
220 "numPhysMatRegs\n");
221 panic_if(params.numPhysCCRegs <=
222 numThreads * regClasses.at(CCRegClass)->numRegs() &&
223 regClasses.at(CCRegClass)->numRegs() != 0,
224 "Not enough physical registers, consider increasing "
225 "numPhysCCRegs\n");
226
227 // Just make this a warning and go ahead anyway, to keep from having to
228 // add checks everywhere.
229 warn_if(regClasses.at(CCRegClass)->numRegs() == 0 &&
230 params.numPhysCCRegs != 0,
231 "Non-zero number of physical CC regs specified, even though\n"
232 " ISA does not use them.");
233
234 rename.setScoreboard(&scoreboard);
235 iew.setScoreboard(&scoreboard);
236
237 // Setup the rename map for whichever stages need it.
238 for (ThreadID tid = 0; tid < numThreads; tid++) {
239 isa[tid] = params.isa[tid];
240 commitRenameMap[tid].init(regClasses, &regFile, &freeList);
241 renameMap[tid].init(regClasses, &regFile, &freeList);
242 }
243
244 // Initialize rename map to assign physical registers to the
245 // architectural registers for active threads only.
246 for (ThreadID tid = 0; tid < active_threads; tid++) {
247 for (auto type = (RegClassType)0; type <= CCRegClass;
248 type = (RegClassType)(type + 1)) {
249 for (auto &id: *regClasses.at(type)) {
250 // Note that we can't use the rename() method because we don't
251 // want special treatment for the zero register at this point
252 PhysRegIdPtr phys_reg = freeList.getReg(type);
253 renameMap[tid].setEntry(id, phys_reg);
254 commitRenameMap[tid].setEntry(id, phys_reg);
255 }
256 }
257 }
258
259 rename.setRenameMap(renameMap);
260 commit.setRenameMap(commitRenameMap);
261 rename.setFreeList(&freeList);
262
263 // Setup the ROB for whichever stages need it.
264 commit.setROB(&rob);
265
266 lastActivatedCycle = 0;
267
268 DPRINTF(O3CPU, "Creating O3CPU object.\n");
269
270 // Setup any thread state.
271 thread.resize(numThreads);
272
273 for (ThreadID tid = 0; tid < numThreads; ++tid) {
274 if (FullSystem) {
275 // SMT is not supported in FS mode yet.
276 assert(numThreads == 1);
277 thread[tid] = new ThreadState(this, 0, NULL);
278 } else {
279 if (tid < params.workload.size()) {
280 DPRINTF(O3CPU, "Workload[%i] process is %#x", tid,
281 thread[tid]);
282 thread[tid] = new ThreadState(this, tid, params.workload[tid]);
283 } else {
284 //Allocate Empty thread so M5 can use later
285 //when scheduling threads to CPU
286 Process* dummy_proc = NULL;
287
288 thread[tid] = new ThreadState(this, tid, dummy_proc);
289 }
290 }
291
293
294 // Setup the TC that will serve as the interface to the threads/CPU.
295 auto *o3_tc = new ThreadContext;
296
297 tc = o3_tc;
298
299 // If we're using a checker, then the TC should be the
300 // CheckerThreadContext.
301 if (params.checker) {
302 tc = new CheckerThreadContext<ThreadContext>(o3_tc, checker);
303 }
304
305 o3_tc->cpu = this;
306 o3_tc->thread = thread[tid];
307
308 // Give the thread the TC.
309 thread[tid]->tc = tc;
310
311 // Add the TC to the CPU's list of TC's.
312 threadContexts.push_back(tc);
313 }
314
315 // O3CPU always requires an interrupt controller.
316 if (!params.switched_out && interrupts.empty()) {
317 fatal("O3CPU %s has no interrupt controller.\n"
318 "Ensure createInterruptController() is called.\n", name());
319 }
320}
321
322void
338
340 : statistics::Group(cpu),
341 ADD_STAT(timesIdled, statistics::units::Count::get(),
342 "Number of times that the entire CPU went into an idle state "
343 "and unscheduled itself"),
344 ADD_STAT(idleCycles, statistics::units::Cycle::get(),
345 "Total number of cycles that the CPU has spent unscheduled due "
346 "to idling"),
347 ADD_STAT(quiesceCycles, statistics::units::Cycle::get(),
348 "Total number of cycles that CPU has spent quiesced or waiting "
349 "for an interrupt")
350{
351 // Register any of the O3CPU's stats here.
354
357
360}
361
362void
364{
365 DPRINTF(O3CPU, "\n\nO3CPU: Ticking main, O3CPU.\n");
366 assert(!switchedOut());
367 assert(drainState() != DrainState::Drained);
368
371
372// activity = false;
373
374 //Tick each of the stages
375 fetch.tick();
376
377 decode.tick();
378
379 rename.tick();
380
381 iew.tick();
382
383 commit.tick();
384
385 // Now advance the time buffers
386 timeBuffer.advance();
387
388 fetchQueue.advance();
389 decodeQueue.advance();
390 renameQueue.advance();
391 iewQueue.advance();
392
394
397 }
398
399 if (!tickEvent.scheduled()) {
400 if (_status == SwitchedOut) {
401 DPRINTF(O3CPU, "Switched out!\n");
402 // increment stat
404 } else if (!activityRec.active() || _status == Idle) {
405 DPRINTF(O3CPU, "Idle!\n");
408 } else {
410 DPRINTF(O3CPU, "Scheduling next tick!\n");
411 }
412 }
413
414 if (!FullSystem)
416
417 tryDrain();
418}
419
420void
422{
424
425 for (ThreadID tid = 0; tid < numThreads; ++tid) {
426 // Set noSquashFromTC so that the CPU doesn't squash when initially
427 // setting up registers.
428 thread[tid]->noSquashFromTC = true;
429 }
430
431 // Clear noSquashFromTC.
432 for (int tid = 0; tid < numThreads; ++tid)
433 thread[tid]->noSquashFromTC = false;
434
436}
437
438void
449
450void
452{
454 std::find(activeThreads.begin(), activeThreads.end(), tid);
455
456 DPRINTF(O3CPU, "[tid:%i] Calling activate thread.\n", tid);
457 assert(!switchedOut());
458
459 if (isActive == activeThreads.end()) {
460 DPRINTF(O3CPU, "[tid:%i] Adding to active threads list\n", tid);
461
462 activeThreads.push_back(tid);
463 }
464}
465
466void
468{
469 // hardware transactional memory
470 // shouldn't deactivate thread in the middle of a transaction
471 assert(!commit.executingHtmTransaction(tid));
472
473 //Remove From Active List, if Active
475 std::find(activeThreads.begin(), activeThreads.end(), tid);
476
477 DPRINTF(O3CPU, "[tid:%i] Calling deactivate thread.\n", tid);
478 assert(!switchedOut());
479
480 if (thread_it != activeThreads.end()) {
481 DPRINTF(O3CPU,"[tid:%i] Removing from active threads list\n",
482 tid);
483 activeThreads.erase(thread_it);
484 }
485
488}
489
492{
493 Counter total(0);
494
495 ThreadID size = thread.size();
496 for (ThreadID i = 0; i < size; i++)
497 total += thread[i]->numInst;
498
499 return total;
500}
501
504{
505 Counter total(0);
506
507 ThreadID size = thread.size();
508 for (ThreadID i = 0; i < size; i++)
509 total += thread[i]->numOp;
510
511 return total;
512}
513
514void
516{
517 assert(!switchedOut());
518
519 // Needs to set each stage to running as well.
520 activateThread(tid);
521
522 // We don't want to wake the CPU if it is drained. In that case,
523 // we just want to flag the thread as active and schedule the tick
524 // event from drainResume() instead.
526 return;
527
528 // If we are time 0 or if the last activation time is in the past,
529 // schedule the next tick and wake up the fetch unit
532
533 // Be sure to signal that there's some activity so the CPU doesn't
534 // deschedule itself.
537
538 Cycles cycles(curCycle() - lastRunningCycle);
539 // @todo: This is an oddity that is only here to match the stats
540 if (cycles != 0)
541 --cycles;
542 cpuStats.quiesceCycles += cycles;
543
545
547
549 }
550}
551
552void
554{
555 DPRINTF(O3CPU,"[tid:%i] Suspending Thread Context.\n", tid);
556 assert(!switchedOut());
557
558 deactivateThread(tid);
559
560 // If this was the last thread then unschedule the tick event.
561 if (activeThreads.size() == 0) {
564 _status = Idle;
565 }
566
567 DPRINTF(Quiesce, "Suspending Context\n");
568
570}
571
572void
574{
575 //For now, this is the same as deallocate
576 DPRINTF(O3CPU,"[tid:%i] Halt Context called. Deallocating\n", tid);
577 assert(!switchedOut());
578
579 deactivateThread(tid);
580 removeThread(tid);
581
582 // If this was the last thread then unschedule the tick event.
583 if (activeThreads.size() == 0) {
584 if (tickEvent.scheduled())
585 {
587 }
589 _status = Idle;
590 }
592}
593
594void
596{
597 DPRINTF(O3CPU,"[tid:%i] Initializing thread into CPU");
598 // Will change now that the PC and thread state is internal to the CPU
599 // and not in the ThreadContext.
600 gem5::ThreadContext *src_tc;
601 if (FullSystem)
602 src_tc = system->threads[tid];
603 else
604 src_tc = tcBase(tid);
605
606 //Bind Int Regs to Rename Map
607 const auto &regClasses = isa[tid]->regClasses();
608
609 for (auto type = (RegClassType)0; type <= CCRegClass;
610 type = (RegClassType)(type + 1)) {
611 for (auto &id: *regClasses.at(type)) {
612 PhysRegIdPtr phys_reg = freeList.getReg(type);
613 renameMap[tid].setEntry(id, phys_reg);
614 scoreboard.setReg(phys_reg);
615 }
616 }
617
618 //Copy Thread Data Into RegFile
619 //copyFromTC(tid);
620
621 //Set PC/NPC/NNPC
622 pcState(src_tc->pcState(), tid);
623
625
626 activateContext(tid);
627
628 //Reset ROB/IQ/LSQ Entries
630}
631
632void
634{
635 DPRINTF(O3CPU,"[tid:%i] Removing thread context from CPU.\n", tid);
636
637 // Copy Thread Data From RegFile
638 // If thread is suspended, it might be re-allocated
639 // copyToTC(tid);
640
641
642 // @todo: 2-27-2008: Fix how we free up rename mappings
643 // here to alleviate the case for double-freeing registers
644 // in SMT workloads.
645
646 // clear all thread-specific states in each stage of the pipeline
647 // since this thread is going to be completely removed from the CPU
648 commit.clearStates(tid);
649 fetch.clearStates(tid);
650 decode.clearStates(tid);
651 rename.clearStates(tid);
652 iew.clearStates(tid);
653
654 // Flush out any old data from the time buffers.
655 for (int i = 0; i < timeBuffer.getSize(); ++i) {
656 timeBuffer.advance();
657 fetchQueue.advance();
658 decodeQueue.advance();
659 renameQueue.advance();
660 iewQueue.advance();
661 }
662
663 // at this step, all instructions in the pipeline should be already
664 // either committed successfully or squashed. All thread-specific
665 // queues in the pipeline must be empty.
666 assert(iew.instQueue.getCount(tid) == 0);
667 assert(iew.ldstQueue.getCount(tid) == 0);
668 assert(commit.rob->isEmpty(tid));
669
670 // Reset ROB/IQ/LSQ Entries
671
672 // Commented out for now. This should be possible to do by
673 // telling all the pipeline stages to drain first, and then
674 // checking until the drain completes. Once the pipeline is
675 // drained, call resetEntries(). - 10-09-06 ktlim
676/*
677 if (activeThreads.size() >= 1) {
678 commit.rob->resetEntries();
679 iew.resetEntries();
680 }
681*/
682}
683
684Fault
686{
687 // Check if there are any outstanding interrupts
688 return interrupts[0]->getInterrupt();
689}
690
691void
693{
694 // Check for interrupts here. For now can copy the code that
695 // exists within isa_fullsys_traits.hh. Also assume that thread 0
696 // is the one that handles the interrupts.
697 // @todo: Possibly consolidate the interrupt checking code.
698 // @todo: Allow other threads to handle interrupts.
699
700 assert(interrupt != NoFault);
701 interrupts[0]->updateIntrInfo();
702
703 DPRINTF(O3CPU, "Interrupt %s being handled\n", interrupt->name());
704 trap(interrupt, 0, nullptr);
705}
706
707void
708CPU::trap(const Fault &fault, ThreadID tid, const StaticInstPtr &inst)
709{
710 // Pass the thread's TC into the invoke method.
711 fault->invoke(threadContexts[tid], inst);
712}
713
714void
716{
717 thread[tid]->serialize(cp);
718}
719
720void
722{
723 thread[tid]->unserialize(cp);
724}
725
728{
729 // Deschedule any power gating event (if any)
731
732 // If the CPU isn't doing anything, then return immediately.
733 if (switchedOut())
734 return DrainState::Drained;
735
736 DPRINTF(Drain, "Draining...\n");
737
738 // We only need to signal a drain to the commit stage as this
739 // initiates squashing controls the draining. Once the commit
740 // stage commits an instruction where it is safe to stop, it'll
741 // squash the rest of the instructions in the pipeline and force
742 // the fetch stage to stall. The pipeline will be drained once all
743 // in-flight instructions have retired.
744 commit.drain();
745
746 // Wake the CPU and record activity so everything can drain out if
747 // the CPU was not able to immediately drain.
748 if (!isCpuDrained()) {
749 // If a thread is suspended, wake it up so it can be drained
750 for (auto t : threadContexts) {
751 if (t->status() == gem5::ThreadContext::Suspended){
752 DPRINTF(Drain, "Currently suspended so activate %i \n",
753 t->threadId());
754 t->activate();
755 // As the thread is now active, change the power state as well
756 activateContext(t->threadId());
757 }
758 }
759
760 wakeCPU();
762
763 DPRINTF(Drain, "CPU not drained\n");
764
766 } else {
767 DPRINTF(Drain, "CPU is already drained\n");
768 if (tickEvent.scheduled())
770
771 // Flush out any old data from the time buffers. In
772 // particular, there might be some data in flight from the
773 // fetch stage that isn't visible in any of the CPU buffers we
774 // test in isCpuDrained().
775 for (int i = 0; i < timeBuffer.getSize(); ++i) {
776 timeBuffer.advance();
777 fetchQueue.advance();
778 decodeQueue.advance();
779 renameQueue.advance();
780 iewQueue.advance();
781 }
782
784 return DrainState::Drained;
785 }
786}
787
788bool
790{
792 return false;
793
794 if (tickEvent.scheduled())
796
797 DPRINTF(Drain, "CPU done draining, processing drain event\n");
799
800 return true;
801}
802
803void
813
814bool
816{
817 bool drained(true);
818
819 if (!instList.empty() || !removeList.empty()) {
820 DPRINTF(Drain, "Main CPU structures not drained.\n");
821 drained = false;
822 }
823
824 if (!fetch.isDrained()) {
825 DPRINTF(Drain, "Fetch not drained.\n");
826 drained = false;
827 }
828
829 if (!decode.isDrained()) {
830 DPRINTF(Drain, "Decode not drained.\n");
831 drained = false;
832 }
833
834 if (!rename.isDrained()) {
835 DPRINTF(Drain, "Rename not drained.\n");
836 drained = false;
837 }
838
839 if (!iew.isDrained()) {
840 DPRINTF(Drain, "IEW not drained.\n");
841 drained = false;
842 }
843
844 if (!commit.isDrained()) {
845 DPRINTF(Drain, "Commit not drained.\n");
846 drained = false;
847 }
848
849 return drained;
850}
851
853
854void
856{
857 if (switchedOut())
858 return;
859
860 DPRINTF(Drain, "Resuming...\n");
862
865
866 _status = Idle;
867 for (ThreadID i = 0; i < thread.size(); i++) {
869 DPRINTF(Drain, "Activating thread: %i\n", i);
872 }
873 }
874
875 assert(!tickEvent.scheduled());
876 if (_status == Running)
878
879 // Reschedule any power gating event (if any)
881}
882
883void
885{
886 DPRINTF(O3CPU, "Switching out\n");
888
890
892
893 if (checker)
895}
896
897void
899{
900 BaseCPU::takeOverFrom(oldCPU);
901
907
908 assert(!tickEvent.scheduled());
909
910 auto *oldO3CPU = dynamic_cast<CPU *>(oldCPU);
911 if (oldO3CPU)
912 globalSeqNum = oldO3CPU->globalSeqNum;
913
915 _status = Idle;
916}
917
918void
920{
921 if (!system->isTimingMode()) {
922 fatal("The O3 CPU requires the memory system to be in "
923 "'timing' mode.\n");
924 }
925}
926
927RegVal
928CPU::readMiscRegNoEffect(int misc_reg, ThreadID tid) const
929{
930 return isa[tid]->readMiscRegNoEffect(misc_reg);
931}
932
933RegVal
934CPU::readMiscReg(int misc_reg, ThreadID tid)
935{
936 executeStats[tid]->numMiscRegReads++;
937 return isa[tid]->readMiscReg(misc_reg);
938}
939
940void
942{
943 isa[tid]->setMiscRegNoEffect(misc_reg, val);
944}
945
946void
948{
949 executeStats[tid]->numMiscRegWrites++;
950 isa[tid]->setMiscReg(misc_reg, val);
951}
952
953RegVal
955{
956 switch (phys_reg->classValue()) {
957 case IntRegClass:
958 executeStats[tid]->numIntRegReads++;
959 break;
960 case FloatRegClass:
961 executeStats[tid]->numFpRegReads++;
962 break;
963 case CCRegClass:
964 executeStats[tid]->numCCRegReads++;
965 break;
966 case VecRegClass:
967 case VecElemClass:
968 executeStats[tid]->numVecRegReads++;
969 break;
970 case VecPredRegClass:
971 executeStats[tid]->numVecPredRegReads++;
972 break;
973 default:
974 break;
975 }
976 return regFile.getReg(phys_reg);
977}
978
979void
981{
982 switch (phys_reg->classValue()) {
983 case IntRegClass:
984 executeStats[tid]->numIntRegReads++;
985 break;
986 case FloatRegClass:
987 executeStats[tid]->numFpRegReads++;
988 break;
989 case CCRegClass:
990 executeStats[tid]->numCCRegReads++;
991 break;
992 case VecRegClass:
993 case VecElemClass:
994 executeStats[tid]->numVecRegReads++;
995 break;
996 case VecPredRegClass:
997 executeStats[tid]->numVecPredRegReads++;
998 break;
999 default:
1000 break;
1001 }
1002 regFile.getReg(phys_reg, val);
1003}
1004
1005void *
1007{
1008 switch (phys_reg->classValue()) {
1009 case VecRegClass:
1010 executeStats[tid]->numVecRegWrites++;
1011 break;
1012 case VecPredRegClass:
1013 executeStats[tid]->numVecPredRegWrites++;
1014 break;
1015 default:
1016 break;
1017 }
1018 return regFile.getWritableReg(phys_reg);
1019}
1020
1021void
1023{
1024 switch (phys_reg->classValue()) {
1025 case IntRegClass:
1026 executeStats[tid]->numIntRegWrites++;
1027 break;
1028 case FloatRegClass:
1029 executeStats[tid]->numFpRegWrites++;
1030 break;
1031 case CCRegClass:
1032 executeStats[tid]->numCCRegWrites++;
1033 break;
1034 case VecRegClass:
1035 case VecElemClass:
1036 executeStats[tid]->numVecRegWrites++;
1037 break;
1038 case VecPredRegClass:
1039 executeStats[tid]->numVecPredRegWrites++;
1040 break;
1041 default:
1042 break;
1043 }
1044 regFile.setReg(phys_reg, val);
1045}
1046
1047void
1048CPU::setReg(PhysRegIdPtr phys_reg, const void *val, ThreadID tid)
1049{
1050 switch (phys_reg->classValue()) {
1051 case IntRegClass:
1052 executeStats[tid]->numIntRegWrites++;
1053 break;
1054 case FloatRegClass:
1055 executeStats[tid]->numFpRegWrites++;
1056 break;
1057 case CCRegClass:
1058 executeStats[tid]->numCCRegWrites++;
1059 break;
1060 case VecRegClass:
1061 case VecElemClass:
1062 executeStats[tid]->numVecRegWrites++;
1063 break;
1064 case VecPredRegClass:
1065 executeStats[tid]->numVecPredRegWrites++;
1066 break;
1067 default:
1068 break;
1069 }
1070 regFile.setReg(phys_reg, val);
1071}
1072
1073RegVal
1075{
1076 const RegId flat = reg.flatten(*isa[tid]);
1077 PhysRegIdPtr phys_reg = commitRenameMap[tid].lookup(flat);
1078 return regFile.getReg(phys_reg);
1079}
1080
1081void
1083{
1084 const RegId flat = reg.flatten(*isa[tid]);
1085 PhysRegIdPtr phys_reg = commitRenameMap[tid].lookup(flat);
1086 regFile.getReg(phys_reg, val);
1087}
1088
1089void *
1091{
1092 const RegId flat = reg.flatten(*isa[tid]);
1093 PhysRegIdPtr phys_reg = commitRenameMap[tid].lookup(flat);
1094 return regFile.getWritableReg(phys_reg);
1095}
1096
1097void
1099{
1100 const RegId flat = reg.flatten(*isa[tid]);
1101 PhysRegIdPtr phys_reg = commitRenameMap[tid].lookup(flat);
1102 regFile.setReg(phys_reg, val);
1103}
1104
1105void
1106CPU::setArchReg(const RegId &reg, const void *val, ThreadID tid)
1107{
1108 const RegId flat = reg.flatten(*isa[tid]);
1109 PhysRegIdPtr phys_reg = commitRenameMap[tid].lookup(flat);
1110 regFile.setReg(phys_reg, val);
1111}
1112
1113const PCStateBase &
1115{
1116 return commit.pcState(tid);
1117}
1118
1119void
1121{
1122 commit.pcState(val, tid);
1123}
1124
1125void
1127{
1128 thread[tid]->noSquashFromTC = true;
1130}
1131
1134{
1135 instList.push_back(inst);
1136
1137 return --(instList.end());
1138}
1139
1140void
1142{
1143 // Keep an instruction count.
1144 if (!inst->isMicroop() || inst->isLastMicroop()) {
1145 thread[tid]->numInst++;
1146 thread[tid]->threadStats.numInsts++;
1147 commitStats[tid]->numInstsNotNOP++;
1148
1149 // Check for instruction-count-based events.
1150 thread[tid]->comInstEventQueue.serviceEvents(thread[tid]->numInst);
1151 }
1152 thread[tid]->numOp++;
1153 thread[tid]->threadStats.numOps++;
1154 commitStats[tid]->numOpsNotNOP++;
1155
1156 probeInstCommit(inst->staticInst, inst->pcState().instAddr());
1157}
1158
1159void
1161{
1162 DPRINTF(O3CPU, "Removing committed instruction [tid:%i] PC %s "
1163 "[sn:%lli]\n",
1164 inst->threadNumber, inst->pcState(), inst->seqNum);
1165
1166 removeInstsThisCycle = true;
1167
1168 // Remove the front instruction.
1169 removeList.push(inst->getInstListIt());
1170}
1171
1172void
1174{
1175 DPRINTF(O3CPU, "Thread %i: Deleting instructions from instruction"
1176 " list.\n", tid);
1177
1178 ListIt end_it;
1179
1180 bool rob_empty = false;
1181
1182 if (instList.empty()) {
1183 return;
1184 } else if (rob.isEmpty(tid)) {
1185 DPRINTF(O3CPU, "ROB is empty, squashing all insts.\n");
1186 end_it = instList.begin();
1187 rob_empty = true;
1188 } else {
1189 end_it = (rob.readTailInst(tid))->getInstListIt();
1190 DPRINTF(O3CPU, "ROB is not empty, squashing insts not in ROB.\n");
1191 }
1192
1193 removeInstsThisCycle = true;
1194
1195 ListIt inst_it = instList.end();
1196
1197 inst_it--;
1198
1199 // Walk through the instruction list, removing any instructions
1200 // that were inserted after the given instruction iterator, end_it.
1201 while (inst_it != end_it) {
1202 assert(!instList.empty());
1203
1204 squashInstIt(inst_it, tid);
1205
1206 inst_it--;
1207 }
1208
1209 // If the ROB was empty, then we actually need to remove the first
1210 // instruction as well.
1211 if (rob_empty) {
1212 squashInstIt(inst_it, tid);
1213 }
1214}
1215
1216void
1218{
1219 assert(!instList.empty());
1220
1221 removeInstsThisCycle = true;
1222
1223 ListIt inst_iter = instList.end();
1224
1225 inst_iter--;
1226
1227 DPRINTF(O3CPU, "Deleting instructions from instruction "
1228 "list that are from [tid:%i] and above [sn:%lli] (end=%lli).\n",
1229 tid, seq_num, (*inst_iter)->seqNum);
1230
1231 while ((*inst_iter)->seqNum > seq_num) {
1232
1233 bool break_loop = (inst_iter == instList.begin());
1234
1235 squashInstIt(inst_iter, tid);
1236
1237 inst_iter--;
1238
1239 if (break_loop)
1240 break;
1241 }
1242}
1243
1244void
1246{
1247 if ((*instIt)->threadNumber == tid) {
1248 DPRINTF(O3CPU, "Squashing instruction, "
1249 "[tid:%i] [sn:%lli] PC %s\n",
1250 (*instIt)->threadNumber,
1251 (*instIt)->seqNum,
1252 (*instIt)->pcState());
1253
1254 // Mark it as squashed.
1255 (*instIt)->setSquashed();
1256
1257 // @todo: Formulate a consistent method for deleting
1258 // instructions from the instruction list
1259 // Remove the instruction from the list.
1260 removeList.push(instIt);
1261 }
1262}
1263
1264void
1266{
1267 while (!removeList.empty()) {
1268 DPRINTF(O3CPU, "Removing instruction, "
1269 "[tid:%i] [sn:%lli] PC %s\n",
1270 (*removeList.front())->threadNumber,
1271 (*removeList.front())->seqNum,
1272 (*removeList.front())->pcState());
1273
1274 instList.erase(removeList.front());
1275
1276 removeList.pop();
1277 }
1278
1279 removeInstsThisCycle = false;
1280}
1281/*
1282void
1283CPU::removeAllInsts()
1284{
1285 instList.clear();
1286}
1287*/
1288void
1290{
1291 int num = 0;
1292
1293 ListIt inst_list_it = instList.begin();
1294
1295 cprintf("Dumping Instruction List\n");
1296
1297 while (inst_list_it != instList.end()) {
1298 cprintf("Instruction:%i\nPC:%#x\n[tid:%i]\n[sn:%lli]\nIssued:%i\n"
1299 "Squashed:%i\n\n",
1300 num, (*inst_list_it)->pcState().instAddr(),
1301 (*inst_list_it)->threadNumber,
1302 (*inst_list_it)->seqNum, (*inst_list_it)->isIssued(),
1303 (*inst_list_it)->isSquashed());
1304 inst_list_it++;
1305 ++num;
1306 }
1307}
1308/*
1309void
1310CPU::wakeDependents(const DynInstPtr &inst)
1311{
1312 iew.wakeDependents(inst);
1313}
1314*/
1315void
1317{
1319 DPRINTF(Activity, "CPU already running.\n");
1320 return;
1321 }
1322
1323 DPRINTF(Activity, "Waking up CPU\n");
1324
1325 Cycles cycles(curCycle() - lastRunningCycle);
1326 // @todo: This is an oddity that is only here to match the stats
1327 if (cycles > 1) {
1328 --cycles;
1329 cpuStats.idleCycles += cycles;
1330 baseStats.numCycles += cycles;
1331 }
1332
1334}
1335
1336void
1338{
1340 return;
1341
1342 wakeCPU();
1343
1344 DPRINTF(Quiesce, "Suspended Processor woken\n");
1345 threadContexts[tid]->activate();
1346}
1347
1350{
1351 for (ThreadID tid = 0; tid < numThreads; tid++) {
1352 if (!tids[tid]) {
1353 tids[tid] = true;
1354 return tid;
1355 }
1356 }
1357
1358 return InvalidThreadID;
1359}
1360
1361void
1363{
1364 if (activeThreads.size() > 1) {
1365 //DEFAULT TO ROUND ROBIN SCHEME
1366 //e.g. Move highest priority to end of thread list
1367 std::list<ThreadID>::iterator list_begin = activeThreads.begin();
1368
1369 unsigned high_thread = *list_begin;
1370
1371 activeThreads.erase(list_begin);
1372
1373 activeThreads.push_back(high_thread);
1374 }
1375}
1376
1377void
1379{
1380 DPRINTF(O3CPU, "Thread %d is inserted to exitingThreads list\n", tid);
1381
1382 // the thread trying to exit can't be already halted
1383 assert(tcBase(tid)->status() != gem5::ThreadContext::Halted);
1384
1385 // make sure the thread has not been added to the list yet
1386 assert(exitingThreads.count(tid) == 0);
1387
1388 // add the thread to exitingThreads list to mark that this thread is
1389 // trying to exit. The boolean value in the pair denotes if a thread is
1390 // ready to exit. The thread is not ready to exit until the corresponding
1391 // exit trap event is processed in the future. Until then, it'll be still
1392 // an active thread that is trying to exit.
1393 exitingThreads.emplace(std::make_pair(tid, false));
1394}
1395
1396bool
1398{
1399 return exitingThreads.count(tid) == 1;
1400}
1401
1402void
1404{
1405 assert(exitingThreads.count(tid) == 1);
1406
1407 // exit trap event has been processed. Now, the thread is ready to exit
1408 // and be removed from the CPU.
1409 exitingThreads[tid] = true;
1410
1411 // we schedule a threadExitEvent in the next cycle to properly clean
1412 // up the thread's states in the pipeline. threadExitEvent has lower
1413 // priority than tickEvent, so the cleanup will happen at the very end
1414 // of the next cycle after all pipeline stages complete their operations.
1415 // We want all stages to complete squashing instructions before doing
1416 // the cleanup.
1417 if (!threadExitEvent.scheduled()) {
1419 }
1420}
1421
1422void
1424{
1425 // there must be at least one thread trying to exit
1426 assert(exitingThreads.size() > 0);
1427
1428 // terminate all threads that are ready to exit
1429 auto it = exitingThreads.begin();
1430 while (it != exitingThreads.end()) {
1431 ThreadID thread_id = it->first;
1432 bool readyToExit = it->second;
1433
1434 if (readyToExit) {
1435 DPRINTF(O3CPU, "Exiting thread %d\n", thread_id);
1436 haltContext(thread_id);
1438 it = exitingThreads.erase(it);
1439 } else {
1440 it++;
1441 }
1442 }
1443}
1444
1445void
1446CPU::htmSendAbortSignal(ThreadID tid, uint64_t htm_uid,
1448{
1449 const Addr addr = 0x0ul;
1450 const int size = 8;
1451 const Request::Flags flags =
1453
1454 // O3-specific actions
1457
1458 // notify l1 d-cache (ruby) that core has aborted transaction
1459 RequestPtr req =
1460 std::make_shared<Request>(addr, size, flags, _dataRequestorId);
1461
1462 req->taskId(taskId());
1463 req->setContext(thread[tid]->contextId());
1464 req->setHtmAbortCause(cause);
1465
1466 assert(req->isHTMAbort());
1467
1468 PacketPtr abort_pkt = Packet::createRead(req);
1469 uint8_t *memData = new uint8_t[8];
1470 assert(memData);
1471 abort_pkt->dataStatic(memData);
1472 abort_pkt->setHtmTransactional(htm_uid);
1473
1474 // TODO include correct error handling here
1475 if (!iew.ldstQueue.getDataPort().sendTimingReq(abort_pkt)) {
1476 panic("HTM abort signal was not sent to the memory subsystem.");
1477 }
1478}
1479
1480} // namespace o3
1481} // namespace gem5
#define DPRINTF(x,...)
Definition trace.hh:210
void advance()
Advances the activity buffer, decrementing the activityCount if active communication just left the ti...
Definition activity.cc:71
void reset()
Clears the time buffer and the activity count.
Definition activity.cc:125
void activity()
Records that there is activity this cycle.
Definition activity.cc:55
bool active()
Returns if the CPU should be active.
Definition activity.hh:91
void init() override
init() is called after all C++ SimObjects have been created and all ports are connected.
Definition base.cc:310
void updateCycleCounters(CPUState state)
base method keeping track of cycle progression
Definition base.hh:561
void schedulePowerGatingEvent()
Definition base.cc:502
@ CPU_STATE_SLEEP
Definition base.hh:552
std::vector< std::unique_ptr< CommitCPUStats > > commitStats
Definition base.hh:821
void regProbePoints() override
Register probe points for this object.
Definition base.cc:374
uint32_t taskId() const
Get cpu task id.
Definition base.hh:211
virtual void suspendContext(ThreadID thread_num)
Notify the CPU that the indicated context is now suspended.
Definition base.cc:550
gem5::BaseCPU::BaseCPUStats baseStats
ThreadID numThreads
Number of threads we're actually simulating (<= SMT_MAX_THREADS).
Definition base.hh:390
void deschedulePowerGatingEvent()
Definition base.cc:494
std::vector< std::unique_ptr< ExecuteCPUStats > > executeStats
Definition base.hh:820
std::vector< BaseInterrupts * > interrupts
Definition base.hh:224
void startup() override
startup() is the final initialization call before simulation.
Definition base.cc:349
virtual void switchOut()
Prepare for another CPU to take over execution.
Definition base.cc:588
virtual void takeOverFrom(BaseCPU *cpu)
Load the state of a CPU from the previous CPU object, invoked on all new CPUs that are about to be sw...
Definition base.cc:602
std::vector< ThreadContext * > threadContexts
Definition base.hh:260
bool switchedOut() const
Determine if the CPU is switched out.
Definition base.hh:373
virtual void probeInstCommit(const StaticInstPtr &inst, Addr pc)
Helper method to trigger PMU probes for a committed instruction.
Definition base.cc:390
RequestorID _dataRequestorId
data side request id that must be placed in all requests
Definition base.hh:129
virtual void activateContext(ThreadID thread_num)
Notify the CPU that the indicated context is now active.
Definition base.cc:530
void switchOut()
Prepare for another CPU to take over execution.
Definition cpu_impl.hh:431
Cycles curCycle() const
Determine the current cycle, corresponding to a tick aligned to a clock edge.
Tick clockEdge(Cycles cycles=Cycles(0)) const
Determine the tick when a cycle begins, by default the current one, but the argument also enables the...
Tick nextCycle() const
Based on the clock of the object, determine the start tick of the first cycle that is at least one cy...
Cycles is a wrapper class for representing cycle counts, i.e.
Definition types.hh:79
A Packet is used to encapsulate a transfer between two objects in the memory system (e....
Definition packet.hh:295
void dataStatic(T *p)
Set the data pointer to the following value that should not be freed.
Definition packet.hh:1175
static PacketPtr createRead(const RequestPtr &req)
Constructor-like methods that return Packets based on Request objects.
Definition packet.hh:1038
void setHtmTransactional(uint64_t val)
Stipulates that this packet/request originates in the CPU executing in transactional mode,...
Definition packet.cc:516
Physical register ID.
Definition reg_class.hh:415
constexpr RegClassType classValue() const
Definition reg_class.hh:280
ProbePointArg generates a point for the class of Arg.
Definition probe.hh:264
Register ID: describe an architectural register with its class and index.
Definition reg_class.hh:94
RegId flatten(const BaseISA &isa) const
Definition reg_class.hh:285
bool sendTimingReq(PacketPtr pkt)
Attempt to send a timing request to the responder port by calling its corresponding receive function.
Definition port.hh:603
@ STRICT_ORDER
The request is required to be strictly ordered by CPU models and is non-speculative.
Definition request.hh:135
@ PHYSICAL
The virtual address is also the physical address.
Definition request.hh:117
@ HTM_ABORT
The request aborts a HTM transaction.
Definition request.hh:216
bool isTimingMode() const
Is the system in timing mode?
Definition system.hh:270
Threads threads
Definition system.hh:310
ThreadContext is the external interface to all thread state for anything outside of the CPU.
virtual void setStatus(Status new_status)=0
@ Halted
Permanently shut down.
@ Suspended
Temporarily inactive.
virtual const PCStateBase & pcState() const =0
O3CPU class, has each of the stages (fetch through commit) within it, as well as all of the time buff...
Definition cpu.hh:94
std::vector< BaseISA * > isa
Definition cpu.hh:447
void instDone(ThreadID tid, const DynInstPtr &inst)
Function to tell the CPU that an instruction has completed.
Definition cpu.cc:1141
IEW iew
The issue/execute/writeback stages.
Definition cpu.hh:414
gem5::Checker< DynInstPtr > * checker
Pointer to the checker, which can dynamically verify instruction results at run time.
Definition cpu.hh:527
void dumpInsts()
Debug function to print all instructions on the list.
Definition cpu.cc:1289
void drainSanityCheck() const
Perform sanity checks after a drain.
Definition cpu.cc:804
void htmSendAbortSignal(ThreadID tid, uint64_t htm_uid, HtmFailureFaultCause cause) override
This function is used to instruct the memory subsystem that a transaction should be aborted and the s...
Definition cpu.cc:1446
std::list< DynInstPtr > instList
List of all the instructions in flight.
Definition cpu.hh:384
RegVal getReg(PhysRegIdPtr phys_reg, ThreadID tid)
Definition cpu.cc:954
ListIt addInst(const DynInstPtr &inst)
Function to add instruction onto the head of the list of the instructions.
Definition cpu.cc:1133
void setArchReg(const RegId &reg, RegVal val, ThreadID tid)
Definition cpu.cc:1098
ROB rob
The re-order buffer.
Definition cpu.hh:432
InstSeqNum globalSeqNum
The global sequence number counter.
Definition cpu.hh:521
void haltContext(ThreadID tid) override
Remove Thread from Active Threads List && Remove Thread Context from CPU.
Definition cpu.cc:573
TimeBuffer< DecodeStruct > decodeQueue
The decode stage's instruction queue.
Definition cpu.hh:471
EventFunctionWrapper tickEvent
The tick event used for scheduling CPU ticks.
Definition cpu.hh:122
void serializeThread(CheckpointOut &cp, ThreadID tid) const override
Serialize a single thread.
Definition cpu.cc:715
void startup() override
startup() is the final initialization call before simulation.
Definition cpu.cc:439
void drainResume() override
Resumes execution after a drain.
Definition cpu.cc:855
Rename rename
The dispatch stage.
Definition cpu.hh:411
void regProbePoints() override
Register probe points.
Definition cpu.cc:323
void deactivateThread(ThreadID tid)
Remove Thread from Active Threads List.
Definition cpu.cc:467
Counter totalInsts() const override
Count the Total Instructions Committed in the CPU.
Definition cpu.cc:491
void trap(const Fault &fault, ThreadID tid, const StaticInstPtr &inst)
Traps to handle given fault.
Definition cpu.cc:708
CPU(const BaseO3CPUParams &params)
Constructs a CPU with the given parameters.
Definition cpu.cc:72
ProbePointArg< PacketPtr > * ppInstAccessComplete
Definition cpu.hh:176
void exitThreads()
Terminate all threads that are ready to exit.
Definition cpu.cc:1423
ThreadID getFreeTid()
Gets a free thread id.
Definition cpu.cc:1349
std::vector< ThreadState * > thread
Pointers to all of the threads in the CPU.
Definition cpu.hh:533
void tick()
Ticks CPU, calling tick() on each stage, and checking the overall activity to see if the CPU should d...
Definition cpu.cc:363
void removeThread(ThreadID tid)
Remove all of a thread's context from CPU.
Definition cpu.cc:633
void commitDrained(ThreadID tid)
Commit has reached a safe point to drain a thread.
Definition cpu.cc:852
void unscheduleTickEvent()
Unschedule tick event, regardless of its current state.
Definition cpu.hh:139
gem5::o3::CPU::CPUStats cpuStats
UnifiedFreeList freeList
The free list.
Definition cpu.hh:423
Status _status
Overall CPU status.
Definition cpu.hh:117
std::list< DynInstPtr >::iterator ListIt
Definition cpu.hh:96
void activateContext(ThreadID tid) override
Add Thread to Active Threads List.
Definition cpu.cc:515
virtual void wakeup(ThreadID tid) override
Definition cpu.cc:1337
bool removeInstsThisCycle
Records if instructions need to be removed this cycle due to being retired or squashed.
Definition cpu.hh:401
void setMiscReg(int misc_reg, RegVal val, ThreadID tid)
Sets a misc.
Definition cpu.cc:947
std::vector< ThreadID > tids
Available thread ids in the cpu.
Definition cpu.hh:548
ProbePointArg< std::pair< DynInstPtr, PacketPtr > > * ppDataAccessComplete
Definition cpu.hh:177
PerThreadUnifiedRenameMap commitRenameMap
The commit rename map.
Definition cpu.hh:429
void setMiscRegNoEffect(int misc_reg, RegVal val, ThreadID tid)
Sets a miscellaneous register.
Definition cpu.cc:941
void removeInstsUntil(const InstSeqNum &seq_num, ThreadID tid)
Remove all instructions younger than the given sequence number.
Definition cpu.cc:1217
std::queue< ListIt > removeList
List of all the instructions that will be removed at the end of this cycle.
Definition cpu.hh:389
TimeBuffer< FetchStruct > fetchQueue
The fetch stage's instruction queue.
Definition cpu.hh:468
void cleanUpRemovedInsts()
Cleans up all instructions on the remove list.
Definition cpu.cc:1265
@ SwitchedOut
Definition cpu.hh:107
Commit commit
The commit stage.
Definition cpu.hh:417
void suspendContext(ThreadID tid) override
Remove Thread from Active Threads List.
Definition cpu.cc:553
void unserializeThread(CheckpointIn &cp, ThreadID tid) override
Unserialize one thread.
Definition cpu.cc:721
void removeInstsNotInROB(ThreadID tid)
Remove all instructions that are not currently in the ROB.
Definition cpu.cc:1173
void takeOverFrom(BaseCPU *oldCPU) override
Takes over from another CPU.
Definition cpu.cc:898
void switchOut() override
Switches out this CPU.
Definition cpu.cc:884
PhysRegFile regFile
The register file.
Definition cpu.hh:420
Cycles lastRunningCycle
The cycle that the CPU was last running, used for statistics.
Definition cpu.hh:539
bool tryDrain()
Check if the pipeline has drained and signal drain done.
Definition cpu.cc:789
ActivityRecorder activityRec
The activity recorder; used to tell if the CPU has any activity remaining or if it can go to idle and...
Definition cpu.hh:484
void processInterrupts(const Fault &interrupt)
Processes any an interrupt fault.
Definition cpu.cc:692
void squashFromTC(ThreadID tid)
Initiates a squash of all in-flight instructions for a given thread.
Definition cpu.cc:1126
TimeBuffer< TimeStruct > timeBuffer
The main time buffer to do backwards communication.
Definition cpu.hh:465
Tick lastActivatedCycle
The cycle that the CPU was last activated by a new thread.
Definition cpu.hh:542
void squashInstIt(const ListIt &instIt, ThreadID tid)
Removes the instruction pointed to by the iterator.
Definition cpu.cc:1245
System * system
Pointer to the system.
Definition cpu.hh:530
Decode decode
The decode stage.
Definition cpu.hh:408
void verifyMemoryMode() const override
Verify that the system is in a memory mode supported by the CPU.
Definition cpu.cc:919
RegVal getArchReg(const RegId &reg, ThreadID tid)
Architectural register accessors.
Definition cpu.cc:1074
TimeBuffer< IEWStruct > iewQueue
The IEW stage's instruction queue.
Definition cpu.hh:477
EventFunctionWrapper threadExitEvent
The exit event used for terminating all ready-to-exit threads.
Definition cpu.hh:125
DrainState drain() override
Starts draining the CPU's pipeline of all instructions in order to stop all memory accesses.
Definition cpu.cc:727
std::list< ThreadID > activeThreads
Active Threads List.
Definition cpu.hh:435
PerThreadUnifiedRenameMap renameMap
The rename map.
Definition cpu.hh:426
Fault getInterrupts()
Returns the Fault for any valid interrupt.
Definition cpu.cc:685
void scheduleTickEvent(Cycles delay)
Schedule tick event, regardless of its current state.
Definition cpu.hh:129
RegVal readMiscRegNoEffect(int misc_reg, ThreadID tid) const
Register accessors.
Definition cpu.cc:928
bool isCpuDrained() const
Check if a system is in a drained state.
Definition cpu.cc:815
Fetch fetch
The fetch stage.
Definition cpu.hh:405
void addThreadToExitingList(ThreadID tid)
Insert tid to the list of threads trying to exit.
Definition cpu.cc:1378
void pcState(const PCStateBase &new_pc_state, ThreadID tid)
Sets the commit PC state of a specific thread.
Definition cpu.cc:1120
void scheduleThreadExitEvent(ThreadID tid)
If a thread is trying to exit and its corresponding trap event has been completed,...
Definition cpu.cc:1403
void updateThreadPriority()
Update The Order In Which We Process Threads.
Definition cpu.cc:1362
void setReg(PhysRegIdPtr phys_reg, RegVal val, ThreadID tid)
Definition cpu.cc:1022
bool isThreadExiting(ThreadID tid) const
Is the thread trying to exit?
Definition cpu.cc:1397
void removeFrontInst(const DynInstPtr &inst)
Remove an instruction from the front end of the list.
Definition cpu.cc:1160
void * getWritableArchReg(const RegId &reg, ThreadID tid)
Definition cpu.cc:1090
RegVal readMiscReg(int misc_reg, ThreadID tid)
Reads a misc.
Definition cpu.cc:934
void init() override
Initialize the CPU.
Definition cpu.cc:421
void activateThread(ThreadID tid)
Add Thread to Active Threads List.
Definition cpu.cc:451
gem5::ThreadContext * tcBase(ThreadID tid)
Returns a pointer to a thread context.
Definition cpu.hh:515
Scoreboard scoreboard
Integer Register Scoreboard.
Definition cpu.hh:445
void * getWritableReg(PhysRegIdPtr phys_reg, ThreadID tid)
Definition cpu.cc:1006
std::unordered_map< ThreadID, bool > exitingThreads
This is a list of threads that are trying to exit.
Definition cpu.hh:442
Counter totalOps() const override
Count the Total Ops (including micro ops) committed in the CPU.
Definition cpu.cc:503
void wakeCPU()
Wakes the CPU, rescheduling the CPU if it's not already active.
Definition cpu.cc:1316
void insertThread(ThreadID tid)
Setup CPU to insert a thread's context.
Definition cpu.cc:595
TimeBuffer< RenameStruct > renameQueue
The rename stage's instruction queue.
Definition cpu.hh:474
void startupStage()
Initializes stage by sending back the number of free entries.
Definition commit.cc:266
bool executingHtmTransaction(ThreadID) const
Is the CPU currently processing a HTM transaction?
Definition commit.cc:378
ROB * rob
ROB interface.
Definition commit.hh:342
void deactivateThread(ThreadID tid)
Deschedules a thread from scheduling.
Definition commit.cc:367
void tick()
Ticks the commit stage, which tries to commit instructions.
Definition commit.cc:581
const PCStateBase & pcState(ThreadID tid)
Reads the PC of a specific thread.
Definition commit.hh:309
void resetHtmStartsStops(ThreadID)
Definition commit.cc:387
void drainSanityCheck() const
Perform sanity checks after a drain.
Definition commit.cc:310
void takeOverFrom()
Takes over from another CPU's thread.
Definition commit.cc:352
void clearStates(ThreadID tid)
Clear all thread-specific states.
Definition commit.cc:286
void drainResume()
Resumes execution after draining.
Definition commit.cc:303
void drain()
Initializes the draining of commit.
Definition commit.cc:300
void generateTCEvent(ThreadID tid)
Records that commit needs to initiate a squash due to an external state update through the TC.
Definition commit.cc:476
void regProbePoints()
Registers probes.
Definition commit.cc:138
void setThreads(std::vector< ThreadState * > &threads)
Sets the list of threads.
Definition commit.cc:200
bool isDrained() const
Has the stage drained?
Definition commit.cc:325
void startupStage()
Definition decode.cc:91
void takeOverFrom()
Takes over from another CPU's thread.
Definition decode.hh:132
bool isDrained() const
Has the stage drained?
Definition decode.cc:206
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:197
void tick()
Ticks decode, processing all input signals and decoding as many instructions as possible.
Definition decode.cc:543
void deactivateThread(ThreadID tid)
For priority-based fetch policies, need to keep update priorityList.
Definition fetch.cc:476
void takeOverFrom()
Takes over from another CPU's thread.
Definition fetch.cc:426
void startupStage()
Initialize stage.
Definition fetch.cc:263
void wakeFromQuiesce()
Tells fetch to wake up from a quiesce instruction.
Definition fetch.cc:443
void drainSanityCheck() const
Perform sanity checks after a drain.
Definition fetch.cc:379
void regProbePoints()
Registers probes.
Definition fetch.cc:151
void drainStall(ThreadID tid)
Stall the fetch stage after reaching a safe drain point.
Definition fetch.cc:434
void drainResume()
Resume after a drain.
Definition fetch.cc:370
void clearStates(ThreadID tid)
Clear all thread-specific states.
Definition fetch.cc:274
bool isDrained() const
Has the stage drained?
Definition fetch.cc:396
void tick()
Ticks the fetch stage, processing all inputs signals and fetching as many instructions as possible.
Definition fetch.cc:816
void takeOverFrom()
Takes over from another CPU's thread.
Definition iew.cc:353
void clearStates(ThreadID tid)
Clear all thread-specific states.
Definition iew.cc:254
void startupStage()
Initializes stage; sends back the number of free IQ and LSQ entries.
Definition iew.cc:231
void drainSanityCheck() const
Perform sanity checks after a drain.
Definition iew.cc:344
bool isDrained() const
Has the stage drained?
Definition iew.cc:316
InstructionQueue instQueue
Instruction queue.
Definition iew.hh:355
void tick()
Ticks IEW stage, causing Dispatch, the IQ, the LSQ, Execute, and Writeback to run for one cycle.
Definition iew.cc:1393
LSQ ldstQueue
Load / store queue.
Definition iew.hh:358
void regProbePoints()
Registers probes.
Definition iew.cc:124
unsigned getCount(ThreadID tid)
Returns the number of used entries for a thread.
RequestPort & getDataPort()
Definition lsq.hh:892
int getCount()
Returns the number of instructions in all of the queues.
Definition lsq.cc:473
void resetHtmStartsStops(ThreadID tid)
Definition lsq.cc:361
RegVal getReg(PhysRegIdPtr phys_reg) const
Definition regfile.hh:173
void * getWritableReg(PhysRegIdPtr phys_reg)
Definition regfile.hh:245
void setReg(PhysRegIdPtr phys_reg, RegVal val)
Definition regfile.hh:263
void resetEntries()
Re-adjust ROB partitioning.
Definition rob.cc:148
DynInstPtr readTailInst(ThreadID tid)
Returns pointer to the tail instruction within the ROB.
Definition rob.cc:516
bool isEmpty() const
Returns if the ROB is empty.
Definition rob.hh:194
void startupStage()
Initializes variables for the stage.
Definition rename.cc:224
void tick()
Ticks rename, which processes all input signals and attempts to rename as many instructions as possib...
Definition rename.cc:392
void drainSanityCheck() const
Perform sanity checks after a drain.
Definition rename.cc:328
void takeOverFrom()
Takes over from another CPU's thread.
Definition rename.cc:322
void regProbePoints()
Registers probes.
Definition rename.cc:182
bool isDrained() const
Has the stage drained?
Definition rename.cc:308
void clearStates(ThreadID tid)
Clear all thread-specific states.
Definition rename.cc:230
void setReg(PhysRegIdPtr phys_reg)
Sets the register as ready.
Definition scoreboard.hh:97
PhysRegIdPtr getReg(RegClassType type)
Gets a free register of type type.
Definition free_list.hh:162
Derived & prereq(const Stat &prereq)
Set the prerequisite stat and marks this stat to print at the end of simulation.
Statistics container.
Definition group.hh:93
STL list class.
Definition stl.hh:51
STL pair class.
Definition stl.hh:58
#define ADD_STAT(n,...)
Convenience macro to add a stat to a statistics group.
Definition group.hh:75
void signalDrainDone() const
Signal that an object is drained.
Definition drain.hh:305
DrainState drainState() const
Return the current drain state of an object.
Definition drain.hh:324
DrainState
Object drain/handover states.
Definition drain.hh:75
@ Draining
Draining buffers pending serialization/handover.
@ Running
Running normally.
@ Drained
Buffers drained, ready for serialization/handover.
void deschedule(Event &event)
Definition eventq.hh:1021
bool scheduled() const
Determine if the current event is scheduled.
Definition eventq.hh:458
void schedule(Event &event, Tick when)
Definition eventq.hh:1012
static const Priority CPU_Tick_Pri
CPU ticks must come after other associated CPU events (such as writebacks).
Definition eventq.hh:207
static const Priority CPU_Exit_Pri
If we want to exit a thread in a CPU, it comes after CPU_Tick_Pri.
Definition eventq.hh:214
#define panic(...)
This implements a cprintf based panic() function.
Definition logging.hh:188
#define fatal_if(cond,...)
Conditional fatal macro that checks the supplied condition and only causes a fatal error if the condi...
Definition logging.hh:236
#define fatal(...)
This implements a cprintf based fatal() function.
Definition logging.hh:200
#define panic_if(cond,...)
Conditional panic macro that checks the supplied condition and only panics if the condition is true a...
Definition logging.hh:214
ProbeManager * getProbeManager()
Get the probe manager for this object.
uint8_t flags
Definition helpers.cc:87
#define warn_if(cond,...)
Conditional warning macro that checks the supplied condition and only prints a warning if the conditi...
Definition logging.hh:283
Bitfield< 5 > t
Definition misc_types.hh:71
Bitfield< 7 > i
Definition misc_types.hh:67
Bitfield< 35, 32 > at
Bitfield< 5, 0 > status
Bitfield< 5, 3 > reg
Definition types.hh:92
Bitfield< 15 > system
Definition misc.hh:1032
Bitfield< 63 > val
Definition misc.hh:804
Bitfield< 3 > addr
Definition types.hh:84
static constexpr int MaxThreads
Definition limits.hh:38
const FlagsType total
Print the total.
Definition info.hh:59
double Counter
All counters are of 64-bit values.
Definition types.hh:46
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
std::shared_ptr< Request > RequestPtr
Definition request.hh:94
uint64_t RegVal
Definition types.hh:173
const ThreadID InvalidThreadID
Definition types.hh:236
void cprintf(const char *format, const Args &...args)
Definition cprintf.hh:155
Tick curTick()
The universal simulation clock.
Definition cur_tick.hh:46
std::ostream CheckpointOut
Definition serialize.hh:66
uint64_t Addr
Address type This will probably be moved somewhere else in the near future.
Definition types.hh:147
PhysRegId * PhysRegIdPtr
Definition reg_class.hh:510
bool FullSystem
The FullSystem variable can be used to determine the current mode of simulation.
Definition root.cc:220
constexpr decltype(nullptr) NoFault
Definition types.hh:253
HtmFailureFaultCause
Definition htm.hh:48
uint64_t InstSeqNum
Definition inst_seq.hh:40
RegClassType
Enumerate the classes of registers.
Definition reg_class.hh:60
@ VecPredRegClass
Definition reg_class.hh:67
@ MatRegClass
Matrix Register.
Definition reg_class.hh:68
@ FloatRegClass
Floating-point register.
Definition reg_class.hh:62
@ CCRegClass
Condition-code register.
Definition reg_class.hh:69
@ VecRegClass
Vector Register.
Definition reg_class.hh:64
@ IntRegClass
Integer register.
Definition reg_class.hh:61
@ VecElemClass
Vector Register Native Elem lane.
Definition reg_class.hh:66
statistics::Scalar numCycles
Definition base.hh:640
statistics::Scalar timesIdled
Stat for total number of times the CPU is descheduled.
Definition cpu.hh:581
statistics::Scalar quiesceCycles
Stat for total number of cycles the CPU spends descheduled due to a quiesce operation or waiting for ...
Definition cpu.hh:586
statistics::Scalar idleCycles
Stat for total number of cycles the CPU spends descheduled.
Definition cpu.hh:583
CPUStats(CPU *cpu)
Definition cpu.cc:339
const std::string & name()
Definition trace.cc:48

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