48#include "debug/Fetch.hh"
49#include "debug/ROB.hh"
50#include "params/BaseO3CPU.hh"
68 if (
robPolicy == SMTQueuePolicy::Dynamic) {
74 }
else if (
robPolicy == SMTQueuePolicy::Partitioned) {
75 DPRINTF(
Fetch,
"ROB sharing policy set to Partitioned\n");
85 }
else if (
robPolicy == SMTQueuePolicy::Threshold) {
88 int threshold = params.smtROBThreshold;;
123 return cpu->name() +
".rob";
129 DPRINTF(
ROB,
"Setting active threads list pointer.\n");
154 if (
robPolicy == SMTQueuePolicy::Partitioned) {
156 }
else if (
robPolicy == SMTQueuePolicy::Threshold &&
157 active_threads == 1) {
167 if (
robPolicy == SMTQueuePolicy::Partitioned) {
198 DPRINTF(
ROB,
"Adding inst PC %s to the ROB.\n", inst->pcState());
209 assert((*
head) == inst);
222 assert((*
tail) == inst);
224 DPRINTF(
ROB,
"[tid:%i] Now has %d instructions.\n", tid,
241 assert(head_inst->readyToCommit());
243 DPRINTF(
ROB,
"[tid:%i] Retiring head instruction, "
244 "instruction PC %s, [sn:%llu]\n", tid, head_inst->pcState(),
250 head_inst->clearInROB();
251 head_inst->setCommitted();
259 cpu->removeFrontInst(head_inst);
267 return instList[tid].front()->readyToCommit();
302 DPRINTF(
ROB,
"[tid:%i] Squashing instructions until [sn:%llu].\n",
308 DPRINTF(
ROB,
"[tid:%i] Done squashing instructions.\n",
317 bool robTailUpdate =
false;
324 if (
cpu->isThreadExiting(tid))
329 for (
int numSquashed = 0;
330 numSquashed < numInstsToSquash &&
335 DPRINTF(
ROB,
"[tid:%i] Squashing instruction PC %s, seq num %i.\n",
348 DPRINTF(
ROB,
"Reached head of instruction list while "
361 if ((*
squashIt[tid]) == (*tail_thread))
362 robTailUpdate =
true;
370 DPRINTF(
ROB,
"[tid:%i] Done squashing instructions.\n",
388 bool first_valid =
true;
397 lowest_num = (*head)->seqNum;
406 assert(head_inst != 0);
408 if (head_inst->seqNum < lowest_num) {
410 lowest_num = head_inst->seqNum;
424 bool first_valid =
true;
445 if ((*tail_thread)->seqNum > (*tail)->seqNum) {
456 DPRINTF(
ROB,
"Does not need to squash due to being empty "
463 DPRINTF(
ROB,
"Starting to squash within the ROB.\n");
487 assert((*head_thread)->isInROB());
507 "The number of ROB reads"),
509 "The number of ROB writes")
517 if ((*it)->seqNum == squash_inst) {
O3CPU class, has each of the stages (fetch through commit) within it, as well as all of the time buff...
Fetch class handles both single threaded and SMT fetch.
bool canCommit()
Is there any commitable head instruction across all threads ready.
int countInsts()
This is more of a debugging function than anything.
void insertInst(const DynInstPtr &inst)
Function to insert an instruction into the ROB.
gem5::o3::ROB::ROBStats stats
unsigned numFreeEntries()
Returns the number of total free entries in the ROB.
void updateTail()
Updates the tail instruction with the new youngest instruction.
InstIt tail
Iterator pointing to the instruction which is the last instruction in the ROB.
void resetEntries()
Re-adjust ROB partitioning.
void squash(InstSeqNum squash_num, ThreadID tid)
Squashes all instructions younger than the given sequence number for the specific thread.
bool isHeadReady(ThreadID tid)
Is the oldest instruction across all threads ready.
ROB(CPU *_cpu, const BaseO3CPUParams ¶ms)
ROB constructor.
void retireHead(ThreadID tid)
Retires the head instruction, removing it from the ROB.
std::list< DynInstPtr > instList[MaxThreads]
ROB List of Instructions.
DynInstPtr findInst(ThreadID tid, InstSeqNum squash_inst)
Returns a pointer to the instruction with the given sequence if it is in the ROB.
InstSeqNum squashedSeqNum[MaxThreads]
The sequence number of the squashed instruction.
std::list< ThreadID > * activeThreads
Active Threads in CPU.
void updateHead()
Updates the head instruction with the new oldest instruction.
void drainSanityCheck() const
Perform sanity checks after a drain.
Status robStatus[MaxThreads]
Per-thread ROB status.
void doSquash(ThreadID tid)
Executes the squash, marking squashed instructions.
const DynInstPtr & readHeadInst(ThreadID tid)
Returns pointer to the head instruction within the ROB.
unsigned maxEntries[MaxThreads]
Max Insts a Thread Can Have in the ROB.
InstIt head
Iterator pointing to the instruction which is the first instruction in in the ROB.
int entryAmount(ThreadID num_threads)
Number of entries needed For 'num_threads' amount of threads.
SMTQueuePolicy robPolicy
ROB resource sharing policy for SMT mode.
DynInstPtr readTailInst(ThreadID tid)
Returns pointer to the tail instruction within the ROB.
InstIt squashIt[MaxThreads]
Iterator used for walking through the list of instructions when squashing.
void setActiveThreads(std::list< ThreadID > *at_ptr)
Sets pointer to the list of active threads.
unsigned numEntries
Number of instructions in the ROB.
void resetState()
Reset the ROB state.
ThreadID numThreads
Number of active threads.
bool doneSquashing[MaxThreads]
Is the ROB done squashing.
CPU * cpu
Pointer to the CPU.
unsigned squashWidth
Number of instructions that can be squashed in a single cycle.
std::list< DynInstPtr >::iterator InstIt
bool isEmpty() const
Returns if the ROB is empty.
void takeOverFrom()
Takes over another CPU's thread.
DynInstPtr dummyInst
Dummy instruction returned if there are no insts left.
int numInstsInROB
Number of instructions in the ROB.
unsigned threadEntries[MaxThreads]
Entries Per Thread.
#define ADD_STAT(n,...)
Convenience macro to add a stat to a statistics group.
static constexpr int MaxThreads
RefCountingPtr< DynInst > DynInstPtr
const FlagsType total
Print the total.
Copyright (c) 2024 Arm Limited All rights reserved.
int16_t ThreadID
Thread index/ID type.
ROBStats(statistics::Group *parent)
statistics::Scalar writes