From 6ad7faa0a9e89c839157f66941b38d12aa2e45bc Mon Sep 17 00:00:00 2001 From: Finn Wilkinson Date: Wed, 19 Jun 2024 12:07:07 +0100 Subject: [PATCH 01/12] Updated logic of emulation core model to ensure all micro-ops finish executing in one cycle. --- src/include/simeng/models/emulation/Core.hh | 3 -- src/lib/models/emulation/Core.cc | 58 +++++++-------------- 2 files changed, 18 insertions(+), 43 deletions(-) diff --git a/src/include/simeng/models/emulation/Core.hh b/src/include/simeng/models/emulation/Core.hh index 9f1d4c2c1d..df62810c7a 100644 --- a/src/include/simeng/models/emulation/Core.hh +++ b/src/include/simeng/models/emulation/Core.hh @@ -71,9 +71,6 @@ class Core : public simeng::Core { /** The length of the available instruction memory. */ uint64_t programByteLength_ = 0; - /** Is the core waiting on a data read? */ - uint64_t pendingReads_ = 0; - /** The number of instructions executed. */ uint64_t instructionsExecuted_ = 0; diff --git a/src/lib/models/emulation/Core.cc b/src/lib/models/emulation/Core.cc index 3998fa91b5..ec38e12c5b 100644 --- a/src/lib/models/emulation/Core.cc +++ b/src/lib/models/emulation/Core.cc @@ -27,6 +27,7 @@ Core::Core(memory::MemoryInterface& instructionMemory, void Core::tick() { ticks_++; + isa_.updateSystemTimerRegisters(®isterFileSet_, ticks_); if (hasHalted_) return; @@ -40,29 +41,7 @@ void Core::tick() { return; } - if (pendingReads_ > 0) { - // Handle pending reads to a uop - auto& uop = microOps_.front(); - - const auto& completedReads = dataMemory_.getCompletedReads(); - for (const auto& response : completedReads) { - assert(pendingReads_ > 0); - uop->supplyData(response.target.address, response.data); - pendingReads_--; - } - dataMemory_.clearCompletedReads(); - - if (pendingReads_ == 0) { - // Load complete: resume execution - execute(uop); - } - - // More data pending, end cycle early - return; - } - // Fetch - // Determine if new uops are needed to be fetched if (!microOps_.size()) { // Find fetched memory that matches the current PC @@ -118,19 +97,23 @@ void Core::tick() { return; } if (addresses.size() > 0) { - // Memory reads are required; request them, set `pendingReads_` - // accordingly, and end the cycle early + // Memory reads required; request them. for (auto const& target : addresses) { dataMemory_.requestRead(target); - // Store addresses for use by next store data operation + // Save addresses for use by instructions that perform a LD and STR + // (i.e. single instruction atomics) previousAddresses_.push_back(target); } - pendingReads_ = addresses.size(); - return; - } else { - // Early execution due to lacking addresses - execute(uop); - return; + // Emulation core can only be used with a Flat memory interface, so data + // is ready immediately. + const auto& completedReads = dataMemory_.getCompletedReads(); + assert(completedReads.size() == addresses.size() && + "Number of completed reads does not match the number of requested " + "reads."); + for (const auto& response : completedReads) { + uop->supplyData(response.target.address, response.data); + } + dataMemory_.clearCompletedReads(); } } else if (uop->isStoreAddress()) { auto addresses = uop->generateAddresses(); @@ -139,23 +122,18 @@ void Core::tick() { handleException(uop); return; } - // Store addresses for use by next store data operation + // Store addresses for use by next store data operation in `execute()` for (auto const& target : addresses) { previousAddresses_.push_back(target); } - if (uop->isStoreData()) { - execute(uop); - } else { - // Fetch memory for next cycle + if (!uop->isStoreData()) { + // No further action needed, fetch memory for next cycle and return early instructionMemory_.requestRead({pc_, FETCH_SIZE}); microOps_.pop(); + return; } - - return; } - execute(uop); - isa_.updateSystemTimerRegisters(®isterFileSet_, ticks_); } bool Core::hasHalted() const { return hasHalted_; } From ba4d6fba88be120d18f4186c17520d808fee6c04 Mon Sep 17 00:00:00 2001 From: Finn Wilkinson Date: Wed, 19 Jun 2024 12:07:56 +0100 Subject: [PATCH 02/12] Ensured LDADD and CASAL atomic instructions that perform both a read and write have their metadata correctly set in instruction decode. --- src/lib/arch/aarch64/Instruction_decode.cc | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/lib/arch/aarch64/Instruction_decode.cc b/src/lib/arch/aarch64/Instruction_decode.cc index bceb3b1488..165c51b9ac 100644 --- a/src/lib/arch/aarch64/Instruction_decode.cc +++ b/src/lib/arch/aarch64/Instruction_decode.cc @@ -487,12 +487,14 @@ void Instruction::decode() { // LDADD* are considered to be both a load and a store if (metadata_.id >= ARM64_INS_LDADD && metadata_.id <= ARM64_INS_LDADDLH) { setInstructionType(InsnType::isLoad); + setInstructionType(InsnType::isStoreData); } // CASAL* are considered to be both a load and a store if (metadata_.opcode == Opcode::AArch64_CASALW || metadata_.opcode == Opcode::AArch64_CASALX) { setInstructionType(InsnType::isLoad); + setInstructionType(InsnType::isStoreData); } if (isInstruction(InsnType::isStoreData)) { From c8cf7f7e84ef949f7275993f63454dec4e36a795 Mon Sep 17 00:00:00 2001 From: Finn Wilkinson Date: Wed, 19 Jun 2024 14:31:34 +0100 Subject: [PATCH 03/12] Updated comments. --- src/lib/models/emulation/Core.cc | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/lib/models/emulation/Core.cc b/src/lib/models/emulation/Core.cc index ec38e12c5b..c2110bd795 100644 --- a/src/lib/models/emulation/Core.cc +++ b/src/lib/models/emulation/Core.cc @@ -97,7 +97,7 @@ void Core::tick() { return; } if (addresses.size() > 0) { - // Memory reads required; request them. + // Memory reads required; request them for (auto const& target : addresses) { dataMemory_.requestRead(target); // Save addresses for use by instructions that perform a LD and STR @@ -105,7 +105,7 @@ void Core::tick() { previousAddresses_.push_back(target); } // Emulation core can only be used with a Flat memory interface, so data - // is ready immediately. + // is ready immediately const auto& completedReads = dataMemory_.getCompletedReads(); assert(completedReads.size() == addresses.size() && "Number of completed reads does not match the number of requested " From 3537d6ea1fa6597ed3f51b2e9a8c4948bed949df Mon Sep 17 00:00:00 2001 From: Finn Wilkinson Date: Wed, 19 Jun 2024 14:46:42 +0100 Subject: [PATCH 04/12] Updated Jenkins expected cycles for default config. --- .jenkins/build_test_run.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.jenkins/build_test_run.sh b/.jenkins/build_test_run.sh index 4b4f237b3c..dfcaf83907 100644 --- a/.jenkins/build_test_run.sh +++ b/.jenkins/build_test_run.sh @@ -63,7 +63,7 @@ run () { cat run echo "" compare_outputs "$(grep "retired:" run | rev | cut -d ' ' -f1 | rev)" "6708" "retired instructions" - compare_outputs "$(grep "cycles:" run | rev | cut -d ' ' -f1 | rev)" "7955" "simulated cycles" + compare_outputs "$(grep "cycles:" run | rev | cut -d ' ' -f1 | rev)" "6736" "simulated cycles" echo "" ./bin/simeng "$SIMENG_TOP"/configs/tx2.yaml > run From d694113fe4143eefd4d3e4426132aec903fa6144 Mon Sep 17 00:00:00 2001 From: Finn Wilkinson Date: Thu, 20 Jun 2024 14:12:00 +0100 Subject: [PATCH 05/12] Added flat memory interface assert and additional retired instruction incrementer to emulation core. --- src/lib/models/emulation/Core.cc | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/src/lib/models/emulation/Core.cc b/src/lib/models/emulation/Core.cc index c2110bd795..34c582b075 100644 --- a/src/lib/models/emulation/Core.cc +++ b/src/lib/models/emulation/Core.cc @@ -106,6 +106,9 @@ void Core::tick() { } // Emulation core can only be used with a Flat memory interface, so data // is ready immediately + assert((config::SimInfo::getConfig()["L1-Data-Memory"]["Interface-Type"] + .as() == "Flat") && + "Emulation core is only compatable with a Flat Memory Interface."); const auto& completedReads = dataMemory_.getCompletedReads(); assert(completedReads.size() == addresses.size() && "Number of completed reads does not match the number of requested " @@ -227,6 +230,11 @@ void Core::processExceptionHandler() { // Clear the handler exceptionHandler_ = nullptr; + // For an exception to reach this part of the code, it must be something akin + // to a system call, which itself should be counted as an instruction + // finishing execution. + instructionsExecuted_++; + // Fetch memory for next cycle instructionMemory_.requestRead({pc_, FETCH_SIZE}); microOps_.pop(); From 6b29d58af3d36fdb37eadda5e37631346b848009 Mon Sep 17 00:00:00 2001 From: Finn Wilkinson Date: Thu, 20 Jun 2024 14:28:25 +0100 Subject: [PATCH 06/12] Updated jenkins retired instruction value for default core. --- .jenkins/build_test_run.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.jenkins/build_test_run.sh b/.jenkins/build_test_run.sh index dfcaf83907..a2e5158903 100644 --- a/.jenkins/build_test_run.sh +++ b/.jenkins/build_test_run.sh @@ -62,7 +62,7 @@ run () { echo "Simulation without configuration file argument:" cat run echo "" - compare_outputs "$(grep "retired:" run | rev | cut -d ' ' -f1 | rev)" "6708" "retired instructions" + compare_outputs "$(grep "retired:" run | rev | cut -d ' ' -f1 | rev)" "6721" "retired instructions" compare_outputs "$(grep "cycles:" run | rev | cut -d ' ' -f1 | rev)" "6736" "simulated cycles" echo "" From 2e07b2658b1f454889bf52413b264534de9fd91e Mon Sep 17 00:00:00 2001 From: Finn Wilkinson Date: Wed, 3 Jul 2024 15:35:49 +0100 Subject: [PATCH 07/12] Updated emulation core to execute all micro-ops in a single cycle. --- src/include/simeng/models/emulation/Core.hh | 3 - src/lib/models/emulation/Core.cc | 215 +++++++++----------- 2 files changed, 101 insertions(+), 117 deletions(-) diff --git a/src/include/simeng/models/emulation/Core.hh b/src/include/simeng/models/emulation/Core.hh index df62810c7a..f1e38d7022 100644 --- a/src/include/simeng/models/emulation/Core.hh +++ b/src/include/simeng/models/emulation/Core.hh @@ -59,9 +59,6 @@ class Core : public simeng::Core { /** A reusable macro-op vector to fill with uops. */ MacroOp macroOp_; - /** An internal buffer for storing one or more uops. */ - std::queue> microOps_; - /** The previously generated addresses. */ std::vector previousAddresses_; diff --git a/src/lib/models/emulation/Core.cc b/src/lib/models/emulation/Core.cc index 34c582b075..51b3221789 100644 --- a/src/lib/models/emulation/Core.cc +++ b/src/lib/models/emulation/Core.cc @@ -17,6 +17,17 @@ Core::Core(memory::MemoryInterface& instructionMemory, architecturalRegisterFileSet_(registerFileSet_), pc_(entryPoint), programByteLength_(programByteLength) { + // Ensure both interface types are flat + assert( + (config::SimInfo::getConfig()["L1-Data-Memory"]["Interface-Type"] + .as() == "Flat") && + "Emulation core is only compatable with a Flat Data Memory Interface."); + assert( + (config::SimInfo::getConfig()["L1-Instruction-Memory"]["Interface-Type"] + .as() == "Flat") && + "Emulation core is only compatable with a Flat Instruction Memory " + "Interface."); + // Pre-load the first instruction instructionMemory_.requestRead({pc_, FETCH_SIZE}); @@ -26,9 +37,6 @@ Core::Core(memory::MemoryInterface& instructionMemory, } void Core::tick() { - ticks_++; - isa_.updateSystemTimerRegisters(®isterFileSet_, ticks_); - if (hasHalted_) return; if (pc_ >= programByteLength_) { @@ -36,107 +44,104 @@ void Core::tick() { return; } - if (exceptionHandler_ != nullptr) { - processExceptionHandler(); - return; - } - - // Fetch - // Determine if new uops are needed to be fetched - if (!microOps_.size()) { - // Find fetched memory that matches the current PC - const auto& fetched = instructionMemory_.getCompletedReads(); - size_t fetchIndex; - for (fetchIndex = 0; fetchIndex < fetched.size(); fetchIndex++) { - if (fetched[fetchIndex].target.address == pc_) { - break; - } - } - if (fetchIndex == fetched.size()) { - // Need to wait for fetched instructions - return; - } + ticks_++; + isa_.updateSystemTimerRegisters(®isterFileSet_, ticks_); - const auto& instructionBytes = fetched[fetchIndex].data; - auto bytesRead = isa_.predecode(instructionBytes.getAsVector(), - FETCH_SIZE, pc_, macroOp_); + // Fetch & Decode + assert(macroOp_.empty() && + "Cannot begin emulation tick with un-executed micro-ops."); + // We only fetch one instruction at a time, so only ever one result in + // complete reads + const auto& instructionBytes = instructionMemory_.getCompletedReads()[0].data; + // Predecode fetched data + auto bytesRead = isa_.predecode(instructionBytes.getAsVector(), + FETCH_SIZE, pc_, macroOp_); + // Clear the fetched data + instructionMemory_.clearCompletedReads(); - // Clear the fetched data - instructionMemory_.clearCompletedReads(); + pc_ += bytesRead; - pc_ += bytesRead; + // Loop over all micro-ops and execute one by one + while (!macroOp_.empty()) { + auto& uop = macroOp_.front(); - // Decode - for (size_t index = 0; index < macroOp_.size(); index++) { - microOps_.push(std::move(macroOp_[index])); + if (uop->exceptionEncountered()) { + handleException(uop); + // If fatal, return + if (hasHalted_) return; + // Else, move onto next micro-op + macroOp_.erase(macroOp_.begin()); + continue; } - } - - auto& uop = microOps_.front(); - - if (uop->exceptionEncountered()) { - handleException(uop); - return; - } - // Issue - auto registers = uop->getSourceRegisters(); - for (size_t i = 0; i < registers.size(); i++) { - auto reg = registers[i]; - if (!uop->isOperandReady(i)) { - uop->supplyOperand(i, registerFileSet_.get(reg)); + // Issue + auto registers = uop->getSourceRegisters(); + for (size_t i = 0; i < registers.size(); i++) { + auto reg = registers[i]; + if (!uop->isOperandReady(i)) { + uop->supplyOperand(i, registerFileSet_.get(reg)); + } } - } - // Execute - if (uop->isLoad()) { - auto addresses = uop->generateAddresses(); - previousAddresses_.clear(); - if (uop->exceptionEncountered()) { - handleException(uop); - return; - } - if (addresses.size() > 0) { - // Memory reads required; request them + // Execute + if (uop->isLoad()) { + auto addresses = uop->generateAddresses(); + previousAddresses_.clear(); + if (uop->exceptionEncountered()) { + handleException(uop); + // If fatal, return + if (hasHalted_) return; + // Else, move onto next micro-op + macroOp_.erase(macroOp_.begin()); + continue; + } + if (addresses.size() > 0) { + // Memory reads required; request them + for (auto const& target : addresses) { + dataMemory_.requestRead(target); + // Save addresses for use by instructions that perform a LD and STR + // (i.e. single instruction atomics) + previousAddresses_.push_back(target); + } + // Emulation core can only be used with a Flat memory interface, so data + // is ready immediately + const auto& completedReads = dataMemory_.getCompletedReads(); + assert( + completedReads.size() == addresses.size() && + "Number of completed reads does not match the number of requested " + "reads."); + for (const auto& response : completedReads) { + uop->supplyData(response.target.address, response.data); + } + dataMemory_.clearCompletedReads(); + } + } else if (uop->isStoreAddress()) { + auto addresses = uop->generateAddresses(); + previousAddresses_.clear(); + if (uop->exceptionEncountered()) { + handleException(uop); + // If fatal, return + if (hasHalted_) return; + // Else, move onto next micro-op + macroOp_.erase(macroOp_.begin()); + continue; + } + // Store addresses for use by next store data operation in `execute()` for (auto const& target : addresses) { - dataMemory_.requestRead(target); - // Save addresses for use by instructions that perform a LD and STR - // (i.e. single instruction atomics) previousAddresses_.push_back(target); } - // Emulation core can only be used with a Flat memory interface, so data - // is ready immediately - assert((config::SimInfo::getConfig()["L1-Data-Memory"]["Interface-Type"] - .as() == "Flat") && - "Emulation core is only compatable with a Flat Memory Interface."); - const auto& completedReads = dataMemory_.getCompletedReads(); - assert(completedReads.size() == addresses.size() && - "Number of completed reads does not match the number of requested " - "reads."); - for (const auto& response : completedReads) { - uop->supplyData(response.target.address, response.data); + if (!uop->isStoreData()) { + // No further action needed, move onto next micro-op + macroOp_.erase(macroOp_.begin()); + continue; } - dataMemory_.clearCompletedReads(); - } - } else if (uop->isStoreAddress()) { - auto addresses = uop->generateAddresses(); - previousAddresses_.clear(); - if (uop->exceptionEncountered()) { - handleException(uop); - return; - } - // Store addresses for use by next store data operation in `execute()` - for (auto const& target : addresses) { - previousAddresses_.push_back(target); - } - if (!uop->isStoreData()) { - // No further action needed, fetch memory for next cycle and return early - instructionMemory_.requestRead({pc_, FETCH_SIZE}); - microOps_.pop(); - return; } + execute(uop); + macroOp_.erase(macroOp_.begin()); } - execute(uop); + instructionsExecuted_++; + // Fetch memory for next cycle + instructionMemory_.requestRead({pc_, FETCH_SIZE}); } bool Core::hasHalted() const { return hasHalted_; } @@ -188,12 +193,6 @@ void Core::execute(std::shared_ptr& uop) { registerFileSet_.set(reg, results[i]); } } - - if (uop->isLastMicroOp()) instructionsExecuted_++; - - // Fetch memory for next cycle - instructionMemory_.requestRead({pc_, FETCH_SIZE}); - microOps_.pop(); } void Core::handleException(const std::shared_ptr& instruction) { @@ -204,16 +203,13 @@ void Core::handleException(const std::shared_ptr& instruction) { void Core::processExceptionHandler() { assert(exceptionHandler_ != nullptr && "Attempted to process an exception handler that wasn't present"); - if (dataMemory_.hasPendingRequests()) { - // Must wait for all memory requests to complete before processing the - // exception - return; - } - bool success = exceptionHandler_->tick(); - if (!success) { - // Handler needs further ticks to complete - return; + while (true) { + bool success = exceptionHandler_->tick(); + if (success) { + // No more ticks needed to complete exception + break; + } } const auto& result = exceptionHandler_->getResult(); @@ -229,15 +225,6 @@ void Core::processExceptionHandler() { // Clear the handler exceptionHandler_ = nullptr; - - // For an exception to reach this part of the code, it must be something akin - // to a system call, which itself should be counted as an instruction - // finishing execution. - instructionsExecuted_++; - - // Fetch memory for next cycle - instructionMemory_.requestRead({pc_, FETCH_SIZE}); - microOps_.pop(); } } // namespace emulation From da6840d7787876c5a7d048934ea4322030d2cbf8 Mon Sep 17 00:00:00 2001 From: Finn Wilkinson Date: Wed, 3 Jul 2024 15:52:08 +0100 Subject: [PATCH 08/12] Added minor comments. --- src/lib/models/emulation/Core.cc | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/lib/models/emulation/Core.cc b/src/lib/models/emulation/Core.cc index 51b3221789..fad4c415d2 100644 --- a/src/lib/models/emulation/Core.cc +++ b/src/lib/models/emulation/Core.cc @@ -83,7 +83,7 @@ void Core::tick() { } } - // Execute + // Execute & Write-back if (uop->isLoad()) { auto addresses = uop->generateAddresses(); previousAddresses_.clear(); @@ -139,6 +139,7 @@ void Core::tick() { execute(uop); macroOp_.erase(macroOp_.begin()); } + // Commit instructionsExecuted_++; // Fetch memory for next cycle instructionMemory_.requestRead({pc_, FETCH_SIZE}); From 8d03f67be77e08937b8e45b6c0b1da2829501b77 Mon Sep 17 00:00:00 2001 From: Finn Wilkinson <56131608+FinnWilkinson@users.noreply.github.com> Date: Wed, 3 Jul 2024 16:07:54 +0100 Subject: [PATCH 09/12] Updated Jenkin's script with new cycles value to match instruction retired count --- .jenkins/build_test_run.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.jenkins/build_test_run.sh b/.jenkins/build_test_run.sh index a2e5158903..52b3a7bdab 100644 --- a/.jenkins/build_test_run.sh +++ b/.jenkins/build_test_run.sh @@ -63,7 +63,7 @@ run () { cat run echo "" compare_outputs "$(grep "retired:" run | rev | cut -d ' ' -f1 | rev)" "6721" "retired instructions" - compare_outputs "$(grep "cycles:" run | rev | cut -d ' ' -f1 | rev)" "6736" "simulated cycles" + compare_outputs "$(grep "cycles:" run | rev | cut -d ' ' -f1 | rev)" "6721" "simulated cycles" echo "" ./bin/simeng "$SIMENG_TOP"/configs/tx2.yaml > run From 9a3e4d5aab0eb6cfa1627e5338e5864eacd4bdf2 Mon Sep 17 00:00:00 2001 From: Finn Wilkinson Date: Wed, 3 Jul 2024 16:55:19 +0100 Subject: [PATCH 10/12] Removed redundant code. --- src/lib/models/emulation/Core.cc | 9 --------- 1 file changed, 9 deletions(-) diff --git a/src/lib/models/emulation/Core.cc b/src/lib/models/emulation/Core.cc index fad4c415d2..dca7c8fadd 100644 --- a/src/lib/models/emulation/Core.cc +++ b/src/lib/models/emulation/Core.cc @@ -69,9 +69,6 @@ void Core::tick() { handleException(uop); // If fatal, return if (hasHalted_) return; - // Else, move onto next micro-op - macroOp_.erase(macroOp_.begin()); - continue; } // Issue @@ -91,9 +88,6 @@ void Core::tick() { handleException(uop); // If fatal, return if (hasHalted_) return; - // Else, move onto next micro-op - macroOp_.erase(macroOp_.begin()); - continue; } if (addresses.size() > 0) { // Memory reads required; request them @@ -122,9 +116,6 @@ void Core::tick() { handleException(uop); // If fatal, return if (hasHalted_) return; - // Else, move onto next micro-op - macroOp_.erase(macroOp_.begin()); - continue; } // Store addresses for use by next store data operation in `execute()` for (auto const& target : addresses) { From ec19a671be3a2a67e3081e9490e6c473b2da2cee Mon Sep 17 00:00:00 2001 From: Finn Wilkinson Date: Thu, 4 Jul 2024 10:16:35 +0100 Subject: [PATCH 11/12] Attended PR comments. --- src/lib/models/emulation/Core.cc | 17 +++++------------ src/lib/models/inorder/Core.cc | 6 +++--- src/lib/models/outoforder/Core.cc | 6 +++--- 3 files changed, 11 insertions(+), 18 deletions(-) diff --git a/src/lib/models/emulation/Core.cc b/src/lib/models/emulation/Core.cc index dca7c8fadd..cd65c7cf30 100644 --- a/src/lib/models/emulation/Core.cc +++ b/src/lib/models/emulation/Core.cc @@ -172,18 +172,11 @@ void Core::execute(std::shared_ptr& uop) { } // Writeback - auto results = uop->getResults(); - auto destinations = uop->getDestinationRegisters(); - if (uop->isStoreData()) { - for (size_t i = 0; i < results.size(); i++) { - auto reg = destinations[i]; - registerFileSet_.set(reg, results[i]); - } - } else { - for (size_t i = 0; i < results.size(); i++) { - auto reg = destinations[i]; - registerFileSet_.set(reg, results[i]); - } + const auto& results = uop->getResults(); + const auto& destinations = uop->getDestinationRegisters(); + for (size_t i = 0; i < results.size(); i++) { + auto reg = destinations[i]; + registerFileSet_.set(reg, results[i]); } } diff --git a/src/lib/models/inorder/Core.cc b/src/lib/models/inorder/Core.cc index 9d36707b70..b196d2cf8c 100644 --- a/src/lib/models/inorder/Core.cc +++ b/src/lib/models/inorder/Core.cc @@ -39,10 +39,11 @@ Core::Core(memory::MemoryInterface& instructionMemory, } void Core::tick() { - ticks_++; - if (hasHalted_) return; + ticks_++; + isa_.updateSystemTimerRegisters(®isterFileSet_, ticks_); + if (exceptionHandler_ != nullptr) { processExceptionHandler(); return; @@ -104,7 +105,6 @@ void Core::tick() { } fetchUnit_.requestFromPC(); - isa_.updateSystemTimerRegisters(®isterFileSet_, ticks_); } bool Core::hasHalted() const { diff --git a/src/lib/models/outoforder/Core.cc b/src/lib/models/outoforder/Core.cc index 5c7793f133..4f7cf0f42d 100644 --- a/src/lib/models/outoforder/Core.cc +++ b/src/lib/models/outoforder/Core.cc @@ -101,10 +101,11 @@ Core::Core(memory::MemoryInterface& instructionMemory, } void Core::tick() { - ticks_++; - if (hasHalted_) return; + ticks_++; + isa_.updateSystemTimerRegisters(®isterFileSet_, ticks_); + if (exceptionHandler_ != nullptr) { processExceptionHandler(); return; @@ -156,7 +157,6 @@ void Core::tick() { flushIfNeeded(); fetchUnit_.requestFromPC(); - isa_.updateSystemTimerRegisters(®isterFileSet_, ticks_); } bool Core::hasHalted() const { From 43e4ca92a92c7b0fdb6769a352ba0a07bd278877 Mon Sep 17 00:00:00 2001 From: Finn Wilkinson Date: Thu, 4 Jul 2024 17:30:47 +0100 Subject: [PATCH 12/12] Final comments addressed. --- src/lib/models/emulation/Core.cc | 9 ++------- 1 file changed, 2 insertions(+), 7 deletions(-) diff --git a/src/lib/models/emulation/Core.cc b/src/lib/models/emulation/Core.cc index cd65c7cf30..bf0129b5ee 100644 --- a/src/lib/models/emulation/Core.cc +++ b/src/lib/models/emulation/Core.cc @@ -130,7 +130,6 @@ void Core::tick() { execute(uop); macroOp_.erase(macroOp_.begin()); } - // Commit instructionsExecuted_++; // Fetch memory for next cycle instructionMemory_.requestRead({pc_, FETCH_SIZE}); @@ -189,12 +188,8 @@ void Core::processExceptionHandler() { assert(exceptionHandler_ != nullptr && "Attempted to process an exception handler that wasn't present"); - while (true) { - bool success = exceptionHandler_->tick(); - if (success) { - // No more ticks needed to complete exception - break; - } + // Tick until true is returned, signifying completion + while (exceptionHandler_->tick() == false) { } const auto& result = exceptionHandler_->getResult();