Skip to content

Commit

Permalink
cpu-o3: add regfile write conflict (#210)
Browse files Browse the repository at this point in the history
Change-Id: I77fa15b0a1bf25dc7a5f9729d99c230ee6b3a88c
  • Loading branch information
tastynoob authored Dec 19, 2024
1 parent 74c799d commit 1a6c8e1
Show file tree
Hide file tree
Showing 4 changed files with 52 additions and 38 deletions.
1 change: 1 addition & 0 deletions src/cpu/o3/commit.cc
Original file line number Diff line number Diff line change
Expand Up @@ -722,6 +722,7 @@ Commit::tick()

if (cpu->curCycle() - lastCommitCycle > 20000) {
if (maybeStucked) {
warn("[sn:%s] %s", rob->head->get()->seqNum, rob->head->get()->staticInst->disassemble(0));
panic("cpu stucked!!\n");
}
warn("cpu may be stucked\n");
Expand Down
10 changes: 4 additions & 6 deletions src/cpu/o3/dyn_inst.hh
Original file line number Diff line number Diff line change
Expand Up @@ -157,7 +157,6 @@ class DynInst : public ExecContext, public RefCounted
protected:
enum Status
{
IqEntry, /// Instruction is in the IQ
RobEntry, /// Instruction is in the ROB
LsqEntry, /// Instruction is in the LSQ
Completed, /// Instruction has completed
Expand All @@ -166,6 +165,7 @@ class DynInst : public ExecContext, public RefCounted
MemDepSolved, /// Memory dependencies are solved
InReadyQue, /// Instruction is in the ready queue
Canceled, /// Instruction is canceled
Scheduled, /// Instruction is scheduled
ArbFailed,
Issued, /// Instruction has issued
Executed, /// Instruction has executed
Expand Down Expand Up @@ -849,8 +849,6 @@ class DynInst : public ExecContext, public RefCounted
/** Returns whether or not this instruction has issued. */
bool isIssued() const { return status[Issued]; }

/** Clears this instruction as being issued. */
void clearIssued() { status.reset(Issued); }

/** Sets this instruction as executed. */
void setExecuted() { status.set(Executed); }
Expand Down Expand Up @@ -886,13 +884,13 @@ class DynInst : public ExecContext, public RefCounted
//Instruction Queue Entry
//-----------------------
/** Sets this instruction as a entry the IQ. */
void setInIQ() { status.set(IqEntry); }
void setScheduled() { status.set(Scheduled); }

/** Sets this instruction as a entry the IQ. */
void clearInIQ() { status.reset(IqEntry); }
void clearScheduled() { status.reset(Scheduled); }

/** Returns whether or not this instruction has issued. */
bool isInIQ() const { return status[IqEntry]; }
bool isScheduled() const { return status[Scheduled]; }

/** Sets this instruction as squashed in the IQ. */
void setSquashedInIQ() { status.set(SquashedInIQ); status.set(Squashed);}
Expand Down
76 changes: 45 additions & 31 deletions src/cpu/o3/issue_queue.cc
Original file line number Diff line number Diff line change
Expand Up @@ -234,8 +234,8 @@ IssueQue::addToFu(const DynInstPtr& inst)
panic("%s [sn:%llu] has alreayd been issued\n", enums::OpClassStrings[inst->opClass()], inst->seqNum);
}
inst->setIssued();
scheduler->addToFU(inst);
POPINST(inst);
scheduler->addToFU(inst);
}

void
Expand All @@ -248,24 +248,12 @@ IssueQue::issueToFu()
if (!inst) {
continue;
}
if (portBusy[inst->issueportid]) {
DPRINTF(Schedule, "port%d busy, retry\n", inst->issueportid);
iqstats->portBusy[inst->issueportid]++;
// replay it
inst->setInReadyQ();
readyQclassify[inst->opClass()]->push(inst); // retry
continue;
}
if (!checkScoreboard(inst)) {
continue;
}
addToFu(inst);
cpu->perfCCT->updateInstPos(inst->seqNum, PerfRecord::AtIssueReadReg);
issued++;
if (!opPipelined[inst->opClass()]) [[unlikely]] {
// set fu busy
portBusy[inst->issueportid] = scheduler->getOpLatency(inst) - 1;
}
}
for (int i = size; !replayQ.empty() && i < outports; i++) {
auto inst = replayQ.front();
Expand Down Expand Up @@ -373,6 +361,21 @@ IssueQue::addIfReady(const DynInstPtr& inst)
}
}

void
IssueQue::cancel(const DynInstPtr& inst)
{
// before issued
assert(!inst->isIssued());

inst->setCancel();
if (inst->isScheduled() && !opPipelined[inst->opClass()]) {
inst->clearScheduled();
portBusy[inst->issueportid] = 0;
}

iqstats->canceledInst++;
}

