From a385d57921f33d71f753863eb21ec2a2fe81a4a6 Mon Sep 17 00:00:00 2001 From: Suraj Shirvankar Date: Tue, 31 Oct 2023 16:10:39 +0100 Subject: [PATCH] Raise exception in LSU when ROB is drained --- core/CPUFactory.cpp | 4 ++++ core/LSU.cpp | 8 ++++++++ core/LSU.hpp | 5 +++-- core/ROB.cpp | 7 +++++++ core/ROB.hpp | 2 ++ 5 files changed, 24 insertions(+), 2 deletions(-) diff --git a/core/CPUFactory.cpp b/core/CPUFactory.cpp index 012e695b..62960b46 100644 --- a/core/CPUFactory.cpp +++ b/core/CPUFactory.cpp @@ -94,6 +94,10 @@ auto olympia::CPUFactory::bindTree_(sparta::RootTreeNode* root_node, setTLB(*private_nodes_.at(num_of_cores)->getResourceAs()); (core_tree_node->getChild("preloader")->getResourceAs())-> preload(); + auto rob = core_tree_node->getChild("rob")->getResourceAs()->getContainer(); + auto lsu = core_tree_node->getChild("lsu")->getResourceAs(); + rob->registerForNotification + (lsu, "rob_notif_channel"); } } diff --git a/core/LSU.cpp b/core/LSU.cpp index 6aff42ed..76667d46 100644 --- a/core/LSU.cpp +++ b/core/LSU.cpp @@ -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; } LSU::~LSU() { @@ -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"); + } } //////////////////////////////////////////////////////////////////////////////// diff --git a/core/LSU.hpp b/core/LSU.hpp index 81a94fa5..afb7e35b 100644 --- a/core/LSU.hpp +++ b/core/LSU.hpp @@ -69,7 +69,7 @@ namespace olympia // Type Name/Alias Declaration //////////////////////////////////////////////////////////////////////////////// - + bool retire_done_and_is_drained_ = false; class LoadStoreInstInfo; using LoadStoreInstInfoPtr = sparta::SpartaSharedPointer; @@ -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, core_types::N_REGFILES>; @@ -293,7 +295,6 @@ namespace olympia //////////////////////////////////////////////////////////////////////////////// // Callbacks //////////////////////////////////////////////////////////////////////////////// - // Send initial credits (ldst_inst_queue_size_) to Dispatch Unit void sendInitialCredits_(); diff --git a/core/ROB.cpp b/core/ROB.cpp index 16dcf3d0..395ce1b7 100644 --- a/core/ROB.cpp +++ b/core/ROB.cpp @@ -53,6 +53,12 @@ namespace olympia // simulation continuing on. ev_ensure_forward_progress_.setContinuing(false); + rob_drained_notif_source_.reset(new sparta::NotificationSource( + 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_)); } @@ -198,6 +204,7 @@ namespace olympia void ROB::onStartingTeardown_() { if ((reorder_buffer_.size() > 0) && (false == rob_stopped_simulation_)) { + rob_drained_notif_source_->postNotification(true); std::cerr << "WARNING! Simulation is ending, but the ROB didn't stop it. Lock up situation?" << std::endl; dumpDebugContent_(std::cerr); } diff --git a/core/ROB.hpp b/core/ROB.hpp index f6a828cc..89aa83d4 100644 --- a/core/ROB.hpp +++ b/core/ROB.hpp @@ -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> rob_drained_notif_source_; + void sendInitialCredits_(); void retireEvent_(); void robAppended_(const InstGroup &);