52#include "enums/OpClass.hh"
53#include "params/BaseO3CPU.hh"
68 :
Event(Stat_Event_Pri, AutoDelete),
69 inst(_inst), fuIdx(fu_idx), iqPtr(iq_ptr), freeFU(false)
76 iqPtr->processFUCompletion(inst, freeFU ? fuIdx : -1);
84 return "Functional unit completion";
88 const BaseO3CPUParams ¶ms)
102 const auto ®_classes = params.isa[0]->regClasses();
105 numPhysRegs = params.numPhysIntRegs + params.numPhysFloatRegs +
106 params.numPhysVecRegs +
107 params.numPhysVecRegs * (
110 params.numPhysVecPredRegs +
111 params.numPhysMatRegs +
112 params.numPhysCCRegs;
130 if (
iqPolicy == SMTQueuePolicy::Dynamic) {
136 }
else if (
iqPolicy == SMTQueuePolicy::Partitioned) {
145 DPRINTF(IQ,
"IQ sharing policy set to Partitioned:"
146 "%i entries per thread.\n",part_amt);
147 }
else if (
iqPolicy == SMTQueuePolicy::Threshold) {
148 double threshold = (double)params.smtIQThreshold / 100;
150 int thresholdIQ = (int)((
double)threshold *
numEntries);
157 DPRINTF(IQ,
"IQ sharing policy set to Threshold:"
158 "%i entries per thread.\n",thresholdIQ);
169 cprintf(
"Nodes traversed: %i, removed: %i\n",
181 : statistics::
Group(cpu),
182 ADD_STAT(instsAdded, statistics::units::Count::get(),
183 "Number of instructions added to the IQ (excludes non-spec)"),
184 ADD_STAT(nonSpecInstsAdded, statistics::units::Count::get(),
185 "Number of non-speculative instructions added to the IQ"),
186 ADD_STAT(instsIssued, statistics::units::Count::get(),
187 "Number of instructions issued"),
188 ADD_STAT(intInstsIssued, statistics::units::Count::get(),
189 "Number of integer instructions issued"),
190 ADD_STAT(floatInstsIssued, statistics::units::Count::get(),
191 "Number of float instructions issued"),
192 ADD_STAT(branchInstsIssued, statistics::units::Count::get(),
193 "Number of branch instructions issued"),
194 ADD_STAT(memInstsIssued, statistics::units::Count::get(),
195 "Number of memory instructions issued"),
196 ADD_STAT(miscInstsIssued, statistics::units::Count::get(),
197 "Number of miscellaneous instructions issued"),
198 ADD_STAT(squashedInstsIssued, statistics::units::Count::get(),
199 "Number of squashed instructions issued"),
200 ADD_STAT(squashedInstsExamined, statistics::units::Count::get(),
201 "Number of squashed instructions iterated over during squash; "
202 "mainly for profiling"),
203 ADD_STAT(squashedOperandsExamined, statistics::units::Count::get(),
204 "Number of squashed operands that are examined and possibly "
205 "removed from graph"),
206 ADD_STAT(squashedNonSpecRemoved, statistics::units::Count::get(),
207 "Number of squashed non-spec instructions that were removed"),
208 ADD_STAT(numIssuedDist, statistics::units::Count::get(),
209 "Number of insts issued each cycle"),
210 ADD_STAT(statFuBusy, statistics::units::Count::get(),
211 "attempts to use FU when none available"),
212 ADD_STAT(statIssuedInstType, statistics::units::Count::get(),
213 "Number of instructions issued per FU type, per thread"),
214 ADD_STAT(issueRate, statistics::units::Rate<
215 statistics::units::Count, statistics::units::Cycle>::get(),
216 "Inst issue rate", instsIssued / cpu->baseStats.numCycles),
217 ADD_STAT(fuBusy, statistics::units::Count::get(),
"FU busy when requested"),
218 ADD_STAT(fuBusyRate, statistics::units::Rate<
219 statistics::units::Count, statistics::units::Count>::get(),
220 "FU busy rate (busy events/executed inst)")
269 .
init(0,total_width,1)
329 : statistics::
Group(parent),
330 ADD_STAT(intInstQueueReads, statistics::units::Count::get(),
331 "Number of integer instruction queue reads"),
332 ADD_STAT(intInstQueueWrites, statistics::units::Count::get(),
333 "Number of integer instruction queue writes"),
334 ADD_STAT(intInstQueueWakeupAccesses, statistics::units::Count::get(),
335 "Number of integer instruction queue wakeup accesses"),
336 ADD_STAT(fpInstQueueReads, statistics::units::Count::get(),
337 "Number of floating instruction queue reads"),
338 ADD_STAT(fpInstQueueWrites, statistics::units::Count::get(),
339 "Number of floating instruction queue writes"),
340 ADD_STAT(fpInstQueueWakeupAccesses, statistics::units::Count::get(),
341 "Number of floating instruction queue wakeup accesses"),
342 ADD_STAT(vecInstQueueReads, statistics::units::Count::get(),
343 "Number of vector instruction queue reads"),
344 ADD_STAT(vecInstQueueWrites, statistics::units::Count::get(),
345 "Number of vector instruction queue writes"),
346 ADD_STAT(vecInstQueueWakeupAccesses, statistics::units::Count::get(),
347 "Number of vector instruction queue wakeup accesses"),
348 ADD_STAT(intAluAccesses, statistics::units::Count::get(),
349 "Number of integer alu accesses"),
350 ADD_STAT(fpAluAccesses, statistics::units::Count::get(),
351 "Number of floating point alu accesses"),
352 ADD_STAT(vecAluAccesses, statistics::units::Count::get(),
353 "Number of vector alu accesses")
355 using namespace statistics;
482 if (
iqPolicy == SMTQueuePolicy::Partitioned) {
499 while (threads != end) {
502 if (
iqPolicy == SMTQueuePolicy::Partitioned) {
504 }
else if (
iqPolicy == SMTQueuePolicy::Threshold &&
505 active_threads == 1) {
565 if (new_inst->isFloating()) {
567 }
else if (new_inst->isVector()) {
575 DPRINTF(IQ,
"Adding instruction [sn:%llu] PC %s to the IQ.\n",
576 new_inst->seqNum, new_inst->pcState());
580 instList[new_inst->threadNumber].push_back(new_inst);
594 if (new_inst->isMemRef()) {
602 count[new_inst->threadNumber]++;
612 if (new_inst->isFloating()) {
614 }
else if (new_inst->isVector()) {
624 DPRINTF(IQ,
"Adding non-speculative instruction [sn:%llu] PC %s "
626 new_inst->seqNum, new_inst->pcState());
630 instList[new_inst->threadNumber].push_back(new_inst);
642 if (new_inst->isMemRef()) {
648 count[new_inst->threadNumber]++;
667 if (inst->isFloating()) {
669 }
else if (inst->isVector()) {
691 while (list_it != list_end_it) {
692 if ((*list_it).oldestInst > queue_entry.
oldestInst) {
712 OpClass op_class = (*list_order_it).
queueType;
721 (*next_it).oldestInst < queue_entry.
oldestInst) {
731 DPRINTF(IQ,
"Processing FU completion [sn:%llu]\n", inst->seqNum);
754 DPRINTF(IQ,
"Attempting to schedule ready instructions from "
777 int total_issued = 0;
781 while (total_issued <
totalWidth && order_it != order_end_it) {
782 OpClass op_class = (*order_it).queueType;
788 if (issuing_inst->isFloating()) {
790 }
else if (issuing_inst->isVector()) {
796 assert(issuing_inst->seqNum == (*order_it).oldestInst);
798 if (issuing_inst->isSquashed()) {
817 ThreadID tid = issuing_inst->threadNumber;
819 if (op_class != No_OpClass) {
821 if (issuing_inst->isFloating()) {
823 }
else if (issuing_inst->isVector()) {
836 if (op_latency ==
Cycles(1)) {
864 DPRINTF(IQ,
"Thread %i: Issuing instruction PC %s "
866 tid, issuing_inst->pcState(),
867 issuing_inst->seqNum);
878 issuing_inst->setIssued();
882 issuing_inst->issueTick =
curTick() - issuing_inst->fetchTick;
885 if (issuing_inst->firstIssue == -1)
886 issuing_inst->firstIssue =
curTick();
888 if (!issuing_inst->isMemRef()) {
893 issuing_inst->clearInIQ();
917 DPRINTF(IQ,
"Not able to schedule any instructions.\n");
924 DPRINTF(IQ,
"Marking nonspeculative instruction [sn:%llu] as ready "
925 "to execute.\n", inst);
931 ThreadID tid = (*inst_it).second->threadNumber;
933 (*inst_it).second->setAtCommit();
935 (*inst_it).second->setCanIssue();
937 if (!(*inst_it).second->isMemRef()) {
943 (*inst_it).second = NULL;
951 DPRINTF(IQ,
"[tid:%i] Committing instructions older than [sn:%llu]\n",
956 while (iq_it !=
instList[tid].end() &&
957 (*iq_it)->seqNum <= inst) {
971 if (completed_inst->isFloating()) {
973 }
else if (completed_inst->isVector()) {
979 completed_inst->lastWakeDependents =
curTick();
981 DPRINTF(IQ,
"Waking dependents of completed instruction.\n");
983 assert(!completed_inst->isSquashed());
988 ThreadID tid = completed_inst->threadNumber;
989 if (completed_inst->isMemRef()) {
992 DPRINTF(IQ,
"Completing mem instruction PC: %s [sn:%llu]\n",
993 completed_inst->pcState(), completed_inst->seqNum);
996 completed_inst->memOpDone(
true);
998 }
else if (completed_inst->isReadBarrier() ||
999 completed_inst->isWriteBarrier()) {
1004 for (
int dest_reg_idx = 0;
1005 dest_reg_idx < completed_inst->numDestRegs();
1009 completed_inst->renamedDestIdx(dest_reg_idx);
1014 DPRINTF(IQ,
"Reg %d [%s] is part of a fix mapping, skipping\n",
1022 completed_inst->setPinnedRegsWritten();
1025 DPRINTF(IQ,
"Reg %d [%s] is pinned, skipping\n",
1030 DPRINTF(IQ,
"Waking any dependents on register %i (%s).\n",
1039 DPRINTF(IQ,
"Waking up a dependent instruction, [sn:%llu] "
1040 "PC %s.\n", dep_inst->seqNum, dep_inst->pcState());
1046 dep_inst->markSrcRegReady();
1069 OpClass op_class = ready_inst->opClass();
1078 (*
readyIt[op_class]).oldestInst) {
1083 DPRINTF(IQ,
"Instruction is ready to issue, putting it onto "
1084 "the ready list, PC %s opclass:%i [sn:%llu].\n",
1085 ready_inst->pcState(), op_class, ready_inst->seqNum);
1091 DPRINTF(IQ,
"Rescheduling mem inst [sn:%llu]\n", resched_inst->seqNum);
1094 resched_inst->translationStarted(
false);
1095 resched_inst->translationCompleted(
false);
1097 resched_inst->clearCanIssue();
1116 blocked_inst->clearIssued();
1117 blocked_inst->clearCanIssue();
1119 DPRINTF(IQ,
"Memory inst [sn:%llu] PC %s is blocked, will be "
1120 "reissued later\n", blocked_inst->seqNum,
1121 blocked_inst->pcState());
1127 DPRINTF(IQ,
"Cache is unblocked, rescheduling blocked memory "
1139 if ((*it)->translationCompleted() || (*it)->isSquashed()) {
1171 DPRINTF(IQ,
"[tid:%i] Starting to squash instructions in "
1191 DPRINTF(IQ,
"[tid:%i] Squashing until sequence number %i!\n",
1196 while (squash_it !=
instList[tid].end() &&
1200 if (squashed_inst->isFloating()) {
1202 }
else if (squashed_inst->isVector()) {
1210 if (squashed_inst->threadNumber != tid ||
1211 squashed_inst->isSquashedInIQ()) {
1216 if (!squashed_inst->isIssued() ||
1217 (squashed_inst->isMemRef() &&
1218 !squashed_inst->memOpDone())) {
1220 DPRINTF(IQ,
"[tid:%i] Instruction [sn:%llu] PC %s squashed.\n",
1221 tid, squashed_inst->seqNum, squashed_inst->pcState());
1223 bool is_acq_rel = squashed_inst->isFullMemBarrier() &&
1224 (squashed_inst->isLoad() ||
1225 (squashed_inst->isStore() &&
1226 !squashed_inst->isStoreConditional()));
1230 (!squashed_inst->isNonSpeculative() &&
1231 !squashed_inst->isStoreConditional() &&
1232 !squashed_inst->isAtomic() &&
1233 !squashed_inst->isReadBarrier() &&
1234 !squashed_inst->isWriteBarrier())) {
1236 for (
int src_reg_idx = 0;
1237 src_reg_idx < squashed_inst->numSrcRegs();
1241 squashed_inst->renamedSrcIdx(src_reg_idx);
1252 if (!squashed_inst->readySrcIdx(src_reg_idx) &&
1261 }
else if (!squashed_inst->isStoreConditional() ||
1262 !squashed_inst->isCompleted()) {
1273 assert(squashed_inst->getFault() !=
NoFault ||
1274 squashed_inst->isMemRef());
1277 (*ns_inst_it).second = NULL;
1288 squashed_inst->setSquashedInIQ();
1292 squashed_inst->setIssued();
1293 squashed_inst->setCanCommit();
1294 squashed_inst->clearInIQ();
1297 count[squashed_inst->threadNumber]--;
1309 for (
int dest_reg_idx = 0;
1310 dest_reg_idx < squashed_inst->numDestRegs();
1314 squashed_inst->renamedDestIdx(dest_reg_idx);
1330 return lhs->seqNum > rhs->seqNum;
1338 int8_t total_src_regs = new_inst->numSrcRegs();
1339 bool return_val =
false;
1341 for (
int src_reg_idx = 0;
1342 src_reg_idx < total_src_regs;
1346 if (!new_inst->readySrcIdx(src_reg_idx)) {
1347 PhysRegIdPtr src_reg = new_inst->renamedSrcIdx(src_reg_idx);
1356 DPRINTF(IQ,
"Instruction PC %s has src reg %i (%s) that "
1357 "is being added to the dependency chain.\n",
1358 new_inst->pcState(), src_reg->
index(),
1367 DPRINTF(IQ,
"Instruction PC %s has src reg %i (%s) that "
1368 "became ready before it reached the IQ.\n",
1369 new_inst->pcState(), src_reg->
index(),
1372 new_inst->markSrcRegReady(src_reg_idx);
1387 int8_t total_dest_regs = new_inst->numDestRegs();
1389 for (
int dest_reg_idx = 0;
1390 dest_reg_idx < total_dest_regs;
1393 PhysRegIdPtr dest_reg = new_inst->renamedDestIdx(dest_reg_idx);
1403 panic(
"Dependency graph %i (%s) (flat: %i) not empty!",
1420 if (inst->readyToIssue()) {
1423 if (inst->isMemRef()) {
1425 DPRINTF(IQ,
"Checking if memory instruction can issue.\n");
1434 OpClass op_class = inst->opClass();
1436 DPRINTF(IQ,
"Instruction is ready to issue, putting it onto "
1437 "the ready list, PC %s opclass:%i [sn:%llu].\n",
1438 inst->pcState(), op_class, inst->seqNum);
1447 (*
readyIt[op_class]).oldestInst) {
1474 cprintf(
"Non speculative list: ");
1476 while (non_spec_it != non_spec_end_it) {
1477 cprintf(
"%s [sn:%llu]", (*non_spec_it).second->pcState(),
1478 (*non_spec_it).second->seqNum);
1490 while (list_order_it != list_order_end_it) {
1491 cprintf(
"%i OpClass:%i [sn:%llu] ",
i, (*list_order_it).queueType,
1492 (*list_order_it).oldestInst);
1510 while (inst_list_it !=
instList[tid].end()) {
1511 cprintf(
"Instruction:%i\n", num);
1512 if (!(*inst_list_it)->isSquashed()) {
1513 if (!(*inst_list_it)->isIssued()) {
1515 cprintf(
"Count:%i\n", valid_num);
1516 }
else if ((*inst_list_it)->isMemRef() &&
1517 !(*inst_list_it)->memOpDone()) {
1521 cprintf(
"Count:%i\n", valid_num);
1525 cprintf(
"PC: %s\n[sn:%llu]\n[tid:%i]\n"
1526 "Issued:%i\nSquashed:%i\n",
1527 (*inst_list_it)->pcState(),
1528 (*inst_list_it)->seqNum,
1529 (*inst_list_it)->threadNumber,
1530 (*inst_list_it)->isIssued(),
1531 (*inst_list_it)->isSquashed());
1533 if ((*inst_list_it)->isMemRef()) {
1534 cprintf(
"MemOpDone:%i\n", (*inst_list_it)->memOpDone());
1544 cprintf(
"Insts to Execute list:\n");
1554 if (!(*inst_list_it)->isSquashed()) {
1555 if (!(*inst_list_it)->isIssued()) {
1557 cprintf(
"Count:%i\n", valid_num);
1558 }
else if ((*inst_list_it)->isMemRef() &&
1559 !(*inst_list_it)->memOpDone()) {
1563 cprintf(
"Count:%i\n", valid_num);
1567 cprintf(
"PC: %s\n[sn:%llu]\n[tid:%i]\n"
1568 "Issued:%i\nSquashed:%i\n",
1569 (*inst_list_it)->pcState(),
1570 (*inst_list_it)->seqNum,
1571 (*inst_list_it)->threadNumber,
1572 (*inst_list_it)->isIssued(),
1573 (*inst_list_it)->isSquashed());
1575 if ((*inst_list_it)->isMemRef()) {
1576 cprintf(
"MemOpDone:%i\n", (*inst_list_it)->memOpDone());
ThreadID numThreads
Number of threads we're actually simulating (<= SMT_MAX_THREADS).
bool switchedOut() const
Determine if the CPU is switched out.
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...
Cycles is a wrapper class for representing cycle counts, i.e.
virtual std::string name() const
const RegIndex & flatIndex() const
Flat index accessor.
constexpr RegIndex index() const
Visible RegId methods.
int getNumPinnedWritesToComplete() const
void decrNumPinnedWritesToComplete()
constexpr const char * className() const
Return a const char* with the register class name.
bool isFixedMapping() const
Returns true if this register is always associated to the same architectural register.
O3CPU class, has each of the stages (fetch through commit) within it, as well as all of the time buff...
void activityThisCycle()
Records that there was time buffer activity this cycle.
void wakeCPU()
Wakes the CPU, rescheduling the CPU if it's not already active.
void freeUnitNextCycle(int fu_idx)
Frees a FU at the end of this cycle.
Cycles getOpLatency(OpClass capability)
Returns the operation execution latency of the given capability.
bool isPipelined(OpClass capability)
Returns the issue latency of the given capability.
static constexpr auto NoCapableFU
static constexpr auto NoFreeFU
int getUnit(OpClass capability)
Gets a FU providing the requested capability.
IEW handles both single threaded and SMT IEW (issue/execute/writeback).
void wakeCPU()
Tells the CPU to wakeup if it has descheduled itself due to no activity.
FU completion event class.
FUCompletion(const DynInstPtr &_inst, int fu_idx, InstructionQueue *iq_ptr)
Construct a FU completion event.
virtual const char * description() const
Return a C string describing the event.
A standard instruction queue class.
std::string name() const
Returns the name of the IQ.
void commit(const InstSeqNum &inst, ThreadID tid=0)
Commits all instructions up to and including the given sequence number, for a specific thread.
gem5::o3::InstructionQueue::IQStats iqStats
void processFUCompletion(const DynInstPtr &inst, int fu_idx)
Process FU completion event.
DynInstPtr getBlockedMemInstToExecute()
Gets a memory instruction that was blocked on the cache.
std::list< DynInstPtr > instList[MaxThreads]
List of all the instructions in the IQ (some of which may be issued).
std::list< DynInstPtr > retryMemInsts
List of instructions that were cache blocked, but a retry has been seen since, so they can now be ret...
void deferMemInst(const DynInstPtr &deferred_inst)
Defers a memory instruction when its DTB translation incurs a hw page table walk.
ReadyInstQueue readyInsts[Num_OpClasses]
List of ready instructions, per op class.
unsigned totalWidth
The total number of instructions that can be issued in one cycle.
void addIfReady(const DynInstPtr &inst)
Moves an instruction to the ready queue if it is ready.
unsigned numEntries
The number of entries in the instruction queue.
void insertBarrier(const DynInstPtr &barr_inst)
Inserts a memory or write barrier into the IQ to make sure loads and stores are ordered properly.
bool queueOnList[Num_OpClasses]
Tracks if each ready queue is on the age order list.
FUPool * fuPool
Function unit pool.
int wakeDependents(const DynInstPtr &completed_inst)
Wakes all dependents of a completed instruction.
std::list< DynInstPtr > deferredMemInsts
List of instructions waiting for their DTB translation to complete (hw page table walk in progress).
TimeBuffer< IssueStruct > * issueToExecuteQueue
The queue to the execute stage.
std::list< DynInstPtr > instsToExecute
List of instructions that are ready to be executed.
void setTimeBuffer(TimeBuffer< TimeStruct > *tb_ptr)
Sets the global time buffer.
unsigned numFreeEntries()
Returns total number of free entries.
std::list< DynInstPtr > blockedMemInsts
List of instructions that have been cache blocked.
void rescheduleMemInst(const DynInstPtr &resched_inst)
Reschedules a memory instruction.
TimeBuffer< TimeStruct >::wire fromCommit
Wire to read information from timebuffer.
void insertNonSpec(const DynInstPtr &new_inst)
Inserts a new, non-speculative instruction into the IQ.
void addReadyMemInst(const DynInstPtr &ready_inst)
Adds a ready memory instruction to the ready list.
void replayMemInst(const DynInstPtr &replay_inst)
Replays a memory instruction.
void resetState()
Resets all instruction queue state.
bool isDrained() const
Determine if we are drained.
unsigned count[MaxThreads]
Per Thread IQ count.
void cacheUnblocked()
Notify instruction queue that a previous blockage has resolved.
std::map< InstSeqNum, DynInstPtr > nonSpecInsts
List of non-speculative instructions that will be scheduled once the IQ gets a signal from commit.
unsigned freeEntries
Number of free IQ entries left.
MemDepUnit memDepUnit[MaxThreads]
The memory dependence unit, which tracks/predicts memory dependences between instructions.
void dumpLists()
Debugging function to dump all the list sizes, as well as print out the list of nonspeculative instru...
void blockMemInst(const DynInstPtr &blocked_inst)
Defers a memory instruction when it is cache blocked.
void drainSanityCheck() const
Perform sanity checks after a drain.
unsigned numPhysRegs
The number of physical registers in the CPU.
DynInstPtr getDeferredMemInstToExecute()
Gets a memory instruction that was referred due to a delayed DTB translation if it is now ready to ex...
void dumpInsts()
Debugging function to dump out all instructions that are in the IQ.
void takeOverFrom()
Takes over execution from another CPU's thread.
SMTQueuePolicy iqPolicy
IQ sharing policy for SMT.
gem5::o3::InstructionQueue::IQIOStats iqIOStats
void moveToYoungerInst(ListOrderIt age_order_it)
Called when the oldest instruction has been removed from a ready queue; this places that ready queue ...
InstructionQueue(CPU *cpu_ptr, IEW *iew_ptr, const BaseO3CPUParams ¶ms)
Constructs an IQ.
InstSeqNum squashedSeqNum[MaxThreads]
The sequence number of the squashed instruction.
void violation(const DynInstPtr &store, const DynInstPtr &faulting_load)
Indicates an ordering violation between a store and a load.
std::list< DynInstPtr >::iterator ListIt
bool hasReadyInsts()
Returns if there are any ready instructions in the IQ.
Cycles commitToIEWDelay
Delay between commit stage and the IQ.
void resetEntries()
Resets max entries for all threads.
int countInsts()
Debugging function to count how many entries are in the IQ.
std::list< ThreadID > * activeThreads
Pointer to list of active threads.
std::list< ListOrderEntry >::iterator ListOrderIt
void setActiveThreads(std::list< ThreadID > *at_ptr)
Sets active threads list.
void addToOrderList(OpClass op_class)
Add an op class to the age order list.
ThreadID numThreads
Number of Total Threads.
TimeBuffer< TimeStruct > * timeBuffer
The backwards time buffer.
void scheduleNonSpec(const InstSeqNum &inst)
Schedules a single specific non-speculative instruction.
std::vector< bool > regScoreboard
A cache of the recently woken registers.
void scheduleReadyInsts()
Schedules ready instructions, adding the ready ones (oldest first) to the queue to execute.
bool isFull()
Returns whether or not the IQ is full.
void squash(ThreadID tid)
Squashes instructions for a thread.
IEW * iewStage
Pointer to IEW stage.
std::list< ListOrderEntry > listOrder
List that contains the age order of the oldest instruction of each ready queue.
~InstructionQueue()
Destructs the IQ.
void doSquash(ThreadID tid)
Does the actual squashing.
void setIssueToExecuteQueue(TimeBuffer< IssueStruct > *i2eQueue)
Sets the timer buffer between issue and execute.
int wbOutstanding
Number of instructions currently in flight to FUs.
void insert(const DynInstPtr &new_inst)
Inserts a new instruction into the IQ.
unsigned maxEntries[MaxThreads]
Max IQ Entries Per Thread.
CPU * cpu
Pointer to the CPU.
bool addToDependents(const DynInstPtr &new_inst)
Adds an instruction to the dependency graph, as a consumer.
int entryAmount(ThreadID num_threads)
Number of entries needed for given amount of threads.
DynInstPtr getInstToExecute()
Returns the oldest scheduled instruction, and removes it from the list of instructions waiting to exe...
DependencyGraph< DynInstPtr > dependGraph
ListOrderIt readyIt[Num_OpClasses]
Iterators of each ready queue.
void addToProducers(const DynInstPtr &new_inst)
Adds an instruction to the dependency graph, as a producer.
std::map< InstSeqNum, DynInstPtr >::iterator NonSpecMapIt
void completeInst(const DynInstPtr &inst)
Notifies completion of an instruction.
void nonSpecInstReady(const DynInstPtr &inst)
Indicate that a non-speculative instruction is ready.
void issue(const DynInstPtr &inst)
Issues the given instruction.
void insert(const DynInstPtr &inst)
Inserts a memory instruction.
void squash(const InstSeqNum &squashed_num, ThreadID tid)
Squashes all instructions up until a given sequence number for a specific thread.
void violation(const DynInstPtr &store_inst, const DynInstPtr &violating_load)
Indicates an ordering violation between a store and a younger load.
void replay()
Replays all instructions that have been rescheduled by moving them to the ready list.
void init(const BaseO3CPUParams ¶ms, ThreadID tid, CPU *cpu)
Initializes the unit with parameters and a thread id.
void regsReady(const DynInstPtr &inst)
Indicate that an instruction has its registers ready.
void insertNonSpec(const DynInstPtr &inst)
Inserts a non-speculative memory instruction.
void reschedule(const DynInstPtr &inst)
Reschedules an instruction to be re-executed.
void insertBarrier(const DynInstPtr &barr_inst)
Inserts a barrier instruction.
void setIQ(InstructionQueue *iq_ptr)
Sets the pointer to the IQ.
Derived & ysubnames(const char **names)
Derived & subname(off_type index, const std::string &name)
Set the subfield name for the given index, and marks this stat to print at the end of simulation.
Derived & flags(Flags _flags)
Set the flags and marks this stat to print at the end of simulation.
Derived & prereq(const Stat &prereq)
Set the prerequisite stat and marks this stat to print at the end of simulation.
void sample(const U &v, int n=1)
Add a value to the distribtion n times.
Distribution & init(Counter min, Counter max, Counter bkt)
Set the parameters of this distribution.
Derived & init(size_type _x, size_type _y)
Derived & init(size_type size)
Set this vector to have the given size.
#define ADD_STAT(n,...)
Convenience macro to add a stat to a statistics group.
void schedule(Event &event, Tick when)
#define panic(...)
This implements a cprintf based panic() function.
static constexpr int MaxThreads
const FlagsType pdf
Print the percent of the total that this entry represents.
const FlagsType total
Print the total.
const FlagsType dist
Print the distribution.
Copyright (c) 2024 - Pranith Kumar Copyright (c) 2020 Inria All rights reserved.
int16_t ThreadID
Thread index/ID type.
static const OpClass Num_OpClasses
void cprintf(const char *format, const Args &...args)
Tick curTick()
The universal simulation clock.
constexpr decltype(nullptr) NoFault
@ VecRegClass
Vector Register.
@ VecElemClass
Vector Register Native Elem lane.
statistics::Scalar intInstQueueReads
statistics::Scalar vecInstQueueWrites
statistics::Scalar fpInstQueueWrites
statistics::Scalar fpInstQueueReads
statistics::Scalar vecInstQueueReads
statistics::Scalar vecAluAccesses
statistics::Scalar intAluAccesses
statistics::Scalar vecInstQueueWakeupAccesses
statistics::Scalar intInstQueueWakeupAccesses
statistics::Scalar intInstQueueWrites
IQIOStats(statistics::Group *parent)
statistics::Scalar fpAluAccesses
statistics::Scalar fpInstQueueWakeupAccesses
statistics::Vector2d statIssuedInstType
Stat for total number issued for each instruction type.
statistics::Scalar floatInstsIssued
Stat for number of floating point instructions issued.
statistics::Vector fuBusy
Number of times the FU was busy.
statistics::Scalar instsAdded
Stat for number of instructions added.
statistics::Distribution numIssuedDist
Distribution of number of instructions in the queue.
statistics::Scalar nonSpecInstsAdded
Stat for number of non-speculative instructions added.
statistics::Scalar squashedInstsExamined
Stat for number of squashed instructions examined when squashing.
statistics::Scalar miscInstsIssued
Stat for number of miscellaneous instructions issued.
statistics::Scalar branchInstsIssued
Stat for number of branch instructions issued.
statistics::Formula fuBusyRate
Number of times the FU was busy per instruction issued.
statistics::Scalar memInstsIssued
Stat for number of memory instructions issued.
statistics::Scalar intInstsIssued
Stat for number of integer instructions issued.
statistics::Scalar instsIssued
statistics::Formula issueRate
Number of instructions issued per cycle.
IQStats(CPU *cpu, const unsigned &total_width)
statistics::Scalar squashedOperandsExamined
Stat for number of squashed instruction operands examined when squashing.
statistics::Scalar squashedInstsIssued
Stat for number of squashed instructions that were ready to issue.
statistics::Vector statFuBusy
Distribution of the cycles it takes to issue an instruction.
statistics::Scalar squashedNonSpecRemoved
Stat for number of non-speculative instructions removed due to a squash.
Entry for the list age ordering by op class.
bool operator()(const DynInstPtr &lhs, const DynInstPtr &rhs) const