gem5  v22.1.0.0
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"
50 #include "cpu/o3/thread_context.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 
64 namespace gem5
65 {
66 
67 struct BaseCPUParams;
68 
69 namespace o3
70 {
71 
72 CPU::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.numPhysCCRegs,
94  params.isa[0]->regClasses()),
95 
96  freeList(name() + ".freelist", &regFile),
97 
98  rob(this, params),
99 
100  scoreboard(name() + ".scoreboard", regFile.totalNumPhysRegs()),
101 
102  isa(numThreads, NULL),
103 
104  timeBuffer(params.backComSize, params.forwardComSize),
105  fetchQueue(params.backComSize, params.forwardComSize),
106  decodeQueue(params.backComSize, params.forwardComSize),
107  renameQueue(params.backComSize, params.forwardComSize),
108  iewQueue(params.backComSize, params.forwardComSize),
109  activityRec(name(), NumStages,
110  params.backComSize + params.forwardComSize,
111  params.activity),
112 
113  globalSeqNum(1),
114  system(params.system),
115  lastRunningCycle(curCycle()),
116  cpuStats(this)
117 {
118  fatal_if(FullSystem && params.numThreads > 1,
119  "SMT is not supported in O3 in full system mode currently.");
120 
121  fatal_if(!FullSystem && params.numThreads < params.workload.size(),
122  "More workload items (%d) than threads (%d) on CPU %s.",
123  params.workload.size(), params.numThreads, name());
124 
125  if (!params.switched_out) {
126  _status = Running;
127  } else {
128  _status = SwitchedOut;
129  }
130 
131  if (params.checker) {
132  BaseCPU *temp_checker = params.checker;
133  checker = dynamic_cast<Checker<DynInstPtr> *>(temp_checker);
134  checker->setIcachePort(&fetch.getInstPort());
135  checker->setSystem(params.system);
136  } else {
137  checker = NULL;
138  }
139 
140  if (!FullSystem) {
141  thread.resize(numThreads);
142  tids.resize(numThreads);
143  }
144 
145  // The stages also need their CPU pointer setup. However this
146  // must be done at the upper level CPU because they have pointers
147  // to the upper level CPU, and not this CPU.
148 
149  // Set up Pointers to the activeThreads list for each stage
150  fetch.setActiveThreads(&activeThreads);
151  decode.setActiveThreads(&activeThreads);
152  rename.setActiveThreads(&activeThreads);
153  iew.setActiveThreads(&activeThreads);
154  commit.setActiveThreads(&activeThreads);
155 
156  // Give each of the stages the time buffer they will use.
157  fetch.setTimeBuffer(&timeBuffer);
158  decode.setTimeBuffer(&timeBuffer);
159  rename.setTimeBuffer(&timeBuffer);
160  iew.setTimeBuffer(&timeBuffer);
161  commit.setTimeBuffer(&timeBuffer);
162 
163  // Also setup each of the stages' queues.
164  fetch.setFetchQueue(&fetchQueue);
165  decode.setFetchQueue(&fetchQueue);
166  commit.setFetchQueue(&fetchQueue);
167  decode.setDecodeQueue(&decodeQueue);
168  rename.setDecodeQueue(&decodeQueue);
169  rename.setRenameQueue(&renameQueue);
170  iew.setRenameQueue(&renameQueue);
171  iew.setIEWQueue(&iewQueue);
172  commit.setIEWQueue(&iewQueue);
173  commit.setRenameQueue(&renameQueue);
174 
175  commit.setIEWStage(&iew);
176  rename.setIEWStage(&iew);
177  rename.setCommitStage(&commit);
178 
179  ThreadID active_threads;
180  if (FullSystem) {
181  active_threads = 1;
182  } else {
183  active_threads = params.workload.size();
184 
185  if (active_threads > MaxThreads) {
186  panic("Workload Size too large. Increase the 'MaxThreads' "
187  "constant in cpu/o3/limits.hh or edit your workload size.");
188  }
189  }
190 
191  // Make Sure That this a Valid Architeture
192  assert(numThreads);
193  const auto &regClasses = params.isa[0]->regClasses();
194 
195  assert(params.numPhysIntRegs >=
196  numThreads * regClasses.at(IntRegClass)->numRegs());
197  assert(params.numPhysFloatRegs >=
198  numThreads * regClasses.at(FloatRegClass)->numRegs());
199  assert(params.numPhysVecRegs >=
200  numThreads * regClasses.at(VecRegClass)->numRegs());
201  assert(params.numPhysVecPredRegs >=
202  numThreads * regClasses.at(VecPredRegClass)->numRegs());
203  assert(params.numPhysCCRegs >=
204  numThreads * regClasses.at(CCRegClass)->numRegs());
205 
206  // Just make this a warning and go ahead anyway, to keep from having to
207  // add checks everywhere.
208  warn_if(regClasses.at(CCRegClass)->numRegs() == 0 &&
209  params.numPhysCCRegs != 0,
210  "Non-zero number of physical CC regs specified, even though\n"
211  " ISA does not use them.");
212 
213  rename.setScoreboard(&scoreboard);
214  iew.setScoreboard(&scoreboard);
215 
216  // Setup the rename map for whichever stages need it.
217  for (ThreadID tid = 0; tid < numThreads; tid++) {
218  isa[tid] = params.isa[tid];
219  commitRenameMap[tid].init(regClasses, &regFile, &freeList);
220  renameMap[tid].init(regClasses, &regFile, &freeList);
221  }
222 
223  // Initialize rename map to assign physical registers to the
224  // architectural registers for active threads only.
225  for (ThreadID tid = 0; tid < active_threads; tid++) {
226  for (auto type = (RegClassType)0; type <= CCRegClass;
227  type = (RegClassType)(type + 1)) {
228  for (auto &id: *regClasses.at(type)) {
229  // Note that we can't use the rename() method because we don't
230  // want special treatment for the zero register at this point
231  PhysRegIdPtr phys_reg = freeList.getReg(type);
232  renameMap[tid].setEntry(id, phys_reg);
233  commitRenameMap[tid].setEntry(id, phys_reg);
234  }
235  }
236  }
237 
238  rename.setRenameMap(renameMap);
239  commit.setRenameMap(commitRenameMap);
240  rename.setFreeList(&freeList);
241 
242  // Setup the ROB for whichever stages need it.
243  commit.setROB(&rob);
244 
245  lastActivatedCycle = 0;
246 
247  DPRINTF(O3CPU, "Creating O3CPU object.\n");
248 
249  // Setup any thread state.
250  thread.resize(numThreads);
251 
252  for (ThreadID tid = 0; tid < numThreads; ++tid) {
253  if (FullSystem) {
254  // SMT is not supported in FS mode yet.
255  assert(numThreads == 1);
256  thread[tid] = new ThreadState(this, 0, NULL);
257  } else {
258  if (tid < params.workload.size()) {
259  DPRINTF(O3CPU, "Workload[%i] process is %#x", tid,
260  thread[tid]);
261  thread[tid] = new ThreadState(this, tid, params.workload[tid]);
262  } else {
263  //Allocate Empty thread so M5 can use later
264  //when scheduling threads to CPU
265  Process* dummy_proc = NULL;
266 
267  thread[tid] = new ThreadState(this, tid, dummy_proc);
268  }
269  }
270 
272 
273  // Setup the TC that will serve as the interface to the threads/CPU.
274  auto *o3_tc = new ThreadContext;
275 
276  tc = o3_tc;
277 
278  // If we're using a checker, then the TC should be the
279  // CheckerThreadContext.
280  if (params.checker) {
281  tc = new CheckerThreadContext<ThreadContext>(o3_tc, checker);
282  }
283 
284  o3_tc->cpu = this;
285  o3_tc->thread = thread[tid];
286 
287  // Give the thread the TC.
288  thread[tid]->tc = tc;
289 
290  // Add the TC to the CPU's list of TC's.
291  threadContexts.push_back(tc);
292  }
293 
294  // O3CPU always requires an interrupt controller.
295  if (!params.switched_out && interrupts.empty()) {
296  fatal("O3CPU %s has no interrupt controller.\n"
297  "Ensure createInterruptController() is called.\n", name());
298  }
299 }
300 
301 void
303 {
305 
307  getProbeManager(), "InstAccessComplete");
310  getProbeManager(), "DataAccessComplete");
311 
316 }
317 
319  : statistics::Group(cpu),
320  ADD_STAT(timesIdled, statistics::units::Count::get(),
321  "Number of times that the entire CPU went into an idle state "
322  "and unscheduled itself"),
323  ADD_STAT(idleCycles, statistics::units::Cycle::get(),
324  "Total number of cycles that the CPU has spent unscheduled due "
325  "to idling"),
326  ADD_STAT(quiesceCycles, statistics::units::Cycle::get(),
327  "Total number of cycles that CPU has spent quiesced or waiting "
328  "for an interrupt"),
329  ADD_STAT(committedInsts, statistics::units::Count::get(),
330  "Number of Instructions Simulated"),
331  ADD_STAT(committedOps, statistics::units::Count::get(),
332  "Number of Ops (including micro ops) Simulated"),
333  ADD_STAT(cpi, statistics::units::Rate<
334  statistics::units::Cycle, statistics::units::Count>::get(),
335  "CPI: Cycles Per Instruction"),
336  ADD_STAT(totalCpi, statistics::units::Rate<
337  statistics::units::Cycle, statistics::units::Count>::get(),
338  "CPI: Total CPI of All Threads"),
339  ADD_STAT(ipc, statistics::units::Rate<
340  statistics::units::Count, statistics::units::Cycle>::get(),
341  "IPC: Instructions Per Cycle"),
342  ADD_STAT(totalIpc, statistics::units::Rate<
343  statistics::units::Count, statistics::units::Cycle>::get(),
344  "IPC: Total IPC of All Threads"),
345  ADD_STAT(intRegfileReads, statistics::units::Count::get(),
346  "Number of integer regfile reads"),
347  ADD_STAT(intRegfileWrites, statistics::units::Count::get(),
348  "Number of integer regfile writes"),
349  ADD_STAT(fpRegfileReads, statistics::units::Count::get(),
350  "Number of floating regfile reads"),
351  ADD_STAT(fpRegfileWrites, statistics::units::Count::get(),
352  "Number of floating regfile writes"),
353  ADD_STAT(vecRegfileReads, statistics::units::Count::get(),
354  "number of vector regfile reads"),
355  ADD_STAT(vecRegfileWrites, statistics::units::Count::get(),
356  "number of vector regfile writes"),
357  ADD_STAT(vecPredRegfileReads, statistics::units::Count::get(),
358  "number of predicate regfile reads"),
359  ADD_STAT(vecPredRegfileWrites, statistics::units::Count::get(),
360  "number of predicate regfile writes"),
361  ADD_STAT(ccRegfileReads, statistics::units::Count::get(),
362  "number of cc regfile reads"),
363  ADD_STAT(ccRegfileWrites, statistics::units::Count::get(),
364  "number of cc regfile writes"),
365  ADD_STAT(miscRegfileReads, statistics::units::Count::get(),
366  "number of misc regfile reads"),
367  ADD_STAT(miscRegfileWrites, statistics::units::Count::get(),
368  "number of misc regfile writes")
369 {
370  // Register any of the O3CPU's stats here.
371  timesIdled
372  .prereq(timesIdled);
373 
374  idleCycles
375  .prereq(idleCycles);
376 
379 
380  // Number of Instructions simulated
381  // --------------------------------
382  // Should probably be in Base CPU but need templated
383  // MaxThreads so put in here instead
385  .init(cpu->numThreads)
387 
389  .init(cpu->numThreads)
391 
392  cpi
393  .precision(6);
395 
396  totalCpi
397  .precision(6);
399 
400  ipc
401  .precision(6);
403 
404  totalIpc
405  .precision(6);
407 
410 
413 
416 
419 
422 
425 
428 
431 
434 
437 
440 
443 }
444 
445 void
447 {
448  DPRINTF(O3CPU, "\n\nO3CPU: Ticking main, O3CPU.\n");
449  assert(!switchedOut());
450  assert(drainState() != DrainState::Drained);
451 
454 
455 // activity = false;
456 
457  //Tick each of the stages
458  fetch.tick();
459 
460  decode.tick();
461 
462  rename.tick();
463 
464  iew.tick();
465 
466  commit.tick();
467 
468  // Now advance the time buffers
469  timeBuffer.advance();
470 
471  fetchQueue.advance();
472  decodeQueue.advance();
473  renameQueue.advance();
474  iewQueue.advance();
475 
477 
478  if (removeInstsThisCycle) {
480  }
481 
482  if (!tickEvent.scheduled()) {
483  if (_status == SwitchedOut) {
484  DPRINTF(O3CPU, "Switched out!\n");
485  // increment stat
487  } else if (!activityRec.active() || _status == Idle) {
488  DPRINTF(O3CPU, "Idle!\n");
491  } else {
493  DPRINTF(O3CPU, "Scheduling next tick!\n");
494  }
495  }
496 
497  if (!FullSystem)
499 
500  tryDrain();
501 }
502 
503 void
505 {
506  BaseCPU::init();
507 
508  for (ThreadID tid = 0; tid < numThreads; ++tid) {
509  // Set noSquashFromTC so that the CPU doesn't squash when initially
510  // setting up registers.
511  thread[tid]->noSquashFromTC = true;
512  }
513 
514  // Clear noSquashFromTC.
515  for (int tid = 0; tid < numThreads; ++tid)
516  thread[tid]->noSquashFromTC = false;
517 
519 }
520 
521 void
523 {
525 
528  iew.startupStage();
531 }
532 
533 void
535 {
537  std::find(activeThreads.begin(), activeThreads.end(), tid);
538 
539  DPRINTF(O3CPU, "[tid:%i] Calling activate thread.\n", tid);
540  assert(!switchedOut());
541 
542  if (isActive == activeThreads.end()) {
543  DPRINTF(O3CPU, "[tid:%i] Adding to active threads list\n", tid);
544 
545  activeThreads.push_back(tid);
546  }
547 }
548 
549 void
551 {
552  // hardware transactional memory
553  // shouldn't deactivate thread in the middle of a transaction
554  assert(!commit.executingHtmTransaction(tid));
555 
556  //Remove From Active List, if Active
558  std::find(activeThreads.begin(), activeThreads.end(), tid);
559 
560  DPRINTF(O3CPU, "[tid:%i] Calling deactivate thread.\n", tid);
561  assert(!switchedOut());
562 
563  if (thread_it != activeThreads.end()) {
564  DPRINTF(O3CPU,"[tid:%i] Removing from active threads list\n",
565  tid);
566  activeThreads.erase(thread_it);
567  }
568 
569  fetch.deactivateThread(tid);
571 }
572 
573 Counter
575 {
576  Counter total(0);
577 
578  ThreadID size = thread.size();
579  for (ThreadID i = 0; i < size; i++)
580  total += thread[i]->numInst;
581 
582  return total;
583 }
584 
585 Counter
587 {
588  Counter total(0);
589 
590  ThreadID size = thread.size();
591  for (ThreadID i = 0; i < size; i++)
592  total += thread[i]->numOp;
593 
594  return total;
595 }
596 
597 void
599 {
600  assert(!switchedOut());
601 
602  // Needs to set each stage to running as well.
603  activateThread(tid);
604 
605  // We don't want to wake the CPU if it is drained. In that case,
606  // we just want to flag the thread as active and schedule the tick
607  // event from drainResume() instead.
609  return;
610 
611  // If we are time 0 or if the last activation time is in the past,
612  // schedule the next tick and wake up the fetch unit
615 
616  // Be sure to signal that there's some activity so the CPU doesn't
617  // deschedule itself.
620 
621  Cycles cycles(curCycle() - lastRunningCycle);
622  // @todo: This is an oddity that is only here to match the stats
623  if (cycles != 0)
624  --cycles;
625  cpuStats.quiesceCycles += cycles;
626 
628 
629  _status = Running;
630 
632  }
633 }
634 
635 void
637 {
638  DPRINTF(O3CPU,"[tid:%i] Suspending Thread Context.\n", tid);
639  assert(!switchedOut());
640 
641  deactivateThread(tid);
642 
643  // If this was the last thread then unschedule the tick event.
644  if (activeThreads.size() == 0) {
647  _status = Idle;
648  }
649 
650  DPRINTF(Quiesce, "Suspending Context\n");
651 
653 }
654 
655 void
657 {
658  //For now, this is the same as deallocate
659  DPRINTF(O3CPU,"[tid:%i] Halt Context called. Deallocating\n", tid);
660  assert(!switchedOut());
661 
662  deactivateThread(tid);
663  removeThread(tid);
664 
665  // If this was the last thread then unschedule the tick event.
666  if (activeThreads.size() == 0) {
667  if (tickEvent.scheduled())
668  {
670  }
672  _status = Idle;
673  }
675 }
676 
677 void
679 {
680  DPRINTF(O3CPU,"[tid:%i] Initializing thread into CPU");
681  // Will change now that the PC and thread state is internal to the CPU
682  // and not in the ThreadContext.
683  gem5::ThreadContext *src_tc;
684  if (FullSystem)
685  src_tc = system->threads[tid];
686  else
687  src_tc = tcBase(tid);
688 
689  //Bind Int Regs to Rename Map
690  const auto &regClasses = isa[tid]->regClasses();
691 
692  for (auto type = (RegClassType)0; type <= CCRegClass;
693  type = (RegClassType)(type + 1)) {
694  for (auto &id: *regClasses.at(type)) {
695  PhysRegIdPtr phys_reg = freeList.getReg(type);
696  renameMap[tid].setEntry(id, phys_reg);
697  scoreboard.setReg(phys_reg);
698  }
699  }
700 
701  //Copy Thread Data Into RegFile
702  //copyFromTC(tid);
703 
704  //Set PC/NPC/NNPC
705  pcState(src_tc->pcState(), tid);
706 
708 
709  activateContext(tid);
710 
711  //Reset ROB/IQ/LSQ Entries
713 }
714 
715 void
717 {
718  DPRINTF(O3CPU,"[tid:%i] Removing thread context from CPU.\n", tid);
719 
720  // Copy Thread Data From RegFile
721  // If thread is suspended, it might be re-allocated
722  // copyToTC(tid);
723 
724 
725  // @todo: 2-27-2008: Fix how we free up rename mappings
726  // here to alleviate the case for double-freeing registers
727  // in SMT workloads.
728 
729  // clear all thread-specific states in each stage of the pipeline
730  // since this thread is going to be completely removed from the CPU
731  commit.clearStates(tid);
732  fetch.clearStates(tid);
733  decode.clearStates(tid);
734  rename.clearStates(tid);
735  iew.clearStates(tid);
736 
737  // Flush out any old data from the time buffers.
738  for (int i = 0; i < timeBuffer.getSize(); ++i) {
739  timeBuffer.advance();
740  fetchQueue.advance();
741  decodeQueue.advance();
742  renameQueue.advance();
743  iewQueue.advance();
744  }
745 
746  // at this step, all instructions in the pipeline should be already
747  // either committed successfully or squashed. All thread-specific
748  // queues in the pipeline must be empty.
749  assert(iew.instQueue.getCount(tid) == 0);
750  assert(iew.ldstQueue.getCount(tid) == 0);
751  assert(commit.rob->isEmpty(tid));
752 
753  // Reset ROB/IQ/LSQ Entries
754 
755  // Commented out for now. This should be possible to do by
756  // telling all the pipeline stages to drain first, and then
757  // checking until the drain completes. Once the pipeline is
758  // drained, call resetEntries(). - 10-09-06 ktlim
759 /*
760  if (activeThreads.size() >= 1) {
761  commit.rob->resetEntries();
762  iew.resetEntries();
763  }
764 */
765 }
766 
767 Fault
769 {
770  // Check if there are any outstanding interrupts
771  return interrupts[0]->getInterrupt();
772 }
773 
774 void
775 CPU::processInterrupts(const Fault &interrupt)
776 {
777  // Check for interrupts here. For now can copy the code that
778  // exists within isa_fullsys_traits.hh. Also assume that thread 0
779  // is the one that handles the interrupts.
780  // @todo: Possibly consolidate the interrupt checking code.
781  // @todo: Allow other threads to handle interrupts.
782 
783  assert(interrupt != NoFault);
784  interrupts[0]->updateIntrInfo();
785 
786  DPRINTF(O3CPU, "Interrupt %s being handled\n", interrupt->name());
787  trap(interrupt, 0, nullptr);
788 }
789 
790 void
791 CPU::trap(const Fault &fault, ThreadID tid, const StaticInstPtr &inst)
792 {
793  // Pass the thread's TC into the invoke method.
794  fault->invoke(threadContexts[tid], inst);
795 }
796 
797 void
799 {
800  thread[tid]->serialize(cp);
801 }
802 
803 void
805 {
806  thread[tid]->unserialize(cp);
807 }
808 
811 {
812  // Deschedule any power gating event (if any)
814 
815  // If the CPU isn't doing anything, then return immediately.
816  if (switchedOut())
817  return DrainState::Drained;
818 
819  DPRINTF(Drain, "Draining...\n");
820 
821  // We only need to signal a drain to the commit stage as this
822  // initiates squashing controls the draining. Once the commit
823  // stage commits an instruction where it is safe to stop, it'll
824  // squash the rest of the instructions in the pipeline and force
825  // the fetch stage to stall. The pipeline will be drained once all
826  // in-flight instructions have retired.
827  commit.drain();
828 
829  // Wake the CPU and record activity so everything can drain out if
830  // the CPU was not able to immediately drain.
831  if (!isCpuDrained()) {
832  // If a thread is suspended, wake it up so it can be drained
833  for (auto t : threadContexts) {
834  if (t->status() == gem5::ThreadContext::Suspended){
835  DPRINTF(Drain, "Currently suspended so activate %i \n",
836  t->threadId());
837  t->activate();
838  // As the thread is now active, change the power state as well
839  activateContext(t->threadId());
840  }
841  }
842 
843  wakeCPU();
845 
846  DPRINTF(Drain, "CPU not drained\n");
847 
848  return DrainState::Draining;
849  } else {
850  DPRINTF(Drain, "CPU is already drained\n");
851  if (tickEvent.scheduled())
853 
854  // Flush out any old data from the time buffers. In
855  // particular, there might be some data in flight from the
856  // fetch stage that isn't visible in any of the CPU buffers we
857  // test in isCpuDrained().
858  for (int i = 0; i < timeBuffer.getSize(); ++i) {
859  timeBuffer.advance();
860  fetchQueue.advance();
861  decodeQueue.advance();
862  renameQueue.advance();
863  iewQueue.advance();
864  }
865 
867  return DrainState::Drained;
868  }
869 }
870 
871 bool
873 {
875  return false;
876 
877  if (tickEvent.scheduled())
879 
880  DPRINTF(Drain, "CPU done draining, processing drain event\n");
881  signalDrainDone();
882 
883  return true;
884 }
885 
886 void
888 {
889  assert(isCpuDrained());
895 }
896 
897 bool
899 {
900  bool drained(true);
901 
902  if (!instList.empty() || !removeList.empty()) {
903  DPRINTF(Drain, "Main CPU structures not drained.\n");
904  drained = false;
905  }
906 
907  if (!fetch.isDrained()) {
908  DPRINTF(Drain, "Fetch not drained.\n");
909  drained = false;
910  }
911 
912  if (!decode.isDrained()) {
913  DPRINTF(Drain, "Decode not drained.\n");
914  drained = false;
915  }
916 
917  if (!rename.isDrained()) {
918  DPRINTF(Drain, "Rename not drained.\n");
919  drained = false;
920  }
921 
922  if (!iew.isDrained()) {
923  DPRINTF(Drain, "IEW not drained.\n");
924  drained = false;
925  }
926 
927  if (!commit.isDrained()) {
928  DPRINTF(Drain, "Commit not drained.\n");
929  drained = false;
930  }
931 
932  return drained;
933 }
934 
936 
937 void
939 {
940  if (switchedOut())
941  return;
942 
943  DPRINTF(Drain, "Resuming...\n");
945 
946  fetch.drainResume();
948 
949  _status = Idle;
950  for (ThreadID i = 0; i < thread.size(); i++) {
952  DPRINTF(Drain, "Activating thread: %i\n", i);
953  activateThread(i);
954  _status = Running;
955  }
956  }
957 
958  assert(!tickEvent.scheduled());
959  if (_status == Running)
961 
962  // Reschedule any power gating event (if any)
964 }
965 
966 void
968 {
969  DPRINTF(O3CPU, "Switching out\n");
971 
972  activityRec.reset();
973 
975 
976  if (checker)
977  checker->switchOut();
978 }
979 
980 void
982 {
983  BaseCPU::takeOverFrom(oldCPU);
984 
988  iew.takeOverFrom();
990 
991  assert(!tickEvent.scheduled());
992 
993  auto *oldO3CPU = dynamic_cast<CPU *>(oldCPU);
994  if (oldO3CPU)
995  globalSeqNum = oldO3CPU->globalSeqNum;
996 
998  _status = Idle;
999 }
1000 
1001 void
1003 {
1004  if (!system->isTimingMode()) {
1005  fatal("The O3 CPU requires the memory system to be in "
1006  "'timing' mode.\n");
1007  }
1008 }
1009 
1010 RegVal
1011 CPU::readMiscRegNoEffect(int misc_reg, ThreadID tid) const
1012 {
1013  return isa[tid]->readMiscRegNoEffect(misc_reg);
1014 }
1015 
1016 RegVal
1017 CPU::readMiscReg(int misc_reg, ThreadID tid)
1018 {
1020  return isa[tid]->readMiscReg(misc_reg);
1021 }
1022 
1023 void
1025 {
1026  isa[tid]->setMiscRegNoEffect(misc_reg, val);
1027 }
1028 
1029 void
1030 CPU::setMiscReg(int misc_reg, RegVal val, ThreadID tid)
1031 {
1033  isa[tid]->setMiscReg(misc_reg, val);
1034 }
1035 
1036 RegVal
1038 {
1039  switch (phys_reg->classValue()) {
1040  case IntRegClass:
1042  break;
1043  case FloatRegClass:
1045  break;
1046  case CCRegClass:
1048  break;
1049  case VecRegClass:
1050  case VecElemClass:
1052  break;
1053  case VecPredRegClass:
1055  break;
1056  default:
1057  break;
1058  }
1059  return regFile.getReg(phys_reg);
1060 }
1061 
1062 void
1063 CPU::getReg(PhysRegIdPtr phys_reg, void *val)
1064 {
1065  switch (phys_reg->classValue()) {
1066  case IntRegClass:
1068  break;
1069  case FloatRegClass:
1071  break;
1072  case CCRegClass:
1074  break;
1075  case VecRegClass:
1076  case VecElemClass:
1078  break;
1079  case VecPredRegClass:
1081  break;
1082  default:
1083  break;
1084  }
1085  regFile.getReg(phys_reg, val);
1086 }
1087 
1088 void *
1090 {
1091  switch (phys_reg->classValue()) {
1092  case VecRegClass:
1094  break;
1095  case VecPredRegClass:
1097  break;
1098  default:
1099  break;
1100  }
1101  return regFile.getWritableReg(phys_reg);
1102 }
1103 
1104 void
1106 {
1107  switch (phys_reg->classValue()) {
1108  case IntRegClass:
1110  break;
1111  case FloatRegClass:
1113  break;
1114  case CCRegClass:
1116  break;
1117  case VecRegClass:
1118  case VecElemClass:
1120  break;
1121  case VecPredRegClass:
1123  break;
1124  default:
1125  break;
1126  }
1127  regFile.setReg(phys_reg, val);
1128 }
1129 
1130 void
1131 CPU::setReg(PhysRegIdPtr phys_reg, const void *val)
1132 {
1133  switch (phys_reg->classValue()) {
1134  case IntRegClass:
1136  break;
1137  case FloatRegClass:
1139  break;
1140  case CCRegClass:
1142  break;
1143  case VecRegClass:
1144  case VecElemClass:
1146  break;
1147  case VecPredRegClass:
1149  break;
1150  default:
1151  break;
1152  }
1153  regFile.setReg(phys_reg, val);
1154 }
1155 
1156 RegVal
1158 {
1159  const RegId flat = reg.flatten(*isa[tid]);
1160  PhysRegIdPtr phys_reg = commitRenameMap[tid].lookup(flat);
1161  return regFile.getReg(phys_reg);
1162 }
1163 
1164 void
1165 CPU::getArchReg(const RegId &reg, void *val, ThreadID tid)
1166 {
1167  const RegId flat = reg.flatten(*isa[tid]);
1168  PhysRegIdPtr phys_reg = commitRenameMap[tid].lookup(flat);
1169  regFile.getReg(phys_reg, val);
1170 }
1171 
1172 void *
1174 {
1175  const RegId flat = reg.flatten(*isa[tid]);
1176  PhysRegIdPtr phys_reg = commitRenameMap[tid].lookup(flat);
1177  return regFile.getWritableReg(phys_reg);
1178 }
1179 
1180 void
1182 {
1183  const RegId flat = reg.flatten(*isa[tid]);
1184  PhysRegIdPtr phys_reg = commitRenameMap[tid].lookup(flat);
1185  regFile.setReg(phys_reg, val);
1186 }
1187 
1188 void
1189 CPU::setArchReg(const RegId &reg, const void *val, ThreadID tid)
1190 {
1191  const RegId flat = reg.flatten(*isa[tid]);
1192  PhysRegIdPtr phys_reg = commitRenameMap[tid].lookup(flat);
1193  regFile.setReg(phys_reg, val);
1194 }
1195 
1196 const PCStateBase &
1198 {
1199  return commit.pcState(tid);
1200 }
1201 
1202 void
1204 {
1205  commit.pcState(val, tid);
1206 }
1207 
1208 void
1210 {
1211  thread[tid]->noSquashFromTC = true;
1212  commit.generateTCEvent(tid);
1213 }
1214 
1217 {
1218  instList.push_back(inst);
1219 
1220  return --(instList.end());
1221 }
1222 
1223 void
1225 {
1226  // Keep an instruction count.
1227  if (!inst->isMicroop() || inst->isLastMicroop()) {
1228  thread[tid]->numInst++;
1229  thread[tid]->threadStats.numInsts++;
1230  cpuStats.committedInsts[tid]++;
1231 
1232  // Check for instruction-count-based events.
1233  thread[tid]->comInstEventQueue.serviceEvents(thread[tid]->numInst);
1234  }
1235  thread[tid]->numOp++;
1236  thread[tid]->threadStats.numOps++;
1237  cpuStats.committedOps[tid]++;
1238 
1239  probeInstCommit(inst->staticInst, inst->pcState().instAddr());
1240 }
1241 
1242 void
1244 {
1245  DPRINTF(O3CPU, "Removing committed instruction [tid:%i] PC %s "
1246  "[sn:%lli]\n",
1247  inst->threadNumber, inst->pcState(), inst->seqNum);
1248 
1249  removeInstsThisCycle = true;
1250 
1251  // Remove the front instruction.
1252  removeList.push(inst->getInstListIt());
1253 }
1254 
1255 void
1257 {
1258  DPRINTF(O3CPU, "Thread %i: Deleting instructions from instruction"
1259  " list.\n", tid);
1260 
1261  ListIt end_it;
1262 
1263  bool rob_empty = false;
1264 
1265  if (instList.empty()) {
1266  return;
1267  } else if (rob.isEmpty(tid)) {
1268  DPRINTF(O3CPU, "ROB is empty, squashing all insts.\n");
1269  end_it = instList.begin();
1270  rob_empty = true;
1271  } else {
1272  end_it = (rob.readTailInst(tid))->getInstListIt();
1273  DPRINTF(O3CPU, "ROB is not empty, squashing insts not in ROB.\n");
1274  }
1275 
1276  removeInstsThisCycle = true;
1277 
1278  ListIt inst_it = instList.end();
1279 
1280  inst_it--;
1281 
1282  // Walk through the instruction list, removing any instructions
1283  // that were inserted after the given instruction iterator, end_it.
1284  while (inst_it != end_it) {
1285  assert(!instList.empty());
1286 
1287  squashInstIt(inst_it, tid);
1288 
1289  inst_it--;
1290  }
1291 
1292  // If the ROB was empty, then we actually need to remove the first
1293  // instruction as well.
1294  if (rob_empty) {
1295  squashInstIt(inst_it, tid);
1296  }
1297 }
1298 
1299 void
1301 {
1302  assert(!instList.empty());
1303 
1304  removeInstsThisCycle = true;
1305 
1306  ListIt inst_iter = instList.end();
1307 
1308  inst_iter--;
1309 
1310  DPRINTF(O3CPU, "Deleting instructions from instruction "
1311  "list that are from [tid:%i] and above [sn:%lli] (end=%lli).\n",
1312  tid, seq_num, (*inst_iter)->seqNum);
1313 
1314  while ((*inst_iter)->seqNum > seq_num) {
1315 
1316  bool break_loop = (inst_iter == instList.begin());
1317 
1318  squashInstIt(inst_iter, tid);
1319 
1320  inst_iter--;
1321 
1322  if (break_loop)
1323  break;
1324  }
1325 }
1326 
1327 void
1328 CPU::squashInstIt(const ListIt &instIt, ThreadID tid)
1329 {
1330  if ((*instIt)->threadNumber == tid) {
1331  DPRINTF(O3CPU, "Squashing instruction, "
1332  "[tid:%i] [sn:%lli] PC %s\n",
1333  (*instIt)->threadNumber,
1334  (*instIt)->seqNum,
1335  (*instIt)->pcState());
1336 
1337  // Mark it as squashed.
1338  (*instIt)->setSquashed();
1339 
1340  // @todo: Formulate a consistent method for deleting
1341  // instructions from the instruction list
1342  // Remove the instruction from the list.
1343  removeList.push(instIt);
1344  }
1345 }
1346 
1347 void
1349 {
1350  while (!removeList.empty()) {
1351  DPRINTF(O3CPU, "Removing instruction, "
1352  "[tid:%i] [sn:%lli] PC %s\n",
1353  (*removeList.front())->threadNumber,
1354  (*removeList.front())->seqNum,
1355  (*removeList.front())->pcState());
1356 
1357  instList.erase(removeList.front());
1358 
1359  removeList.pop();
1360  }
1361 
1362  removeInstsThisCycle = false;
1363 }
1364 /*
1365 void
1366 CPU::removeAllInsts()
1367 {
1368  instList.clear();
1369 }
1370 */
1371 void
1373 {
1374  int num = 0;
1375 
1376  ListIt inst_list_it = instList.begin();
1377 
1378  cprintf("Dumping Instruction List\n");
1379 
1380  while (inst_list_it != instList.end()) {
1381  cprintf("Instruction:%i\nPC:%#x\n[tid:%i]\n[sn:%lli]\nIssued:%i\n"
1382  "Squashed:%i\n\n",
1383  num, (*inst_list_it)->pcState().instAddr(),
1384  (*inst_list_it)->threadNumber,
1385  (*inst_list_it)->seqNum, (*inst_list_it)->isIssued(),
1386  (*inst_list_it)->isSquashed());
1387  inst_list_it++;
1388  ++num;
1389  }
1390 }
1391 /*
1392 void
1393 CPU::wakeDependents(const DynInstPtr &inst)
1394 {
1395  iew.wakeDependents(inst);
1396 }
1397 */
1398 void
1400 {
1401  if (activityRec.active() || tickEvent.scheduled()) {
1402  DPRINTF(Activity, "CPU already running.\n");
1403  return;
1404  }
1405 
1406  DPRINTF(Activity, "Waking up CPU\n");
1407 
1408  Cycles cycles(curCycle() - lastRunningCycle);
1409  // @todo: This is an oddity that is only here to match the stats
1410  if (cycles > 1) {
1411  --cycles;
1412  cpuStats.idleCycles += cycles;
1413  baseStats.numCycles += cycles;
1414  }
1415 
1417 }
1418 
1419 void
1421 {
1423  return;
1424 
1425  wakeCPU();
1426 
1427  DPRINTF(Quiesce, "Suspended Processor woken\n");
1428  threadContexts[tid]->activate();
1429 }
1430 
1431 ThreadID
1433 {
1434  for (ThreadID tid = 0; tid < numThreads; tid++) {
1435  if (!tids[tid]) {
1436  tids[tid] = true;
1437  return tid;
1438  }
1439  }
1440 
1441  return InvalidThreadID;
1442 }
1443 
1444 void
1446 {
1447  if (activeThreads.size() > 1) {
1448  //DEFAULT TO ROUND ROBIN SCHEME
1449  //e.g. Move highest priority to end of thread list
1450  std::list<ThreadID>::iterator list_begin = activeThreads.begin();
1451 
1452  unsigned high_thread = *list_begin;
1453 
1454  activeThreads.erase(list_begin);
1455 
1456  activeThreads.push_back(high_thread);
1457  }
1458 }
1459 
1460 void
1462 {
1463  DPRINTF(O3CPU, "Thread %d is inserted to exitingThreads list\n", tid);
1464 
1465  // the thread trying to exit can't be already halted
1466  assert(tcBase(tid)->status() != gem5::ThreadContext::Halted);
1467 
1468  // make sure the thread has not been added to the list yet
1469  assert(exitingThreads.count(tid) == 0);
1470 
1471  // add the thread to exitingThreads list to mark that this thread is
1472  // trying to exit. The boolean value in the pair denotes if a thread is
1473  // ready to exit. The thread is not ready to exit until the corresponding
1474  // exit trap event is processed in the future. Until then, it'll be still
1475  // an active thread that is trying to exit.
1476  exitingThreads.emplace(std::make_pair(tid, false));
1477 }
1478 
1479 bool
1481 {
1482  return exitingThreads.count(tid) == 1;
1483 }
1484 
1485 void
1487 {
1488  assert(exitingThreads.count(tid) == 1);
1489 
1490  // exit trap event has been processed. Now, the thread is ready to exit
1491  // and be removed from the CPU.
1492  exitingThreads[tid] = true;
1493 
1494  // we schedule a threadExitEvent in the next cycle to properly clean
1495  // up the thread's states in the pipeline. threadExitEvent has lower
1496  // priority than tickEvent, so the cleanup will happen at the very end
1497  // of the next cycle after all pipeline stages complete their operations.
1498  // We want all stages to complete squashing instructions before doing
1499  // the cleanup.
1500  if (!threadExitEvent.scheduled()) {
1502  }
1503 }
1504 
1505 void
1507 {
1508  // there must be at least one thread trying to exit
1509  assert(exitingThreads.size() > 0);
1510 
1511  // terminate all threads that are ready to exit
1512  auto it = exitingThreads.begin();
1513  while (it != exitingThreads.end()) {
1514  ThreadID thread_id = it->first;
1515  bool readyToExit = it->second;
1516 
1517  if (readyToExit) {
1518  DPRINTF(O3CPU, "Exiting thread %d\n", thread_id);
1519  haltContext(thread_id);
1521  it = exitingThreads.erase(it);
1522  } else {
1523  it++;
1524  }
1525  }
1526 }
1527 
1528 void
1529 CPU::htmSendAbortSignal(ThreadID tid, uint64_t htm_uid,
1530  HtmFailureFaultCause cause)
1531 {
1532  const Addr addr = 0x0ul;
1533  const int size = 8;
1534  const Request::Flags flags =
1536 
1537  // O3-specific actions
1540 
1541  // notify l1 d-cache (ruby) that core has aborted transaction
1542  RequestPtr req =
1543  std::make_shared<Request>(addr, size, flags, _dataRequestorId);
1544 
1545  req->taskId(taskId());
1546  req->setContext(thread[tid]->contextId());
1547  req->setHtmAbortCause(cause);
1548 
1549  assert(req->isHTMAbort());
1550 
1551  PacketPtr abort_pkt = Packet::createRead(req);
1552  uint8_t *memData = new uint8_t[8];
1553  assert(memData);
1554  abort_pkt->dataStatic(memData);
1555  abort_pkt->setHtmTransactional(htm_uid);
1556 
1557  // TODO include correct error handling here
1558  if (!iew.ldstQueue.getDataPort().sendTimingReq(abort_pkt)) {
1559  panic("HTM abort signal was not sent to the memory subsystem.");
1560  }
1561 }
1562 
1563 } // namespace o3
1564 } // namespace gem5
#define DPRINTF(x,...)
Definition: trace.hh:186
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:273
void updateCycleCounters(CPUState state)
base method keeping track of cycle progression
Definition: base.hh:544
void schedulePowerGatingEvent()
Definition: base.cc:452
@ CPU_STATE_ON
Definition: base.hh:534
@ CPU_STATE_SLEEP
Definition: base.hh:535
void regProbePoints() override
Register probe points for this object.
Definition: base.cc:337
uint32_t taskId() const
Get cpu task id.
Definition: base.hh:207
virtual void suspendContext(ThreadID thread_num)
Notify the CPU that the indicated context is now suspended.
Definition: base.cc:494
gem5::BaseCPU::BaseCPUStats baseStats
ThreadID numThreads
Number of threads we're actually simulating (<= SMT_MAX_THREADS).
Definition: base.hh:367
void deschedulePowerGatingEvent()
Definition: base.cc:444
std::vector< BaseInterrupts * > interrupts
Definition: base.hh:220
void startup() override
startup() is the final initialization call before simulation.
Definition: base.cc:312
virtual void switchOut()
Prepare for another CPU to take over execution.
Definition: base.cc:532
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:546
std::vector< ThreadContext * > threadContexts
Definition: base.hh:256
bool switchedOut() const
Determine if the CPU is switched out.
Definition: base.hh:356
virtual void probeInstCommit(const StaticInstPtr &inst, Addr pc)
Helper method to trigger PMU probes for a committed instruction.
Definition: base.cc:353
RequestorID _dataRequestorId
data side request id that must be placed in all requests
Definition: base.hh:127
virtual void activateContext(ThreadID thread_num)
Notify the CPU that the indicated context is now active.
Definition: base.cc:480
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:294
void dataStatic(T *p)
Set the data pointer to the following value that should not be freed.
Definition: packet.hh:1162
static PacketPtr createRead(const RequestPtr &req)
Constructor-like methods that return Packets based on Request objects.
Definition: packet.hh:1035
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:392
constexpr RegClassType classValue() const
Definition: reg_class.hh:272
ProbePointArg generates a point for the class of Arg.
Definition: probe.hh:264
Register ID: describe an architectural register with its class and index.
Definition: reg_class.hh:91
bool sendTimingReq(PacketPtr pkt)
Attempt to send a timing request to the responder port by calling its corresponding receive function.
Definition: port.hh:495
@ 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:273
Threads threads
Definition: system.hh:313
ThreadContext is the external interface to all thread state for anything outside of the CPU.
virtual void setStatus(Status new_status)=0
virtual const PCStateBase & pcState() const =0
@ Halted
Permanently shut down.
@ Suspended
Temporarily inactive.
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:1224
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:1372
void drainSanityCheck() const
Perform sanity checks after a drain.
Definition: cpu.cc:887
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:1529
std::list< DynInstPtr > instList
List of all the instructions in flight.
Definition: cpu.hh:381
ListIt addInst(const DynInstPtr &inst)
Function to add instruction onto the head of the list of the instructions.
Definition: cpu.cc:1216
void setArchReg(const RegId &reg, RegVal val, ThreadID tid)
Definition: cpu.cc:1181
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:656
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:798
void startup() override
startup() is the final initialization call before simulation.
Definition: cpu.cc:522
void drainResume() override
Resumes execution after a drain.
Definition: cpu.cc:938
RegVal getReg(PhysRegIdPtr phys_reg)
Definition: cpu.cc:1037
Rename rename
The dispatch stage.
Definition: cpu.hh:408
void regProbePoints() override
Register probe points.
Definition: cpu.cc:302
void deactivateThread(ThreadID tid)
Remove Thread from Active Threads List.
Definition: cpu.cc:550
Counter totalInsts() const override
Count the Total Instructions Committed in the CPU.
Definition: cpu.cc:574
void trap(const Fault &fault, ThreadID tid, const StaticInstPtr &inst)
Traps to handle given fault.
Definition: cpu.cc:791
CPU(const BaseO3CPUParams &params)
Constructs a CPU with the given parameters.
Definition: cpu.cc:72
ProbePointArg< PacketPtr > * ppInstAccessComplete
Definition: cpu.hh:173
void * getWritableReg(PhysRegIdPtr phys_reg)
Definition: cpu.cc:1089
void exitThreads()
Terminate all threads that are ready to exit.
Definition: cpu.cc:1506
ThreadID getFreeTid()
Gets a free thread id.
Definition: cpu.cc:1432
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:446
void removeThread(ThreadID tid)
Remove all of a thread's context from CPU.
Definition: cpu.cc:716
void commitDrained(ThreadID tid)
Commit has reached a safe point to drain a thread.
Definition: cpu.cc:935
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:598
virtual void wakeup(ThreadID tid) override
Definition: cpu.cc:1420
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:1030
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:1024
void removeInstsUntil(const InstSeqNum &seq_num, ThreadID tid)
Remove all instructions younger than the given sequence number.
Definition: cpu.cc:1300
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:1348
@ SwitchedOut
Definition: cpu.hh:107
void setReg(PhysRegIdPtr phys_reg, RegVal val)
Definition: cpu.cc:1105
Commit commit
The commit stage.
Definition: cpu.hh:414
void suspendContext(ThreadID tid) override
Remove Thread from Active Threads List.
Definition: cpu.cc:636
void unserializeThread(CheckpointIn &cp, ThreadID tid) override
Unserialize one thread.
Definition: cpu.cc:804
void removeInstsNotInROB(ThreadID tid)
Remove all instructions that are not currently in the ROB.
Definition: cpu.cc:1256
void takeOverFrom(BaseCPU *oldCPU) override
Takes over from another CPU.
Definition: cpu.cc:981
void switchOut() override
Switches out this CPU.
Definition: cpu.cc:967
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:872
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:775
void squashFromTC(ThreadID tid)
Initiates a squash of all in-flight instructions for a given thread.
Definition: cpu.cc:1209
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:1328
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:1002
gem5::ThreadContext * tcBase(ThreadID tid)
Returns a pointer to a thread context.
Definition: cpu.hh:512
RegVal getArchReg(const RegId &reg, ThreadID tid)
Architectural register accessors.
Definition: cpu.cc:1157
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:810
std::list< ThreadID > activeThreads
Active Threads List.
Definition: cpu.hh:432
Fault getInterrupts()
Returns the Fault for any valid interrupt.
Definition: cpu.cc:768
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:1011
bool isCpuDrained() const
Check if a system is in a drained state.
Definition: cpu.cc:898
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:1461
void pcState(const PCStateBase &new_pc_state, ThreadID tid)
Sets the commit PC state of a specific thread.
Definition: cpu.cc:1203
void scheduleThreadExitEvent(ThreadID tid)
If a thread is trying to exit and its corresponding trap event has been completed,...
Definition: cpu.cc:1486
void updateThreadPriority()
Update The Order In Which We Process Threads.
Definition: cpu.cc:1445
bool isThreadExiting(ThreadID tid) const
Is the thread trying to exit?
Definition: cpu.cc:1480
void removeFrontInst(const DynInstPtr &inst)
Remove an instruction from the front end of the list.
Definition: cpu.cc:1243
void * getWritableArchReg(const RegId &reg, ThreadID tid)
Definition: cpu.cc:1173
RegVal readMiscReg(int misc_reg, ThreadID tid)
Reads a misc.
Definition: cpu.cc:1017
void init() override
Initialize the CPU.
Definition: cpu.cc:504
void activateThread(ThreadID tid)
Add Thread to Active Threads List.
Definition: cpu.cc:534
Scoreboard scoreboard
Integer Register Scoreboard.
Definition: cpu.hh:442
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:586
void wakeCPU()
Wakes the CPU, rescheduling the CPU if it's not already active.
Definition: cpu.cc:1399
void insertThread(ThreadID tid)
Setup CPU to insert a thread's context.
Definition: cpu.cc:678
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:313
bool executingHtmTransaction(ThreadID) const
Is the CPU currently processing a HTM transaction?
Definition: commit.cc:425
ROB * rob
ROB interface.
Definition: commit.hh:342
void deactivateThread(ThreadID tid)
Deschedules a thread from scheduling.
Definition: commit.cc:414
void tick()
Ticks the commit stage, which tries to commit instructions.
Definition: commit.cc:628
void resetHtmStartsStops(ThreadID)
Definition: commit.cc:434
void drainSanityCheck() const
Perform sanity checks after a drain.
Definition: commit.cc:357
void takeOverFrom()
Takes over from another CPU's thread.
Definition: commit.cc:399
void clearStates(ThreadID tid)
Clear all thread-specific states.
Definition: commit.cc:333
void drainResume()
Resumes execution after draining.
Definition: commit.cc:350
const PCStateBase & pcState(ThreadID tid)
Reads the PC of a specific thread.
Definition: commit.hh:309
void drain()
Initializes the draining of commit.
Definition: commit.cc:347
void generateTCEvent(ThreadID tid)
Records that commit needs to initiate a squash due to an external state update through the TC.
Definition: commit.cc:523
void regProbePoints()
Registers probes.
Definition: commit.cc:138
void setThreads(std::vector< ThreadState * > &threads)
Sets the list of threads.
Definition: commit.cc:247
bool isDrained() const
Has the stage drained?
Definition: commit.cc:372
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:499
void takeOverFrom()
Takes over from another CPU's thread.
Definition: fetch.cc:449
void startupStage()
Initialize stage.
Definition: fetch.cc:286
void wakeFromQuiesce()
Tells fetch to wake up from a quiesce instruction.
Definition: fetch.cc:466
void drainSanityCheck() const
Perform sanity checks after a drain.
Definition: fetch.cc:402
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:457
void drainResume()
Resume after a drain.
Definition: fetch.cc:393
void clearStates(ThreadID tid)
Clear all thread-specific states.
Definition: fetch.cc:297
bool isDrained() const
Has the stage drained?
Definition: fetch.cc:419
void tick()
Ticks the fetch stage, processing all inputs signals and fetching as many instructions as possible.
Definition: fetch.cc:838
void takeOverFrom()
Takes over from another CPU's thread.
Definition: iew.cc:391
void clearStates(ThreadID tid)
Clear all thread-specific states.
Definition: iew.cc:292
void startupStage()
Initializes stage; sends back the number of free IQ and LSQ entries.
Definition: iew.cc:269
void drainSanityCheck() const
Perform sanity checks after a drain.
Definition: iew.cc:382
bool isDrained() const
Has the stage drained?
Definition: iew.cc:354
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:1431
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.
Definition: inst_queue.hh:275
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:163
void * getWritableReg(PhysRegIdPtr phys_reg)
Definition: regfile.hh:230
void setReg(PhysRegIdPtr phys_reg, RegVal val)
Definition: regfile.hh:246
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:221
void tick()
Ticks rename, which processes all input signals and attempts to rename as many instructions as possib...
Definition: rename.cc:389
void drainSanityCheck() const
Perform sanity checks after a drain.
Definition: rename.cc:325
void takeOverFrom()
Takes over from another CPU's thread.
Definition: rename.cc:319
void regProbePoints()
Registers probes.
Definition: rename.cc:179
bool isDrained() const
Has the stage drained?
Definition: rename.cc:305
void clearStates(ThreadID tid)
Clear all thread-specific states.
Definition: rename.cc:227
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.
Definition: rename_map.hh:247
PhysRegIdPtr lookup(const RegId &arch_reg) const
Look up the physical register mapped to an architectural register.
Definition: rename_map.hh:225
Derived & flags(Flags _flags)
Set the flags and marks this stat to print at the end of simulation.
Definition: statistics.hh:358
Derived & prereq(const Stat &prereq)
Set the prerequisite stat and marks this stat to print at the end of simulation.
Definition: statistics.hh:372
Derived & precision(int _precision)
Set the precision and marks this stat to print at the end of simulation.
Definition: statistics.hh:346
Statistics container.
Definition: group.hh:94
Derived & init(size_type size)
Set this vector to have the given size.
Definition: statistics.hh:1040
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:1028
bool scheduled() const
Determine if the current event is scheduled.
Definition: eventq.hh:465
void schedule(Event &event, Tick when)
Definition: eventq.hh:1019
static const Priority CPU_Tick_Pri
CPU ticks must come after other associated CPU events (such as writebacks).
Definition: eventq.hh:204
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:211
#define panic(...)
This implements a cprintf based panic() function.
Definition: logging.hh:178
#define fatal_if(cond,...)
Conditional fatal macro that checks the supplied condition and only causes a fatal error if the condi...
Definition: logging.hh:226
#define fatal(...)
This implements a cprintf based fatal() function.
Definition: logging.hh:190
ProbeManager * getProbeManager()
Get the probe manager for this object.
Definition: sim_object.cc:120
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:273
Bitfield< 7 > i
Definition: misc_types.hh:67
Bitfield< 5, 0 > status
Definition: misc_types.hh:429
Bitfield< 18 > sum
Definition: misc.hh:560
Bitfield< 51 > t
Definition: pagetable.hh:56
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
void quiesceCycles(ThreadContext *tc, uint64_t cycles)
Definition: pseudo_inst.cc:139
const FlagsType total
Print the total.
Definition: info.hh:60
double Counter
All counters are of 64-bit values.
Definition: types.hh:47
Reference material can be found at the JEDEC website: UFS standard http://www.jedec....
std::shared_ptr< FaultBase > Fault
Definition: types.hh:248
int16_t ThreadID
Thread index/ID type.
Definition: types.hh:235
std::shared_ptr< Request > RequestPtr
Definition: request.hh:92
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
@ FloatRegClass
Floating-point register.
Definition: reg_class.hh:61
@ CCRegClass
Condition-code register.
Definition: reg_class.hh:67
@ 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:487
statistics::Scalar numCycles
Definition: base.hh:620
statistics::Scalar timesIdled
Stat for total number of times the CPU is descheduled.
Definition: cpu.hh:578
statistics::Scalar ccRegfileReads
Definition: cpu.hh:611
statistics::Scalar ccRegfileWrites
Definition: cpu.hh:612
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 intRegfileReads
Definition: cpu.hh:599
statistics::Scalar vecRegfileWrites
Definition: cpu.hh:606
statistics::Formula ipc
Stat for the IPC per thread.
Definition: cpu.hh:594
statistics::Scalar miscRegfileReads
Definition: cpu.hh:614
statistics::Scalar fpRegfileWrites
Definition: cpu.hh:603
statistics::Scalar vecPredRegfileWrites
Definition: cpu.hh:609
statistics::Formula totalCpi
Stat for the total CPI.
Definition: cpu.hh:592
statistics::Scalar vecPredRegfileReads
Definition: cpu.hh:608
statistics::Scalar vecRegfileReads
Definition: cpu.hh:605
statistics::Vector committedInsts
Stat for the number of committed instructions per thread.
Definition: cpu.hh:585
statistics::Scalar fpRegfileReads
Definition: cpu.hh:602
statistics::Scalar idleCycles
Stat for total number of cycles the CPU spends descheduled.
Definition: cpu.hh:580
statistics::Formula cpi
Stat for the CPI per thread.
Definition: cpu.hh:590
statistics::Scalar intRegfileWrites
Definition: cpu.hh:600
statistics::Scalar miscRegfileWrites
Definition: cpu.hh:615
statistics::Formula totalIpc
Stat for the total IPC.
Definition: cpu.hh:596
CPUStats(CPU *cpu)
Definition: cpu.cc:318
statistics::Vector committedOps
Stat for the number of committed ops (including micro ops) per thread.
Definition: cpu.hh:588
const std::string & name()
Definition: trace.cc:49

Generated on Wed Dec 21 2022 10:22:24 for gem5 by doxygen 1.9.1