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

Generated on Mon Jul 10 2023 14:24:29 for gem5 by doxygen 1.9.7