45 #ifndef __CPU_O3_INST_QUEUE_IMPL_HH__ 46 #define __CPU_O3_INST_QUEUE_IMPL_HH__ 54 #include "debug/IQ.hh" 55 #include "enums/OpClass.hh" 56 #include "params/DerivO3CPU.hh" 66 :
Event(Stat_Event_Pri, AutoDelete),
67 inst(_inst), fuIdx(fu_idx), iqPtr(iq_ptr), freeFU(false)
84 return "Functional unit completion";
89 DerivO3CPUParams *params)
104 numPhysRegs = params->numPhysIntRegs + params->numPhysFloatRegs +
105 params->numPhysVecRegs +
107 params->numPhysVecPredRegs +
108 params->numPhysCCRegs;
118 for (
ThreadID tid = 0; tid < Impl::MaxThreads; tid++) {
126 if (
iqPolicy == SMTQueuePolicy::Dynamic) {
132 }
else if (
iqPolicy == SMTQueuePolicy::Partitioned) {
141 DPRINTF(IQ,
"IQ sharing policy set to Partitioned:" 142 "%i entries per thread.\n",part_amt);
143 }
else if (
iqPolicy == SMTQueuePolicy::Threshold) {
144 double threshold = (double)params->smtIQThreshold / 100;
146 int thresholdIQ = (
int)((double)threshold *
numEntries);
153 DPRINTF(IQ,
"IQ sharing policy set to Threshold:" 154 "%i entries per thread.\n",thresholdIQ);
161 template <
class Impl>
166 cprintf(
"Nodes traversed: %i, removed: %i\n",
171 template <
class Impl>
175 return cpu->name() +
".iq";
178 template <
class Impl>
182 using namespace Stats;
185 .
desc(
"Number of instructions added to the IQ (excludes non-spec)")
189 .
name(
name() +
".iqNonSpecInstsAdded")
190 .
desc(
"Number of non-speculative instructions added to the IQ")
195 .
desc(
"Number of instructions issued")
200 .
desc(
"Number of integer instructions issued")
204 .
name(
name() +
".iqFloatInstsIssued")
205 .
desc(
"Number of float instructions issued")
209 .
name(
name() +
".iqBranchInstsIssued")
210 .
desc(
"Number of branch instructions issued")
215 .
desc(
"Number of memory instructions issued")
219 .
name(
name() +
".iqMiscInstsIssued")
220 .
desc(
"Number of miscellaneous instructions issued")
224 .
name(
name() +
".iqSquashedInstsIssued")
225 .
desc(
"Number of squashed instructions issued")
229 .
name(
name() +
".iqSquashedInstsExamined")
230 .
desc(
"Number of squashed instructions iterated over during squash;" 231 " mainly for profiling")
235 .
name(
name() +
".iqSquashedOperandsExamined")
236 .
desc(
"Number of squashed operands that are examined and possibly " 237 "removed from graph")
241 .
name(
name() +
".iqSquashedNonSpecRemoved")
242 .
desc(
"Number of squashed non-spec instructions that were removed")
258 .
desc(
"Number of insts issued each cycle")
275 .
desc(
"Type of FU issued")
299 .
desc(
"Inst issue rate")
307 .
desc(
"attempts to use FU when none available")
317 .
desc(
"FU busy when requested")
323 .
desc(
"FU busy rate (busy events/executed inst)")
334 .
name(
name() +
".int_inst_queue_reads")
335 .
desc(
"Number of integer instruction queue reads")
339 .
name(
name() +
".int_inst_queue_writes")
340 .
desc(
"Number of integer instruction queue writes")
344 .
name(
name() +
".int_inst_queue_wakeup_accesses")
345 .
desc(
"Number of integer instruction queue wakeup accesses")
349 .
name(
name() +
".fp_inst_queue_reads")
350 .
desc(
"Number of floating instruction queue reads")
354 .
name(
name() +
".fp_inst_queue_writes")
355 .
desc(
"Number of floating instruction queue writes")
359 .
name(
name() +
".fp_inst_queue_wakeup_accesses")
360 .
desc(
"Number of floating instruction queue wakeup accesses")
364 .
name(
name() +
".vec_inst_queue_reads")
365 .
desc(
"Number of vector instruction queue reads")
369 .
name(
name() +
".vec_inst_queue_writes")
370 .
desc(
"Number of vector instruction queue writes")
374 .
name(
name() +
".vec_inst_queue_wakeup_accesses")
375 .
desc(
"Number of vector instruction queue wakeup accesses")
380 .
desc(
"Number of integer alu accesses")
385 .
desc(
"Number of floating point alu accesses")
390 .
desc(
"Number of vector alu accesses")
395 template <
class Impl>
400 for (
ThreadID tid = 0; tid < Impl::MaxThreads; tid++) {
417 for (
ThreadID tid = 0; tid < Impl::MaxThreads; ++tid) {
435 template <
class Impl>
442 template <
class Impl>
449 template <
class Impl>
458 template <
class Impl>
471 template <
class Impl>
481 template <
class Impl>
488 template <
class Impl>
492 if (
iqPolicy == SMTQueuePolicy::Partitioned) {
500 template <
class Impl>
510 while (threads != end) {
513 if (
iqPolicy == SMTQueuePolicy::Partitioned) {
515 }
else if (
iqPolicy == SMTQueuePolicy::Threshold &&
516 active_threads == 1) {
523 template <
class Impl>
530 template <
class Impl>
539 template <
class Impl>
550 template <
class Impl>
561 template <
class Impl>
578 template <
class Impl>
582 if (new_inst->isFloating()) {
584 }
else if (new_inst->isVector()) {
592 DPRINTF(IQ,
"Adding instruction [sn:%llu] PC %s to the IQ.\n",
593 new_inst->seqNum, new_inst->pcState());
597 instList[new_inst->threadNumber].push_back(new_inst);
611 if (new_inst->isMemRef()) {
619 count[new_inst->threadNumber]++;
624 template <
class Impl>
630 if (new_inst->isFloating()) {
632 }
else if (new_inst->isVector()) {
642 DPRINTF(IQ,
"Adding non-speculative instruction [sn:%llu] PC %s " 644 new_inst->seqNum, new_inst->pcState());
648 instList[new_inst->threadNumber].push_back(new_inst);
660 if (new_inst->isMemRef()) {
666 count[new_inst->threadNumber]++;
671 template <
class Impl>
680 template <
class Impl>
681 typename Impl::DynInstPtr
687 if (inst->isFloating()) {
689 }
else if (inst->isVector()) {
697 template <
class Impl>
712 while (list_it != list_end_it) {
713 if ((*list_it).oldestInst > queue_entry.
oldestInst) {
724 template <
class Impl>
734 OpClass op_class = (*list_order_it).
queueType;
743 (*next_it).oldestInst < queue_entry.
oldestInst) {
750 template <
class Impl>
754 DPRINTF(IQ,
"Processing FU completion [sn:%llu]\n", inst->seqNum);
755 assert(!
cpu->switchedOut());
774 template <
class Impl>
778 DPRINTF(IQ,
"Attempting to schedule ready instructions from " 801 int total_issued = 0;
805 while (total_issued <
totalWidth && order_it != order_end_it) {
806 OpClass op_class = (*order_it).queueType;
812 if (issuing_inst->isFloating()) {
814 }
else if (issuing_inst->isVector()) {
820 assert(issuing_inst->seqNum == (*order_it).oldestInst);
822 if (issuing_inst->isSquashed()) {
841 ThreadID tid = issuing_inst->threadNumber;
843 if (op_class != No_OpClass) {
845 if (issuing_inst->isFloating()) {
847 }
else if (issuing_inst->isVector()) {
860 if (op_latency ==
Cycles(1)) {
875 cpu->schedule(execution,
888 DPRINTF(IQ,
"Thread %i: Issuing instruction PC %s " 890 tid, issuing_inst->pcState(),
891 issuing_inst->seqNum);
902 issuing_inst->setIssued();
906 issuing_inst->issueTick =
curTick() - issuing_inst->fetchTick;
909 if (!issuing_inst->isMemRef()) {
914 issuing_inst->clearInIQ();
936 cpu->activityThisCycle();
938 DPRINTF(IQ,
"Not able to schedule any instructions.\n");
942 template <
class Impl>
946 DPRINTF(IQ,
"Marking nonspeculative instruction [sn:%llu] as ready " 947 "to execute.\n", inst);
953 ThreadID tid = (*inst_it).second->threadNumber;
955 (*inst_it).second->setAtCommit();
957 (*inst_it).second->setCanIssue();
959 if (!(*inst_it).second->isMemRef()) {
965 (*inst_it).second = NULL;
970 template <
class Impl>
974 DPRINTF(IQ,
"[tid:%i] Committing instructions older than [sn:%llu]\n",
979 while (iq_it !=
instList[tid].end() &&
980 (*iq_it)->seqNum <= inst) {
988 template <
class Impl>
995 if (completed_inst->isFloating()) {
997 }
else if (completed_inst->isVector()) {
1003 DPRINTF(IQ,
"Waking dependents of completed instruction.\n");
1005 assert(!completed_inst->isSquashed());
1013 if (completed_inst->isMemRef()) {
1016 }
else if (completed_inst->isMemBarrier() ||
1017 completed_inst->isWriteBarrier()) {
1021 for (
int dest_reg_idx = 0;
1022 dest_reg_idx < completed_inst->numDestRegs();
1026 completed_inst->renamedDestRegIdx(dest_reg_idx);
1031 DPRINTF(IQ,
"Reg %d [%s] is part of a fix mapping, skipping\n",
1039 completed_inst->setPinnedRegsWritten();
1042 DPRINTF(IQ,
"Reg %d [%s] is pinned, skipping\n",
1047 DPRINTF(IQ,
"Waking any dependents on register %i (%s).\n",
1056 DPRINTF(IQ,
"Waking up a dependent instruction, [sn:%llu] " 1057 "PC %s.\n", dep_inst->seqNum, dep_inst->pcState());
1063 dep_inst->markSrcRegReady();
1083 template <
class Impl>
1087 OpClass op_class = ready_inst->opClass();
1096 (*
readyIt[op_class]).oldestInst) {
1101 DPRINTF(IQ,
"Instruction is ready to issue, putting it onto " 1102 "the ready list, PC %s opclass:%i [sn:%llu].\n",
1103 ready_inst->pcState(), op_class, ready_inst->seqNum);
1106 template <
class Impl>
1110 DPRINTF(IQ,
"Rescheduling mem inst [sn:%llu]\n", resched_inst->seqNum);
1113 resched_inst->translationStarted(
false);
1114 resched_inst->translationCompleted(
false);
1116 resched_inst->clearCanIssue();
1120 template <
class Impl>
1127 template <
class Impl>
1131 ThreadID tid = completed_inst->threadNumber;
1133 DPRINTF(IQ,
"Completing mem instruction PC: %s [sn:%llu]\n",
1134 completed_inst->pcState(), completed_inst->seqNum);
1138 completed_inst->memOpDone(
true);
1144 template <
class Impl>
1151 template <
class Impl>
1155 blocked_inst->clearIssued();
1156 blocked_inst->clearCanIssue();
1160 template <
class Impl>
1169 template <
class Impl>
1170 typename Impl::DynInstPtr
1175 if ((*it)->translationCompleted() || (*it)->isSquashed()) {
1184 template <
class Impl>
1185 typename Impl::DynInstPtr
1197 template <
class Impl>
1206 template <
class Impl>
1210 DPRINTF(IQ,
"[tid:%i] Starting to squash instructions in " 1223 template <
class Impl>
1231 DPRINTF(IQ,
"[tid:%i] Squashing until sequence number %i!\n",
1236 while (squash_it !=
instList[tid].end() &&
1240 if (squashed_inst->isFloating()) {
1242 }
else if (squashed_inst->isVector()) {
1250 if (squashed_inst->threadNumber != tid ||
1251 squashed_inst->isSquashedInIQ()) {
1256 if (!squashed_inst->isIssued() ||
1257 (squashed_inst->isMemRef() &&
1258 !squashed_inst->memOpDone())) {
1260 DPRINTF(IQ,
"[tid:%i] Instruction [sn:%llu] PC %s squashed.\n",
1261 tid, squashed_inst->seqNum, squashed_inst->pcState());
1263 bool is_acq_rel = squashed_inst->isMemBarrier() &&
1264 (squashed_inst->isLoad() ||
1265 (squashed_inst->isStore() &&
1266 !squashed_inst->isStoreConditional()));
1270 (!squashed_inst->isNonSpeculative() &&
1271 !squashed_inst->isStoreConditional() &&
1272 !squashed_inst->isAtomic() &&
1273 !squashed_inst->isMemBarrier() &&
1274 !squashed_inst->isWriteBarrier())) {
1276 for (
int src_reg_idx = 0;
1277 src_reg_idx < squashed_inst->numSrcRegs();
1281 squashed_inst->renamedSrcRegIdx(src_reg_idx);
1292 if (!squashed_inst->isReadySrcRegIdx(src_reg_idx) &&
1301 }
else if (!squashed_inst->isStoreConditional() ||
1302 !squashed_inst->isCompleted()) {
1313 assert(squashed_inst->getFault() !=
NoFault ||
1314 squashed_inst->isMemRef());
1317 (*ns_inst_it).second = NULL;
1328 squashed_inst->setSquashedInIQ();
1332 squashed_inst->setIssued();
1333 squashed_inst->setCanCommit();
1334 squashed_inst->clearInIQ();
1337 count[squashed_inst->threadNumber]--;
1349 for (
int dest_reg_idx = 0;
1350 dest_reg_idx < squashed_inst->numDestRegs();
1354 squashed_inst->renamedDestRegIdx(dest_reg_idx);
1366 template <
class Impl>
1372 int8_t total_src_regs = new_inst->numSrcRegs();
1373 bool return_val =
false;
1375 for (
int src_reg_idx = 0;
1376 src_reg_idx < total_src_regs;
1380 if (!new_inst->isReadySrcRegIdx(src_reg_idx)) {
1381 PhysRegIdPtr src_reg = new_inst->renamedSrcRegIdx(src_reg_idx);
1390 DPRINTF(IQ,
"Instruction PC %s has src reg %i (%s) that " 1391 "is being added to the dependency chain.\n",
1392 new_inst->pcState(), src_reg->
index(),
1401 DPRINTF(IQ,
"Instruction PC %s has src reg %i (%s) that " 1402 "became ready before it reached the IQ.\n",
1403 new_inst->pcState(), src_reg->
index(),
1406 new_inst->markSrcRegReady(src_reg_idx);
1414 template <
class Impl>
1422 int8_t total_dest_regs = new_inst->numDestRegs();
1424 for (
int dest_reg_idx = 0;
1425 dest_reg_idx < total_dest_regs;
1428 PhysRegIdPtr dest_reg = new_inst->renamedDestRegIdx(dest_reg_idx);
1438 panic(
"Dependency graph %i (%s) (flat: %i) not empty!",
1450 template <
class Impl>
1456 if (inst->readyToIssue()) {
1459 if (inst->isMemRef()) {
1461 DPRINTF(IQ,
"Checking if memory instruction can issue.\n");
1470 OpClass op_class = inst->opClass();
1472 DPRINTF(IQ,
"Instruction is ready to issue, putting it onto " 1473 "the ready list, PC %s opclass:%i [sn:%llu].\n",
1474 inst->pcState(), op_class, inst->seqNum);
1483 (*
readyIt[op_class]).oldestInst) {
1490 template <
class Impl>
1497 template <
class Impl>
1512 cprintf(
"Non speculative list: ");
1514 while (non_spec_it != non_spec_end_it) {
1515 cprintf(
"%s [sn:%llu]", (*non_spec_it).second->pcState(),
1516 (*non_spec_it).second->seqNum);
1528 while (list_order_it != list_order_end_it) {
1529 cprintf(
"%i OpClass:%i [sn:%llu] ", i, (*list_order_it).queueType,
1530 (*list_order_it).oldestInst);
1540 template <
class Impl>
1549 while (inst_list_it !=
instList[tid].end()) {
1550 cprintf(
"Instruction:%i\n", num);
1551 if (!(*inst_list_it)->isSquashed()) {
1552 if (!(*inst_list_it)->isIssued()) {
1554 cprintf(
"Count:%i\n", valid_num);
1555 }
else if ((*inst_list_it)->isMemRef() &&
1556 !(*inst_list_it)->memOpDone()) {
1560 cprintf(
"Count:%i\n", valid_num);
1564 cprintf(
"PC: %s\n[sn:%llu]\n[tid:%i]\n" 1565 "Issued:%i\nSquashed:%i\n",
1566 (*inst_list_it)->pcState(),
1567 (*inst_list_it)->seqNum,
1568 (*inst_list_it)->threadNumber,
1569 (*inst_list_it)->isIssued(),
1570 (*inst_list_it)->isSquashed());
1572 if ((*inst_list_it)->isMemRef()) {
1573 cprintf(
"MemOpDone:%i\n", (*inst_list_it)->memOpDone());
1583 cprintf(
"Insts to Execute list:\n");
1593 if (!(*inst_list_it)->isSquashed()) {
1594 if (!(*inst_list_it)->isIssued()) {
1596 cprintf(
"Count:%i\n", valid_num);
1597 }
else if ((*inst_list_it)->isMemRef() &&
1598 !(*inst_list_it)->memOpDone()) {
1602 cprintf(
"Count:%i\n", valid_num);
1606 cprintf(
"PC: %s\n[sn:%llu]\n[tid:%i]\n" 1607 "Issued:%i\nSquashed:%i\n",
1608 (*inst_list_it)->pcState(),
1609 (*inst_list_it)->seqNum,
1610 (*inst_list_it)->threadNumber,
1611 (*inst_list_it)->isIssued(),
1612 (*inst_list_it)->isSquashed());
1614 if ((*inst_list_it)->isMemRef()) {
1615 cprintf(
"MemOpDone:%i\n", (*inst_list_it)->memOpDone());
1625 #endif//__CPU_O3_INST_QUEUE_IMPL_HH__ Stats::Scalar iqMiscInstsIssued
Stat for number of miscellaneous instructions issued.
int wbOutstanding
Number of instructions currently in flight to FUs.
#define panic(...)
This implements a cprintf based panic() function.
void regStats()
Registers statistics.
const FlagsType pdf
Print the percent of the total that this entry represents.
std::list< ThreadID > * activeThreads
Pointer to list of active threads.
Stats::Scalar iqFloatInstsIssued
Stat for number of floating point instructions issued.
void completed(const DynInstPtr &inst)
Completes a memory instruction.
void replayMemInst(const DynInstPtr &replay_inst)
Replays a memory instruction.
Stats::Scalar vecInstQueueReads
Derived & init(size_type _x, size_type _y)
decltype(nullptr) constexpr NoFault
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...
Cycles is a wrapper class for representing cycle counts, i.e.
void insertNonSpec(const DynInstPtr &new_inst)
Inserts a new, non-speculative instruction into the IQ.
Stats::Scalar fpAluAccesses
void doSquash(ThreadID tid)
Does the actual squashing.
void scheduleReadyInsts()
Schedules ready instructions, adding the ready ones (oldest first) to the queue to execute...
int getNumPinnedWritesToComplete() const
Stats::Scalar intAluAccesses
void violation(const DynInstPtr &store_inst, const DynInstPtr &violating_load)
Indicates an ordering violation between a store and a younger load.
Stats::Scalar iqInstsAdded
Stat for number of instructions added.
InstructionQueue(O3CPU *cpu_ptr, IEW *iew_ptr, DerivO3CPUParams *params)
Constructs an IQ.
bool queueOnList[Num_OpClasses]
Tracks if each ready queue is on the age order list.
Stats::Scalar fpInstQueueWakeupAccesses
std::list< DynInstPtr > instsToExecute
List of instructions that are ready to be executed.
void regStats()
Registers statistics.
void dumpInsts()
Debugging function to dump out all instructions that are in the IQ.
void replay()
Replays all instructions that have been rescheduled by moving them to the ready list.
InstSeqNum squashedSeqNum[Impl::MaxThreads]
The sequence number of the squashed instruction.
Impl::DynInstPtr DynInstPtr
void violation(const DynInstPtr &store, const DynInstPtr &faulting_load)
Indicates an ordering violation between a store and a load.
void scheduleNonSpec(const InstSeqNum &inst)
Schedules a single specific non-speculative instruction.
DynInstPtr getInstToExecute()
Returns the oldest scheduled instruction, and removes it from the list of instructions waiting to exe...
Cycles getOpLatency(OpClass capability)
Returns the operation execution latency of the given capability.
Stats::Scalar iqInstsIssued
FU completion event class.
Stats::Scalar iqMemInstsIssued
Stat for number of memory instructions issued.
void freeUnitNextCycle(int fu_idx)
Frees a FU at the end of this cycle.
void addToOrderList(OpClass op_class)
Add an op class to the age order list.
void setActiveThreads(std::list< ThreadID > *at_ptr)
Sets active threads list.
void insertBarrier(const DynInstPtr &barr_inst)
Inserts a memory or write barrier into the IQ to make sure loads and stores are ordered properly...
void setIQ(InstructionQueue< Impl > *iq_ptr)
Sets the pointer to the IQ.
unsigned numEntries
The number of entries in the instruction queue.
static constexpr auto NoCapableFU
std::list< DynInstPtr > instList[Impl::MaxThreads]
List of all the instructions in the IQ (some of which may be issued).
bool addToDependents(const DynInstPtr &new_inst)
Adds an instruction to the dependency graph, as a consumer.
Derived & flags(Flags _flags)
Set the flags and marks this stat to print at the end of simulation.
void decrNumPinnedWritesToComplete()
DynInstPtr inst
Executing instruction.
void wakeDependents(const DynInstPtr &inst)
Wakes any dependents of a memory instruction.
Derived & init(size_type size)
Set this vector to have the given size.
void rescheduleMemInst(const DynInstPtr &resched_inst)
Reschedules a memory instruction.
void setTimeBuffer(TimeBuffer< TimeStruct > *tb_ptr)
Sets the global time buffer.
std::vector< bool > regScoreboard
A cache of the recently woken registers.
Stats::Scalar fpInstQueueWrites
void nonSpecInstReady(const DynInstPtr &inst)
Indicate that a non-speculative instruction is ready.
std::list< DynInstPtr > blockedMemInsts
List of instructions that have been cache blocked.
bool isFull()
Returns whether or not the IQ is full.
unsigned numFreeEntries()
Returns total number of free entries.
Tick curTick()
The current simulated tick.
int fuIdx
Index of the FU used for executing.
bool hasReadyInsts()
Returns if there are any ready instructions in the IQ.
Stats::Scalar intInstQueueWakeupAccesses
Stats::Scalar iqSquashedNonSpecRemoved
Stat for number of non-speculative instructions removed due to a squash.
void insertNonSpec(const DynInstPtr &inst)
Inserts a non-speculative memory instruction.
void issue(const DynInstPtr &inst)
Issues the given instruction.
Derived & prereq(const Stat &prereq)
Set the prerequisite stat and marks this stat to print at the end of simulation.
TimeBuffer< IssueStruct > * issueToExecuteQueue
The queue to the execute stage.
int wakeDependents(const DynInstPtr &completed_inst)
Wakes all dependents of a completed instruction.
IEW * iewStage
Pointer to IEW stage.
Stats::Scalar intInstQueueWrites
void addReadyMemInst(const DynInstPtr &ready_inst)
Adds a ready memory instruction to the ready list.
ReadyInstQueue readyInsts[Num_OpClasses]
List of ready instructions, per op class.
void regsReady(const DynInstPtr &inst)
Indicate that an instruction has its registers ready.
void commit(const InstSeqNum &inst, ThreadID tid=0)
Commits all instructions up to and including the given sequence number, for a specific thread...
std::map< InstSeqNum, DynInstPtr > nonSpecInsts
List of non-speculative instructions that will be scheduled once the IQ gets a signal from commit...
std::list< ListOrderEntry > listOrder
List that contains the age order of the oldest instruction of each ready queue.
void addIfReady(const DynInstPtr &inst)
Moves an instruction to the ready queue if it is ready.
Distribution & init(Counter min, Counter max, Counter bkt)
Set the parameters of this distribution.
Stats::Scalar iqBranchInstsIssued
Stat for number of branch instructions issued.
static scfx_rep_node * list
virtual const char * description() const
Return a C string describing the event.
unsigned count[Impl::MaxThreads]
Per Thread IQ count.
void takeOverFrom()
Takes over execution from another CPU's thread.
TimeBuffer< TimeStruct > * timeBuffer
The backwards time buffer.
Cycles commitToIEWDelay
Delay between commit stage and the IQ.
Stats::Scalar iqSquashedInstsIssued
Stat for number of squashed instructions that were ready to issue.
Stats::Formula fuBusyRate
Number of times the FU was busy per instruction issued.
std::list< ListOrderEntry >::iterator ListOrderIt
Stats::Scalar vecAluAccesses
void reschedule(const DynInstPtr &inst)
Reschedules an instruction to be re-executed.
std::string name() const
Returns the name of the IQ.
const FlagsType total
Print the total.
std::list< DynInstPtr > retryMemInsts
List of instructions that were cache blocked, but a retry has been seen since, so they can now be ret...
TimeBuffer< TimeStruct >::wire fromCommit
Wire to read information from timebuffer.
void insert(const DynInstPtr &inst)
Inserts a memory instruction.
void deferMemInst(const DynInstPtr &deferred_inst)
Defers a memory instruction when its DTB translation incurs a hw page table walk. ...
DynInstPtr getBlockedMemInstToExecute()
Gets a memory instruction that was blocked on the cache.
void resetState()
Resets all instruction queue state.
~InstructionQueue()
Destructs the IQ.
DynInstPtr getDeferredMemInstToExecute()
Gets a memory instruction that was referred due to a delayed DTB translation if it is now ready to ex...
Derived & name(const std::string &name)
Set the name and marks this stat to print at the end of simulation.
void drainSanityCheck() const
Perform sanity checks after a drain.
int16_t ThreadID
Thread index/ID type.
void squash(ThreadID tid)
Squashes instructions for a thread.
Stats::Vector2d statIssuedInstType
Stat for total number issued for each instruction type.
void init(DerivO3CPUParams *params, ThreadID tid)
Initializes the unit with parameters and a thread id.
SMTQueuePolicy iqPolicy
IQ sharing policy for SMT.
DependencyGraph< DynInstPtr > dependGraph
int countInsts()
Debugging function to count how many entries are in the IQ.
const PhysRegIndex & flatIndex() const
Flat index accessor.
bool freeFU
Should the FU be added to the list to be freed upon completing this event.
Stats::Scalar iqSquashedOperandsExamined
Stat for number of squashed instruction operands examined when squashing.
void blockMemInst(const DynInstPtr &blocked_inst)
Defers a memory instruction when it is cache blocked.
void resetEntries()
Resets max entries for all threads.
Stats::Scalar fpInstQueueReads
Stats::Scalar vecInstQueueWrites
static const OpClass Num_OpClasses
void completeMemInst(const DynInstPtr &completed_inst)
Completes a memory operation.
std::map< InstSeqNum, DynInstPtr >::iterator NonSpecMapIt
void squash(const InstSeqNum &squashed_num, ThreadID tid)
Squashes all instructions up until a given sequence number for a specific thread. ...
int entryAmount(ThreadID num_threads)
Number of entries needed for given amount of threads.
Stats::Scalar iqSquashedInstsExamined
Stat for number of squashed instructions examined when squashing.
O3CPU * cpu
Pointer to the CPU.
ListOrderIt readyIt[Num_OpClasses]
Iterators of each ready queue.
void processFUCompletion(const DynInstPtr &inst, int fu_idx)
Process FU completion event.
Stats::Scalar iqIntInstsIssued
Stat for number of integer instructions issued.
const RegIndex & index() const
Index accessors.
Stats::Vector fuBusy
Number of times the FU was busy.
void completeBarrier(const DynInstPtr &inst)
Completes a barrier instruction.
Entry for the list age ordering by op class.
std::list< DynInstPtr >::iterator ListIt
unsigned maxEntries[Impl::MaxThreads]
Max IQ Entries Per Thread.
Stats::Scalar vecInstQueueWakeupAccesses
void setIssueToExecuteQueue(TimeBuffer< IssueStruct > *i2eQueue)
Sets the timer buffer between issue and execute.
void cacheUnblocked()
Notify instruction queue that a previous blockage has resolved.
void moveToYoungerInst(ListOrderIt age_order_it)
Called when the oldest instruction has been removed from a ready queue; this places that ready queue ...
Stats::Scalar iqNonSpecInstsAdded
Stat for number of non-speculative instructions added.
Derived & desc(const std::string &_desc)
Set the description and marks this stat to print at the end of simulation.
int getUnit(OpClass capability)
Gets a FU providing the requested capability.
Stats::Formula issueRate
Number of instructions issued per cycle.
unsigned numPhysRegs
The number of physical registers in the CPU.
Stats::Scalar intInstQueueReads
MemDepUnit memDepUnit[Impl::MaxThreads]
The memory dependence unit, which tracks/predicts memory dependences between instructions.
Derived & ysubnames(const char **names)
constexpr unsigned NumVecElemPerVecReg
void addToProducers(const DynInstPtr &new_inst)
Adds an instruction to the dependency graph, as a producer.
bool isPipelined(OpClass capability)
Returns the issue latency of the given capability.
void insertBarrier(const DynInstPtr &barr_inst)
Inserts a barrier instruction.
FUPool * fuPool
Function unit pool.
const FlagsType dist
Print the distribution.
bool isFixedMapping() const
Returns true if this register is always associated to the same architectural register.
std::list< DynInstPtr > deferredMemInsts
List of instructions waiting for their DTB translation to complete (hw page table walk in progress)...
bool isDrained() const
Determine if we are drained.
FUCompletion(const DynInstPtr &_inst, int fu_idx, InstructionQueue< Impl > *iq_ptr)
Construct a FU completion event.
InstructionQueue< Impl > * iqPtr
Pointer back to the instruction queue.
A standard instruction queue class.
unsigned totalWidth
The total number of instructions that can be issued in one cycle.
void dumpLists()
Debugging function to dump all the list sizes, as well as print out the list of nonspeculative instru...
Stats::Distribution numIssuedDist
Distribution of number of instructions in the queue.
unsigned freeEntries
Number of free IQ entries left.
Stats::Vector statFuBusy
Distribution of the cycles it takes to issue an instruction.
const char * className() const
Return a const char* with the register class name.
void sample(const U &v, int n=1)
Add a value to the distribtion n times.
ThreadID numThreads
Number of Total Threads.
void cprintf(const char *format, const Args &...args)
static constexpr auto NoFreeFU
void insert(const DynInstPtr &new_inst)
Inserts a new instruction into the IQ.