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

Generated on Fri Feb 28 2020 16:26:56 for gem5 by doxygen 1.8.13