Skip to content

Commit

Permalink
Fixing bugs, credit system should be good
Browse files Browse the repository at this point in the history
  • Loading branch information
aarongchan committed Jul 18, 2024
1 parent e70fd31 commit 3a40aa9
Show file tree
Hide file tree
Showing 5 changed files with 94 additions and 97 deletions.
5 changes: 1 addition & 4 deletions core/Decode.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -268,10 +268,7 @@ namespace olympia
ILOG("Vector uop gen: " << inst);
vec_uop_gen_->setInst(inst);

// Original instruction will act as the first UOp
inst->setUOpID(0); // set UOpID()

while(vec_uop_gen_->getNumUopsRemaining() > 1)
while(vec_uop_gen_->getNumUopsRemaining() >= 1)
{
const InstPtr uop = vec_uop_gen_->generateUop();
if (insts->size() < num_to_decode)
Expand Down
11 changes: 10 additions & 1 deletion core/ROB.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -155,11 +155,20 @@ namespace olympia
{
out_rob_retire_ack_.send(ex_inst_ptr);
}

// sending retired instruction to rename
out_rob_retire_ack_rename_.send(ex_inst_ptr);

++num_retired_;
++retired_this_cycle;
if(ex_inst_ptr->hasUOps()){
// we have to send back the number of UOps because dispatch and other resources
// count Uop instructions against their credit count. If we don't do this,
// will lead to starvation
retired_this_cycle += ex_inst_ptr->getUOpCount();
}
else{
++retired_this_cycle;
}
reorder_buffer_.pop();

ILOG("retiring " << ex_inst);
Expand Down
88 changes: 48 additions & 40 deletions core/Rename.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -143,58 +143,66 @@ namespace olympia
{
sparta_assert(inst_ptr->getStatus() == Inst::Status::RETIRED,
"Get ROB Ack, but the inst hasn't retired yet!");
auto const & dests = inst_ptr->getDestOpInfoList();
if (dests.size() > 0)
{
sparta_assert(dests.size() == 1); // we should only have one destination
const auto dest = dests[0];
const auto rf = olympia::coreutils::determineRegisterFile(dest);
const auto num = dest.field_value;
const bool is_x0 = (num == 0 && rf == core_types::RF_INTEGER);
if (!is_x0)
int lmul = 1;
if(inst_ptr->hasUOps()){
lmul = inst_ptr->getUOpCount();
}
// loop through all Uops, mark dest/srcs accordingly
for(int i = 0; i < lmul; ++i){
auto const & dests = inst_ptr->getDestOpInfoList();
if (dests.size() > 0)
{
auto const & original_dest = inst_ptr->getRenameData().getOriginalDestination();
--reference_counter_[original_dest.rf][original_dest.val];
// free previous PRF mapping if no references from srcs, there should be a new dest
// mapping for the ARF -> PRF so we know it's free to be pushed to freelist if it
// has no other src references
if (reference_counter_[original_dest.rf][original_dest.val] <= 0)
sparta_assert(dests.size() == 1); // we should only have one destination
const auto dest = dests[0];
const auto rf = olympia::coreutils::determineRegisterFile(dest);
const auto num = dest.field_value + i;
const bool is_x0 = (num == 0 && rf == core_types::RF_INTEGER);
if (!is_x0)
{
freelist_[original_dest.rf].push(original_dest.val);
auto const & original_dest = inst_ptr->getRenameData().getOriginalDestination();
--reference_counter_[original_dest.rf][original_dest.val];
// free previous PRF mapping if no references from srcs, there should be a new dest
// mapping for the ARF -> PRF so we know it's free to be pushed to freelist if it
// has no other src references
if (reference_counter_[original_dest.rf][original_dest.val] <= 0)
{
freelist_[original_dest.rf].push(original_dest.val);
}
}
}
}

const auto & srcs = inst_ptr->getRenameData().getSourceList();
// decrement reference to data register
if (inst_ptr->isLoadStoreInst())
{
const auto & data_reg = inst_ptr->getRenameData().getDataReg();
if (data_reg.field_id == mavis::InstMetaData::OperandFieldID::RS2
&& data_reg.is_x0 != true)
const auto & srcs = inst_ptr->getRenameData().getSourceList();
// decrement reference to data register
if (inst_ptr->isLoadStoreInst())
{
--reference_counter_[data_reg.rf][data_reg.val];
if (reference_counter_[data_reg.rf][data_reg.val] <= 0)
const auto & data_reg = inst_ptr->getRenameData().getDataReg();
if (data_reg.field_id == mavis::InstMetaData::OperandFieldID::RS2
&& data_reg.is_x0 != true)
{
// freeing data register value, because it's not in the source list, so won't
// get caught below
freelist_[data_reg.rf].push(data_reg.val);
--reference_counter_[data_reg.rf][data_reg.val + i];
if (reference_counter_[data_reg.rf][data_reg.val + i] <= 0)
{
// freeing data register value, because it's not in the source list, so won't
// get caught below
freelist_[data_reg.rf].push(data_reg.val + i);
}
}
}
}
// freeing references to PRF
for (const auto & src : srcs)
{
--reference_counter_[src.rf][src.val];
if (reference_counter_[src.rf][src.val] <= 0)
// freeing references to PRF
for (const auto & src : srcs)
{
// freeing a register in the case where it still has references and has already been
// retired we wait until the last reference is retired to then free the prf any
// "valid" PRF that is the true mapping of an ARF will have a reference_counter of
// at least 1, and thus shouldn't be retired
freelist_[src.rf].push(src.val);
--reference_counter_[src.rf][src.val+i];
if (reference_counter_[src.rf][src.val+i] <= 0)
{
// freeing a register in the case where it still has references and has already been
// retired we wait until the last reference is retired to then free the prf any
// "valid" PRF that is the true mapping of an ARF will have a reference_counter of
// at least 1, and thus shouldn't be retired
freelist_[src.rf].push(src.val+i);
}
}
}

// Instruction queue bookkeeping
if (SPARTA_EXPECT_TRUE(!inst_queue_.empty()))
{
Expand Down
77 changes: 28 additions & 49 deletions core/VLSU.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -281,37 +281,35 @@ namespace olympia
// NOTE:
// win_ptr should always point to an instruction ready to be issued
// Otherwise assertion error should already be fired in arbitrateInstIssue_()
if(win_ptr != nullptr){
++VLSU_insts_issued_;
// Append load/store pipe
ldst_pipeline_.append(win_ptr);

// if the element width is greater than data width, we can only pull data width then
uint32_t width = data_width_ < win_ptr->getInstPtr()->getEEW() ? data_width_ : win_ptr->getInstPtr()->getEEW();
// Set total number of vector iterations
win_ptr->setTotalVectorIter(Inst::VLEN/width);

// We append to replay queue to prevent ref count of the shared pointer to drop before
// calling pop below
if (allow_speculative_load_exec_)
{
ILOG("Appending to replay queue " << win_ptr);
appendToReplayQueue_(win_ptr);
}
++VLSU_insts_issued_;
// Append load/store pipe
ldst_pipeline_.append(win_ptr);

// if the element width is greater than data width, we can only pull data width then
uint32_t width = data_width_ < win_ptr->getInstPtr()->getEEW() ? data_width_ : win_ptr->getInstPtr()->getEEW();
// Set total number of vector iterations
win_ptr->setTotalVectorIter(Inst::VLEN/width);
ILOG(win_ptr->getInstPtr() << " " << Inst::VLEN/width)
// We append to replay queue to prevent ref count of the shared pointer to drop before
// calling pop below
if (allow_speculative_load_exec_)
{
ILOG("Appending to replay queue " << win_ptr);
appendToReplayQueue_(win_ptr);
}

// Remove inst from ready queue
win_ptr->setInReadyQueue(false);
// Remove inst from ready queue
win_ptr->setInReadyQueue(false);

// Update instruction issue info
win_ptr->setState(LoadStoreInstInfo::IssueState::ISSUED);
win_ptr->setPriority(LoadStoreInstInfo::IssuePriority::LOWEST);
// Update instruction issue info
win_ptr->setState(LoadStoreInstInfo::IssueState::ISSUED);
win_ptr->setPriority(LoadStoreInstInfo::IssuePriority::LOWEST);

// Schedule another instruction issue event if possible
if (isReadyToIssueInsts_())
{
ILOG("IssueInst_ issue");
uev_issue_inst_.schedule(sparta::Clock::Cycle(1));
}
// Schedule another instruction issue event if possible
if (isReadyToIssueInsts_())
{
ILOG("IssueInst_ issue");
uev_issue_inst_.schedule(sparta::Clock::Cycle(1));
}
}

Expand Down Expand Up @@ -619,6 +617,7 @@ namespace olympia
}
const LoadStoreInstInfoPtr & load_store_info_ptr = ldst_pipeline_[complete_stage_];
uint32_t total_iters = load_store_info_ptr->getTotalVectorIter();
ILOG(load_store_info_ptr->getVectorIter() << " total: " << total_iters << " "<< load_store_info_ptr->getInstPtr())
// we're done load/storing all vector bits, can complete
const MemoryAccessInfoPtr & mem_access_info_ptr =
load_store_info_ptr->getMemoryAccessInfoPtr();
Expand Down Expand Up @@ -775,7 +774,7 @@ namespace olympia
load_store_info_ptr->getInstPtr()->setTargetVAddr(addr + load_store_info_ptr->getInstPtr()->getStride());
// increment vector LSU count
uint32_t vector_iter = load_store_info_ptr->getVectorIter();
ILOG("Multiple passes needed for VLSU, pass number " << vector_iter << " of " << total_iters);
ILOG("Multiple passes needed for VLSU, pass number " << vector_iter << " of " << total_iters << " " << load_store_info_ptr->getInstPtr());
load_store_info_ptr->setVectorIter(++vector_iter);

bool iterate = true;
Expand Down Expand Up @@ -1151,26 +1150,6 @@ namespace olympia
sparta_assert(ready_queue_.size() > 0, "Arbitration fails: issue is empty!");

LoadStoreInstInfoPtr ready_inst_ = ready_queue_.top();
// int stages_filled = 0;
// for (int stage = 0; stage <= complete_stage_; stage++)
// {
// if (ldst_pipeline_.isValid(stage))
// {
// stages_filled++;
// const auto & pipeline_inst = ldst_pipeline_[stage];
// // pipeline_inst->getInstPtr()->getUniqueID() == ready_inst_->getInstPtr()->getUniqueID() works
// if (pipeline_inst->getInstPtr()->getUOpID() == ready_inst_->getInstPtr()->getUOpID() && pipeline_inst->getInstPtr()->getUniqueID() == ready_inst_->getInstPtr()->getUniqueID()){
// uev_issue_inst_.schedule(sparta::Clock::Cycle(1));
// ILOG("Delaying issue, due to instruction still in ldst pipeline" << ready_inst_ << ready_inst_->getInstPtr())
// return nullptr;
// }
// }
// }
// if(stages_filled == complete_stage_){
// ILOG("No pipeline slots open, rescheduling")
// uev_issue_inst_.schedule(sparta::Clock::Cycle(1));
// return nullptr;
// }
ILOG("Arbitrating instruction, popping from queue: " << ready_inst_->getInstPtr());
ready_queue_.pop();

Expand Down
10 changes: 7 additions & 3 deletions core/VectorUopGenerator.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -28,16 +28,18 @@ namespace olympia

if(num_uops_to_generate_ > 1)
{
// Original instruction will act as the first UOp
inst->setUOpID(0); // set UOpID()
current_inst_ = inst;
current_inst_->setUOpCount(num_uops_to_generate_);
ILOG("Inst: " << current_inst_ << " is being split into " << num_uops_to_generate_ << " UOPs");
// Inst counts as the first uop
--num_uops_to_generate_;
}
else
{
ILOG("Inst: " << inst << " does not need to generate uops");
}
// Inst counts as the first uop
--num_uops_to_generate_;
}

const InstPtr VectorUopGenerator::generateUop()
Expand Down Expand Up @@ -75,7 +77,9 @@ namespace olympia
// Set weak pointer to parent vector instruction (first uop)
sparta::SpartaWeakPointer<olympia::Inst> weak_ptr_inst = current_inst_;
uop->setUOpParent(weak_ptr_inst);

uop->setEEW(current_inst_->getEEW());
uop->setMOP(current_inst_->getMOP());
uop->setStride(current_inst_->getStride());
if(uop->isLoadStoreInst()){
// set base address according to LMUL, i.e if we're on the 3rd
// LMUL Uop, it's base address should be base address + 3 * EEW
Expand Down

0 comments on commit 3a40aa9

Please sign in to comment.