gem5  v20.0.0.3
cpu.cc
Go to the documentation of this file.
1 /*
2  * Copyright (c) 2011-2012, 2014, 2016, 2017, 2019 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 "arch/generic/traits.hh"
46 #include "arch/kernel_stats.hh"
47 #include "config/the_isa.hh"
48 #include "cpu/activity.hh"
49 #include "cpu/checker/cpu.hh"
51 #include "cpu/o3/isa_specific.hh"
52 #include "cpu/o3/thread_context.hh"
53 #include "cpu/quiesce_event.hh"
54 #include "cpu/simple_thread.hh"
55 #include "cpu/thread_context.hh"
56 #include "debug/Activity.hh"
57 #include "debug/Drain.hh"
58 #include "debug/O3CPU.hh"
59 #include "debug/Quiesce.hh"
60 #include "enums/MemoryMode.hh"
61 #include "sim/core.hh"
62 #include "sim/full_system.hh"
63 #include "sim/process.hh"
64 #include "sim/stat_control.hh"
65 #include "sim/system.hh"
66 
67 struct BaseCPUParams;
68 
69 using namespace TheISA;
70 using namespace std;
71 
72 BaseO3CPU::BaseO3CPU(BaseCPUParams *params)
73  : BaseCPU(params)
74 {
75 }
76 
77 void
79 {
81 }
82 
83 template <class Impl>
85  : BaseO3CPU(params),
86  itb(params->itb),
87  dtb(params->dtb),
88  tickEvent([this]{ tick(); }, "FullO3CPU tick",
89  false, Event::CPU_Tick_Pri),
90  threadExitEvent([this]{ exitThreads(); }, "FullO3CPU exit threads",
91  false, Event::CPU_Exit_Pri),
92 #ifndef NDEBUG
93  instcount(0),
94 #endif
95  removeInstsThisCycle(false),
96  fetch(this, params),
97  decode(this, params),
98  rename(this, params),
99  iew(this, params),
100  commit(this, params),
101 
102  /* It is mandatory that all SMT threads use the same renaming mode as
103  * they are sharing registers and rename */
105  regFile(params->numPhysIntRegs,
106  params->numPhysFloatRegs,
107  params->numPhysVecRegs,
108  params->numPhysVecPredRegs,
109  params->numPhysCCRegs,
110  vecMode),
111 
112  freeList(name() + ".freelist", &regFile),
113 
114  rob(this, params),
115 
116  scoreboard(name() + ".scoreboard",
118 
119  isa(numThreads, NULL),
120 
121  timeBuffer(params->backComSize, params->forwardComSize),
122  fetchQueue(params->backComSize, params->forwardComSize),
123  decodeQueue(params->backComSize, params->forwardComSize),
124  renameQueue(params->backComSize, params->forwardComSize),
125  iewQueue(params->backComSize, params->forwardComSize),
127  params->backComSize + params->forwardComSize,
128  params->activity),
129 
130  globalSeqNum(1),
131  system(params->system),
133 {
134  if (!params->switched_out) {
135  _status = Running;
136  } else {
138  }
139 
140  if (params->checker) {
141  BaseCPU *temp_checker = params->checker;
142  checker = dynamic_cast<Checker<Impl> *>(temp_checker);
143  checker->setIcachePort(&this->fetch.getInstPort());
144  checker->setSystem(params->system);
145  } else {
146  checker = NULL;
147  }
148 
149  if (!FullSystem) {
150  thread.resize(numThreads);
151  tids.resize(numThreads);
152  }
153 
154  // The stages also need their CPU pointer setup. However this
155  // must be done at the upper level CPU because they have pointers
156  // to the upper level CPU, and not this FullO3CPU.
157 
158  // Set up Pointers to the activeThreads list for each stage
159  fetch.setActiveThreads(&activeThreads);
160  decode.setActiveThreads(&activeThreads);
161  rename.setActiveThreads(&activeThreads);
162  iew.setActiveThreads(&activeThreads);
163  commit.setActiveThreads(&activeThreads);
164 
165  // Give each of the stages the time buffer they will use.
166  fetch.setTimeBuffer(&timeBuffer);
167  decode.setTimeBuffer(&timeBuffer);
168  rename.setTimeBuffer(&timeBuffer);
169  iew.setTimeBuffer(&timeBuffer);
170  commit.setTimeBuffer(&timeBuffer);
171 
172  // Also setup each of the stages' queues.
173  fetch.setFetchQueue(&fetchQueue);
174  decode.setFetchQueue(&fetchQueue);
175  commit.setFetchQueue(&fetchQueue);
176  decode.setDecodeQueue(&decodeQueue);
177  rename.setDecodeQueue(&decodeQueue);
178  rename.setRenameQueue(&renameQueue);
179  iew.setRenameQueue(&renameQueue);
180  iew.setIEWQueue(&iewQueue);
181  commit.setIEWQueue(&iewQueue);
182  commit.setRenameQueue(&renameQueue);
183 
184  commit.setIEWStage(&iew);
185  rename.setIEWStage(&iew);
186  rename.setCommitStage(&commit);
187 
188  ThreadID active_threads;
189  if (FullSystem) {
190  active_threads = 1;
191  } else {
192  active_threads = params->workload.size();
193 
194  if (active_threads > Impl::MaxThreads) {
195  panic("Workload Size too large. Increase the 'MaxThreads' "
196  "constant in your O3CPU impl. file (e.g. o3/alpha/impl.hh) "
197  "or edit your workload size.");
198  }
199  }
200 
201  //Make Sure That this a Valid Architeture
202  assert(params->numPhysIntRegs >= numThreads * TheISA::NumIntRegs);
203  assert(params->numPhysFloatRegs >= numThreads * TheISA::NumFloatRegs);
204  assert(params->numPhysVecRegs >= numThreads * TheISA::NumVecRegs);
205  assert(params->numPhysVecPredRegs >= numThreads * TheISA::NumVecPredRegs);
206  assert(params->numPhysCCRegs >= numThreads * TheISA::NumCCRegs);
207 
208  rename.setScoreboard(&scoreboard);
209  iew.setScoreboard(&scoreboard);
210 
211  // Setup the rename map for whichever stages need it.
212  for (ThreadID tid = 0; tid < numThreads; tid++) {
213  isa[tid] = dynamic_cast<TheISA::ISA *>(params->isa[tid]);
214  assert(isa[tid]);
215  assert(RenameMode<TheISA::ISA>::equalsInit(isa[tid], isa[0]));
216 
217  // Only Alpha has an FP zero register, so for other ISAs we
218  // use an invalid FP register index to avoid special treatment
219  // of any valid FP reg.
220  RegIndex invalidFPReg = TheISA::NumFloatRegs + 1;
221 
222  commitRenameMap[tid].init(&regFile, TheISA::ZeroReg, invalidFPReg,
223  &freeList, vecMode);
224 
225  renameMap[tid].init(&regFile, TheISA::ZeroReg, invalidFPReg,
226  &freeList, vecMode);
227  }
228 
229  // Initialize rename map to assign physical registers to the
230  // architectural registers for active threads only.
231  for (ThreadID tid = 0; tid < active_threads; tid++) {
232  for (RegIndex ridx = 0; ridx < TheISA::NumIntRegs; ++ridx) {
233  // Note that we can't use the rename() method because we don't
234  // want special treatment for the zero register at this point
235  PhysRegIdPtr phys_reg = freeList.getIntReg();
236  renameMap[tid].setEntry(RegId(IntRegClass, ridx), phys_reg);
237  commitRenameMap[tid].setEntry(RegId(IntRegClass, ridx), phys_reg);
238  }
239 
240  for (RegIndex ridx = 0; ridx < TheISA::NumFloatRegs; ++ridx) {
241  PhysRegIdPtr phys_reg = freeList.getFloatReg();
242  renameMap[tid].setEntry(RegId(FloatRegClass, ridx), phys_reg);
243  commitRenameMap[tid].setEntry(
244  RegId(FloatRegClass, ridx), phys_reg);
245  }
246 
247  /* Here we need two 'interfaces' the 'whole register' and the
248  * 'register element'. At any point only one of them will be
249  * active. */
250  if (vecMode == Enums::Full) {
251  /* Initialize the full-vector interface */
252  for (RegIndex ridx = 0; ridx < TheISA::NumVecRegs; ++ridx) {
253  RegId rid = RegId(VecRegClass, ridx);
254  PhysRegIdPtr phys_reg = freeList.getVecReg();
255  renameMap[tid].setEntry(rid, phys_reg);
256  commitRenameMap[tid].setEntry(rid, phys_reg);
257  }
258  } else {
259  /* Initialize the vector-element interface */
260  for (RegIndex ridx = 0; ridx < TheISA::NumVecRegs; ++ridx) {
261  for (ElemIndex ldx = 0; ldx < TheISA::NumVecElemPerVecReg;
262  ++ldx) {
263  RegId lrid = RegId(VecElemClass, ridx, ldx);
264  PhysRegIdPtr phys_elem = freeList.getVecElem();
265  renameMap[tid].setEntry(lrid, phys_elem);
266  commitRenameMap[tid].setEntry(lrid, phys_elem);
267  }
268  }
269  }
270 
271  for (RegIndex ridx = 0; ridx < TheISA::NumVecPredRegs; ++ridx) {
272  PhysRegIdPtr phys_reg = freeList.getVecPredReg();
273  renameMap[tid].setEntry(RegId(VecPredRegClass, ridx), phys_reg);
274  commitRenameMap[tid].setEntry(
275  RegId(VecPredRegClass, ridx), phys_reg);
276  }
277 
278  for (RegIndex ridx = 0; ridx < TheISA::NumCCRegs; ++ridx) {
279  PhysRegIdPtr phys_reg = freeList.getCCReg();
280  renameMap[tid].setEntry(RegId(CCRegClass, ridx), phys_reg);
281  commitRenameMap[tid].setEntry(RegId(CCRegClass, ridx), phys_reg);
282  }
283  }
284 
285  rename.setRenameMap(renameMap);
286  commit.setRenameMap(commitRenameMap);
287  rename.setFreeList(&freeList);
288 
289  // Setup the ROB for whichever stages need it.
290  commit.setROB(&rob);
291 
292  lastActivatedCycle = 0;
293 
294  DPRINTF(O3CPU, "Creating O3CPU object.\n");
295 
296  // Setup any thread state.
297  this->thread.resize(this->numThreads);
298 
299  for (ThreadID tid = 0; tid < this->numThreads; ++tid) {
300  if (FullSystem) {
301  // SMT is not supported in FS mode yet.
302  assert(this->numThreads == 1);
303  this->thread[tid] = new Thread(this, 0, NULL);
304  } else {
305  if (tid < params->workload.size()) {
306  DPRINTF(O3CPU, "Workload[%i] process is %#x",
307  tid, this->thread[tid]);
308  this->thread[tid] = new typename FullO3CPU<Impl>::Thread(
309  (typename Impl::O3CPU *)(this),
310  tid, params->workload[tid]);
311 
312  //usedTids[tid] = true;
313  //threadMap[tid] = tid;
314  } else {
315  //Allocate Empty thread so M5 can use later
316  //when scheduling threads to CPU
317  Process* dummy_proc = NULL;
318 
319  this->thread[tid] = new typename FullO3CPU<Impl>::Thread(
320  (typename Impl::O3CPU *)(this),
321  tid, dummy_proc);
322  //usedTids[tid] = false;
323  }
324  }
325 
326  ThreadContext *tc;
327 
328  // Setup the TC that will serve as the interface to the threads/CPU.
330 
331  tc = o3_tc;
332 
333  // If we're using a checker, then the TC should be the
334  // CheckerThreadContext.
335  if (params->checker) {
337  o3_tc, this->checker);
338  }
339 
340  o3_tc->cpu = (typename Impl::O3CPU *)(this);
341  assert(o3_tc->cpu);
342  o3_tc->thread = this->thread[tid];
343 
344  // Setup quiesce event.
345  this->thread[tid]->quiesceEvent = new EndQuiesceEvent(tc);
346 
347  // Give the thread the TC.
348  this->thread[tid]->tc = tc;
349 
350  // Add the TC to the CPU's list of TC's.
351  this->threadContexts.push_back(tc);
352  }
353 
354  // FullO3CPU always requires an interrupt controller.
355  if (!params->switched_out && interrupts.empty()) {
356  fatal("FullO3CPU %s has no interrupt controller.\n"
357  "Ensure createInterruptController() is called.\n", name());
358  }
359 
360  for (ThreadID tid = 0; tid < this->numThreads; tid++)
361  this->thread[tid]->setFuncExeInst(0);
362 }
363 
364 template <class Impl>
366 {
367 }
368 
369 template <class Impl>
370 void
372 {
374 
375  ppInstAccessComplete = new ProbePointArg<PacketPtr>(getProbeManager(), "InstAccessComplete");
377 
378  fetch.regProbePoints();
379  rename.regProbePoints();
380  iew.regProbePoints();
381  commit.regProbePoints();
382 }
383 
384 template <class Impl>
385 void
387 {
389 
390  // Register any of the O3CPU's stats here.
391  timesIdled
392  .name(name() + ".timesIdled")
393  .desc("Number of times that the entire CPU went into an idle state and"
394  " unscheduled itself")
395  .prereq(timesIdled);
396 
397  idleCycles
398  .name(name() + ".idleCycles")
399  .desc("Total number of cycles that the CPU has spent unscheduled due "
400  "to idling")
401  .prereq(idleCycles);
402 
404  .name(name() + ".quiesceCycles")
405  .desc("Total number of cycles that CPU has spent quiesced or waiting "
406  "for an interrupt")
408 
409  // Number of Instructions simulated
410  // --------------------------------
411  // Should probably be in Base CPU but need templated
412  // MaxThreads so put in here instead
414  .init(numThreads)
415  .name(name() + ".committedInsts")
416  .desc("Number of Instructions Simulated")
418 
420  .init(numThreads)
421  .name(name() + ".committedOps")
422  .desc("Number of Ops (including micro ops) Simulated")
424 
425  cpi
426  .name(name() + ".cpi")
427  .desc("CPI: Cycles Per Instruction")
428  .precision(6);
430 
431  totalCpi
432  .name(name() + ".cpi_total")
433  .desc("CPI: Total CPI of All Threads")
434  .precision(6);
436 
437  ipc
438  .name(name() + ".ipc")
439  .desc("IPC: Instructions Per Cycle")
440  .precision(6);
442 
443  totalIpc
444  .name(name() + ".ipc_total")
445  .desc("IPC: Total IPC of All Threads")
446  .precision(6);
448 
449  this->fetch.regStats();
450  this->decode.regStats();
451  this->rename.regStats();
452  this->iew.regStats();
453  this->commit.regStats();
454  this->rob.regStats();
455 
457  .name(name() + ".int_regfile_reads")
458  .desc("number of integer regfile reads")
460 
462  .name(name() + ".int_regfile_writes")
463  .desc("number of integer regfile writes")
465 
467  .name(name() + ".fp_regfile_reads")
468  .desc("number of floating regfile reads")
470 
472  .name(name() + ".fp_regfile_writes")
473  .desc("number of floating regfile writes")
475 
477  .name(name() + ".vec_regfile_reads")
478  .desc("number of vector regfile reads")
480 
482  .name(name() + ".vec_regfile_writes")
483  .desc("number of vector regfile writes")
485 
487  .name(name() + ".pred_regfile_reads")
488  .desc("number of predicate regfile reads")
490 
492  .name(name() + ".pred_regfile_writes")
493  .desc("number of predicate regfile writes")
495 
497  .name(name() + ".cc_regfile_reads")
498  .desc("number of cc regfile reads")
500 
502  .name(name() + ".cc_regfile_writes")
503  .desc("number of cc regfile writes")
505 
507  .name(name() + ".misc_regfile_reads")
508  .desc("number of misc regfile reads")
510 
512  .name(name() + ".misc_regfile_writes")
513  .desc("number of misc regfile writes")
515 }
516 
517 template <class Impl>
518 void
520 {
521  DPRINTF(O3CPU, "\n\nFullO3CPU: Ticking main, FullO3CPU.\n");
522  assert(!switchedOut());
523  assert(drainState() != DrainState::Drained);
524 
525  ++numCycles;
527 
528 // activity = false;
529 
530  //Tick each of the stages
531  fetch.tick();
532 
533  decode.tick();
534 
535  rename.tick();
536 
537  iew.tick();
538 
539  commit.tick();
540 
541  // Now advance the time buffers
543 
547  iewQueue.advance();
548 
550 
551  if (removeInstsThisCycle) {
553  }
554 
555  if (!tickEvent.scheduled()) {
556  if (_status == SwitchedOut) {
557  DPRINTF(O3CPU, "Switched out!\n");
558  // increment stat
560  } else if (!activityRec.active() || _status == Idle) {
561  DPRINTF(O3CPU, "Idle!\n");
563  timesIdled++;
564  } else {
566  DPRINTF(O3CPU, "Scheduling next tick!\n");
567  }
568  }
569 
570  if (!FullSystem)
572 
573  tryDrain();
574 }
575 
576 template <class Impl>
577 void
579 {
580  BaseCPU::init();
581 
582  for (ThreadID tid = 0; tid < numThreads; ++tid) {
583  // Set noSquashFromTC so that the CPU doesn't squash when initially
584  // setting up registers.
585  thread[tid]->noSquashFromTC = true;
586  // Initialise the ThreadContext's memory proxies
587  thread[tid]->initMemProxies(thread[tid]->getTC());
588  }
589 
590  // Clear noSquashFromTC.
591  for (int tid = 0; tid < numThreads; ++tid)
592  thread[tid]->noSquashFromTC = false;
593 
594  commit.setThreads(thread);
595 }
596 
597 template <class Impl>
598 void
600 {
602  for (int tid = 0; tid < numThreads; ++tid)
603  isa[tid]->startup(threadContexts[tid]);
604 
605  fetch.startupStage();
606  decode.startupStage();
607  iew.startupStage();
608  rename.startupStage();
609  commit.startupStage();
610 }
611 
612 template <class Impl>
613 void
615 {
616  list<ThreadID>::iterator isActive =
617  std::find(activeThreads.begin(), activeThreads.end(), tid);
618 
619  DPRINTF(O3CPU, "[tid:%i] Calling activate thread.\n", tid);
620  assert(!switchedOut());
621 
622  if (isActive == activeThreads.end()) {
623  DPRINTF(O3CPU, "[tid:%i] Adding to active threads list\n",
624  tid);
625 
626  activeThreads.push_back(tid);
627  }
628 }
629 
630 template <class Impl>
631 void
633 {
634  //Remove From Active List, if Active
635  list<ThreadID>::iterator thread_it =
636  std::find(activeThreads.begin(), activeThreads.end(), tid);
637 
638  DPRINTF(O3CPU, "[tid:%i] Calling deactivate thread.\n", tid);
639  assert(!switchedOut());
640 
641  if (thread_it != activeThreads.end()) {
642  DPRINTF(O3CPU,"[tid:%i] Removing from active threads list\n",
643  tid);
644  activeThreads.erase(thread_it);
645  }
646 
647  fetch.deactivateThread(tid);
648  commit.deactivateThread(tid);
649 }
650 
651 template <class Impl>
652 Counter
654 {
655  Counter total(0);
656 
657  ThreadID size = thread.size();
658  for (ThreadID i = 0; i < size; i++)
659  total += thread[i]->numInst;
660 
661  return total;
662 }
663 
664 template <class Impl>
665 Counter
667 {
668  Counter total(0);
669 
670  ThreadID size = thread.size();
671  for (ThreadID i = 0; i < size; i++)
672  total += thread[i]->numOp;
673 
674  return total;
675 }
676 
677 template <class Impl>
678 void
680 {
681  assert(!switchedOut());
682 
683  // Needs to set each stage to running as well.
684  activateThread(tid);
685 
686  // We don't want to wake the CPU if it is drained. In that case,
687  // we just want to flag the thread as active and schedule the tick
688  // event from drainResume() instead.
690  return;
691 
692  // If we are time 0 or if the last activation time is in the past,
693  // schedule the next tick and wake up the fetch unit
696 
697  // Be sure to signal that there's some activity so the CPU doesn't
698  // deschedule itself.
700  fetch.wakeFromQuiesce();
701 
702  Cycles cycles(curCycle() - lastRunningCycle);
703  // @todo: This is an oddity that is only here to match the stats
704  if (cycles != 0)
705  --cycles;
706  quiesceCycles += cycles;
707 
709 
710  _status = Running;
711 
713  }
714 }
715 
716 template <class Impl>
717 void
719 {
720  DPRINTF(O3CPU,"[tid:%i] Suspending Thread Context.\n", tid);
721  assert(!switchedOut());
722 
723  deactivateThread(tid);
724 
725  // If this was the last thread then unschedule the tick event.
726  if (activeThreads.size() == 0) {
729  _status = Idle;
730  }
731 
732  DPRINTF(Quiesce, "Suspending Context\n");
733 
735 }
736 
737 template <class Impl>
738 void
740 {
741  //For now, this is the same as deallocate
742  DPRINTF(O3CPU,"[tid:%i] Halt Context called. Deallocating\n", tid);
743  assert(!switchedOut());
744 
745  deactivateThread(tid);
746  removeThread(tid);
747 
749 }
750 
751 template <class Impl>
752 void
754 {
755  DPRINTF(O3CPU,"[tid:%i] Initializing thread into CPU");
756  // Will change now that the PC and thread state is internal to the CPU
757  // and not in the ThreadContext.
758  ThreadContext *src_tc;
759  if (FullSystem)
760  src_tc = system->threadContexts[tid];
761  else
762  src_tc = tcBase(tid);
763 
764  //Bind Int Regs to Rename Map
765 
766  for (RegId reg_id(IntRegClass, 0); reg_id.index() < TheISA::NumIntRegs;
767  reg_id.index()++) {
768  PhysRegIdPtr phys_reg = freeList.getIntReg();
769  renameMap[tid].setEntry(reg_id, phys_reg);
770  scoreboard.setReg(phys_reg);
771  }
772 
773  //Bind Float Regs to Rename Map
774  for (RegId reg_id(FloatRegClass, 0); reg_id.index() < TheISA::NumFloatRegs;
775  reg_id.index()++) {
776  PhysRegIdPtr phys_reg = freeList.getFloatReg();
777  renameMap[tid].setEntry(reg_id, phys_reg);
778  scoreboard.setReg(phys_reg);
779  }
780 
781  //Bind condition-code Regs to Rename Map
782  for (RegId reg_id(CCRegClass, 0); reg_id.index() < TheISA::NumCCRegs;
783  reg_id.index()++) {
784  PhysRegIdPtr phys_reg = freeList.getCCReg();
785  renameMap[tid].setEntry(reg_id, phys_reg);
786  scoreboard.setReg(phys_reg);
787  }
788 
789  //Copy Thread Data Into RegFile
790  //this->copyFromTC(tid);
791 
792  //Set PC/NPC/NNPC
793  pcState(src_tc->pcState(), tid);
794 
796 
797  activateContext(tid);
798 
799  //Reset ROB/IQ/LSQ Entries
800  commit.rob->resetEntries();
801 }
802 
803 template <class Impl>
804 void
806 {
807  DPRINTF(O3CPU,"[tid:%i] Removing thread context from CPU.\n", tid);
808 
809  // Copy Thread Data From RegFile
810  // If thread is suspended, it might be re-allocated
811  // this->copyToTC(tid);
812 
813 
814  // @todo: 2-27-2008: Fix how we free up rename mappings
815  // here to alleviate the case for double-freeing registers
816  // in SMT workloads.
817 
818  // clear all thread-specific states in each stage of the pipeline
819  // since this thread is going to be completely removed from the CPU
820  commit.clearStates(tid);
821  fetch.clearStates(tid);
822  decode.clearStates(tid);
823  rename.clearStates(tid);
824  iew.clearStates(tid);
825 
826  // at this step, all instructions in the pipeline should be already
827  // either committed successfully or squashed. All thread-specific
828  // queues in the pipeline must be empty.
829  assert(iew.instQueue.getCount(tid) == 0);
830  assert(iew.ldstQueue.getCount(tid) == 0);
831  assert(commit.rob->isEmpty(tid));
832 
833  // Reset ROB/IQ/LSQ Entries
834 
835  // Commented out for now. This should be possible to do by
836  // telling all the pipeline stages to drain first, and then
837  // checking until the drain completes. Once the pipeline is
838  // drained, call resetEntries(). - 10-09-06 ktlim
839 /*
840  if (activeThreads.size() >= 1) {
841  commit.rob->resetEntries();
842  iew.resetEntries();
843  }
844 */
845 }
846 
847 template <class Impl>
848 void
850 {
851  if (vecMode == Enums::Elem) {
852  for (auto v = 0; v < TheISA::NumVecRegs; v++)
853  for (auto e = 0; e < TheISA::NumVecElemPerVecReg; e++)
855  commitRenameMap[tid].lookup(
856  RegId(VecElemClass, v, e)
857  )
858  );
859  } else if (vecMode == Enums::Full) {
860  for (auto v = 0; v < TheISA::NumVecRegs; v++)
862  commitRenameMap[tid].lookup(
864  )
865  );
866  }
867 }
868 
869 template <class Impl>
870 void
872 {
873  auto pc = this->pcState(tid);
874 
875  // new_mode is the new vector renaming mode
876  auto new_mode = RenameMode<TheISA::ISA>::mode(pc);
877 
878  // We update vecMode only if there has been a change
879  if (new_mode != vecMode) {
880  vecMode = new_mode;
881 
882  renameMap[tid].switchMode(vecMode);
883  commitRenameMap[tid].switchMode(vecMode);
884  renameMap[tid].switchFreeList(freelist);
885  setVectorsAsReady(tid);
886  }
887 }
888 
889 template <class Impl>
890 Fault
892 {
893  // Check if there are any outstanding interrupts
894  return this->interrupts[0]->getInterrupt(this->threadContexts[0]);
895 }
896 
897 template <class Impl>
898 void
900 {
901  // Check for interrupts here. For now can copy the code that
902  // exists within isa_fullsys_traits.hh. Also assume that thread 0
903  // is the one that handles the interrupts.
904  // @todo: Possibly consolidate the interrupt checking code.
905  // @todo: Allow other threads to handle interrupts.
906 
907  assert(interrupt != NoFault);
908  this->interrupts[0]->updateIntrInfo(this->threadContexts[0]);
909 
910  DPRINTF(O3CPU, "Interrupt %s being handled\n", interrupt->name());
911  this->trap(interrupt, 0, nullptr);
912 }
913 
914 template <class Impl>
915 void
917  const StaticInstPtr &inst)
918 {
919  // Pass the thread's TC into the invoke method.
920  fault->invoke(this->threadContexts[tid], inst);
921 }
922 
923 template <class Impl>
924 void
926 {
927  DPRINTF(O3CPU, "[tid:%i] Executing syscall().\n\n", tid);
928 
929  DPRINTF(Activity,"Activity: syscall() called.\n");
930 
931  // Temporarily increase this by one to account for the syscall
932  // instruction.
933  ++(this->thread[tid]->funcExeInst);
934 
935  // Execute the actual syscall.
936  this->thread[tid]->syscall(fault);
937 
938  // Decrease funcExeInst by one as the normal commit will handle
939  // incrementing it.
940  --(this->thread[tid]->funcExeInst);
941 }
942 
943 template <class Impl>
944 void
946 {
947  thread[tid]->serialize(cp);
948 }
949 
950 template <class Impl>
951 void
953 {
954  thread[tid]->unserialize(cp);
955 }
956 
957 template <class Impl>
960 {
961  // Deschedule any power gating event (if any)
963 
964  // If the CPU isn't doing anything, then return immediately.
965  if (switchedOut())
966  return DrainState::Drained;
967 
968  DPRINTF(Drain, "Draining...\n");
969 
970  // We only need to signal a drain to the commit stage as this
971  // initiates squashing controls the draining. Once the commit
972  // stage commits an instruction where it is safe to stop, it'll
973  // squash the rest of the instructions in the pipeline and force
974  // the fetch stage to stall. The pipeline will be drained once all
975  // in-flight instructions have retired.
976  commit.drain();
977 
978  // Wake the CPU and record activity so everything can drain out if
979  // the CPU was not able to immediately drain.
980  if (!isCpuDrained()) {
981  // If a thread is suspended, wake it up so it can be drained
982  for (auto t : threadContexts) {
983  if (t->status() == ThreadContext::Suspended){
984  DPRINTF(Drain, "Currently suspended so activate %i \n",
985  t->threadId());
986  t->activate();
987  // As the thread is now active, change the power state as well
988  activateContext(t->threadId());
989  }
990  }
991 
992  wakeCPU();
994 
995  DPRINTF(Drain, "CPU not drained\n");
996 
997  return DrainState::Draining;
998  } else {
999  DPRINTF(Drain, "CPU is already drained\n");
1000  if (tickEvent.scheduled())
1002 
1003  // Flush out any old data from the time buffers. In
1004  // particular, there might be some data in flight from the
1005  // fetch stage that isn't visible in any of the CPU buffers we
1006  // test in isCpuDrained().
1007  for (int i = 0; i < timeBuffer.getSize(); ++i) {
1008  timeBuffer.advance();
1009  fetchQueue.advance();
1010  decodeQueue.advance();
1011  renameQueue.advance();
1012  iewQueue.advance();
1013  }
1014 
1015  drainSanityCheck();
1016  return DrainState::Drained;
1017  }
1018 }
1019 
1020 template <class Impl>
1021 bool
1023 {
1025  return false;
1026 
1027  if (tickEvent.scheduled())
1029 
1030  DPRINTF(Drain, "CPU done draining, processing drain event\n");
1031  signalDrainDone();
1032 
1033  return true;
1034 }
1035 
1036 template <class Impl>
1037 void
1039 {
1040  assert(isCpuDrained());
1041  fetch.drainSanityCheck();
1042  decode.drainSanityCheck();
1043  rename.drainSanityCheck();
1044  iew.drainSanityCheck();
1045  commit.drainSanityCheck();
1046 }
1047 
1048 template <class Impl>
1049 bool
1051 {
1052  bool drained(true);
1053 
1054  if (!instList.empty() || !removeList.empty()) {
1055  DPRINTF(Drain, "Main CPU structures not drained.\n");
1056  drained = false;
1057  }
1058 
1059  if (!fetch.isDrained()) {
1060  DPRINTF(Drain, "Fetch not drained.\n");
1061  drained = false;
1062  }
1063 
1064  if (!decode.isDrained()) {
1065  DPRINTF(Drain, "Decode not drained.\n");
1066  drained = false;
1067  }
1068 
1069  if (!rename.isDrained()) {
1070  DPRINTF(Drain, "Rename not drained.\n");
1071  drained = false;
1072  }
1073 
1074  if (!iew.isDrained()) {
1075  DPRINTF(Drain, "IEW not drained.\n");
1076  drained = false;
1077  }
1078 
1079  if (!commit.isDrained()) {
1080  DPRINTF(Drain, "Commit not drained.\n");
1081  drained = false;
1082  }
1083 
1084  return drained;
1085 }
1086 
1087 template <class Impl>
1088 void
1090 {
1091  fetch.drainStall(tid);
1092 }
1093 
1094 template <class Impl>
1095 void
1097 {
1098  if (switchedOut())
1099  return;
1100 
1101  DPRINTF(Drain, "Resuming...\n");
1102  verifyMemoryMode();
1103 
1104  fetch.drainResume();
1105  commit.drainResume();
1106 
1107  _status = Idle;
1108  for (ThreadID i = 0; i < thread.size(); i++) {
1109  if (thread[i]->status() == ThreadContext::Active) {
1110  DPRINTF(Drain, "Activating thread: %i\n", i);
1111  activateThread(i);
1112  _status = Running;
1113  }
1114  }
1115 
1116  assert(!tickEvent.scheduled());
1117  if (_status == Running)
1119 
1120  // Reschedule any power gating event (if any)
1122 }
1123 
1124 template <class Impl>
1125 void
1127 {
1128  DPRINTF(O3CPU, "Switching out\n");
1130 
1131  activityRec.reset();
1132 
1133  _status = SwitchedOut;
1134 
1135  if (checker)
1136  checker->switchOut();
1137 }
1138 
1139 template <class Impl>
1140 void
1142 {
1143  BaseCPU::takeOverFrom(oldCPU);
1144 
1145  fetch.takeOverFrom();
1146  decode.takeOverFrom();
1147  rename.takeOverFrom();
1148  iew.takeOverFrom();
1149  commit.takeOverFrom();
1150 
1151  assert(!tickEvent.scheduled());
1152 
1153  FullO3CPU<Impl> *oldO3CPU = dynamic_cast<FullO3CPU<Impl>*>(oldCPU);
1154  if (oldO3CPU)
1155  globalSeqNum = oldO3CPU->globalSeqNum;
1156 
1158  _status = Idle;
1159 }
1160 
1161 template <class Impl>
1162 void
1164 {
1165  if (!system->isTimingMode()) {
1166  fatal("The O3 CPU requires the memory system to be in "
1167  "'timing' mode.\n");
1168  }
1169 }
1170 
1171 template <class Impl>
1172 RegVal
1174 {
1175  return this->isa[tid]->readMiscRegNoEffect(misc_reg);
1176 }
1177 
1178 template <class Impl>
1179 RegVal
1181 {
1182  miscRegfileReads++;
1183  return this->isa[tid]->readMiscReg(misc_reg, tcBase(tid));
1184 }
1185 
1186 template <class Impl>
1187 void
1189 {
1190  this->isa[tid]->setMiscRegNoEffect(misc_reg, val);
1191 }
1192 
1193 template <class Impl>
1194 void
1196 {
1198  this->isa[tid]->setMiscReg(misc_reg, val, tcBase(tid));
1199 }
1200 
1201 template <class Impl>
1202 RegVal
1204 {
1205  intRegfileReads++;
1206  return regFile.readIntReg(phys_reg);
1207 }
1208 
1209 template <class Impl>
1210 RegVal
1212 {
1213  fpRegfileReads++;
1214  return regFile.readFloatReg(phys_reg);
1215 }
1216 
1217 template <class Impl>
1218 auto
1220  -> const VecRegContainer&
1221 {
1222  vecRegfileReads++;
1223  return regFile.readVecReg(phys_reg);
1224 }
1225 
1226 template <class Impl>
1227 auto
1229  -> VecRegContainer&
1230 {
1231  vecRegfileWrites++;
1232  return regFile.getWritableVecReg(phys_reg);
1233 }
1234 
1235 template <class Impl>
1236 auto
1238 {
1239  vecRegfileReads++;
1240  return regFile.readVecElem(phys_reg);
1241 }
1242 
1243 template <class Impl>
1244 auto
1246  -> const VecPredRegContainer&
1247 {
1249  return regFile.readVecPredReg(phys_reg);
1250 }
1251 
1252 template <class Impl>
1253 auto
1256 {
1258  return regFile.getWritableVecPredReg(phys_reg);
1259 }
1260 
1261 template <class Impl>
1262 RegVal
1264 {
1265  ccRegfileReads++;
1266  return regFile.readCCReg(phys_reg);
1267 }
1268 
1269 template <class Impl>
1270 void
1272 {
1273  intRegfileWrites++;
1274  regFile.setIntReg(phys_reg, val);
1275 }
1276 
1277 template <class Impl>
1278 void
1280 {
1281  fpRegfileWrites++;
1282  regFile.setFloatReg(phys_reg, val);
1283 }
1284 
1285 template <class Impl>
1286 void
1288 {
1289  vecRegfileWrites++;
1290  regFile.setVecReg(phys_reg, val);
1291 }
1292 
1293 template <class Impl>
1294 void
1296 {
1297  vecRegfileWrites++;
1298  regFile.setVecElem(phys_reg, val);
1299 }
1300 
1301 template <class Impl>
1302 void
1304  const VecPredRegContainer& val)
1305 {
1307  regFile.setVecPredReg(phys_reg, val);
1308 }
1309 
1310 template <class Impl>
1311 void
1313 {
1314  ccRegfileWrites++;
1315  regFile.setCCReg(phys_reg, val);
1316 }
1317 
1318 template <class Impl>
1319 RegVal
1321 {
1322  intRegfileReads++;
1323  PhysRegIdPtr phys_reg = commitRenameMap[tid].lookup(
1324  RegId(IntRegClass, reg_idx));
1325 
1326  return regFile.readIntReg(phys_reg);
1327 }
1328 
1329 template <class Impl>
1330 RegVal
1332 {
1333  fpRegfileReads++;
1334  PhysRegIdPtr phys_reg = commitRenameMap[tid].lookup(
1335  RegId(FloatRegClass, reg_idx));
1336 
1337  return regFile.readFloatReg(phys_reg);
1338 }
1339 
1340 template <class Impl>
1341 auto
1343  -> const VecRegContainer&
1344 {
1345  PhysRegIdPtr phys_reg = commitRenameMap[tid].lookup(
1346  RegId(VecRegClass, reg_idx));
1347  return readVecReg(phys_reg);
1348 }
1349 
1350 template <class Impl>
1351 auto
1353  -> VecRegContainer&
1354 {
1355  PhysRegIdPtr phys_reg = commitRenameMap[tid].lookup(
1356  RegId(VecRegClass, reg_idx));
1357  return getWritableVecReg(phys_reg);
1358 }
1359 
1360 template <class Impl>
1361 auto
1363  ThreadID tid) const -> const VecElem&
1364 {
1365  PhysRegIdPtr phys_reg = commitRenameMap[tid].lookup(
1366  RegId(VecElemClass, reg_idx, ldx));
1367  return readVecElem(phys_reg);
1368 }
1369 
1370 template <class Impl>
1371 auto
1373  -> const VecPredRegContainer&
1374 {
1375  PhysRegIdPtr phys_reg = commitRenameMap[tid].lookup(
1376  RegId(VecPredRegClass, reg_idx));
1377  return readVecPredReg(phys_reg);
1378 }
1379 
1380 template <class Impl>
1381 auto
1384 {
1385  PhysRegIdPtr phys_reg = commitRenameMap[tid].lookup(
1386  RegId(VecPredRegClass, reg_idx));
1387  return getWritableVecPredReg(phys_reg);
1388 }
1389 
1390 template <class Impl>
1391 RegVal
1393 {
1394  ccRegfileReads++;
1395  PhysRegIdPtr phys_reg = commitRenameMap[tid].lookup(
1396  RegId(CCRegClass, reg_idx));
1397 
1398  return regFile.readCCReg(phys_reg);
1399 }
1400 
1401 template <class Impl>
1402 void
1404 {
1405  intRegfileWrites++;
1406  PhysRegIdPtr phys_reg = commitRenameMap[tid].lookup(
1407  RegId(IntRegClass, reg_idx));
1408 
1409  regFile.setIntReg(phys_reg, val);
1410 }
1411 
1412 template <class Impl>
1413 void
1415 {
1416  fpRegfileWrites++;
1417  PhysRegIdPtr phys_reg = commitRenameMap[tid].lookup(
1418  RegId(FloatRegClass, reg_idx));
1419 
1420  regFile.setFloatReg(phys_reg, val);
1421 }
1422 
1423 template <class Impl>
1424 void
1426  ThreadID tid)
1427 {
1428  PhysRegIdPtr phys_reg = commitRenameMap[tid].lookup(
1429  RegId(VecRegClass, reg_idx));
1430  setVecReg(phys_reg, val);
1431 }
1432 
1433 template <class Impl>
1434 void
1436  const VecElem& val, ThreadID tid)
1437 {
1438  PhysRegIdPtr phys_reg = commitRenameMap[tid].lookup(
1439  RegId(VecElemClass, reg_idx, ldx));
1440  setVecElem(phys_reg, val);
1441 }
1442 
1443 template <class Impl>
1444 void
1446  ThreadID tid)
1447 {
1448  PhysRegIdPtr phys_reg = commitRenameMap[tid].lookup(
1449  RegId(VecPredRegClass, reg_idx));
1450  setVecPredReg(phys_reg, val);
1451 }
1452 
1453 template <class Impl>
1454 void
1456 {
1457  ccRegfileWrites++;
1458  PhysRegIdPtr phys_reg = commitRenameMap[tid].lookup(
1459  RegId(CCRegClass, reg_idx));
1460 
1461  regFile.setCCReg(phys_reg, val);
1462 }
1463 
1464 template <class Impl>
1467 {
1468  return commit.pcState(tid);
1469 }
1470 
1471 template <class Impl>
1472 void
1474 {
1475  commit.pcState(val, tid);
1476 }
1477 
1478 template <class Impl>
1479 Addr
1481 {
1482  return commit.instAddr(tid);
1483 }
1484 
1485 template <class Impl>
1486 Addr
1488 {
1489  return commit.nextInstAddr(tid);
1490 }
1491 
1492 template <class Impl>
1493 MicroPC
1495 {
1496  return commit.microPC(tid);
1497 }
1498 
1499 template <class Impl>
1500 void
1502 {
1503  this->thread[tid]->noSquashFromTC = true;
1504  this->commit.generateTCEvent(tid);
1505 }
1506 
1507 template <class Impl>
1508 typename FullO3CPU<Impl>::ListIt
1510 {
1511  instList.push_back(inst);
1512 
1513  return --(instList.end());
1514 }
1515 
1516 template <class Impl>
1517 void
1519 {
1520  // Keep an instruction count.
1521  if (!inst->isMicroop() || inst->isLastMicroop()) {
1522  thread[tid]->numInst++;
1523  thread[tid]->numInsts++;
1524  committedInsts[tid]++;
1525  system->totalNumInsts++;
1526 
1527  // Check for instruction-count-based events.
1528  thread[tid]->comInstEventQueue.serviceEvents(thread[tid]->numInst);
1529  }
1530  thread[tid]->numOp++;
1531  thread[tid]->numOps++;
1532  committedOps[tid]++;
1533 
1534  probeInstCommit(inst->staticInst, inst->instAddr());
1535 }
1536 
1537 template <class Impl>
1538 void
1540 {
1541  DPRINTF(O3CPU, "Removing committed instruction [tid:%i] PC %s "
1542  "[sn:%lli]\n",
1543  inst->threadNumber, inst->pcState(), inst->seqNum);
1544 
1545  removeInstsThisCycle = true;
1546 
1547  // Remove the front instruction.
1548  removeList.push(inst->getInstListIt());
1549 }
1550 
1551 template <class Impl>
1552 void
1554 {
1555  DPRINTF(O3CPU, "Thread %i: Deleting instructions from instruction"
1556  " list.\n", tid);
1557 
1558  ListIt end_it;
1559 
1560  bool rob_empty = false;
1561 
1562  if (instList.empty()) {
1563  return;
1564  } else if (rob.isEmpty(tid)) {
1565  DPRINTF(O3CPU, "ROB is empty, squashing all insts.\n");
1566  end_it = instList.begin();
1567  rob_empty = true;
1568  } else {
1569  end_it = (rob.readTailInst(tid))->getInstListIt();
1570  DPRINTF(O3CPU, "ROB is not empty, squashing insts not in ROB.\n");
1571  }
1572 
1573  removeInstsThisCycle = true;
1574 
1575  ListIt inst_it = instList.end();
1576 
1577  inst_it--;
1578 
1579  // Walk through the instruction list, removing any instructions
1580  // that were inserted after the given instruction iterator, end_it.
1581  while (inst_it != end_it) {
1582  assert(!instList.empty());
1583 
1584  squashInstIt(inst_it, tid);
1585 
1586  inst_it--;
1587  }
1588 
1589  // If the ROB was empty, then we actually need to remove the first
1590  // instruction as well.
1591  if (rob_empty) {
1592  squashInstIt(inst_it, tid);
1593  }
1594 }
1595 
1596 template <class Impl>
1597 void
1599 {
1600  assert(!instList.empty());
1601 
1602  removeInstsThisCycle = true;
1603 
1604  ListIt inst_iter = instList.end();
1605 
1606  inst_iter--;
1607 
1608  DPRINTF(O3CPU, "Deleting instructions from instruction "
1609  "list that are from [tid:%i] and above [sn:%lli] (end=%lli).\n",
1610  tid, seq_num, (*inst_iter)->seqNum);
1611 
1612  while ((*inst_iter)->seqNum > seq_num) {
1613 
1614  bool break_loop = (inst_iter == instList.begin());
1615 
1616  squashInstIt(inst_iter, tid);
1617 
1618  inst_iter--;
1619 
1620  if (break_loop)
1621  break;
1622  }
1623 }
1624 
1625 template <class Impl>
1626 inline void
1628 {
1629  if ((*instIt)->threadNumber == tid) {
1630  DPRINTF(O3CPU, "Squashing instruction, "
1631  "[tid:%i] [sn:%lli] PC %s\n",
1632  (*instIt)->threadNumber,
1633  (*instIt)->seqNum,
1634  (*instIt)->pcState());
1635 
1636  // Mark it as squashed.
1637  (*instIt)->setSquashed();
1638 
1639  // @todo: Formulate a consistent method for deleting
1640  // instructions from the instruction list
1641  // Remove the instruction from the list.
1642  removeList.push(instIt);
1643  }
1644 }
1645 
1646 template <class Impl>
1647 void
1649 {
1650  while (!removeList.empty()) {
1651  DPRINTF(O3CPU, "Removing instruction, "
1652  "[tid:%i] [sn:%lli] PC %s\n",
1653  (*removeList.front())->threadNumber,
1654  (*removeList.front())->seqNum,
1655  (*removeList.front())->pcState());
1656 
1657  instList.erase(removeList.front());
1658 
1659  removeList.pop();
1660  }
1661 
1662  removeInstsThisCycle = false;
1663 }
1664 /*
1665 template <class Impl>
1666 void
1667 FullO3CPU<Impl>::removeAllInsts()
1668 {
1669  instList.clear();
1670 }
1671 */
1672 template <class Impl>
1673 void
1675 {
1676  int num = 0;
1677 
1678  ListIt inst_list_it = instList.begin();
1679 
1680  cprintf("Dumping Instruction List\n");
1681 
1682  while (inst_list_it != instList.end()) {
1683  cprintf("Instruction:%i\nPC:%#x\n[tid:%i]\n[sn:%lli]\nIssued:%i\n"
1684  "Squashed:%i\n\n",
1685  num, (*inst_list_it)->instAddr(), (*inst_list_it)->threadNumber,
1686  (*inst_list_it)->seqNum, (*inst_list_it)->isIssued(),
1687  (*inst_list_it)->isSquashed());
1688  inst_list_it++;
1689  ++num;
1690  }
1691 }
1692 /*
1693 template <class Impl>
1694 void
1695 FullO3CPU<Impl>::wakeDependents(const DynInstPtr &inst)
1696 {
1697  iew.wakeDependents(inst);
1698 }
1699 */
1700 template <class Impl>
1701 void
1703 {
1704  if (activityRec.active() || tickEvent.scheduled()) {
1705  DPRINTF(Activity, "CPU already running.\n");
1706  return;
1707  }
1708 
1709  DPRINTF(Activity, "Waking up CPU\n");
1710 
1711  Cycles cycles(curCycle() - lastRunningCycle);
1712  // @todo: This is an oddity that is only here to match the stats
1713  if (cycles > 1) {
1714  --cycles;
1715  idleCycles += cycles;
1716  numCycles += cycles;
1717  }
1718 
1720 }
1721 
1722 template <class Impl>
1723 void
1725 {
1726  if (this->thread[tid]->status() != ThreadContext::Suspended)
1727  return;
1728 
1729  this->wakeCPU();
1730 
1731  DPRINTF(Quiesce, "Suspended Processor woken\n");
1732  this->threadContexts[tid]->activate();
1733 }
1734 
1735 template <class Impl>
1736 ThreadID
1738 {
1739  for (ThreadID tid = 0; tid < numThreads; tid++) {
1740  if (!tids[tid]) {
1741  tids[tid] = true;
1742  return tid;
1743  }
1744  }
1745 
1746  return InvalidThreadID;
1747 }
1748 
1749 template <class Impl>
1750 void
1752 {
1753  if (activeThreads.size() > 1) {
1754  //DEFAULT TO ROUND ROBIN SCHEME
1755  //e.g. Move highest priority to end of thread list
1756  list<ThreadID>::iterator list_begin = activeThreads.begin();
1757 
1758  unsigned high_thread = *list_begin;
1759 
1760  activeThreads.erase(list_begin);
1761 
1762  activeThreads.push_back(high_thread);
1763  }
1764 }
1765 
1766 template <class Impl>
1767 void
1769 {
1770  DPRINTF(O3CPU, "Thread %d is inserted to exitingThreads list\n", tid);
1771 
1772  // the thread trying to exit can't be already halted
1773  assert(tcBase(tid)->status() != ThreadContext::Halted);
1774 
1775  // make sure the thread has not been added to the list yet
1776  assert(exitingThreads.count(tid) == 0);
1777 
1778  // add the thread to exitingThreads list to mark that this thread is
1779  // trying to exit. The boolean value in the pair denotes if a thread is
1780  // ready to exit. The thread is not ready to exit until the corresponding
1781  // exit trap event is processed in the future. Until then, it'll be still
1782  // an active thread that is trying to exit.
1783  exitingThreads.emplace(std::make_pair(tid, false));
1784 }
1785 
1786 template <class Impl>
1787 bool
1789 {
1790  return exitingThreads.count(tid) == 1;
1791 }
1792 
1793 template <class Impl>
1794 void
1796 {
1797  assert(exitingThreads.count(tid) == 1);
1798 
1799  // exit trap event has been processed. Now, the thread is ready to exit
1800  // and be removed from the CPU.
1801  exitingThreads[tid] = true;
1802 
1803  // we schedule a threadExitEvent in the next cycle to properly clean
1804  // up the thread's states in the pipeline. threadExitEvent has lower
1805  // priority than tickEvent, so the cleanup will happen at the very end
1806  // of the next cycle after all pipeline stages complete their operations.
1807  // We want all stages to complete squashing instructions before doing
1808  // the cleanup.
1809  if (!threadExitEvent.scheduled()) {
1811  }
1812 }
1813 
1814 template <class Impl>
1815 void
1817 {
1818  // there must be at least one thread trying to exit
1819  assert(exitingThreads.size() > 0);
1820 
1821  // terminate all threads that are ready to exit
1822  auto it = exitingThreads.begin();
1823  while (it != exitingThreads.end()) {
1824  ThreadID thread_id = it->first;
1825  bool readyToExit = it->second;
1826 
1827  if (readyToExit) {
1828  DPRINTF(O3CPU, "Exiting thread %d\n", thread_id);
1829  haltContext(thread_id);
1830  tcBase(thread_id)->setStatus(ThreadContext::Halted);
1831  it = exitingThreads.erase(it);
1832  } else {
1833  it++;
1834  }
1835  }
1836 }
1837 
1838 // Forward declaration of FullO3CPU.
1839 template class FullO3CPU<O3CPUImpl>;
bool isCpuDrained() const
Check if a system is in a drained state.
Definition: cpu.cc:1050
#define panic(...)
This implements a cprintf based panic() function.
Definition: logging.hh:163
void unserializeThread(CheckpointIn &cp, ThreadID tid) override
Unserialize one thread.
Definition: cpu.cc:952
#define DPRINTF(x,...)
Definition: trace.hh:225
std::vector< ThreadID > tids
Available thread ids in the cpu.
Definition: cpu.hh:713
Stats::Scalar timesIdled
Stat for total number of times the CPU is descheduled.
Definition: cpu.hh:754
bool removeInstsThisCycle
Records if instructions need to be removed this cycle due to being retired or squashed.
Definition: cpu.hh:558
void setVecElem(PhysRegIdPtr reg_idx, const VecElem &val)
Definition: cpu.cc:1295
virtual void probeInstCommit(const StaticInstPtr &inst, Addr pc)
Helper method to trigger PMU probes for a committed instruction.
Definition: base.cc:366
Bitfield< 28 > v
decltype(nullptr) constexpr NoFault
Definition: types.hh:243
Cycles is a wrapper class for representing cycle counts, i.e.
Definition: types.hh:81
ThreadID getFreeTid()
Gets a free thread id.
Definition: cpu.cc:1737
std::unordered_map< ThreadID, bool > exitingThreads
This is a list of threads that are trying to exit.
Definition: cpu.hh:602
void squashFromTC(ThreadID tid)
Initiates a squash of all in-flight instructions for a given thread.
Definition: cpu.cc:1501
#define fatal(...)
This implements a cprintf based fatal() function.
Definition: logging.hh:171
Floating-point register.
Definition: reg_class.hh:54
System * system
Pointer to the system.
Definition: cpu.hh:695
Bitfield< 7 > i
void scheduleTickEvent(Cycles delay)
Schedule tick event, regardless of its current state.
Definition: cpu.hh:139
std::vector< Thread * > thread
Pointers to all of the threads in the CPU.
Definition: cpu.hh:698
void switchRenameMode(ThreadID tid, UnifiedFreeList *freelist)
Check if a change in renaming is needed for vector registers.
Definition: cpu.cc:871
Fault getInterrupts()
Returns the Fault for any valid interrupt.
Definition: cpu.cc:891
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:205
ThreadID numThreads
Number of threads we&#39;re actually simulating (<= SMT_MAX_THREADS).
Definition: base.hh:374
VecPredRegContainer & getWritableVecPredReg(PhysRegIdPtr phys_reg)
Definition: regfile.hh:281
Vector Register Abstraction This generic class is the model in a particularization of MVC...
Definition: vec_reg.hh:156
VecRegContainer & getWritableArchVecReg(int reg_idx, ThreadID tid)
Read architectural vector register for modification.
Definition: cpu.cc:1352
void activateContext(ThreadID tid) override
Add Thread to Active Threads List.
Definition: cpu.cc:679
virtual TheISA::PCState pcState() const =0
Stats::Formula ipc
Stat for the IPC per thread.
Definition: cpu.hh:769
void takeOverFrom(BaseCPU *oldCPU) override
Takes over from another CPU.
Definition: cpu.cc:1141
Stats::Scalar intRegfileReads
Definition: cpu.hh:774
virtual void setStatus(Status new_status)=0
std::vector< BaseInterrupts * > interrupts
Definition: base.hh:218
TheISA::VecElem VecElem
Definition: cpu.hh:102
const VecElem & readVecElem(PhysRegIdPtr phys_reg) const
Reads a vector element.
Definition: regfile.hh:257
~FullO3CPU()
Destructor.
Definition: cpu.cc:365
Stats::Scalar vecPredRegfileWrites
Definition: cpu.hh:784
void wakeCPU()
Wakes the CPU, rescheduling the CPU if it&#39;s not already active.
Definition: cpu.cc:1702
Stats::Vector committedInsts
Stat for the number of committed instructions per thread.
Definition: cpu.hh:761
Stats::Scalar vecRegfileReads
Definition: cpu.hh:780
const VecRegContainer & readVecReg(PhysRegIdPtr reg_idx) const
Definition: cpu.cc:1219
Status _status
Overall CPU status.
Definition: cpu.hh:128
CPUPolicy::Decode decode
The decode stage.
Definition: cpu.hh:565
virtual void activateContext(ThreadID thread_num)
Notify the CPU that the indicated context is now active.
Definition: base.cc:487
void activity()
Records that there is activity this cycle.
Definition: activity.cc:54
void setCCReg(PhysRegIdPtr phys_reg, RegVal val)
Sets a condition-code register to the given value.
Definition: regfile.hh:363
BaseO3CPU(BaseCPUParams *params)
Definition: cpu.cc:72
bool FullSystem
The FullSystem variable can be used to determine the current mode of simulation.
Definition: root.cc:132
unsigned getSize()
Definition: timebuf.hh:241
CPUPolicy::FreeList freeList
The free list.
Definition: cpu.hh:583
const int NumFloatRegs
Definition: registers.hh:83
bool switchedOut() const
Determine if the CPU is switched out.
Definition: base.hh:363
uint64_t RegVal
Definition: types.hh:166
Stats::Scalar miscRegfileReads
Definition: cpu.hh:789
EventFunctionWrapper threadExitEvent
The exit event used for terminating all ready-to-exit threads.
Definition: cpu.hh:136
void advance()
Definition: timebuf.hh:176
constexpr unsigned NumVecElemPerVecReg
Definition: registers.hh:66
ProbePointArg< std::pair< DynInstPtr, PacketPtr > > * ppDataAccessComplete
Definition: cpu.hh:191
void reset()
Clears the time buffer and the activity count.
Definition: activity.cc:124
Overload hash function for BasicBlockRange type.
Definition: vec_reg.hh:587
static Enums::VecRegRenameMode mode(const TheISA::PCState &)
Definition: traits.hh:58
Stats::Vector committedOps
Stat for the number of committed ops (including micro ops) per thread.
Definition: cpu.hh:763
Definition: cprintf.cc:40
void insertThread(ThreadID tid)
Setup CPU to insert a thread&#39;s context.
Definition: cpu.cc:753
void setArchFloatReg(int reg_idx, RegVal val, ThreadID tid)
Definition: cpu.cc:1414
FullO3CPU(DerivO3CPUParams *params)
Constructs a CPU with the given parameters.
Definition: cpu.cc:84
void setArchVecElem(const RegIndex &reg_idx, const ElemIndex &ldx, const VecElem &val, ThreadID tid)
Definition: cpu.cc:1435
Derived & flags(Flags _flags)
Set the flags and marks this stat to print at the end of simulation.
Definition: statistics.hh:333
RegVal readIntReg(PhysRegIdPtr phys_reg) const
Reads an integer register.
Definition: regfile.hh:182
ThreadContext is the external interface to all thread state for anything outside of the CPU...
void tick()
Ticks CPU, calling tick() on each stage, and checking the overall activity to see if the CPU should d...
Definition: cpu.cc:519
const VecElem & readArchVecElem(const RegIndex &reg_idx, const ElemIndex &ldx, ThreadID tid) const
Definition: cpu.cc:1362
TimeBuffer< TimeStruct > timeBuffer
The main time buffer to do backwards communication.
Definition: cpu.hh:636
Event for timing out quiesce instruction.
CPUPolicy::Fetch fetch
The fetch stage.
Definition: cpu.hh:562
ListIt addInst(const DynInstPtr &inst)
Function to add instruction onto the head of the list of the instructions.
Definition: cpu.cc:1509
void trap(const Fault &fault, ThreadID tid, const StaticInstPtr &inst)
Traps to handle given fault.
Definition: cpu.cc:916
CPUPolicy::ROB rob
The re-order buffer.
Definition: cpu.hh:592
DrainState
Object drain/handover states.
Definition: drain.hh:71
void removeInstsUntil(const InstSeqNum &seq_num, ThreadID tid)
Remove all instructions younger than the given sequence number.
Definition: cpu.cc:1598
Derived & init(size_type size)
Set this vector to have the given size.
Definition: statistics.hh:1149
void squashInstIt(const ListIt &instIt, ThreadID tid)
Removes the instruction pointed to by the iterator.
Definition: cpu.cc:1627
Bitfield< 63 > val
Definition: misc.hh:769
RegVal readArchFloatReg(int reg_idx, ThreadID tid)
Definition: cpu.cc:1331
Templated Checker class.
Definition: cpu.hh:618
void regStats() override
Callback to set stat parameters.
Definition: base.cc:384
DrainState drainState() const
Return the current drain state of an object.
Definition: drain.hh:308
Derived ThreadContext class for use with the Checker.
Bitfield< 5, 0 > status
Stats::Formula totalCpi
Stat for the total CPI.
Definition: cpu.hh:767
void verifyMemoryMode() const override
Verify that the system is in a memory mode supported by the CPU.
Definition: cpu.cc:1163
std::vector< ThreadContext * > threadContexts
Definition: base.hh:263
void syscall(ThreadID tid, Fault *fault)
Executes a syscall.
Definition: cpu.cc:925
void setVecReg(PhysRegIdPtr reg_idx, const VecRegContainer &val)
Definition: cpu.cc:1287
Vector Register Native Elem lane.
Definition: reg_class.hh:58
void deactivateThread(ThreadID tid)
Remove Thread from Active Threads List.
Definition: cpu.cc:632
Definition: cpu.hh:79
RegVal readMiscReg(int misc_reg, ThreadID tid)
Reads a misc.
Definition: cpu.cc:1180
Draining buffers pending serialization/handover.
void setArchIntReg(int reg_idx, RegVal val, ThreadID tid)
Architectural register accessors.
Definition: cpu.cc:1403
Tick curTick()
The current simulated tick.
Definition: core.hh:44
Bitfield< 4 > pc
const VecElem & readVecElem(PhysRegIdPtr reg_idx) const
Definition: cpu.cc:1237
void setMiscReg(int misc_reg, RegVal val, ThreadID tid)
Sets a misc.
Definition: cpu.cc:1195
Bitfield< 18 > sum
Definition: registers.hh:610
VecRegContainer & getWritableVecReg(PhysRegIdPtr phys_reg)
Reads a vector register for modification.
Definition: regfile.hh:219
RegVal readArchIntReg(int reg_idx, ThreadID tid)
Definition: cpu.cc:1320
std::list< ThreadID > activeThreads
Active Threads List.
Definition: cpu.hh:595
void schedulePowerGatingEvent()
Definition: base.cc:459
void setFloatReg(PhysRegIdPtr phys_reg, RegVal val)
Definition: cpu.cc:1279
void serializeThread(CheckpointOut &cp, ThreadID tid) const override
Serialize a single thread.
Definition: cpu.cc:945
uint16_t RegIndex
Definition: types.hh:40
void setVecPredReg(PhysRegIdPtr phys_reg, const VecPredRegContainer &val)
Sets a predicate register to the given value.
Definition: regfile.hh:351
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:555
void suspendContext(ThreadID tid) override
Remove Thread from Active Threads List.
Definition: cpu.cc:718
void haltContext(ThreadID tid) override
Remove Thread from Active Threads List && Remove Thread Context from CPU.
Definition: cpu.cc:739
void updateCycleCounters(CPUState state)
base method keeping track of cycle progression
Definition: base.hh:528
Stats::Scalar miscRegfileWrites
Definition: cpu.hh:790
Stats::Scalar intRegfileWrites
Definition: cpu.hh:775
RegVal readCCReg(PhysRegIdPtr phys_reg)
Reads a condition-code register.
Definition: regfile.hh:289
VecRegContainer & getWritableVecReg(PhysRegIdPtr reg_idx)
Read physical vector register for modification.
Definition: cpu.cc:1228
CPUPolicy::Commit commit
The commit stage.
Definition: cpu.hh:574
void setReg(PhysRegIdPtr phys_reg)
Sets the register as ready.
Definition: scoreboard.hh:95
Cycles lastRunningCycle
The cycle that the CPU was last running, used for statistics.
Definition: cpu.hh:704
Derived & prereq(const Stat &prereq)
Set the prerequisite stat and marks this stat to print at the end of simulation.
Definition: statistics.hh:347
void startup() override
startup() is the final initialization call before simulation.
Definition: base.cc:320
Condition-code register.
Definition: reg_class.hh:60
Addr instAddr(ThreadID tid)
Reads the commit PC of a specific thread.
Definition: cpu.cc:1480
void setArchVecPredReg(int reg_idx, const VecPredRegContainer &val, ThreadID tid)
Definition: cpu.cc:1445
ProbePointArg< PacketPtr > * ppInstAccessComplete
Definition: cpu.hh:190
std::vector< ThreadContext * > threadContexts
Definition: system.hh:182
TimeBuffer< DecodeStruct > decodeQueue
The decode stage&#39;s instruction queue.
Definition: cpu.hh:642
void setVecElem(PhysRegIdPtr phys_reg, const VecElem val)
Sets a vector register to the given value.
Definition: regfile.hh:339
void deschedule(Event &event)
Definition: eventq.hh:943
EventFunctionWrapper tickEvent
The tick event used for scheduling CPU ticks.
Definition: cpu.hh:133
uint16_t MicroPC
Definition: types.hh:142
static const Priority CPU_Tick_Pri
CPU ticks must come after other associated CPU events (such as writebacks).
Definition: eventq.hh:198
Cycles curCycle() const
Determine the current cycle, corresponding to a tick aligned to a clock edge.
void setFloatReg(PhysRegIdPtr phys_reg, RegVal val)
Definition: regfile.hh:314
MicroPC microPC(ThreadID tid)
Reads the commit micro PC of a specific thread.
Definition: cpu.cc:1494
uint64_t InstSeqNum
Definition: inst_seq.hh:37
Counter totalInsts() const override
Count the Total Instructions Committed in the CPU.
Definition: cpu.cc:653
void schedule(Event &event, Tick when)
Definition: eventq.hh:934
void setVecReg(PhysRegIdPtr phys_reg, const VecRegContainer &val)
Sets a vector register to the given value.
Definition: regfile.hh:327
void setVectorsAsReady(ThreadID tid)
Mark vector fields in scoreboard as ready right after switching vector mode, since software may read ...
Definition: cpu.cc:849
TimeBuffer< FetchStruct > fetchQueue
The fetch stage&#39;s instruction queue.
Definition: cpu.hh:639
void activateThread(ThreadID tid)
Add Thread to Active Threads List.
Definition: cpu.cc:614
STL list class.
Definition: stl.hh:51
Tick lastActivatedCycle
The cycle that the CPU was last activated by a new thread.
Definition: cpu.hh:707
void init() override
Initialize the CPU.
Definition: cpu.cc:578
int instcount
Count of total number of dynamic instructions in flight.
Definition: cpu.hh:537
void unscheduleTickEvent()
Unschedule tick event, regardless of its current state.
Definition: cpu.hh:148
Tick nextCycle() const
Based on the clock of the object, determine the start tick of the first cycle that is at least one cy...
void removeThread(ThreadID tid)
Remove all of a thread&#39;s context from CPU.
Definition: cpu.cc:805
uint64_t Addr
Address type This will probably be moved somewhere else in the near future.
Definition: types.hh:140
void regStats()
Callback to set stat parameters.
Definition: cpu.cc:78
Derived & precision(int _precision)
Set the precision and marks this stat to print at the end of simulation.
Definition: statistics.hh:321
Stats::Scalar fpRegfileReads
Definition: cpu.hh:777
int64_t Counter
Statistics counter type.
Definition: types.hh:56
Enums::VecRegRenameMode vecMode
The rename mode of the vector registers.
Definition: cpu.hh:577
Stats::Scalar fpRegfileWrites
Definition: cpu.hh:778
const VecRegContainer & readArchVecReg(int reg_idx, ThreadID tid) const
Definition: cpu.cc:1342
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...
bool tryDrain()
Check if the pipeline has drained and signal drain done.
Definition: cpu.cc:1022
Stats::Scalar vecRegfileWrites
Definition: cpu.hh:781
RegVal readIntReg(PhysRegIdPtr phys_reg)
Definition: cpu.cc:1203
Stats::Scalar quiesceCycles
Stat for total number of cycles the CPU spends descheduled due to a quiesce operation or waiting for ...
Definition: cpu.hh:759
std::queue< ListIt > removeList
List of all the instructions that will be removed at the end of this cycle.
Definition: cpu.hh:546
const FlagsType total
Print the total.
Definition: info.hh:49
virtual void switchOut()
Prepare for another CPU to take over execution.
Definition: base.cc:539
void setMiscRegNoEffect(int misc_reg, RegVal val, ThreadID tid)
Sets a miscellaneous register.
Definition: cpu.cc:1188
const ThreadID InvalidThreadID
Definition: types.hh:226
void removeInstsNotInROB(ThreadID tid)
Remove all instructions that are not currently in the ROB.
Definition: cpu.cc:1553
Stats::Formula cpi
Stat for the CPI per thread.
Definition: cpu.hh:765
Checker< Impl > * checker
Pointer to the checker, which can dynamically verify instruction results at run time.
Definition: cpu.hh:692
bool isThreadExiting(ThreadID tid) const
Is the thread trying to exit?
Definition: cpu.cc:1788
bool scheduled() const
Determine if the current event is scheduled.
Definition: eventq.hh:459
ProbeManager * getProbeManager()
Get the probe manager for this object.
Definition: sim_object.cc:117
FreeList class that simply holds the list of free integer and floating point registers.
Definition: free_list.hh:115
Physical register ID.
Definition: reg_class.hh:223
const VecPredRegContainer & readVecPredReg(PhysRegIdPtr phys_reg) const
Reads a predicate register.
Definition: regfile.hh:270
Bitfield< 9 > e
Derived & name(const std::string &name)
Set the name and marks this stat to print at the end of simulation.
Definition: statistics.hh:276
int16_t ThreadID
Thread index/ID type.
Definition: types.hh:225
void switchOut() override
Switches out this CPU.
Definition: cpu.cc:1126
virtual const std::string name() const
Definition: sim_object.hh:129
O3CPU * cpu
Pointer to the CPU.
ProbePointArg generates a point for the class of Arg.
void regProbePoints() override
Register probe points for this object.
Definition: base.cc:350
ThreadContext * tcBase(ThreadID tid)
Returns a pointer to a thread context.
Definition: cpu.hh:680
void setCCReg(PhysRegIdPtr phys_reg, RegVal val)
Definition: cpu.cc:1312
TimeBuffer< IEWStruct > iewQueue
The IEW stage&#39;s instruction queue.
Definition: cpu.hh:648
std::ostream CheckpointOut
Definition: serialize.hh:63
O3ThreadState< Impl > Thread
Definition: cpu.hh:108
const int NumIntRegs
Definition: registers.hh:82
uint16_t ElemIndex
Logical vector register elem index type.
Definition: types.hh:43
Permanently shut down.
void startup() override
startup() is the final initialization call before simulation.
Definition: cpu.cc:599
void setArchCCReg(int reg_idx, RegVal val, ThreadID tid)
Definition: cpu.cc:1455
PhysRegFile regFile
The register file.
Definition: cpu.hh:580
void dumpInsts()
Debug function to print all instructions on the list.
Definition: cpu.cc:1674
void deschedulePowerGatingEvent()
Definition: base.cc:451
RegVal readFloatReg(PhysRegIdPtr phys_reg)
Definition: cpu.cc:1211
void setIntReg(PhysRegIdPtr phys_reg, RegVal val)
Sets an integer register to the given value.
Definition: regfile.hh:302
void setVecPredReg(PhysRegIdPtr reg_idx, const VecPredRegContainer &val)
Definition: cpu.cc:1303
const VecPredRegContainer & readArchVecPredReg(int reg_idx, ThreadID tid) const
Definition: cpu.cc:1372
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:655
const int NumCCRegs
Definition: registers.hh:84
Stats::Scalar vecPredRegfileReads
Definition: cpu.hh:783
Stats::Scalar idleCycles
Stat for total number of cycles the CPU spends descheduled.
Definition: cpu.hh:756
Generic predicate register container.
Definition: vec_pred_reg.hh:47
bool active()
Returns if the CPU should be active.
Definition: activity.hh:88
RegVal readCCReg(PhysRegIdPtr phys_reg)
Definition: cpu.cc:1263
Stats::Scalar numCycles
Definition: base.hh:599
void signalDrainDone() const
Signal that an object is drained.
Definition: drain.hh:289
void exitThreads()
Terminate all threads that are ready to exit.
Definition: cpu.cc:1816
const VecRegContainer & readVecReg(PhysRegIdPtr phys_reg) const
Reads a vector register.
Definition: regfile.hh:206
Addr nextInstAddr(ThreadID tid)
Reads the next PC of a specific thread.
Definition: cpu.cc:1487
void init() override
init() is called after all C++ SimObjects have been created and all ports are connected.
Definition: base.cc:277
Helper structure to get the vector register mode for a given ISA.
Definition: traits.hh:53
const RegIndex & index() const
Index accessors.
Definition: reg_class.hh:173
CPUPolicy::RenameMap commitRenameMap[Impl::MaxThreads]
The commit rename map.
Definition: cpu.hh:589
Counter totalOps() const override
Count the Total Ops (including micro ops) committed in the CPU.
Definition: cpu.cc:666
Stats::Scalar ccRegfileReads
Definition: cpu.hh:786
unsigned totalNumPhysRegs() const
Definition: regfile.hh:173
O3CPUImpl ::O3CPU O3CPU
Definition: cpu.hh:100
const int NumVecPredRegs
Definition: registers.hh:98
const VecPredRegContainer & readVecPredReg(PhysRegIdPtr reg_idx) const
Definition: cpu.cc:1245
InstSeqNum globalSeqNum
The global sequence number counter.
Definition: cpu.hh:686
TimeBuffer< RenameStruct > renameQueue
The rename stage&#39;s instruction queue.
Definition: cpu.hh:645
void removeFrontInst(const DynInstPtr &inst)
Remove an instruction from the front end of the list.
Definition: cpu.cc:1539
Scoreboard scoreboard
Integer Register Scoreboard.
Definition: cpu.hh:605
Derived ThreadContext class for use with the O3CPU.
Definition: cpu.hh:72
Register ID: describe an architectural register with its class and index.
Definition: reg_class.hh:75
void regStats() override
Registers statistics.
Definition: cpu.cc:386
Integer register.
Definition: reg_class.hh:53
RegVal readFloatReg(PhysRegIdPtr phys_reg) const
Definition: regfile.hh:192
Derived & desc(const std::string &_desc)
Set the description and marks this stat to print at the end of simulation.
Definition: statistics.hh:309
Temporarily inactive.
DrainState drain() override
Starts draining the CPU&#39;s pipeline of all instructions in order to stop all memory accesses...
Definition: cpu.cc:959
void setArchVecReg(int reg_idx, const VecRegContainer &val, ThreadID tid)
Definition: cpu.cc:1425
RegVal readArchCCReg(int reg_idx, ThreadID tid)
Definition: cpu.cc:1392
CPUPolicy::IEW iew
The issue/execute/writeback stages.
Definition: cpu.hh:571
Vector Register.
Definition: reg_class.hh:56
void setIntReg(PhysRegIdPtr phys_reg, RegVal val)
Definition: cpu.cc:1271
const int ZeroReg
Definition: registers.hh:118
std::list< DynInstPtr >::iterator ListIt
Definition: cpu.hh:110
Bitfield< 5 > t
std::vector< TheISA::ISA * > isa
Definition: cpu.hh:607
bool isTimingMode() const
Is the system in timing mode?
Definition: system.hh:142
void scheduleThreadExitEvent(ThreadID tid)
If a thread is trying to exit and its corresponding trap event has been completed, schedule an event to terminate the thread.
Definition: cpu.cc:1795
std::list< DynInstPtr > instList
List of all the instructions in flight.
Definition: cpu.hh:541
void cleanUpRemovedInsts()
Cleans up all instructions on the remove list.
Definition: cpu.cc:1648
void advance()
Advances the activity buffer, decrementing the activityCount if active communication just left the ti...
Definition: activity.cc:70
void drainSanityCheck() const
Perform sanity checks after a drain.
Definition: cpu.cc:1038
VecPredRegContainer & getWritableVecPredReg(PhysRegIdPtr reg_idx)
Definition: cpu.cc:1254
void drainResume() override
Resumes execution after a drain.
Definition: cpu.cc:1096
O3CPUImpl ::DynInstPtr DynInstPtr
Definition: cpu.hh:99
VecPredRegContainer & getWritableArchVecPredReg(int reg_idx, ThreadID tid)
Definition: cpu.cc:1382
GenericISA::DelaySlotPCState< MachInst > PCState
Definition: types.hh:41
void commitDrained(ThreadID tid)
Commit has reached a safe point to drain a thread.
Definition: cpu.cc:1089
Running normally.
virtual void wakeup(ThreadID tid) override
Definition: cpu.cc:1724
O3ThreadState< Impl > * thread
Pointer to the thread state that this TC corrseponds to.
void instDone(ThreadID tid, const DynInstPtr &inst)
Function to tell the CPU that an instruction has completed.
Definition: cpu.cc:1518
std::shared_ptr< FaultBase > Fault
Definition: types.hh:238
const Params * params() const
Definition: base.hh:307
void updateThreadPriority()
Update The Order In Which We Process Threads.
Definition: cpu.cc:1751
void processInterrupts(const Fault &interrupt)
Processes any an interrupt fault.
Definition: cpu.cc:899
Stats::Formula totalIpc
Stat for the total IPC.
Definition: cpu.hh:771
RegVal readMiscRegNoEffect(int misc_reg, ThreadID tid) const
Register accessors.
Definition: cpu.cc:1173
CPUPolicy::RenameMap renameMap[Impl::MaxThreads]
The rename map.
Definition: cpu.hh:586
void pcState(const TheISA::PCState &newPCState, ThreadID tid)
Sets the commit PC state of a specific thread.
Definition: cpu.cc:1473
Counter totalNumInsts
Definition: system.hh:480
virtual void suspendContext(ThreadID thread_num)
Notify the CPU that the indicated context is now suspended.
Definition: base.cc:501
void cprintf(const char *format, const Args &...args)
Definition: cprintf.hh:152
void addThreadToExitingList(ThreadID tid)
Insert tid to the list of threads trying to exit.
Definition: cpu.cc:1768
FullO3CPU class, has each of the stages (fetch through commit) within it, as well as all of the time ...
Definition: cpu.hh:94
void regProbePoints() override
Register probe points.
Definition: cpu.cc:371
Stats::Scalar ccRegfileWrites
Definition: cpu.hh:787
CPUPolicy::Rename rename
The dispatch stage.
Definition: cpu.hh:568
const int NumVecRegs
Definition: registers.hh:97

Generated on Fri Jul 3 2020 15:42:38 for gem5 by doxygen 1.8.13