Skip to content

Commit

Permalink
Fixed decode bug, UOps now increment counter for parent instead of lo…
Browse files Browse the repository at this point in the history
…oping
  • Loading branch information
aarongchan committed May 22, 2024
1 parent daaa41f commit a9dd8fb
Show file tree
Hide file tree
Showing 5 changed files with 38 additions and 22 deletions.
11 changes: 8 additions & 3 deletions core/Decode.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -170,7 +170,7 @@ namespace olympia
uop_queue_.pop();
}
else{
const auto & inst = fetch_queue_.read(0);
auto & inst = fetch_queue_.read(0);
// if we're waiting on a vset, but it's a scalar instruction
// we can process all scalars after the vset until we reach a vset the decode queue
if(inst->isVset() && inst->getSourceOpInfoList()[0].field_value == 0 && inst->getDestOpInfoList()[0].field_value != 0){
Expand All @@ -184,6 +184,9 @@ namespace olympia
}
if (inst->getLMUL() > 1 && !inst->isVset())
{
// update num_decode based on UOp count as well
num_decode = std::min(uop_queue_credits_, fetch_queue_.size() + uop_queue_.size() + inst->getLMUL()-1);
num_decode = std::min(num_decode, num_to_decode_);
// lmul > 1, fracture instruction into UOps
inst->setUOp(true); // mark instruction to denote it has UOPs
// turn this into a state machine
Expand All @@ -195,6 +198,7 @@ namespace olympia
// which doesn't factor in the uop amount per instruction
insts->emplace_back(inst);
inst->setStatus(Inst::Status::DECODED);
inst->setUOpCount(VCSRs_.lmul);
fetch_queue_.pop();
for (uint32_t j = 1; j < VCSRs_.lmul; ++j)
{
Expand Down Expand Up @@ -227,7 +231,8 @@ namespace olympia
InstPtr inst_uop_ptr(new Inst(*new_inst));
inst_uop_ptr->setVCSRs(VCSRs_);
inst_uop_ptr->setUOpID(j);
inst->appendUOp(inst_uop_ptr);
sparta::SpartaWeakPointer<olympia::Inst> weak_ptr_inst = inst;
inst_uop_ptr->setUOpParent(weak_ptr_inst);
if(i < num_decode){
insts->emplace_back(inst_uop_ptr);
inst_uop_ptr->setStatus(Inst::Status::DECODED);
Expand Down Expand Up @@ -295,7 +300,7 @@ namespace olympia

// If we still have credits to send instructions as well as
// instructions in the queue, schedule another decode session
if (uop_queue_credits_ > 0 && fetch_queue_.size() > 0)
if (uop_queue_credits_ > 0 && (fetch_queue_.size() + uop_queue_.size()) > 0)
{
ev_decode_insts_event_.schedule(1);
}
Expand Down
5 changes: 5 additions & 0 deletions core/ExecutePipe.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -165,6 +165,11 @@ namespace olympia
ex_inst->setStatus(Inst::Status::COMPLETED);
complete_event_.collect(*ex_inst);
ILOG("Completing inst: " << ex_inst);
if(ex_inst->isUOp()){
sparta_assert(!ex_inst->getUOpParent().expired(), "UOp instruction parent shared pointer is expired");
auto shared_ex_inst = ex_inst->getUOpParent().lock();
shared_ex_inst->incrementUOpDoneCount();
}
out_execute_pipe_.send(1);
}

Expand Down
2 changes: 1 addition & 1 deletion core/Fetch.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -98,13 +98,13 @@ namespace olympia
ILOG("Sending: " << ex_inst << " down the pipe");
}
else{
ILOG("Stalling due to waiting on vset");
// store fetched instruction in queue
fetched_queue_.push((ex_inst));
break;
}
}
else{
ILOG("Stalling due to waiting on vset");
break;
}
}
Expand Down
23 changes: 18 additions & 5 deletions core/Inst.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -201,10 +201,6 @@ namespace olympia
// UOpIDs start at 1, because we use 0 as default UOpID on initialization
bool isUOp() const { return uopid_ > 0; }

void appendUOp(PtrType & inst) { uop_insts_.emplace_back(inst); }

std::vector<PtrType> getUOpInsts() { return uop_insts_; }

// Set the instruction's Program ID. This ID is specific to
// an instruction's retire pointer. The same instruction in a
// trace will have the same program ID (as compared to
Expand Down Expand Up @@ -246,6 +242,16 @@ namespace olympia
VCSRs_.vl = inputVCSRs.vl;
}

void setUOpParent(sparta::SpartaWeakPointer<olympia::Inst> & uop_parent){
uop_parent_ = uop_parent;
}

void setUOpCount(uint64_t uop_count){
uop_count_ = uop_count;
}

void incrementUOpDoneCount(){ uop_done_count_++; }

sparta::memory::addr_t getTargetVAddr() const { return target_vaddr_; }

uint32_t getSEW() const { return VCSRs_.sew; }
Expand All @@ -254,6 +260,11 @@ namespace olympia

uint32_t getVL() const { return VCSRs_.vl; }

uint64_t getUOpDoneCount(){ return uop_done_count_; }

sparta::SpartaWeakPointer<olympia::Inst> getUOpParent() { return uop_parent_; }

uint64_t getUOpCount() const { return uop_count_; }
// Branch instruction was taken (always set for JAL/JALR)
void setTakenBranch(bool taken) { is_taken_branch_ = taken; }

Expand Down Expand Up @@ -403,9 +414,11 @@ namespace olympia
const bool is_call_;
const bool is_return_;
bool has_uops_;
std::vector<PtrType> uop_insts_;
uint64_t uop_done_count_ = 1; // start at 1 because the uop count includes the parent instruction
uint64_t uop_count_ = 0;
VCSRs VCSRs_;

sparta::SpartaWeakPointer<olympia::Inst> uop_parent_;
// Did this instruction mispredict?
bool is_mispredicted_ = false;
bool is_taken_branch_ = false;
Expand Down
19 changes: 6 additions & 13 deletions core/ROB.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -137,20 +137,13 @@ namespace olympia
sparta_assert(ex_inst.isSpeculative() == false,
"Uh, oh! A speculative instruction is being retired: " << ex_inst);
bool uops_done = true;
if (ex_inst.hasUOps())

if (ex_inst_ptr->hasUOps() && ex_inst_ptr->getUOpDoneCount() < ex_inst_ptr->getUOpCount())
{
// check if UOps are done
// for(auto & i : *in_reorder_buffer_write_.pullData()) {
// weakptr from child to parent instruction, increment when done
for (const auto & inst : ex_inst.getUOpInsts())
{
if (inst->getStatus() != Inst::Status::COMPLETED)
{
uops_done = false;
ILOG("UOP: " << inst << " is not done for instruction: " << ex_inst);
break;
}
}
// if UOps are all done, you can retire parent
uops_done = false;
ILOG("UOP: " << ex_inst << " is not done for instruction: " << ex_inst);
break;
}
if ((ex_inst.getStatus() == Inst::Status::COMPLETED) && uops_done)
{
Expand Down

0 comments on commit a9dd8fb

Please sign in to comment.