Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Raise exception in LSU when ROB is drained #108

Merged
merged 15 commits into from
Dec 21, 2023
Merged
Show file tree
Hide file tree
Changes from 3 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions core/CPUFactory.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -94,6 +94,10 @@ auto olympia::CPUFactory::bindTree_(sparta::RootTreeNode* root_node,
setTLB(*private_nodes_.at(num_of_cores)->getResourceAs<olympia::SimpleTLB>());
(core_tree_node->getChild("preloader")->getResourceAs<olympia::Preloader>())->
preload();
auto rob = core_tree_node->getChild("rob")->getResourceAs<olympia::ROB>()->getContainer();
auto lsu = core_tree_node->getChild("lsu")->getResourceAs<olympia::LSU>();
rob->registerForNotification<bool, LSU, &LSU::onRobDrained_>
(lsu, "rob_notif_channel");
h0lyalg0rithm marked this conversation as resolved.
Show resolved Hide resolved
h0lyalg0rithm marked this conversation as resolved.
Show resolved Hide resolved
}
}

Expand Down
16 changes: 16 additions & 0 deletions core/LSU.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -80,7 +80,10 @@ namespace olympia
// Both cache and MMU try to drive the single BIU port at the same cycle
// Here we give cache the higher priority
ILOG("LSU construct: #" << node->getGroupIdx());
}

void LSU::onRobDrained_(const bool &val){
retire_done_and_is_drained_ = val;
h0lyalg0rithm marked this conversation as resolved.
Show resolved Hide resolved
}

LSU::~LSU() {
Expand All @@ -92,6 +95,11 @@ namespace olympia
<< ": "
<< memory_access_allocator_.getNumAllocated()
<< " MemoryAccessInfo objects allocated/created");

if(retire_done_and_is_drained_){
bool ldst_queue_empty_ = ldst_inst_queue_.empty();
sparta_assert(ldst_queue_empty_, "Issue queue has pending instructions");
h0lyalg0rithm marked this conversation as resolved.
Show resolved Hide resolved
}
}

////////////////////////////////////////////////////////////////////////////////
Expand Down Expand Up @@ -453,6 +461,14 @@ namespace olympia
// Otherwise, assertion error is fired inside arbitrateInstIssue_()
}

void LSU::dumpDebugContent_(std::ostream & output) const
{
output << "LSU Contents" << std::endl;
for (const auto & entry : ldst_inst_queue_)
{
output << '\t' << entry << std::endl;
}
}

////////////////////////////////////////////////////////////////////////////////
// Regular Function/Subroutine Call
Expand Down
6 changes: 4 additions & 2 deletions core/LSU.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -69,7 +69,7 @@ namespace olympia
// Type Name/Alias Declaration
////////////////////////////////////////////////////////////////////////////////


bool retire_done_and_is_drained_ = false;
class LoadStoreInstInfo;

using LoadStoreInstInfoPtr = sparta::SpartaSharedPointer<LoadStoreInstInfo>;
Expand Down Expand Up @@ -196,6 +196,8 @@ namespace olympia
SPARTA_ADDPAIR("state", &LoadStoreInstInfo::getState),
SPARTA_FLATTEN( &LoadStoreInstInfo::getMemoryAccessInfoPtr))
};

void onRobDrained_(const bool &val);
private:

using ScoreboardViews = std::array<std::unique_ptr<sparta::ScoreboardView>, core_types::N_REGFILES>;
Expand Down Expand Up @@ -293,7 +295,6 @@ namespace olympia
////////////////////////////////////////////////////////////////////////////////
// Callbacks
////////////////////////////////////////////////////////////////////////////////

// Send initial credits (ldst_inst_queue_size_) to Dispatch Unit
void sendInitialCredits_();

Expand Down Expand Up @@ -325,6 +326,7 @@ namespace olympia
// Handle instruction flush in LSU
void handleFlush_(const FlushCriteria &);

void dumpDebugContent_(std::ostream& output) const override final;
////////////////////////////////////////////////////////////////////////////////
// Regular Function/Subroutine Call
////////////////////////////////////////////////////////////////////////////////
Expand Down
7 changes: 7 additions & 0 deletions core/ROB.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,12 @@ namespace olympia
// simulation continuing on.
ev_ensure_forward_progress_.setContinuing(false);

rob_drained_notif_source_.reset(new sparta::NotificationSource<bool>(
this->getContainer(),
"rob_notif_channel",
"Notification channel for rob",
"rob_notif_channel"
));
// Send initial credits to anyone that cares. Probably Dispatch.
sparta::StartupEvent(node, CREATE_SPARTA_HANDLER(ROB, sendInitialCredits_));
}
Expand Down Expand Up @@ -198,6 +204,7 @@ namespace olympia

void ROB::onStartingTeardown_() {
if ((reorder_buffer_.size() > 0) && (false == rob_stopped_simulation_)) {
rob_drained_notif_source_->postNotification(true);
h0lyalg0rithm marked this conversation as resolved.
Show resolved Hide resolved
std::cerr << "WARNING! Simulation is ending, but the ROB didn't stop it. Lock up situation?" << std::endl;
dumpDebugContent_(std::cerr);
}
Expand Down
2 changes: 2 additions & 0 deletions core/ROB.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -116,6 +116,8 @@ namespace olympia
sparta::Event<> ev_ensure_forward_progress_{&unit_event_set_, "forward_progress_check",
CREATE_SPARTA_HANDLER(ROB, checkForwardProgress_)};

std::unique_ptr<sparta::NotificationSource<bool>> rob_drained_notif_source_;

void sendInitialCredits_();
void retireEvent_();
void robAppended_(const InstGroup &);
Expand Down
10 changes: 10 additions & 0 deletions test/core/rename/Rename_test.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -133,6 +133,14 @@ class olympia::LSUTester
// while the ADD instruction is running, the STORE instruction should NOT issue
EXPECT_TRUE(lsu.lsu_insts_issued_ == 0);
}

void clear_entries(olympia::LSU &lsu){
h0lyalg0rithm marked this conversation as resolved.
Show resolved Hide resolved
auto iter = lsu.ldst_inst_queue_.begin();
while(iter != lsu.ldst_inst_queue_.end()){
auto x(iter++);
lsu.ldst_inst_queue_.erase(x);
}
}
};

//
Expand Down Expand Up @@ -427,6 +435,7 @@ void runTest(int argc, char **argv)
cls.runSimulator(&sim, 6);
executepipe_tester.test_dependent_integer_first_instruction(*my_executepipe);
lsu_tester.test_dependent_lsu_instruction(*my_lsu);
lsu_tester.clear_entries(*my_lsu);
}
else if(input_file == "raw_float_lsu.json"){
// testing RAW dependency for data operand
Expand All @@ -440,6 +449,7 @@ void runTest(int argc, char **argv)
cls.runSimulator(&sim, 6);
executepipe_tester.test_dependent_integer_first_instruction(*my_executepipe);
lsu_tester.test_dependent_lsu_instruction(*my_lsu);
lsu_tester.clear_entries(*my_lsu);
}
else{
sparta::Scheduler sched;
Expand Down