gem5 [DEVELOP-FOR-25.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
292 gem5::ThreadContext *tc;
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
324{
326
328 getProbeManager(), "InstAccessComplete");
331 getProbeManager(), "DataAccessComplete");
332
333 fetch.regProbePoints();
334 rename.regProbePoints();
335 iew.regProbePoints();
336 commit.regProbePoints();
337}
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.
353 .prereq(timesIdled);
354
356 .prereq(idleCycles);
357
359 .prereq(quiesceCycles);
360}
361
362void
364{
365 DPRINTF(O3CPU, "\n\nO3CPU: Ticking main, O3CPU.\n");
366 assert(!switchedOut());
367 assert(drainState() != DrainState::Drained);
368
369 ++baseStats.numCycles;
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
393 activityRec.advance();
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");
407 cpuStats.timesIdled++;
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
435 commit.setThreads(thread);
436}
437
438void
440{
442
443 fetch.startupStage();
444 decode.startupStage();
445 iew.startupStage();
446 rename.startupStage();
447 commit.startupStage();
448}
449
450void
452{
453 auto active_it = std::find(
454 activeThreads.begin(), activeThreads.end(), tid);
455
456 DPRINTF(O3CPU, "[tid:%i] Calling activate thread.\n", tid);
457 assert(!switchedOut());
458
459 if (active_it == 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
474 auto active_it = std::find(
475 activeThreads.begin(), activeThreads.end(), tid);
476
477 DPRINTF(O3CPU, "[tid:%i] Calling deactivate thread.\n", tid);
478 assert(!switchedOut());
479
480 if (active_it != activeThreads.end()) {
481 DPRINTF(O3CPU,"[tid:%i] Removing from active threads list\n",
482 tid);
483 activeThreads.erase(active_it);
484 }
485
486 fetch.deactivateThread(tid);
487 commit.deactivateThread(tid);
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.
535 activityRec.activity();
536 fetch.wakeFromQuiesce();
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
629 commit.rob->resetEntries();
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 // at this step, all instructions in the pipeline should be already
655 // either committed successfully or squashed. All thread-specific
656 // queues in the pipeline must be empty.
657 assert(iew.instQueue.getCount(tid) == 0);
658 assert(iew.ldstQueue.getCount(tid) == 0);
659 assert(commit.rob->isEmpty(tid));
660
661 // Reset ROB/IQ/LSQ Entries
662
663 // Commented out for now. This should be possible to do by
664 // telling all the pipeline stages to drain first, and then
665 // checking until the drain completes. Once the pipeline is
666 // drained, call resetEntries(). - 10-09-06 ktlim
667/*
668 if (activeThreads.size() >= 1) {
669 commit.rob->resetEntries();
670 iew.resetEntries();
671 }
672*/
673}
674
675Fault
677{
678 // Check if there are any outstanding interrupts
679 return interrupts[0]->getInterrupt();
680}
681
682void
684{
685 // Check for interrupts here. For now can copy the code that
686 // exists within isa_fullsys_traits.hh. Also assume that thread 0
687 // is the one that handles the interrupts.
688 // @todo: Possibly consolidate the interrupt checking code.
689 // @todo: Allow other threads to handle interrupts.
690
691 assert(interrupt != NoFault);
692 interrupts[0]->updateIntrInfo();
693
694 DPRINTF(O3CPU, "Interrupt %s being handled\n", interrupt->name());
695 trap(interrupt, 0, nullptr);
696}
697
698void
699CPU::trap(const Fault &fault, ThreadID tid, const StaticInstPtr &inst)
700{
701 // Pass the thread's TC into the invoke method.
702 fault->invoke(threadContexts[tid], inst);
703}
704
705void
707{
708 thread[tid]->serialize(cp);
709}
710
711void
713{
714 thread[tid]->unserialize(cp);
715}
716
719{
720 // Deschedule any power gating event (if any)
722
723 // If the CPU isn't doing anything, then return immediately.
724 if (switchedOut())
725 return DrainState::Drained;
726
727 DPRINTF(Drain, "Draining...\n");
728
729 // We only need to signal a drain to the commit stage as this
730 // initiates squashing controls the draining. Once the commit
731 // stage commits an instruction where it is safe to stop, it'll
732 // squash the rest of the instructions in the pipeline and force
733 // the fetch stage to stall. The pipeline will be drained once all
734 // in-flight instructions have retired.
735 commit.drain();
736
737 // Wake the CPU and record activity so everything can drain out if
738 // the CPU was not able to immediately drain.
739 if (!isCpuDrained()) {
740 // If a thread is suspended, wake it up so it can be drained
741 for (auto t : threadContexts) {
742 if (t->status() == gem5::ThreadContext::Suspended){
743 DPRINTF(Drain, "Currently suspended so activate %i \n",
744 t->threadId());
745 t->activate();
746 // As the thread is now active, change the power state as well
747 activateContext(t->threadId());
748 }
749 }
750
751 wakeCPU();
752 activityRec.activity();
753
754 DPRINTF(Drain, "CPU not drained\n");
755
757 } else {
758 DPRINTF(Drain, "CPU is already drained\n");
759 if (tickEvent.scheduled())
761
762 // Flush out any old data from the time buffers. In
763 // particular, there might be some data in flight from the
764 // fetch stage that isn't visible in any of the CPU buffers we
765 // test in isCpuDrained().
766 for (int i = 0; i < timeBuffer.getSize(); ++i) {
767 timeBuffer.advance();
768 fetchQueue.advance();
769 decodeQueue.advance();
770 renameQueue.advance();
771 iewQueue.advance();
772 }
773
775 return DrainState::Drained;
776 }
777}
778
779bool
781{
783 return false;
784
785 if (tickEvent.scheduled())
787
788 DPRINTF(Drain, "CPU done draining, processing drain event\n");
790
791 return true;
792}
793
794void
796{
797 assert(isCpuDrained());
798 fetch.drainSanityCheck();
799 decode.drainSanityCheck();
800 rename.drainSanityCheck();
801 iew.drainSanityCheck();
802 commit.drainSanityCheck();
803}
804
805bool
807{
808 bool drained(true);
809
810 if (!instList.empty() || !removeList.empty()) {
811 DPRINTF(Drain, "Main CPU structures not drained.\n");
812 drained = false;
813 }
814
815 if (!fetch.isDrained()) {
816 DPRINTF(Drain, "Fetch not drained.\n");
817 drained = false;
818 }
819
820 if (!decode.isDrained()) {
821 DPRINTF(Drain, "Decode not drained.\n");
822 drained = false;
823 }
824
825 if (!rename.isDrained()) {
826 DPRINTF(Drain, "Rename not drained.\n");
827 drained = false;
828 }
829
830 if (!iew.isDrained()) {
831 DPRINTF(Drain, "IEW not drained.\n");
832 drained = false;
833 }
834
835 if (!commit.isDrained()) {
836 DPRINTF(Drain, "Commit not drained.\n");
837 drained = false;
838 }
839
840 return drained;
841}
842
843void CPU::commitDrained(ThreadID tid) { fetch.drainStall(tid); }
844
845void
847{
848 if (switchedOut())
849 return;
850
851 DPRINTF(Drain, "Resuming...\n");
853
854 fetch.drainResume();
855 commit.drainResume();
856
857 _status = Idle;
858 for (ThreadID i = 0; i < thread.size(); i++) {
860 DPRINTF(Drain, "Activating thread: %i\n", i);
863 }
864 }
865
866 assert(!tickEvent.scheduled());
867 if (_status == Running)
869
870 // Reschedule any power gating event (if any)
872}
873
874void
876{
877 DPRINTF(O3CPU, "Switching out\n");
879
880 activityRec.reset();
881
883
884 if (checker)
885 checker->switchOut();
886}
887
888void
890{
891 BaseCPU::takeOverFrom(oldCPU);
892
893 fetch.takeOverFrom();
894 decode.takeOverFrom();
895 rename.takeOverFrom();
896 iew.takeOverFrom();
897 commit.takeOverFrom();
898
899 assert(!tickEvent.scheduled());
900
901 auto *oldO3CPU = dynamic_cast<CPU *>(oldCPU);
902 if (oldO3CPU)
903 globalSeqNum = oldO3CPU->globalSeqNum;
904
906 _status = Idle;
907}
908
909void
911{
912 if (!system->isTimingMode()) {
913 fatal("The O3 CPU requires the memory system to be in "
914 "'timing' mode.\n");
915 }
916}
917
918RegVal
920{
921 return isa[tid]->readMiscRegNoEffect(misc_reg);
922}
923
924RegVal
926{
927 executeStats[tid]->numMiscRegReads++;
928 return isa[tid]->readMiscReg(misc_reg);
929}
930
931void
933{
934 isa[tid]->setMiscRegNoEffect(misc_reg, val);
935}
936
937void
939{
940 executeStats[tid]->numMiscRegWrites++;
941 isa[tid]->setMiscReg(misc_reg, val);
942}
943
944RegVal
946{
947 switch (phys_reg->classValue()) {
948 case IntRegClass:
949 executeStats[tid]->numIntRegReads++;
950 break;
951 case FloatRegClass:
952 executeStats[tid]->numFpRegReads++;
953 break;
954 case CCRegClass:
955 executeStats[tid]->numCCRegReads++;
956 break;
957 case VecRegClass:
958 case VecElemClass:
959 executeStats[tid]->numVecRegReads++;
960 break;
961 case VecPredRegClass:
962 executeStats[tid]->numVecPredRegReads++;
963 break;
964 default:
965 break;
966 }
967 return regFile.getReg(phys_reg);
968}
969
970void
972{
973 switch (phys_reg->classValue()) {
974 case IntRegClass:
975 executeStats[tid]->numIntRegReads++;
976 break;
977 case FloatRegClass:
978 executeStats[tid]->numFpRegReads++;
979 break;
980 case CCRegClass:
981 executeStats[tid]->numCCRegReads++;
982 break;
983 case VecRegClass:
984 case VecElemClass:
985 executeStats[tid]->numVecRegReads++;
986 break;
987 case VecPredRegClass:
988 executeStats[tid]->numVecPredRegReads++;
989 break;
990 default:
991 break;
992 }
993 regFile.getReg(phys_reg, val);
994}
995
996void *
998{
999 switch (phys_reg->classValue()) {
1000 case VecRegClass:
1001 executeStats[tid]->numVecRegWrites++;
1002 break;
1003 case VecPredRegClass:
1004 executeStats[tid]->numVecPredRegWrites++;
1005 break;
1006 default:
1007 break;
1008 }
1009 return regFile.getWritableReg(phys_reg);
1010}
1011
1012void
1014{
1015 switch (phys_reg->classValue()) {
1016 case IntRegClass:
1017 executeStats[tid]->numIntRegWrites++;
1018 break;
1019 case FloatRegClass:
1020 executeStats[tid]->numFpRegWrites++;
1021 break;
1022 case CCRegClass:
1023 executeStats[tid]->numCCRegWrites++;
1024 break;
1025 case VecRegClass:
1026 case VecElemClass:
1027 executeStats[tid]->numVecRegWrites++;
1028 break;
1029 case VecPredRegClass:
1030 executeStats[tid]->numVecPredRegWrites++;
1031 break;
1032 default:
1033 break;
1034 }
1035 regFile.setReg(phys_reg, val);
1036}
1037
1038void
1039CPU::setReg(PhysRegIdPtr phys_reg, const void *val, ThreadID tid)
1040{
1041 switch (phys_reg->classValue()) {
1042 case IntRegClass:
1043 executeStats[tid]->numIntRegWrites++;
1044 break;
1045 case FloatRegClass:
1046 executeStats[tid]->numFpRegWrites++;
1047 break;
1048 case CCRegClass:
1049 executeStats[tid]->numCCRegWrites++;
1050 break;
1051 case VecRegClass:
1052 case VecElemClass:
1053 executeStats[tid]->numVecRegWrites++;
1054 break;
1055 case VecPredRegClass:
1056 executeStats[tid]->numVecPredRegWrites++;
1057 break;
1058 default:
1059 break;
1060 }
1061 regFile.setReg(phys_reg, val);
1062}
1063
1064RegVal
1066{
1067 const RegId flat = reg.flatten(*isa[tid]);
1068 PhysRegIdPtr phys_reg = commitRenameMap[tid].lookup(flat);
1069 return regFile.getReg(phys_reg);
1070}
1071
1072void
1074{
1075 const RegId flat = reg.flatten(*isa[tid]);
1076 PhysRegIdPtr phys_reg = commitRenameMap[tid].lookup(flat);
1077 regFile.getReg(phys_reg, val);
1078}
1079
1080void *
1082{
1083 const RegId flat = reg.flatten(*isa[tid]);
1084 PhysRegIdPtr phys_reg = commitRenameMap[tid].lookup(flat);
1085 return regFile.getWritableReg(phys_reg);
1086}
1087
1088void
1090{
1091 const RegId flat = reg.flatten(*isa[tid]);
1092 PhysRegIdPtr phys_reg = commitRenameMap[tid].lookup(flat);
1093 regFile.setReg(phys_reg, val);
1094}
1095
1096void
1097CPU::setArchReg(const RegId &reg, const void *val, ThreadID tid)
1098{
1099 const RegId flat = reg.flatten(*isa[tid]);
1100 PhysRegIdPtr phys_reg = commitRenameMap[tid].lookup(flat);
1101 regFile.setReg(phys_reg, val);
1102}
1103
1104const PCStateBase &
1106{
1107 return commit.pcState(tid);
1108}
1109
1110void
1112{
1113 commit.pcState(val, tid);
1114}
1115
1116void
1118{
1119 thread[tid]->noSquashFromTC = true;
1120 commit.generateTCEvent(tid);
1121}
1122
1125{
1126 instList.push_back(inst);
1127
1128 return --(instList.end());
1129}
1130
1131void
1133{
1134 // Keep an instruction count.
1135 if (!inst->isMicroop() || inst->isLastMicroop()) {
1136 thread[tid]->numInst++;
1137 thread[tid]->threadStats.numInsts++;
1138 commitStats[tid]->numInstsNotNOP++;
1139
1140 // Check for instruction-count-based events.
1141 thread[tid]->comInstEventQueue.serviceEvents(thread[tid]->numInst);
1142 }
1143 thread[tid]->numOp++;
1144 thread[tid]->threadStats.numOps++;
1145 commitStats[tid]->numOpsNotNOP++;
1146
1147 probeInstCommit(inst->staticInst, inst->pcState().instAddr());
1148}
1149
1150void
1152{
1153 DPRINTF(O3CPU, "Removing committed instruction [tid:%i] PC %s "
1154 "[sn:%lli]\n",
1155 inst->threadNumber, inst->pcState(), inst->seqNum);
1156
1157 removeInstsThisCycle = true;
1158
1159 // Remove the front instruction.
1160 removeList.push(inst->getInstListIt());
1161}
1162
1163void
1165{
1166 DPRINTF(O3CPU, "Thread %i: Deleting instructions from instruction"
1167 " list.\n", tid);
1168
1169 ListIt end_it;
1170
1171 bool rob_empty = false;
1172
1173 if (instList.empty()) {
1174 return;
1175 } else if (rob.isEmpty(tid)) {
1176 DPRINTF(O3CPU, "ROB is empty, squashing all insts.\n");
1177 end_it = instList.begin();
1178 rob_empty = true;
1179 } else {
1180 end_it = (rob.readTailInst(tid))->getInstListIt();
1181 DPRINTF(O3CPU, "ROB is not empty, squashing insts not in ROB.\n");
1182 }
1183
1184 removeInstsThisCycle = true;
1185
1186 ListIt inst_it = instList.end();
1187
1188 inst_it--;
1189
1190 // Walk through the instruction list, removing any instructions
1191 // that were inserted after the given instruction iterator, end_it.
1192 while (inst_it != end_it) {
1193 assert(!instList.empty());
1194
1195 squashInstIt(inst_it, tid);
1196
1197 inst_it--;
1198 }
1199
1200 // If the ROB was empty, then we actually need to remove the first
1201 // instruction as well.
1202 if (rob_empty) {
1203 squashInstIt(inst_it, tid);
1204 }
1205}
1206
1207void
1209{
1210 assert(!instList.empty());
1211
1212 removeInstsThisCycle = true;
1213
1214 ListIt inst_iter = instList.end();
1215
1216 inst_iter--;
1217
1218 DPRINTF(O3CPU, "Deleting instructions from instruction "
1219 "list that are from [tid:%i] and above [sn:%lli] (end=%lli).\n",
1220 tid, seq_num, (*inst_iter)->seqNum);
1221
1222 while ((*inst_iter)->seqNum > seq_num) {
1223
1224 bool break_loop = (inst_iter == instList.begin());
1225
1226 squashInstIt(inst_iter, tid);
1227
1228 inst_iter--;
1229
1230 if (break_loop)
1231 break;
1232 }
1233}
1234
1235void
1237{
1238 if ((*instIt)->threadNumber == tid) {
1239 DPRINTF(O3CPU, "Squashing instruction, "
1240 "[tid:%i] [sn:%lli] PC %s\n",
1241 (*instIt)->threadNumber,
1242 (*instIt)->seqNum,
1243 (*instIt)->pcState());
1244
1245 // Mark it as squashed.
1246 (*instIt)->setSquashed();
1247
1248 // @todo: Formulate a consistent method for deleting
1249 // instructions from the instruction list
1250 // Remove the instruction from the list.
1251 removeList.push(instIt);
1252 }
1253}
1254
1255void
1257{
1258 while (!removeList.empty()) {
1259 DPRINTF(O3CPU, "Removing instruction, "
1260 "[tid:%i] [sn:%lli] PC %s\n",
1261 (*removeList.front())->threadNumber,
1262 (*removeList.front())->seqNum,
1263 (*removeList.front())->pcState());
1264
1265 instList.erase(removeList.front());
1266
1267 removeList.pop();
1268 }
1269
1270 removeInstsThisCycle = false;
1271}
1272/*
1273void
1274CPU::removeAllInsts()
1275{
1276 instList.clear();
1277}
1278*/
1279void
1281{
1282 int num = 0;
1283
1284 ListIt inst_list_it = instList.begin();
1285
1286 cprintf("Dumping Instruction List\n");
1287
1288 while (inst_list_it != instList.end()) {
1289 cprintf("Instruction:%i\nPC:%#x\n[tid:%i]\n[sn:%lli]\nIssued:%i\n"
1290 "Squashed:%i\n\n",
1291 num, (*inst_list_it)->pcState().instAddr(),
1292 (*inst_list_it)->threadNumber,
1293 (*inst_list_it)->seqNum, (*inst_list_it)->isIssued(),
1294 (*inst_list_it)->isSquashed());
1295 inst_list_it++;
1296 ++num;
1297 }
1298}
1299/*
1300void
1301CPU::wakeDependents(const DynInstPtr &inst)
1302{
1303 iew.wakeDependents(inst);
1304}
1305*/
1306void
1308{
1309 if (activityRec.active() || tickEvent.scheduled()) {
1310 DPRINTF(Activity, "CPU already running.\n");
1311 return;
1312 }
1313
1314 DPRINTF(Activity, "Waking up CPU\n");
1315
1316 Cycles cycles(curCycle() - lastRunningCycle);
1317 // @todo: This is an oddity that is only here to match the stats
1318 if (cycles > 1) {
1319 --cycles;
1320 cpuStats.idleCycles += cycles;
1321 baseStats.numCycles += cycles;
1322 }
1323
1325}
1326
1327void
1329{
1331 return;
1332
1333 wakeCPU();
1334
1335 DPRINTF(Quiesce, "Suspended Processor woken\n");
1336 threadContexts[tid]->activate();
1337}
1338
1341{
1342 for (ThreadID tid = 0; tid < numThreads; tid++) {
1343 if (!tids[tid]) {
1344 tids[tid] = true;
1345 return tid;
1346 }
1347 }
1348
1349 return InvalidThreadID;
1350}
1351
1352void
1354{
1355 if (activeThreads.size() > 1) {
1356 //DEFAULT TO ROUND ROBIN SCHEME
1357 //e.g. Move highest priority to end of thread list
1358 auto list_begin = activeThreads.begin();
1359
1360 unsigned high_thread = *list_begin;
1361
1362 activeThreads.erase(list_begin);
1363
1364 activeThreads.push_back(high_thread);
1365 }
1366}
1367
1368void
1370{
1371 DPRINTF(O3CPU, "Thread %d is inserted to exitingThreads list\n", tid);
1372
1373 // the thread trying to exit can't be already halted
1374 assert(tcBase(tid)->status() != gem5::ThreadContext::Halted);
1375
1376 // make sure the thread has not been added to the list yet
1377 assert(exitingThreads.count(tid) == 0);
1378
1379 // add the thread to exitingThreads list to mark that this thread is
1380 // trying to exit. The boolean value in the pair denotes if a thread is
1381 // ready to exit. The thread is not ready to exit until the corresponding
1382 // exit trap event is processed in the future. Until then, it'll be still
1383 // an active thread that is trying to exit.
1384 exitingThreads.emplace(std::make_pair(tid, false));
1385}
1386
1387bool
1389{
1390 return exitingThreads.count(tid) == 1;
1391}
1392
1393void
1395{
1396 assert(exitingThreads.count(tid) == 1);
1397
1398 // exit trap event has been processed. Now, the thread is ready to exit
1399 // and be removed from the CPU.
1400 exitingThreads[tid] = true;
1401
1402 // we schedule a threadExitEvent in the next cycle to properly clean
1403 // up the thread's states in the pipeline. threadExitEvent has lower
1404 // priority than tickEvent, so the cleanup will happen at the very end
1405 // of the next cycle after all pipeline stages complete their operations.
1406 // We want all stages to complete squashing instructions before doing
1407 // the cleanup.
1408 if (!threadExitEvent.scheduled()) {
1410 }
1411}
1412
1413void
1415{
1416 // there must be at least one thread trying to exit
1417 assert(exitingThreads.size() > 0);
1418
1419 // terminate all threads that are ready to exit
1420 auto it = exitingThreads.begin();
1421 while (it != exitingThreads.end()) {
1422 ThreadID thread_id = it->first;
1423 bool readyToExit = it->second;
1424
1425 if (readyToExit) {
1426 DPRINTF(O3CPU, "Exiting thread %d\n", thread_id);
1427 haltContext(thread_id);
1429 it = exitingThreads.erase(it);
1430 } else {
1431 it++;
1432 }
1433 }
1434}
1435
1436void
1437CPU::htmSendAbortSignal(ThreadID tid, uint64_t htm_uid,
1439{
1440 const Addr addr = 0x0ul;
1441 const int size = 8;
1442 const Request::Flags flags =
1444
1445 // O3-specific actions
1446 iew.ldstQueue.resetHtmStartsStops(tid);
1447 commit.resetHtmStartsStops(tid);
1448
1449 // notify l1 d-cache (ruby) that core has aborted transaction
1450 RequestPtr req =
1451 std::make_shared<Request>(addr, size, flags, _dataRequestorId);
1452
1453 req->taskId(taskId());
1454 req->setContext(thread[tid]->contextId());
1455 req->setHtmAbortCause(cause);
1456
1457 assert(req->isHTMAbort());
1458
1459 PacketPtr abort_pkt = Packet::createRead(req);
1460 uint8_t *memData = new uint8_t[8];
1461 assert(memData);
1462 abort_pkt->dataStatic(memData);
1463 abort_pkt->setHtmTransactional(htm_uid);
1464
1465 // TODO include correct error handling here
1466 if (!iew.ldstQueue.getDataPort().sendTimingReq(abort_pkt)) {
1467 panic("HTM abort signal was not sent to the memory subsystem.");
1468 }
1469}
1470
1471} // namespace o3
1472} // 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:320
void updateCycleCounters(CPUState state)
base method keeping track of cycle progression
Definition base.hh:588
void schedulePowerGatingEvent()
Definition base.cc:514
@ CPU_STATE_SLEEP
Definition base.hh:579
std::vector< std::unique_ptr< CommitCPUStats > > commitStats
Definition base.hh:848
void regProbePoints() override
Register probe points for this object.
Definition base.cc:384
uint32_t taskId() const
Get cpu task id.
Definition base.hh:236
virtual void suspendContext(ThreadID thread_num)
Notify the CPU that the indicated context is now suspended.
Definition base.cc:567
gem5::BaseCPU::BaseCPUStats baseStats
ThreadID numThreads
Number of threads we're actually simulating (<= SMT_MAX_THREADS).
Definition base.hh:417
void deschedulePowerGatingEvent()
Definition base.cc:506
std::vector< std::unique_ptr< ExecuteCPUStats > > executeStats
Definition base.hh:847
std::vector< BaseInterrupts * > interrupts
Definition base.hh:249
void startup() override
startup() is the final initialization call before simulation.
Definition base.cc:359
virtual void switchOut()
Prepare for another CPU to take over execution.
Definition base.cc:610
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:624
std::vector< ThreadContext * > threadContexts
Definition base.hh:285
bool switchedOut() const
Determine if the CPU is switched out.
Definition base.hh:400
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:400
RequestorID _dataRequestorId
data side request id that must be placed in all requests
Definition base.hh:130
virtual void activateContext(ThreadID thread_num)
Notify the CPU that the indicated context is now active.
Definition base.cc:542
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:280
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:447
void instDone(ThreadID tid, const DynInstPtr &inst)
Function to tell the CPU that an instruction has completed.
Definition cpu.cc:1132
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:1280
void drainSanityCheck() const
Perform sanity checks after a drain.
Definition cpu.cc:795
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:1437
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:945
ListIt addInst(const DynInstPtr &inst)
Function to add instruction onto the head of the list of the instructions.
Definition cpu.cc:1124
void setArchReg(const RegId &reg, RegVal val, ThreadID tid)
Definition cpu.cc:1089
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:706
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:846
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:699
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:1414
ThreadID getFreeTid()
Gets a free thread id.
Definition cpu.cc:1340
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:843
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:1328
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:938
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:932
void removeInstsUntil(const InstSeqNum &seq_num, ThreadID tid)
Remove all instructions younger than the given sequence number.
Definition cpu.cc:1208
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:1256
@ 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:712
void removeInstsNotInROB(ThreadID tid)
Remove all instructions that are not currently in the ROB.
Definition cpu.cc:1164
void takeOverFrom(BaseCPU *oldCPU) override
Takes over from another CPU.
Definition cpu.cc:889
void switchOut() override
Switches out this CPU.
Definition cpu.cc:875
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:780
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:683
void squashFromTC(ThreadID tid)
Initiates a squash of all in-flight instructions for a given thread.
Definition cpu.cc:1117
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:1236
BaseMMU * mmu
Definition cpu.hh:110
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:910
RegVal getArchReg(const RegId &reg, ThreadID tid)
Architectural register accessors.
Definition cpu.cc:1065
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:718
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:676
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:919
bool isCpuDrained() const
Check if a system is in a drained state.
Definition cpu.cc:806
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:1369
void pcState(const PCStateBase &new_pc_state, ThreadID tid)
Sets the commit PC state of a specific thread.
Definition cpu.cc:1111
void scheduleThreadExitEvent(ThreadID tid)
If a thread is trying to exit and its corresponding trap event has been completed,...
Definition cpu.cc:1394
void updateThreadPriority()
Update The Order In Which We Process Threads.
Definition cpu.cc:1353
void setReg(PhysRegIdPtr phys_reg, RegVal val, ThreadID tid)
Definition cpu.cc:1013
bool isThreadExiting(ThreadID tid) const
Is the thread trying to exit?
Definition cpu.cc:1388
void removeFrontInst(const DynInstPtr &inst)
Remove an instruction from the front end of the list.
Definition cpu.cc:1151
void * getWritableArchReg(const RegId &reg, ThreadID tid)
Definition cpu.cc:1081
RegVal readMiscReg(int misc_reg, ThreadID tid)
Reads a misc.
Definition cpu.cc:925
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:997
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:1307
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
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: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.
Definition drain.hh:77
@ Running
Running normally.
Definition drain.hh:76
@ Drained
Buffers drained, ready for serialization/handover.
Definition drain.hh:78
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:510
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: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 Mon May 26 2025 09:19:07 for gem5 by doxygen 1.13.2