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

Generated on Mon Oct 27 2025 04:13:00 for gem5 by doxygen 1.14.0