49 #include "arch/kernel_stats.hh"
50 #include "config/the_isa.hh"
59 #include "debug/Activity.hh"
60 #include "debug/Drain.hh"
61 #include "debug/O3CPU.hh"
62 #include "debug/Quiesce.hh"
63 #include "enums/MemoryMode.hh"
70 #if THE_ISA == ALPHA_ISA
72 #include "debug/Activity.hh"
78 using namespace TheISA;
100 fetch->processCacheCompletion(pkt);
109 fetch->recvReqRetry();
112 template <
class Impl>
116 return lsq->recvTimingResp(pkt);
119 template <
class Impl>
123 for (
ThreadID tid = 0; tid < cpu->numThreads; tid++) {
124 if (cpu->getCpuAddrMonitor(tid)->doMonitor(pkt)) {
128 lsq->recvTimingSnoopReq(pkt);
131 template <
class Impl>
138 template <
class Impl>
140 :
Event(CPU_Tick_Pri), cpu(c)
144 template <
class Impl>
151 template <
class Impl>
155 return "FullO3CPU tick";
158 template <
class Impl>
174 regFile(params->numPhysIntRegs,
175 params->numPhysFloatRegs,
176 params->numPhysCCRegs),
186 isa(numThreads, NULL),
191 timeBuffer(params->backComSize, params->forwardComSize),
192 fetchQueue(params->backComSize, params->forwardComSize),
193 decodeQueue(params->backComSize, params->forwardComSize),
194 renameQueue(params->backComSize, params->forwardComSize),
195 iewQueue(params->backComSize, params->forwardComSize),
197 params->backComSize + params->forwardComSize,
204 if (!params->switched_out) {
210 if (params->checker) {
211 BaseCPU *temp_checker = params->checker;
214 checker->setSystem(params->system);
220 thread.resize(numThreads);
221 tids.resize(numThreads);
262 active_threads = params->workload.size();
264 if (active_threads > Impl::MaxThreads) {
265 panic(
"Workload Size too large. Increase the 'MaxThreads' "
266 "constant in your O3CPU impl. file (e.g. o3/alpha/impl.hh) "
267 "or edit your workload size.");
280 for (
ThreadID tid = 0; tid < numThreads; tid++) {
281 isa[tid] = params->isa[tid];
286 RegIndex invalidFPReg = TheISA::NumFloatRegs + 1;
299 for (
ThreadID tid = 0; tid < active_threads; tid++) {
304 renameMap[tid].setIntEntry(ridx, phys_reg);
310 renameMap[tid].setFloatEntry(ridx, phys_reg);
316 renameMap[tid].setCCEntry(ridx, phys_reg);
331 for (
ThreadID tid = 0; tid < numThreads; tid++)
338 this->
thread.resize(this->numThreads);
340 for (
ThreadID tid = 0; tid < this->numThreads; ++tid) {
343 assert(this->numThreads == 1);
346 if (tid < params->workload.size()) {
350 (
typename Impl::O3CPU *)(
this),
351 tid, params->workload[tid]);
361 (
typename Impl::O3CPU *)(
this),
376 if (params->checker) {
381 o3_tc->
cpu = (
typename Impl::O3CPU *)(
this);
389 this->
thread[tid]->tc = tc;
392 this->threadContexts.push_back(tc);
396 if (!params->switched_out && interrupts.empty()) {
397 fatal(
"FullO3CPU %s has no interrupt controller.\n"
398 "Ensure createInterruptController() is called.\n",
name());
401 for (
ThreadID tid = 0; tid < this->numThreads; tid++)
402 this->
thread[tid]->setFuncExeInst(0);
405 template <
class Impl>
410 template <
class Impl>
414 BaseCPU::regProbePoints();
419 fetch.regProbePoints();
420 rename.regProbePoints();
421 iew.regProbePoints();
422 commit.regProbePoints();
425 template <
class Impl>
433 .name(
name() +
".timesIdled")
434 .desc(
"Number of times that the entire CPU went into an idle state and"
435 " unscheduled itself")
439 .name(
name() +
".idleCycles")
440 .desc(
"Total number of cycles that the CPU has spent unscheduled due "
445 .name(
name() +
".quiesceCycles")
446 .desc(
"Total number of cycles that CPU has spent quiesced or waiting "
456 .name(
name() +
".committedInsts")
457 .desc(
"Number of Instructions Simulated")
462 .name(
name() +
".committedOps")
463 .desc(
"Number of Ops (including micro ops) Simulated")
467 .name(
name() +
".cpi")
468 .desc(
"CPI: Cycles Per Instruction")
470 cpi = numCycles / committedInsts;
473 .name(
name() +
".cpi_total")
474 .desc(
"CPI: Total CPI of All Threads")
476 totalCpi = numCycles /
sum(committedInsts);
479 .name(
name() +
".ipc")
480 .desc(
"IPC: Instructions Per Cycle")
482 ipc = committedInsts / numCycles;
485 .name(
name() +
".ipc_total")
486 .desc(
"IPC: Total IPC of All Threads")
488 totalIpc =
sum(committedInsts) / numCycles;
490 this->fetch.regStats();
491 this->decode.regStats();
492 this->rename.regStats();
493 this->iew.regStats();
494 this->commit.regStats();
495 this->rob.regStats();
498 .name(
name() +
".int_regfile_reads")
499 .desc(
"number of integer regfile reads")
500 .prereq(intRegfileReads);
503 .name(
name() +
".int_regfile_writes")
504 .desc(
"number of integer regfile writes")
505 .prereq(intRegfileWrites);
508 .name(
name() +
".fp_regfile_reads")
509 .desc(
"number of floating regfile reads")
510 .prereq(fpRegfileReads);
513 .name(
name() +
".fp_regfile_writes")
514 .desc(
"number of floating regfile writes")
515 .prereq(fpRegfileWrites);
518 .name(
name() +
".cc_regfile_reads")
519 .desc(
"number of cc regfile reads")
520 .prereq(ccRegfileReads);
523 .name(
name() +
".cc_regfile_writes")
524 .desc(
"number of cc regfile writes")
525 .prereq(ccRegfileWrites);
528 .name(
name() +
".misc_regfile_reads")
529 .desc(
"number of misc regfile reads")
530 .prereq(miscRegfileReads);
533 .name(
name() +
".misc_regfile_writes")
534 .desc(
"number of misc regfile writes")
535 .prereq(miscRegfileWrites);
538 template <
class Impl>
542 DPRINTF(
O3CPU,
"\n\nFullO3CPU: Ticking main, FullO3CPU.\n");
543 assert(!switchedOut());
563 timeBuffer.advance();
565 fetchQueue.advance();
566 decodeQueue.advance();
567 renameQueue.advance();
570 activityRec.advance();
572 if (removeInstsThisCycle) {
573 cleanUpRemovedInsts();
576 if (!tickEvent.scheduled()) {
577 if (_status == SwitchedOut) {
580 lastRunningCycle = curCycle();
581 }
else if (!activityRec.active() || _status == Idle) {
583 lastRunningCycle = curCycle();
586 schedule(tickEvent, clockEdge(
Cycles(1)));
592 updateThreadPriority();
597 template <
class Impl>
603 for (
ThreadID tid = 0; tid < numThreads; ++tid) {
606 thread[tid]->noSquashFromTC =
true;
608 thread[tid]->initMemProxies(thread[tid]->getTC());
612 for (
ThreadID tid = 0; tid < numThreads; tid++) {
619 for (
int tid = 0; tid < numThreads; ++tid)
620 thread[tid]->noSquashFromTC =
false;
622 commit.setThreads(thread);
625 template <
class Impl>
630 for (
int tid = 0; tid < numThreads; ++tid)
631 isa[tid]->startup(threadContexts[tid]);
633 fetch.startupStage();
634 decode.startupStage();
636 rename.startupStage();
637 commit.startupStage();
640 template <
class Impl>
645 std::find(activeThreads.begin(), activeThreads.end(), tid);
647 DPRINTF(
O3CPU,
"[tid:%i]: Calling activate thread.\n", tid);
648 assert(!switchedOut());
650 if (isActive == activeThreads.end()) {
651 DPRINTF(
O3CPU,
"[tid:%i]: Adding to active threads list\n",
654 activeThreads.push_back(tid);
658 template <
class Impl>
664 std::find(activeThreads.begin(), activeThreads.end(), tid);
666 DPRINTF(
O3CPU,
"[tid:%i]: Calling deactivate thread.\n", tid);
667 assert(!switchedOut());
669 if (thread_it != activeThreads.end()) {
670 DPRINTF(
O3CPU,
"[tid:%i]: Removing from active threads list\n",
672 activeThreads.erase(thread_it);
675 fetch.deactivateThread(tid);
676 commit.deactivateThread(tid);
679 template <
class Impl>
687 total += thread[
i]->numInst;
692 template <
class Impl>
700 total += thread[
i]->numOp;
705 template <
class Impl>
709 assert(!switchedOut());
722 if (lastActivatedCycle == 0 || lastActivatedCycle <
curTick()) {
723 scheduleTickEvent(
Cycles(0));
727 activityRec.activity();
728 fetch.wakeFromQuiesce();
730 Cycles cycles(curCycle() - lastRunningCycle);
736 lastActivatedCycle =
curTick();
740 BaseCPU::activateContext(tid);
744 template <
class Impl>
748 DPRINTF(
O3CPU,
"[tid: %i]: Suspending Thread Context.\n", tid);
749 assert(!switchedOut());
751 deactivateThread(tid);
754 if (activeThreads.size() == 0) {
755 unscheduleTickEvent();
756 lastRunningCycle = curCycle();
760 DPRINTF(Quiesce,
"Suspending Context\n");
762 BaseCPU::suspendContext(tid);
765 template <
class Impl>
770 DPRINTF(
O3CPU,
"[tid:%i]: Halt Context called. Deallocating", tid);
771 assert(!switchedOut());
773 deactivateThread(tid);
777 template <
class Impl>
786 src_tc =
system->threadContexts[tid];
788 src_tc = tcBase(tid);
794 renameMap[tid].setEntry(ireg,phys_reg);
795 scoreboard.setReg(phys_reg);
803 renameMap[tid].setEntry(freg,phys_reg);
804 scoreboard.setReg(phys_reg);
810 creg < max_reg; creg++) {
813 renameMap[tid].setEntry(creg,phys_reg);
814 scoreboard.setReg(phys_reg);
821 pcState(src_tc->
pcState(), tid);
825 activateContext(tid);
828 commit.rob->resetEntries();
832 template <
class Impl>
836 DPRINTF(
O3CPU,
"[tid:%i] Removing thread context from CPU.\n", tid);
850 scoreboard.unsetReg(phys_reg);
851 freeList.addReg(phys_reg);
858 scoreboard.unsetReg(phys_reg);
859 freeList.addReg(phys_reg);
866 scoreboard.unsetReg(phys_reg);
867 freeList.addReg(phys_reg);
871 DynInstPtr inst = commit.rob->readHeadInst(tid);
873 fetch.squash(0, squash_seq_num, inst, tid);
875 rename.squash(squash_seq_num, tid);
877 iew.ldstQueue.squash(squash_seq_num, tid);
878 commit.rob->squash(squash_seq_num, tid);
881 assert(iew.instQueue.getCount(tid) == 0);
882 assert(iew.ldstQueue.getCount(tid) == 0);
898 template <
class Impl>
902 #if THE_ISA == ALPHA_ISA
906 this->thread[tid]->kernelStats->hwrei();
913 template <
class Impl>
917 #if THE_ISA == ALPHA_ISA
918 if (this->thread[tid]->kernelStats)
919 this->thread[tid]->kernelStats->callpal(palFunc,
920 this->threadContexts[tid]);
931 if (this->
system->breakpoint())
939 template <
class Impl>
944 return this->interrupts[0]->getInterrupt(this->threadContexts[0]);
947 template <
class Impl>
958 this->interrupts[0]->updateIntrInfo(this->threadContexts[0]);
960 DPRINTF(
O3CPU,
"Interrupt %s being handled\n", interrupt->name());
961 this->trap(interrupt, 0,
nullptr);
964 template <
class Impl>
970 fault->invoke(this->threadContexts[tid], inst);
973 template <
class Impl>
977 DPRINTF(
O3CPU,
"[tid:%i] Executing syscall().\n\n", tid);
979 DPRINTF(Activity,
"Activity: syscall() called.\n");
983 ++(this->thread[tid]->funcExeInst);
986 this->thread[tid]->syscall(callnum, fault);
990 --(this->thread[tid]->funcExeInst);
993 template <
class Impl>
997 thread[tid]->serialize(cp);
1000 template <
class Impl>
1004 thread[tid]->unserialize(cp);
1007 template <
class Impl>
1015 DPRINTF(Drain,
"Draining...\n");
1029 activityRec.activity();
1031 DPRINTF(Drain,
"CPU not drained\n");
1035 DPRINTF(Drain,
"CPU is already drained\n");
1036 if (tickEvent.scheduled())
1037 deschedule(tickEvent);
1043 for (
int i = 0;
i < timeBuffer.getSize(); ++
i) {
1044 timeBuffer.advance();
1045 fetchQueue.advance();
1046 decodeQueue.advance();
1047 renameQueue.advance();
1056 template <
class Impl>
1063 if (tickEvent.scheduled())
1064 deschedule(tickEvent);
1066 DPRINTF(Drain,
"CPU done draining, processing drain event\n");
1072 template <
class Impl>
1076 assert(isDrained());
1077 fetch.drainSanityCheck();
1078 decode.drainSanityCheck();
1079 rename.drainSanityCheck();
1080 iew.drainSanityCheck();
1081 commit.drainSanityCheck();
1084 template <
class Impl>
1090 if (!instList.empty() || !removeList.empty()) {
1091 DPRINTF(Drain,
"Main CPU structures not drained.\n");
1095 if (!fetch.isDrained()) {
1096 DPRINTF(Drain,
"Fetch not drained.\n");
1100 if (!decode.isDrained()) {
1101 DPRINTF(Drain,
"Decode not drained.\n");
1105 if (!rename.isDrained()) {
1106 DPRINTF(Drain,
"Rename not drained.\n");
1110 if (!iew.isDrained()) {
1111 DPRINTF(Drain,
"IEW not drained.\n");
1115 if (!commit.isDrained()) {
1116 DPRINTF(Drain,
"Commit not drained.\n");
1123 template <
class Impl>
1127 fetch.drainStall(tid);
1130 template <
class Impl>
1137 DPRINTF(Drain,
"Resuming...\n");
1140 fetch.drainResume();
1141 commit.drainResume();
1146 DPRINTF(Drain,
"Activating thread: %i\n",
i);
1152 assert(!tickEvent.scheduled());
1154 schedule(tickEvent, nextCycle());
1157 template <
class Impl>
1162 BaseCPU::switchOut();
1164 activityRec.reset();
1166 _status = SwitchedOut;
1169 checker->switchOut();
1172 template <
class Impl>
1178 fetch.takeOverFrom();
1179 decode.takeOverFrom();
1180 rename.takeOverFrom();
1182 commit.takeOverFrom();
1184 assert(!tickEvent.scheduled());
1190 lastRunningCycle = curCycle();
1194 template <
class Impl>
1198 if (!
system->isTimingMode()) {
1199 fatal(
"The O3 CPU requires the memory system to be in "
1200 "'timing' mode.\n");
1204 template <
class Impl>
1208 return this->isa[tid]->readMiscRegNoEffect(misc_reg);
1211 template <
class Impl>
1216 return this->isa[tid]->readMiscReg(misc_reg, tcBase(tid));
1219 template <
class Impl>
1224 this->isa[tid]->setMiscRegNoEffect(misc_reg, val);
1227 template <
class Impl>
1232 miscRegfileWrites++;
1233 this->isa[tid]->setMiscReg(misc_reg, val, tcBase(tid));
1236 template <
class Impl>
1241 return regFile.readIntReg(reg_idx);
1244 template <
class Impl>
1249 return regFile.readFloatReg(reg_idx);
1252 template <
class Impl>
1257 return regFile.readFloatRegBits(reg_idx);
1260 template <
class Impl>
1265 return regFile.readCCReg(reg_idx);
1268 template <
class Impl>
1273 regFile.setIntReg(reg_idx, val);
1276 template <
class Impl>
1281 regFile.setFloatReg(reg_idx, val);
1284 template <
class Impl>
1289 regFile.setFloatRegBits(reg_idx, val);
1292 template <
class Impl>
1297 regFile.setCCReg(reg_idx, val);
1300 template <
class Impl>
1305 PhysRegIndex phys_reg = commitRenameMap[tid].lookupInt(reg_idx);
1307 return regFile.readIntReg(phys_reg);
1310 template <
class Impl>
1315 PhysRegIndex phys_reg = commitRenameMap[tid].lookupFloat(reg_idx);
1317 return regFile.readFloatReg(phys_reg);
1320 template <
class Impl>
1325 PhysRegIndex phys_reg = commitRenameMap[tid].lookupFloat(reg_idx);
1327 return regFile.readFloatRegBits(phys_reg);
1330 template <
class Impl>
1335 PhysRegIndex phys_reg = commitRenameMap[tid].lookupCC(reg_idx);
1337 return regFile.readCCReg(phys_reg);
1340 template <
class Impl>
1345 PhysRegIndex phys_reg = commitRenameMap[tid].lookupInt(reg_idx);
1347 regFile.setIntReg(phys_reg, val);
1350 template <
class Impl>
1355 PhysRegIndex phys_reg = commitRenameMap[tid].lookupFloat(reg_idx);
1357 regFile.setFloatReg(phys_reg, val);
1360 template <
class Impl>
1365 PhysRegIndex phys_reg = commitRenameMap[tid].lookupFloat(reg_idx);
1367 regFile.setFloatRegBits(phys_reg, val);
1370 template <
class Impl>
1375 PhysRegIndex phys_reg = commitRenameMap[tid].lookupCC(reg_idx);
1377 regFile.setCCReg(phys_reg, val);
1380 template <
class Impl>
1384 return commit.pcState(tid);
1387 template <
class Impl>
1391 commit.pcState(val, tid);
1394 template <
class Impl>
1398 return commit.instAddr(tid);
1401 template <
class Impl>
1405 return commit.nextInstAddr(tid);
1408 template <
class Impl>
1412 return commit.microPC(tid);
1415 template <
class Impl>
1419 this->thread[tid]->noSquashFromTC =
true;
1420 this->commit.generateTCEvent(tid);
1423 template <
class Impl>
1427 instList.push_back(inst);
1429 return --(instList.end());
1432 template <
class Impl>
1437 if (!inst->isMicroop() || inst->isLastMicroop()) {
1438 thread[tid]->numInst++;
1439 thread[tid]->numInsts++;
1440 committedInsts[tid]++;
1444 comInstEventQueue[tid]->serviceEvents(thread[tid]->numInst);
1445 system->instEventQueue.serviceEvents(
system->totalNumInsts);
1447 thread[tid]->numOp++;
1448 thread[tid]->numOps++;
1449 committedOps[tid]++;
1451 probeInstCommit(inst->staticInst);
1454 template <
class Impl>
1458 DPRINTF(
O3CPU,
"Removing committed instruction [tid:%i] PC %s "
1460 inst->threadNumber, inst->pcState(), inst->seqNum);
1462 removeInstsThisCycle =
true;
1465 removeList.push(inst->getInstListIt());
1468 template <
class Impl>
1472 DPRINTF(
O3CPU,
"Thread %i: Deleting instructions from instruction"
1477 bool rob_empty =
false;
1479 if (instList.empty()) {
1481 }
else if (rob.isEmpty(tid)) {
1482 DPRINTF(
O3CPU,
"ROB is empty, squashing all insts.\n");
1483 end_it = instList.begin();
1486 end_it = (rob.readTailInst(tid))->getInstListIt();
1487 DPRINTF(
O3CPU,
"ROB is not empty, squashing insts not in ROB.\n");
1490 removeInstsThisCycle =
true;
1492 ListIt inst_it = instList.end();
1498 while (inst_it != end_it) {
1499 assert(!instList.empty());
1501 squashInstIt(inst_it, tid);
1509 squashInstIt(inst_it, tid);
1513 template <
class Impl>
1517 assert(!instList.empty());
1519 removeInstsThisCycle =
true;
1521 ListIt inst_iter = instList.end();
1525 DPRINTF(
O3CPU,
"Deleting instructions from instruction "
1526 "list that are from [tid:%i] and above [sn:%lli] (end=%lli).\n",
1527 tid, seq_num, (*inst_iter)->seqNum);
1529 while ((*inst_iter)->seqNum > seq_num) {
1531 bool break_loop = (inst_iter == instList.begin());
1533 squashInstIt(inst_iter, tid);
1542 template <
class Impl>
1546 if ((*instIt)->threadNumber == tid) {
1548 "[tid:%i] [sn:%lli] PC %s\n",
1549 (*instIt)->threadNumber,
1551 (*instIt)->pcState());
1554 (*instIt)->setSquashed();
1559 removeList.push(instIt);
1563 template <
class Impl>
1567 while (!removeList.empty()) {
1569 "[tid:%i] [sn:%lli] PC %s\n",
1570 (*removeList.front())->threadNumber,
1571 (*removeList.front())->seqNum,
1572 (*removeList.front())->pcState());
1574 instList.erase(removeList.front());
1579 removeInstsThisCycle =
false;
1589 template <
class Impl>
1595 ListIt inst_list_it = instList.begin();
1597 cprintf(
"Dumping Instruction List\n");
1599 while (inst_list_it != instList.end()) {
1600 cprintf(
"Instruction:%i\nPC:%#x\n[tid:%i]\n[sn:%lli]\nIssued:%i\n"
1602 num, (*inst_list_it)->instAddr(), (*inst_list_it)->threadNumber,
1603 (*inst_list_it)->seqNum, (*inst_list_it)->isIssued(),
1604 (*inst_list_it)->isSquashed());
1617 template <
class Impl>
1621 if (activityRec.active() || tickEvent.scheduled()) {
1622 DPRINTF(Activity,
"CPU already running.\n");
1626 DPRINTF(Activity,
"Waking up CPU\n");
1628 Cycles cycles(curCycle() - lastRunningCycle);
1632 idleCycles += cycles;
1633 numCycles += cycles;
1634 ppCycles->notify(cycles);
1637 schedule(tickEvent, clockEdge());
1640 template <
class Impl>
1649 DPRINTF(Quiesce,
"Suspended Processor woken\n");
1650 this->threadContexts[tid]->activate();
1653 template <
class Impl>
1657 for (
ThreadID tid = 0; tid < numThreads; tid++) {
1667 template <
class Impl>
1671 if (activeThreads.size() > 1) {
1676 unsigned high_thread = *list_begin;
1678 activeThreads.erase(list_begin);
1680 activeThreads.push_back(high_thread);
void unserializeThread(CheckpointIn &cp, ThreadID tid) override
DcachePort dcachePort
Data port.
std::vector< ThreadID > tids
Available thread ids in the cpu.
bool isUncacheable() const
Accessor functions for flags.
bool removeInstsThisCycle
Records if instructions need to be removed this cycle due to being retired or squashed.
virtual void recvReqRetry()
Handles doing a retry of a failed fetch.
decltype(nullptr) constexpr NoFault
void setArchFloatReg(int reg_idx, float val, ThreadID tid)
Cycles is a wrapper class for representing cycle counts, i.e.
void syscall(int64_t callnum, ThreadID tid, Fault *fault)
Executes a syscall.
ThreadID getFreeTid()
Gets a free thread id.
const char * description() const
Returns the description of the tick event.
void squashFromTC(ThreadID tid)
Initiates a squash of all in-flight instructions for a given thread.
const std::string & name()
IcachePort icachePort
Instruction port.
System * system
Pointer to the system.
uint64_t readIntReg(int reg_idx)
std::vector< Thread * > thread
Pointers to all of the threads in the CPU.
DrainState
Object drain/handover states.
Fault getInterrupts()
Returns the Fault for any valid interrupt.
TickEvent(FullO3CPU< Impl > *c)
Constructs a tick event.
void activateContext(ThreadID tid) override
Add Thread to Active Threads List.
void takeOverFrom(BaseCPU *oldCPU) override
Takes over from another CPU.
virtual void setStatus(Status new_status)=0
Fault hwrei(ThreadID tid)
HW return from error interrupt.
void wakeCPU()
Wakes the CPU, rescheduling the CPU if it's not already active.
TheISA::CCReg readArchCCReg(int reg_idx, ThreadID tid)
Status _status
Overall CPU status.
CPUPolicy::Decode decode
The decode stage.
BaseO3CPU(BaseCPUParams *params)
bool FullSystem
The FullSystem variable can be used to determine the current mode of simulation.
CPUPolicy::FreeList freeList
The free list.
TheISA::MiscReg readMiscReg(int misc_reg, ThreadID tid)
Reads a misc.
uint64_t readArchIntReg(int reg_idx, ThreadID tid)
void quiesceCycles(ThreadContext *tc, uint64_t cycles)
virtual TheISA::PCState pcState()=0
void setArchIntReg(int reg_idx, uint64_t val, ThreadID tid)
Architectural register accessors.
void insertThread(ThreadID tid)
Setup CPU to insert a thread's context.
FullO3CPU(DerivO3CPUParams *params)
Constructs a CPU with the given parameters.
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...
TimeBuffer< TimeStruct > timeBuffer
The main time buffer to do backwards communication.
Event for timing out quiesce instruction.
CPUPolicy::Fetch fetch
The fetch stage.
void trap(const Fault &fault, ThreadID tid, const StaticInstPtr &inst)
Traps to handle given fault.
void setMiscRegNoEffect(int misc_reg, const TheISA::MiscReg &val, ThreadID tid)
Sets a miscellaneous register.
void removeFrontInst(DynInstPtr &inst)
Remove an instruction from the front end of the list.
CPUPolicy::ROB rob
The re-order buffer.
void removeInstsUntil(const InstSeqNum &seq_num, ThreadID tid)
Remove all instructions younger than the given sequence number.
void squashInstIt(const ListIt &instIt, ThreadID tid)
Removes the instruction pointed to by the iterator.
void drainSanityCheck() const
Perform sanity checks after a drain.
Derived ThreadContext class for use with the Checker.
void verifyMemoryMode() const override
virtual void recvReqRetry()
Handles doing a retry of the previous send.
void setArchFloatRegInt(int reg_idx, uint64_t val, ThreadID tid)
void deactivateThread(ThreadID tid)
Remove Thread from Active Threads List.
Tick curTick()
The current simulated tick.
std::list< ThreadID > activeThreads
Active Threads List.
void serializeThread(CheckpointOut &cp, ThreadID tid) const override
void suspendContext(ThreadID tid) override
Remove Thread from Active Threads List.
void takeOverFrom(ThreadContext &ntc, ThreadContext &otc)
Copy state between thread contexts in preparation for CPU handover.
void haltContext(ThreadID tid) override
Remove Thread from Active Threads List && Remove Thread Context from CPU.
void initCPU(ThreadContext *tc, int cpuId)
CPUPolicy::Commit commit
The commit stage.
Cycles lastRunningCycle
The cycle that the CPU was last running, used for statistics.
Addr instAddr(ThreadID tid)
Reads the commit PC of a specific thread.
TimeBuffer< DecodeStruct > decodeQueue
The decode stage's instruction queue.
const RequestPtr req
A pointer to the original request.
ListIt addInst(DynInstPtr &inst)
Function to add instruction onto the head of the list of the instructions.
MicroPC microPC(ThreadID tid)
Reads the commit micro PC of a specific thread.
Counter totalInsts() const override
Count the Total Instructions Committed in the CPU.
TheISA::CCReg readCCReg(int reg_idx)
virtual void recvTimingSnoopReq(PacketPtr pkt)
Receive a timing snoop request from the slave port.
TimeBuffer< FetchStruct > fetchQueue
The fetch stage's instruction queue.
void activateThread(ThreadID tid)
Add Thread to Active Threads List.
Tick lastActivatedCycle
The cycle that the CPU was last activated by a new thread.
void init() override
Initialize the CPU.
int instcount
Count of total number of dynamic instructions in flight.
void removeThread(ThreadID tid)
Remove all of a thread's context from CPU.
uint64_t Addr
Address type This will probably be moved somewhere else in the near future.
bool cacheResponding() const
Draining buffers pending serialization/handover.
int64_t Counter
Statistics counter type.
A Packet is used to encapsulate a transfer between two objects in the memory system (e...
virtual bool recvTimingResp(PacketPtr pkt)
Timing version of receive.
bool tryDrain()
Check if the pipeline has drained and signal drain done.
const FlagsType total
Print the total.
const ThreadID InvalidThreadID
void removeInstsNotInROB(ThreadID tid)
Remove all instructions that are not currently in the ROB.
Checker< Impl > * checker
Pointer to the checker, which can dynamically verify instruction results at run time.
void setIntReg(int reg_idx, uint64_t val)
int16_t ThreadID
Thread index/ID type.
TheISA::FloatReg readFloatReg(int reg_idx)
DefaultFetch< Impl > * fetch
Pointer to fetch.
void switchOut() override
Switches out this CPU.
ProbePointArg generates a point for the class of Arg.
void exitSimLoop(const std::string &message, int exit_code, Tick when, Tick repeat, bool serialize)
Schedule an event to exit the simulation loop (returning to Python) at the end of the current cycle (...
O3CPU * cpu
Pointer to the CPU.
void wakeCPU(ThreadContext *tc, uint64_t cpuid)
TimeBuffer< IEWStruct > iewQueue
The IEW stage's instruction queue.
void process()
Processes a tick event, calling tick() on the CPU.
bool simPalCheck(int palFunc, ThreadID tid)
std::ostream CheckpointOut
static int numSystemsRunning
O3ThreadState< Impl > Thread
void setMiscReg(int misc_reg, const TheISA::MiscReg &val, ThreadID tid)
Sets a misc.
PhysRegFile regFile
The register file.
void dumpInsts()
Debug function to print all instructions on the list.
GenericISA::SimplePCState< MachInst > PCState
void setFloatRegBits(int reg_idx, TheISA::FloatRegBits val)
ActivityRecorder activityRec
The activity recorder; used to tell if the CPU has any activity remaining or if it can go to idle and...
void setFloatReg(int reg_idx, TheISA::FloatReg val)
O3ThreadState< Impl > * thread
Pointer to the thread state that this TC corrseponds to.
virtual int contextId() const =0
TheISA::FloatRegBits readFloatRegBits(int reg_idx)
Addr nextInstAddr(ThreadID tid)
Reads the next PC of a specific thread.
uint64_t readArchFloatRegInt(int reg_idx, ThreadID tid)
void setCCReg(int reg_idx, TheISA::CCReg val)
CPUPolicy::RenameMap commitRenameMap[Impl::MaxThreads]
The commit rename map.
Counter totalOps() const override
Count the Total Ops (including micro ops) committed in the CPU.
InstSeqNum globalSeqNum
The global sequence number counter.
TimeBuffer< RenameStruct > renameQueue
The rename stage's instruction queue.
TheISA::MiscReg readMiscRegNoEffect(int misc_reg, ThreadID tid) const
Register accessors.
Scoreboard scoreboard
Integer Register Scoreboard.
Derived ThreadContext class for use with the O3CPU.
void regStats() override
Registers statistics.
DrainState drain() override
Starts draining the CPU's pipeline of all instructions in order to stop all memory accesses...
CPUPolicy::IEW iew
The issue/execute/writeback stages.
void setArchCCReg(int reg_idx, TheISA::CCReg val, ThreadID tid)
std::list< DynInstPtr >::iterator ListIt
float readArchFloatReg(int reg_idx, ThreadID tid)
std::vector< TheISA::ISA * > isa
void cleanUpRemovedInsts()
Cleans up all instructions on the remove list.
virtual bool recvTimingResp(PacketPtr pkt)
Timing version of receive.
TickEvent tickEvent
The tick event used for scheduling CPU ticks.
void drainResume() override
Resumes execution after a drain.
Impl::DynInstPtr DynInstPtr
void commitDrained(ThreadID tid)
Commit has reached a safe point to drain a thread.
virtual void wakeup(ThreadID tid) override
std::shared_ptr< FaultBase > Fault
void instDone(ThreadID tid, DynInstPtr &inst)
Function to tell the CPU that an instruction has completed.
void updateThreadPriority()
Update The Order In Which We Process Threads.
void processInterrupts(const Fault &interrupt)
Processes any an interrupt fault.
const FlagsType init
This Stat is Initialized.
CPUPolicy::RenameMap renameMap[Impl::MaxThreads]
The rename map.
bool isDrained() const
Check if a system is in a drained state.
void pcState(const TheISA::PCState &newPCState, ThreadID tid)
Sets the commit PC state of a specific thread.
void cprintf(const char *format, const Args &...args)
FullO3CPU class, has each of the stages (fetch through commit) within it, as well as all of the time ...
void regProbePoints() override
Register probe points.
CPUPolicy::Rename rename
The dispatch stage.