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()) {
837 if (op_latency ==
Cycles(1)) {
853 issuing_inst->setNoCapableFU();
875 DPRINTF(IQ,
"Thread %i: Issuing instruction PC %s "
877 tid, issuing_inst->pcState(),
878 issuing_inst->seqNum);
889 issuing_inst->setIssued();
893 issuing_inst->issueTick =
curTick() - issuing_inst->fetchTick;
896 if (issuing_inst->firstIssue == -1)
897 issuing_inst->firstIssue =
curTick();
899 if (!issuing_inst->isMemRef()) {
904 issuing_inst->clearInIQ();
929 DPRINTF(IQ,
"Not able to schedule any instructions.\n");
936 DPRINTF(IQ,
"Marking nonspeculative instruction [sn:%llu] as ready "
937 "to execute.\n", inst);
943 ThreadID tid = (*inst_it).second->threadNumber;
945 (*inst_it).second->setAtCommit();
947 (*inst_it).second->setCanIssue();
949 if (!(*inst_it).second->isMemRef()) {
955 (*inst_it).second = NULL;
963 DPRINTF(IQ,
"[tid:%i] Committing instructions older than [sn:%llu]\n",
968 while (iq_it !=
instList[tid].end() &&
969 (*iq_it)->seqNum <= inst) {
983 if (completed_inst->isFloating()) {
985 }
else if (completed_inst->isVector()) {
991 completed_inst->lastWakeDependents =
curTick();
993 DPRINTF(IQ,
"Waking dependents of completed instruction.\n");
995 assert(!completed_inst->isSquashed());
1000 ThreadID tid = completed_inst->threadNumber;
1001 if (completed_inst->isMemRef()) {
1004 DPRINTF(IQ,
"Completing mem instruction PC: %s [sn:%llu]\n",
1005 completed_inst->pcState(), completed_inst->seqNum);
1008 completed_inst->memOpDone(
true);
1010 }
else if (completed_inst->isReadBarrier() ||
1011 completed_inst->isWriteBarrier()) {
1016 for (
int dest_reg_idx = 0;
1017 dest_reg_idx < completed_inst->numDestRegs();
1021 completed_inst->renamedDestIdx(dest_reg_idx);
1026 DPRINTF(IQ,
"Reg %d [%s] is part of a fix mapping, skipping\n",
1034 completed_inst->setPinnedRegsWritten();
1037 DPRINTF(IQ,
"Reg %d [%s] is pinned, skipping\n",
1042 DPRINTF(IQ,
"Waking any dependents on register %i (%s).\n",
1051 DPRINTF(IQ,
"Waking up a dependent instruction, [sn:%llu] "
1052 "PC %s.\n", dep_inst->seqNum, dep_inst->pcState());
1058 dep_inst->markSrcRegReady();
1081 OpClass op_class = ready_inst->opClass();
1090 (*
readyIt[op_class]).oldestInst) {
1095 DPRINTF(IQ,
"Instruction is ready to issue, putting it onto "
1096 "the ready list, PC %s opclass:%i [sn:%llu].\n",
1097 ready_inst->pcState(), op_class, ready_inst->seqNum);
1103 DPRINTF(IQ,
"Rescheduling mem inst [sn:%llu]\n", resched_inst->seqNum);
1106 resched_inst->translationStarted(
false);
1107 resched_inst->translationCompleted(
false);
1109 resched_inst->clearCanIssue();
1128 blocked_inst->clearIssued();
1129 blocked_inst->clearCanIssue();
1131 DPRINTF(IQ,
"Memory inst [sn:%llu] PC %s is blocked, will be "
1132 "reissued later\n", blocked_inst->seqNum,
1133 blocked_inst->pcState());
1139 DPRINTF(IQ,
"Cache is unblocked, rescheduling blocked memory "
1151 if ((*it)->translationCompleted() || (*it)->isSquashed()) {
1183 DPRINTF(IQ,
"[tid:%i] Starting to squash instructions in "
1203 DPRINTF(IQ,
"[tid:%i] Squashing until sequence number %i!\n",
1208 while (squash_it !=
instList[tid].end() &&
1212 if (squashed_inst->isFloating()) {
1214 }
else if (squashed_inst->isVector()) {
1222 if (squashed_inst->threadNumber != tid ||
1223 squashed_inst->isSquashedInIQ()) {
1228 if (!squashed_inst->isIssued() ||
1229 (squashed_inst->isMemRef() &&
1230 !squashed_inst->memOpDone())) {
1232 DPRINTF(IQ,
"[tid:%i] Instruction [sn:%llu] PC %s squashed.\n",
1233 tid, squashed_inst->seqNum, squashed_inst->pcState());
1235 bool is_acq_rel = squashed_inst->isFullMemBarrier() &&
1236 (squashed_inst->isLoad() ||
1237 (squashed_inst->isStore() &&
1238 !squashed_inst->isStoreConditional()));
1242 (!squashed_inst->isNonSpeculative() &&
1243 !squashed_inst->isStoreConditional() &&
1244 !squashed_inst->isAtomic() &&
1245 !squashed_inst->isReadBarrier() &&
1246 !squashed_inst->isWriteBarrier())) {
1248 for (
int src_reg_idx = 0;
1249 src_reg_idx < squashed_inst->numSrcRegs();
1253 squashed_inst->renamedSrcIdx(src_reg_idx);
1264 if (!squashed_inst->readySrcIdx(src_reg_idx) &&
1273 }
else if (!squashed_inst->isStoreConditional() ||
1274 !squashed_inst->isCompleted()) {
1285 assert(squashed_inst->getFault() !=
NoFault ||
1286 squashed_inst->isMemRef());
1289 (*ns_inst_it).second = NULL;
1300 squashed_inst->setSquashedInIQ();
1304 squashed_inst->setIssued();
1305 squashed_inst->setCanCommit();
1306 squashed_inst->clearInIQ();
1309 count[squashed_inst->threadNumber]--;
1321 for (
int dest_reg_idx = 0;
1322 dest_reg_idx < squashed_inst->numDestRegs();
1326 squashed_inst->renamedDestIdx(dest_reg_idx);
1342 return lhs->seqNum > rhs->seqNum;
1350 int8_t total_src_regs = new_inst->numSrcRegs();
1351 bool return_val =
false;
1353 for (
int src_reg_idx = 0;
1354 src_reg_idx < total_src_regs;
1358 if (!new_inst->readySrcIdx(src_reg_idx)) {
1359 PhysRegIdPtr src_reg = new_inst->renamedSrcIdx(src_reg_idx);
1368 DPRINTF(IQ,
"Instruction PC %s has src reg %i (%s) that "
1369 "is being added to the dependency chain.\n",
1370 new_inst->pcState(), src_reg->
index(),
1379 DPRINTF(IQ,
"Instruction PC %s has src reg %i (%s) that "
1380 "became ready before it reached the IQ.\n",
1381 new_inst->pcState(), src_reg->
index(),
1384 new_inst->markSrcRegReady(src_reg_idx);
1399 int8_t total_dest_regs = new_inst->numDestRegs();
1401 for (
int dest_reg_idx = 0;
1402 dest_reg_idx < total_dest_regs;
1405 PhysRegIdPtr dest_reg = new_inst->renamedDestIdx(dest_reg_idx);
1415 panic(
"Dependency graph %i (%s) (flat: %i) not empty!",
1432 if (inst->readyToIssue()) {
1435 if (inst->isMemRef()) {
1437 DPRINTF(IQ,
"Checking if memory instruction can issue.\n");
1446 OpClass op_class = inst->opClass();
1448 DPRINTF(IQ,
"Instruction is ready to issue, putting it onto "
1449 "the ready list, PC %s opclass:%i [sn:%llu].\n",
1450 inst->pcState(), op_class, inst->seqNum);
1459 (*
readyIt[op_class]).oldestInst) {
1486 cprintf(
"Non speculative list: ");
1488 while (non_spec_it != non_spec_end_it) {
1489 cprintf(
"%s [sn:%llu]", (*non_spec_it).second->pcState(),
1490 (*non_spec_it).second->seqNum);
1502 while (list_order_it != list_order_end_it) {
1503 cprintf(
"%i OpClass:%i [sn:%llu] ",
i, (*list_order_it).queueType,
1504 (*list_order_it).oldestInst);
1522 while (inst_list_it !=
instList[tid].end()) {
1523 cprintf(
"Instruction:%i\n", num);
1524 if (!(*inst_list_it)->isSquashed()) {
1525 if (!(*inst_list_it)->isIssued()) {
1527 cprintf(
"Count:%i\n", valid_num);
1528 }
else if ((*inst_list_it)->isMemRef() &&
1529 !(*inst_list_it)->memOpDone()) {
1533 cprintf(
"Count:%i\n", valid_num);
1537 cprintf(
"PC: %s\n[sn:%llu]\n[tid:%i]\n"
1538 "Issued:%i\nSquashed:%i\n",
1539 (*inst_list_it)->pcState(),
1540 (*inst_list_it)->seqNum,
1541 (*inst_list_it)->threadNumber,
1542 (*inst_list_it)->isIssued(),
1543 (*inst_list_it)->isSquashed());
1545 if ((*inst_list_it)->isMemRef()) {
1546 cprintf(
"MemOpDone:%i\n", (*inst_list_it)->memOpDone());
1556 cprintf(
"Insts to Execute list:\n");
1566 if (!(*inst_list_it)->isSquashed()) {
1567 if (!(*inst_list_it)->isIssued()) {
1569 cprintf(
"Count:%i\n", valid_num);
1570 }
else if ((*inst_list_it)->isMemRef() &&
1571 !(*inst_list_it)->memOpDone()) {
1575 cprintf(
"Count:%i\n", valid_num);
1579 cprintf(
"PC: %s\n[sn:%llu]\n[tid:%i]\n"
1580 "Issued:%i\nSquashed:%i\n",
1581 (*inst_list_it)->pcState(),
1582 (*inst_list_it)->seqNum,
1583 (*inst_list_it)->threadNumber,
1584 (*inst_list_it)->isIssued(),
1585 (*inst_list_it)->isSquashed());
1587 if ((*inst_list_it)->isMemRef()) {
1588 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
Instruction asked for a FU but this FUPool does not have a FU for this instruction op type.
static constexpr auto NoFreeFU
Instruction asked for a FU but all FU for this op type have already been allocated to other instructi...
static constexpr auto NoNeedFU
Named constants to differentiate cases where an instruction asked the FUPool for a free FU but did no...
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 Arm Limited 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