48#include "debug/Fetch.hh"
49#include "debug/ROB.hh"
50#include "params/BaseO3CPU.hh"
59 : robPolicy(params.smtROBPolicy),
61 numEntries(params.numROBEntries),
62 squashWidth(params.squashWidth),
64 numThreads(params.numThreads),
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;;
129 DPRINTF(
ROB,
"Setting active threads list pointer.\n");
156 while (threads != end) {
159 if (
robPolicy == SMTQueuePolicy::Partitioned) {
161 }
else if (
robPolicy == SMTQueuePolicy::Threshold &&
162 active_threads == 1) {
172 if (
robPolicy == SMTQueuePolicy::Partitioned) {
203 DPRINTF(
ROB,
"Adding inst PC %s to the ROB.\n", inst->pcState());
214 assert((*
head) == inst);
227 assert((*
tail) == inst);
229 DPRINTF(
ROB,
"[tid:%i] Now has %d instructions.\n", tid,
246 assert(head_inst->readyToCommit());
248 DPRINTF(
ROB,
"[tid:%i] Retiring head instruction, "
249 "instruction PC %s, [sn:%llu]\n", tid, head_inst->pcState(),
255 head_inst->clearInROB();
256 head_inst->setCommitted();
272 return instList[tid].front()->readyToCommit();
285 while (threads != end) {
312 DPRINTF(
ROB,
"[tid:%i] Squashing instructions until [sn:%llu].\n",
318 DPRINTF(
ROB,
"[tid:%i] Done squashing instructions.\n",
327 bool robTailUpdate =
false;
339 for (
int numSquashed = 0;
340 numSquashed < numInstsToSquash &&
345 DPRINTF(
ROB,
"[tid:%i] Squashing instruction PC %s, seq num %i.\n",
358 DPRINTF(
ROB,
"Reached head of instruction list while "
371 if ((*
squashIt[tid]) == (*tail_thread))
372 robTailUpdate =
true;
380 DPRINTF(
ROB,
"[tid:%i] Done squashing instructions.\n",
398 bool first_valid =
true;
404 while (threads != end) {
412 lowest_num = (*head)->seqNum;
421 assert(head_inst != 0);
423 if (head_inst->seqNum < lowest_num) {
425 lowest_num = head_inst->seqNum;
439 bool first_valid =
true;
444 while (threads != end) {
465 if ((*tail_thread)->seqNum > (*tail)->seqNum) {
476 DPRINTF(
ROB,
"Does not need to squash due to being empty "
483 DPRINTF(
ROB,
"Starting to squash within the ROB.\n");
507 assert((*head_thread)->isInROB());
525 : statistics::
Group(parent,
"rob"),
526 ADD_STAT(reads, statistics::units::Count::get(),
527 "The number of ROB reads"),
528 ADD_STAT(writes, statistics::units::Count::get(),
529 "The number of ROB writes")
537 if ((*it)->seqNum == squash_inst) {
virtual std::string name() const
O3CPU class, has each of the stages (fetch through commit) within it, as well as all of the time buff...
bool isThreadExiting(ThreadID tid) const
Is the thread trying to exit?
void removeFrontInst(const DynInstPtr &inst)
Remove an instruction from the front end of the list.
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
const FlagsType total
Print the total.
Copyright (c) 2024 - Pranith Kumar Copyright (c) 2020 Inria All rights reserved.
int16_t ThreadID
Thread index/ID type.
ROBStats(statistics::Group *parent)
statistics::Scalar writes