void
IssueQue::selectInst()
{
Expand All @@ -389,6 +392,10 @@ IssueQue::selectInst()
}
if (!readyQ->empty()) {
auto inst = readyQ->top();
if (portBusy[pi] & (1llu << scheduler->getCorrectedOpLat(inst))) {
continue;
}

DPRINTF(Schedule, "[sn %ld] was selected\n", inst->seqNum);

// get regfile read port
Expand Down Expand Up @@ -431,9 +438,16 @@ IssueQue::scheduleInst()
} else [[likely]] {
DPRINTF(Schedule, "[sn:%llu] no conflict, scheduled\n", inst->seqNum);
iqstats->portissued[pi]++;
inst->clearInIQ();
inst->setScheduled();
toIssue->push(inst);
inst->issueportid = pi;

if (!opPipelined[inst->opClass()]) {
portBusy[pi] = -1ll;
} else if (scheduler->getCorrectedOpLat(inst) > 1) {
portBusy[pi] |= 1ll << scheduler->getCorrectedOpLat(inst);
}

scheduler->specWakeUpDependents(inst, this);
cpu->perfCCT->updateInstPos(inst->seqNum, PerfRecord::AtIssueArb);
}
Expand All @@ -451,12 +465,12 @@ IssueQue::tick()
}
instNumInsert = 0;

for (auto& t : portBusy) {
t = t > 0 ? t - 1 : t;
}

scheduleInst();
inflightIssues.advance();

for (auto& t : portBusy) {
t = t >> 1;
}
}

bool
Expand All @@ -472,8 +486,8 @@ IssueQue::ready()
bool
IssueQue::full()
{
bool full = instNumInsert + instNum >= iqsize;
full |= replayQ.size() > replayQsize; // TODO: parameterize it
bool full = instNum >= iqsize;
full |= replayQ.size() > replayQsize;
if (full) {
DPRINTF(Schedule, "has full!\n");
}
Expand All @@ -493,7 +507,6 @@ IssueQue::insert(const DynInstPtr& inst)
cpu->perfCCT->updateInstPos(inst->seqNum, PerfRecord::AtIssueQue);

DPRINTF(Schedule, "[sn:%llu] %s insert into %s\n", inst->seqNum, enums::OpClassStrings[inst->opClass()], iqname);
DPRINTF(Schedule, "[sn:%llu] instNum++\n", inst->seqNum);
inst->issueQue = this;
instList.emplace_back(inst);
bool addToDepGraph = false;
Expand Down Expand Up @@ -551,17 +564,20 @@ IssueQue::doSquash(const InstSeqNum seqNum)
{
for (auto it = instList.begin(); it != instList.end();) {
if ((*it)->seqNum > seqNum) {
(*it)->setSquashedInIQ();
(*it)->setCanCommit();
(*it)->clearInIQ();
(*it)->setCancel();
if (!(*it)->isIssued()) {
POPINST((*it));
(*it)->setIssued();
} else if ((*it)->issueportid >= 0) {
}
if ((*it)->isScheduled() && !opPipelined[(*it)->opClass()]) {
portBusy[(*it)->issueportid] = 0;
}

(*it)->setSquashedInIQ();
(*it)->setCanCommit();
(*it)->clearScheduled();
(*it)->setCancel();
it = instList.erase(it);
assert(instList.size() >= instNum);
} else {
it++;
}
Expand Down Expand Up @@ -734,6 +750,8 @@ Scheduler::addToFU(const DynInstPtr& inst)
void
Scheduler::tick()
{
// we need to update portBusy counter each cycle
cpu->activateStage(CPU::IEWIdx);
for (auto it : issueQues) {
it->tick();
}
Expand Down Expand Up @@ -821,7 +839,6 @@ Scheduler::addProducer(const DynInstPtr& inst)
void
Scheduler::insert(const DynInstPtr& inst)
{
inst->setInIQ();
auto& iqs = dispTable[inst->opClass()];
bool inserted = false;

Expand Down Expand Up @@ -853,7 +870,6 @@ Scheduler::insert(const DynInstPtr& inst)
void
Scheduler::insertNonSpec(const DynInstPtr& inst)
{
inst->setInIQ();
auto& iqs = dispTable[inst->opClass()];

for (auto iq : iqs) {
Expand Down Expand Up @@ -976,11 +992,9 @@ Scheduler::loadCancel(const DynInstPtr& inst)
int srcIdx = it.first;
auto& depInst = it.second;
if (depInst->readySrcIdx(srcIdx) && depInst->renamedSrcIdx(srcIdx) != cpu->vecOnesPhysRegId) {
assert(!depInst->isIssued());
DPRINTF(Schedule, "cancel [sn:%llu], clear src p%d ready\n", depInst->seqNum,
depInst->renamedSrcIdx(srcIdx)->flatIndex());
depInst->setCancel();
iq->iqstats->canceledInst++;
depInst->issueQue->cancel(depInst);
depInst->clearSrcRegReady(srcIdx);
dfs.push(depInst);
}
Expand Down
3 changes: 2 additions & 1 deletion src/cpu/o3/issue_queue.hh
Original file line number Diff line number Diff line change
Expand Up @@ -107,7 +107,7 @@ class IssueQue : public SimObject
// issueport : regfileport : priority
std::vector<std::vector<std::pair<int, int>>> intRfTypePortId;
std::vector<std::vector<std::pair<int, int>>> fpRfTypePortId;
std::vector<int> portBusy;
std::vector<int64_t> portBusy;
// opclass mapping to pipeid
std::vector<ReadyQue*> readyQclassify;
// s0: wakeup inst, add ready inst to readyInstsQue
Expand Down Expand Up @@ -145,6 +145,7 @@ class IssueQue : public SimObject
void selectInst();
void scheduleInst();
void addIfReady(const DynInstPtr& inst);
void cancel(const DynInstPtr& inst);

public:
inline void clearBusy(uint32_t pi) { portBusy.at(pi) = 0; }
Expand Down

0 comments on commit 1a6c8e1

Please sign in to comment.