diff --git a/src/include/simeng/Core.hh b/src/include/simeng/Core.hh index 75b2d2033c..68c2b3656a 100644 --- a/src/include/simeng/Core.hh +++ b/src/include/simeng/Core.hh @@ -33,13 +33,6 @@ class Core { /** Retrieve a map of statistics to report. */ virtual std::map getStats() const = 0; - - /** Increment value of the Virtual Counter Timer system register. */ - virtual void incVCT(uint64_t iterations) = 0; - - /** Change the value of the Processor Cycle Counter system register to number - * of cycles completed. */ - virtual void updatePCC(uint64_t iterations) = 0; }; } // namespace simeng diff --git a/src/include/simeng/ModelConfig.hh b/src/include/simeng/ModelConfig.hh index 37dd89c4fc..6f6fb8b6f1 100644 --- a/src/include/simeng/ModelConfig.hh +++ b/src/include/simeng/ModelConfig.hh @@ -79,7 +79,7 @@ class ModelConfig { /** Given a node, value requirements, and possibly a deafult value, * validate the value held within the node. All methods perform, at - * least, an existance and "read as type" check with the latter + * least, an existence and "read as type" check with the latter * reading the value as the given type within a try catch * expressions. */ // Set of values requirement, no default value diff --git a/src/include/simeng/SpecialFileDirGen.hh b/src/include/simeng/SpecialFileDirGen.hh index f6ba628ba2..faf5d2fac5 100644 --- a/src/include/simeng/SpecialFileDirGen.hh +++ b/src/include/simeng/SpecialFileDirGen.hh @@ -22,8 +22,7 @@ class SpecialFileDirGen { private: /** Path to the root of the SimEng special files directory. */ - const std::string specialFilesDir_ = - SIMENG_SOURCE_DIR "/src/lib/kernel/specialFiles"; + const std::string specialFilesDir_ = SIMENG_BUILD_DIR "/specialFiles"; /** Values declared in YAML config file needed to create the Special Files * Directory tree. */ diff --git a/src/include/simeng/arch/Architecture.hh b/src/include/simeng/arch/Architecture.hh index d3f635ed23..b9ebc78a92 100644 --- a/src/include/simeng/arch/Architecture.hh +++ b/src/include/simeng/arch/Architecture.hh @@ -94,11 +94,9 @@ class Architecture { /** Returns the maximum size of a valid instruction in bytes. */ virtual uint8_t getMaxInstructionSize() const = 0; - /** Returns the system register for the Virtual Counter Timer. */ - virtual simeng::Register getVCTreg() const = 0; - - /** Returns the system register for the Processor Cycle Counter. */ - virtual simeng::Register getPCCreg() const = 0; + /** Updates System registers of any system-based timers. */ + virtual void updateSystemTimerRegisters(RegisterFileSet* regFile, + const uint64_t iterations) const = 0; }; } // namespace arch diff --git a/src/include/simeng/arch/aarch64/Architecture.hh b/src/include/simeng/arch/aarch64/Architecture.hh index 5cf93451fb..d62786c8aa 100644 --- a/src/include/simeng/arch/aarch64/Architecture.hh +++ b/src/include/simeng/arch/aarch64/Architecture.hh @@ -54,11 +54,9 @@ class Architecture : public arch::Architecture { /** Returns the current vector length set by the provided configuration. */ uint64_t getVectorLength() const; - /** Returns the system register for the Virtual Counter Timer. */ - simeng::Register getVCTreg() const override; - - /** Returns the system register for the Processor Cycle Counter. */ - simeng::Register getPCCreg() const override; + /** Updates System registers of any system-based timers. */ + void updateSystemTimerRegisters(RegisterFileSet* regFile, + const uint64_t iterations) const override; /** Retrieve an ExecutionInfo object for the requested instruction. If a * opcode-based override has been defined for the latency and/or @@ -98,6 +96,16 @@ class Architecture : public arch::Architecture { /** The vector length used by the SVE extension in bits. */ uint64_t VL_; + + /** System Register of Virtual Counter Timer. */ + simeng::Register VCTreg_; + + /** System Register of Processor Cycle Counter. */ + simeng::Register PCCreg_; + + /** Modulo component used to define the frequency at which the VCT is updated. + */ + double vctModulo_; }; } // namespace aarch64 diff --git a/src/include/simeng/arch/aarch64/helpers/auxiliaryFunctions.hh b/src/include/simeng/arch/aarch64/helpers/auxiliaryFunctions.hh index be29e2577a..2362564199 100644 --- a/src/include/simeng/arch/aarch64/helpers/auxiliaryFunctions.hh +++ b/src/include/simeng/arch/aarch64/helpers/auxiliaryFunctions.hh @@ -265,16 +265,22 @@ class AuxFunc { static uint16_t sveGetPattern(const std::string operandStr, const uint8_t esize, const uint16_t VL_) { const uint16_t elements = VL_ / esize; - // If not pattern then same as ALL - if (operandStr.find(",") == std::string::npos) return elements; - - // Get pattern string - std::string pattern(operandStr.substr(operandStr.find(",") + 2)); - if (pattern.find(',') != std::string::npos) { - pattern.erase(pattern.find(",")); + const std::vector patterns = { + "pow2", "vl1", "vl2", "vl3", "vl4", "vl5", "vl6", "vl7", "vl8", + "vl16", "vl32", "vl64", "vl128", "vl256", "mul3", "mul4", "all"}; + + // If no pattern present in operandStr then same behaviour as ALL + std::string pattern = "all"; + for (uint8_t i = 0; i < patterns.size(); i++) { + if (operandStr.find(patterns[i]) != std::string::npos) { + pattern = patterns[i]; + // Don't break when pattern found as vl1 will be found in vl128 etc + } } - if (pattern == "pow2") { + if (pattern == "all") + return elements; + else if (pattern == "pow2") { int n = 1; while (elements >= std::pow(2, n)) { n = n + 1; @@ -310,8 +316,6 @@ class AuxFunc { return elements - (elements % 4); else if (pattern == "mul3") return elements - (elements % 3); - else if (pattern == "all") - return elements; return 0; } diff --git a/src/include/simeng/arch/aarch64/helpers/sve.hh b/src/include/simeng/arch/aarch64/helpers/sve.hh index 5ed762f431..6dd6469dff 100644 --- a/src/include/simeng/arch/aarch64/helpers/sve.hh +++ b/src/include/simeng/arch/aarch64/helpers/sve.hh @@ -1180,6 +1180,8 @@ class sveHelp { // Get pattern const uint16_t count = AuxFunc::sveGetPattern(metadata.operandStr, sizeof(T) * 8, VL_bits); + // Exit early if count == 0 + if (count == 0) return out; for (int i = 0; i < partition_num; i++) { if (i < count) { @@ -1479,15 +1481,17 @@ class sveHelp { const uint16_t VL_bits) { const D d = operands[0].get(); const uint8_t imm = metadata.operands[1].imm; + const uint16_t count = + AuxFunc::sveGetPattern(metadata.operandStr, N, VL_bits); // The range of possible values does not fit in the range of any integral // type, so a double is used as an intermediate value. The end result must // be saturated to fit in uint64_t. - auto intermediate = double(d) - (imm * (VL_bits / N)); + auto intermediate = double(d) - (imm * count); if (intermediate < 0) { return (uint64_t)0; } - return (uint64_t)(d - (imm * (VL_bits / N))); + return (uint64_t)(d - (imm * count)); } /** Helper function for SVE instructions with the format `uzp<1,2> zd, zn, diff --git a/src/include/simeng/models/emulation/Core.hh b/src/include/simeng/models/emulation/Core.hh index c89c169f8d..9152c6df03 100644 --- a/src/include/simeng/models/emulation/Core.hh +++ b/src/include/simeng/models/emulation/Core.hh @@ -44,13 +44,6 @@ class Core : public simeng::Core { /** Retrieve a map of statistics to report. */ std::map getStats() const override; - /** Increment value of the Virtual Counter Timer system register. */ - void incVCT(uint64_t iterations) override; - - /** Change the value of the Processor Cycle Counter system register to number - * of cycles completed. */ - void updatePCC(uint64_t iterations) override; - private: /** Execute an instruction. */ void execute(std::shared_ptr& uop); @@ -112,12 +105,6 @@ class Core : public simeng::Core { /** The number of branches executed. */ uint64_t branchesExecuted_ = 0; - - /** System Register of Virtual Counter Timer. */ - simeng::Register VCTreg_; - - /** System Register of Processor Cycle Counter. */ - simeng::Register PCCreg_; }; } // namespace emulation diff --git a/src/include/simeng/models/inorder/Core.hh b/src/include/simeng/models/inorder/Core.hh index df49d6ed8b..96e4087bb4 100644 --- a/src/include/simeng/models/inorder/Core.hh +++ b/src/include/simeng/models/inorder/Core.hh @@ -45,13 +45,6 @@ class Core : public simeng::Core { /** Generate a map of statistics to report. */ std::map getStats() const override; - /** Increment value of the Virtual Counter Timer system register. */ - void incVCT(uint64_t iterations) override; - - /** Change the value of the Processor Cycle Counter system register to number - * of cycles completed. */ - void updatePCC(uint64_t iterations) override; - private: /** Raise an exception to the core, providing the generating instruction. */ void raiseException(const std::shared_ptr& instruction); @@ -139,12 +132,6 @@ class Core : public simeng::Core { /** The active exception handler. */ std::shared_ptr exceptionHandler_; - - /** System Register of Virtual Counter Timer. */ - simeng::Register VCTreg_; - - /** System Register of Processor Cycle Counter. */ - simeng::Register PCCreg_; }; } // namespace inorder diff --git a/src/include/simeng/models/outoforder/Core.hh b/src/include/simeng/models/outoforder/Core.hh index 0cbe3f8b45..56fcda230e 100644 --- a/src/include/simeng/models/outoforder/Core.hh +++ b/src/include/simeng/models/outoforder/Core.hh @@ -54,13 +54,6 @@ class Core : public simeng::Core { /** Generate a map of statistics to report. */ std::map getStats() const override; - /** Increment value of the Virtual Counter Timer system register. */ - void incVCT(uint64_t iterations) override; - - /** Change the value of the Processor Cycle Counter system register to number - * of cycles completed. */ - void updatePCC(uint64_t iterations) override; - private: /** Raise an exception to the core, providing the generating instruction. */ void raiseException(const std::shared_ptr& instruction); @@ -169,12 +162,6 @@ class Core : public simeng::Core { /** The active exception handler. */ std::shared_ptr exceptionHandler_; - - /** System Register of Virtual Counter Timer. */ - simeng::Register VCTreg_; - - /** System Register of Processor Cycle Counter. */ - simeng::Register PCCreg_; }; } // namespace outoforder diff --git a/src/include/simeng/version.hh.in b/src/include/simeng/version.hh.in index 1ce0b0de89..5f1e8f410b 100644 --- a/src/include/simeng/version.hh.in +++ b/src/include/simeng/version.hh.in @@ -8,5 +8,6 @@ #define SIMENG_SOURCE_DIR "${PROJECT_SOURCE_DIR}" #define SIMENG_LLVM_VERSION @SIMENG_LLVM_VERSION@ #define SIMENG_ENABLE_TESTS "${SIMENG_ENABLE_TESTS}" +#define SIMENG_BUILD_DIR "${CMAKE_BINARY_DIR}" #endif \ No newline at end of file diff --git a/src/lib/GenericPredictor.cc b/src/lib/GenericPredictor.cc index 965231f3d1..4030a85133 100644 --- a/src/lib/GenericPredictor.cc +++ b/src/lib/GenericPredictor.cc @@ -40,7 +40,7 @@ BranchPrediction GenericPredictor::predict(uint64_t address, BranchType type, BranchPrediction prediction = {direction, target}; // Ammend prediction based on branch type - if (type == BranchType::Unconditional || type == BranchType::LoopClosing) { + if (type == BranchType::Unconditional) { prediction.taken = true; } else if (type == BranchType::Return) { prediction.taken = true; @@ -60,6 +60,8 @@ BranchPrediction GenericPredictor::predict(uint64_t address, BranchType type, ras_.push_back(address + 4); // Record that this address is a branch-and-link instruction rasHistory_[address] = 0; + } else if (type == BranchType::Conditional) { + if (!prediction.taken) prediction.target = address + 4; } return prediction; } diff --git a/src/lib/ModelConfig.cc b/src/lib/ModelConfig.cc index 6d4b68ad56..35ec09ee03 100644 --- a/src/lib/ModelConfig.cc +++ b/src/lib/ModelConfig.cc @@ -180,7 +180,7 @@ void ModelConfig::validate() { char port_msg[10]; sprintf(port_msg, "Port %zu ", i); std::string port_num = std::string(port_msg); - // Check for existance of Portname field and record name + // Check for existence of Portname field and record name if (nodeChecker(port_node["Portname"], port_num + "Portname", std::vector{}, ExpectedValue::String)) { @@ -195,7 +195,7 @@ void ModelConfig::validate() { << "\" already used\n"; } } - // Check for existance of Instruction-Support field + // Check for existence of Instruction-Support field if (!(port_node["Instruction-Support"].IsDefined()) || port_node["Instruction-Support"].IsNull()) { missing_ << "\t- " << port_num << "Instruction-Support\n"; @@ -248,7 +248,7 @@ void ModelConfig::validate() { nodeChecker(rs["Size"], rs_num + "Size", std::make_pair(1, UINT16_MAX), ExpectedValue::UInteger); - // Check for existance of Ports field + // Check for existence of Ports field if (!(rs["Ports"].IsDefined()) || rs["Ports"].IsNull()) { missing_ << "\t- " << rs_num << "Ports\n"; continue; @@ -597,7 +597,7 @@ template int ModelConfig::nodeChecker(const YAML::Node& node, const std::string& field, const std::vector& value_set, uint8_t expected) { - // Check for the existance of the given node + // Check for the existence of the given node if (!(node.IsDefined()) || node.IsNull()) { missing_ << "\t- " << field << "\n"; return 0; @@ -610,7 +610,7 @@ template int ModelConfig::nodeChecker(YAML::Node node, const std::string& field, const std::vector& value_set, uint8_t expected, T default_value) { - // Check for the existance of the given node + // Check for the existence of the given node if (!(node.IsDefined()) || node.IsNull()) { node = default_value; return 1; @@ -622,7 +622,7 @@ int ModelConfig::nodeChecker(YAML::Node node, const std::string& field, template int ModelConfig::nodeChecker(const YAML::Node& node, const std::string& field, const std::pair& bounds, uint8_t expected) { - // Check for the existance of the given node + // Check for the existence of the given node if (!(node.IsDefined()) || node.IsNull()) { missing_ << "\t- " << field << "\n"; return 0; @@ -635,7 +635,7 @@ template int ModelConfig::nodeChecker(YAML::Node node, const std::string& field, const std::pair& bounds, uint8_t expected, const T& default_value) { - // Check for the existance of the given node + // Check for the existence of the given node if (!(node.IsDefined()) || node.IsNull()) { node = default_value; return 1; diff --git a/src/lib/arch/aarch64/Architecture.cc b/src/lib/arch/aarch64/Architecture.cc index 6733d3910c..f901615022 100644 --- a/src/lib/arch/aarch64/Architecture.cc +++ b/src/lib/arch/aarch64/Architecture.cc @@ -13,7 +13,9 @@ std::forward_list Architecture::metadataCache; Architecture::Architecture(kernel::Linux& kernel, YAML::Node config) : linux_(kernel), microDecoder_(std::make_unique(config)), - VL_(config["Core"]["Vector-Length"].as()) { + VL_(config["Core"]["Vector-Length"].as()), + vctModulo_((config["Core"]["Clock-Frequency"].as() * 1e9) / + (config["Core"]["Timer-Frequency"].as() * 1e6)) { if (cs_open(CS_ARCH_ARM64, CS_MODE_ARM, &capstoneHandle) != CS_ERR_OK) { std::cerr << "Could not create capstone handle" << std::endl; exit(1); @@ -30,6 +32,14 @@ Architecture::Architecture(kernel::Linux& kernel, YAML::Node config) systemRegisterMap_[ARM64_SYSREG_CNTVCT_EL0] = systemRegisterMap_.size(); systemRegisterMap_[ARM64_SYSREG_PMCCNTR_EL0] = systemRegisterMap_.size(); + // Get Virtual Counter Timer and Processor Cycle Counter system registers. + VCTreg_ = { + RegisterType::SYSTEM, + static_cast(getSystemRegisterTag(ARM64_SYSREG_CNTVCT_EL0))}; + PCCreg_ = { + RegisterType::SYSTEM, + static_cast(getSystemRegisterTag(ARM64_SYSREG_PMCCNTR_EL0))}; + // Instantiate an ExecutionInfo entry for each group in the InstructionGroup // namespace. for (int i = 0; i < NUM_GROUPS; i++) { @@ -267,15 +277,15 @@ uint8_t Architecture::getMaxInstructionSize() const { return 4; } uint64_t Architecture::getVectorLength() const { return VL_; } -simeng::Register Architecture::getVCTreg() const { - return {RegisterType::SYSTEM, - static_cast(getSystemRegisterTag(ARM64_SYSREG_CNTVCT_EL0))}; -} +void Architecture::updateSystemTimerRegisters(RegisterFileSet* regFile, + const uint64_t iterations) const { + // Update the Processor Cycle Counter to total cycles completed. + regFile->set(PCCreg_, iterations); -simeng::Register Architecture::getPCCreg() const { - return { - RegisterType::SYSTEM, - static_cast(getSystemRegisterTag(ARM64_SYSREG_PMCCNTR_EL0))}; + // Update Virtual Counter Timer at correct frequency. + if (iterations % (uint64_t)vctModulo_ == 0) { + regFile->set(VCTreg_, regFile->get(VCTreg_).get() + 1); + } } } // namespace aarch64 diff --git a/src/lib/arch/aarch64/Instruction_execute.cc b/src/lib/arch/aarch64/Instruction_execute.cc index 0653e7f361..78c91fd6b3 100644 --- a/src/lib/arch/aarch64/Instruction_execute.cc +++ b/src/lib/arch/aarch64/Instruction_execute.cc @@ -7769,9 +7769,10 @@ void Instruction::execute() { uint64_t mini[2] = {0}; for (int i = 0; i < 2; i++) { uint64_t shifted_active = 1ull << ((i % 8) * 8); - if (p[i / 8] & shifted_active) + if (p[i / 8] & shifted_active) { mini[i] = memoryData[index].get(); - index++; + index++; + } } // Duplicate mini-vector into output vector diff --git a/src/lib/models/emulation/Core.cc b/src/lib/models/emulation/Core.cc index 302b7f62c3..e9a5f575fb 100644 --- a/src/lib/models/emulation/Core.cc +++ b/src/lib/models/emulation/Core.cc @@ -27,10 +27,6 @@ Core::Core(MemoryInterface& instructionMemory, MemoryInterface& dataMemory, // Query and apply initial state auto state = isa.getInitialState(); applyStateChange(state); - - // Get Virtual Counter Timer and Processor Cycle Counter system registers. - VCTreg_ = isa_.getVCTreg(); - PCCreg_ = isa_.getPCCreg(); } void Core::tick() { @@ -163,6 +159,7 @@ void Core::tick() { } execute(uop); + isa_.updateSystemTimerRegisters(®isterFileSet_, ticks_); } void Core::execute(std::shared_ptr& uop) { @@ -286,16 +283,6 @@ void Core::applyStateChange(const arch::ProcessStateChange& change) { } } -void Core::incVCT(uint64_t iterations) { - registerFileSet_.set(VCTreg_, iterations); - return; -} - -void Core::updatePCC(uint64_t iterations) { - registerFileSet_.set(PCCreg_, iterations); - return; -} - bool Core::hasHalted() const { return hasHalted_; } const ArchitecturalRegisterFileSet& Core::getArchitecturalRegisterFileSet() diff --git a/src/lib/models/inorder/Core.cc b/src/lib/models/inorder/Core.cc index 73091577ed..2885d53654 100644 --- a/src/lib/models/inorder/Core.cc +++ b/src/lib/models/inorder/Core.cc @@ -39,10 +39,6 @@ Core::Core(FlatMemoryInterface& instructionMemory, // Query and apply initial state auto state = isa.getInitialState(); applyStateChange(state); - - // Get Virtual Counter Timer and Processor Cycle Counter system registers. - VCTreg_ = isa_.getVCTreg(); - PCCreg_ = isa_.getPCCreg(); }; void Core::tick() { @@ -112,6 +108,7 @@ void Core::tick() { } fetchUnit_.requestFromPC(); + isa_.updateSystemTimerRegisters(®isterFileSet_, ticks_); } bool Core::hasHalted() const { @@ -344,16 +341,6 @@ void Core::applyStateChange(const arch::ProcessStateChange& change) { } } -void Core::incVCT(uint64_t iterations) { - registerFileSet_.set(VCTreg_, iterations); - return; -} - -void Core::updatePCC(uint64_t iterations) { - registerFileSet_.set(PCCreg_, iterations); - return; -} - void Core::handleLoad(const std::shared_ptr& instruction) { loadData(instruction); if (instruction->exceptionEncountered()) { diff --git a/src/lib/models/outoforder/Core.cc b/src/lib/models/outoforder/Core.cc index 2b673244fe..bd4a947bb7 100644 --- a/src/lib/models/outoforder/Core.cc +++ b/src/lib/models/outoforder/Core.cc @@ -117,10 +117,6 @@ Core::Core(MemoryInterface& instructionMemory, MemoryInterface& dataMemory, // Query and apply initial state auto state = isa.getInitialState(); applyStateChange(state); - - // Get Virtual Counter Timer and Processor Cycle Counter system registers. - VCTreg_ = isa_.getVCTreg(); - PCCreg_ = isa_.getPCCreg(); }; void Core::tick() { @@ -179,6 +175,7 @@ void Core::tick() { flushIfNeeded(); fetchUnit_.requestFromPC(); + isa_.updateSystemTimerRegisters(®isterFileSet_, ticks_); } void Core::flushIfNeeded() { @@ -379,16 +376,6 @@ void Core::applyStateChange(const arch::ProcessStateChange& change) { } } -void Core::incVCT(uint64_t iterations) { - registerFileSet_.set(VCTreg_, iterations); - return; -} - -void Core::updatePCC(uint64_t iterations) { - registerFileSet_.set(PCCreg_, iterations); - return; -} - const ArchitecturalRegisterFileSet& Core::getArchitecturalRegisterFileSet() const { return mappedRegisterFileSet_; diff --git a/src/lib/pipeline/LoadStoreQueue.cc b/src/lib/pipeline/LoadStoreQueue.cc index a6dc2b34cb..044990c9a4 100644 --- a/src/lib/pipeline/LoadStoreQueue.cc +++ b/src/lib/pipeline/LoadStoreQueue.cc @@ -425,7 +425,7 @@ void LoadStoreQueue::tick() { // Iterate over requests ready this cycle while (itInsn != itReq->second.end()) { - // Increment count of this request type + // Speculatively increment count of this request type reqCounts[isStore]++; // Ensure the limit on the number of permitted operations is adhered @@ -437,6 +437,9 @@ void LoadStoreQueue::tick() { } else if (reqCounts[isStore] > reqLimits_[isStore]) { // No more requests of this type can be scheduled this cycle exceededLimits[isStore] = true; + // Remove speculative increment to ensure it doesn't count for + // comparisons aginast the totalLimit_ + reqCounts[isStore]--; break; } else { // Schedule requests from the queue of addresses in @@ -520,6 +523,12 @@ void LoadStoreQueue::tick() { while (completedLoads_.size() > 0 && count < completionSlots_.size()) { const auto& insn = completedLoads_.front(); + // Don't process load instruction if it has been flushed + if (insn->isFlushed()) { + completedLoads_.pop(); + continue; + } + // Forward the results forwardOperands_(insn->getDestinationRegisters(), insn->getResults()); diff --git a/src/tools/simeng/main.cc b/src/tools/simeng/main.cc index f3174f8a53..984834dae3 100644 --- a/src/tools/simeng/main.cc +++ b/src/tools/simeng/main.cc @@ -28,27 +28,15 @@ enum class SimulationMode { Emulation, InOrderPipelined, OutOfOrder }; -float clockFreq_; -uint32_t timerFreq_; - /** Tick the provided core model until it halts. */ int simulate(simeng::Core& core, simeng::MemoryInterface& instructionMemory, simeng::MemoryInterface& dataMemory) { uint64_t iterations = 0; - uint64_t vitrualCounter = 0; - double timerModulo = (clockFreq_ * 1e9) / (timerFreq_ * 1e6); // Tick the core and memory interfaces until the program has halted while (!core.hasHalted() || dataMemory.hasPendingRequests()) { // Tick the core core.tick(); - // Update the Processor Cycle Counter to total cycles completed. - core.updatePCC(iterations); - // Update Virtual Counter Timer at correct frequency. - if (iterations % (uint64_t)timerModulo == 0) { - vitrualCounter++; - core.incVCT(vitrualCounter); - } // Tick memory instructionMemory.tick(); @@ -87,9 +75,6 @@ int main(int argc, char** argv) { mode = SimulationMode::OutOfOrder; } - clockFreq_ = config["Core"]["Clock-Frequency"].as(); - timerFreq_ = config["Core"]["Timer-Frequency"].as(); - if (argc > 2) { executablePath = std::string(argv[2]); } diff --git a/test/regression/aarch64/AArch64RegressionTest.hh b/test/regression/aarch64/AArch64RegressionTest.hh index b7482b24ac..39aab4caeb 100644 --- a/test/regression/aarch64/AArch64RegressionTest.hh +++ b/test/regression/aarch64/AArch64RegressionTest.hh @@ -6,10 +6,10 @@ #define AARCH64_CONFIG \ ("{Core: {Simulation-Mode: emulation, Clock-Frequency: 2.5, " \ - "Micro-Operations: False}, Fetch: {Fetch-Block-Size: 32, " \ - "Loop-Buffer-Size: 64, Loop-Detection-Threshold: 4}, Process-Image: " \ - "{Heap-Size: 100000, Stack-Size: 100000}, Register-Set: " \ - "{GeneralPurpose-Count: 154, FloatingPoint/SVE-Count: 90, " \ + "Timer-Frequency: 100, Micro-Operations: False}, Fetch: " \ + "{Fetch-Block-Size: 32, Loop-Buffer-Size: 64, Loop-Detection-Threshold: " \ + "4}, Process-Image: {Heap-Size: 100000, Stack-Size: 100000}, " \ + "Register-Set: {GeneralPurpose-Count: 154, FloatingPoint/SVE-Count: 90, " \ "Predicate-Count: 17, Conditional-Count: 128}, Pipeline-Widths: { Commit: " \ "4, Dispatch-Rate: 4, FrontEnd: 4, LSQ-Completion: 2}, Queue-Sizes: {ROB: " \ "180, Load: 64, Store: 36}, Branch-Predictor: {BTB-Tag-Bits: 11, " \ diff --git a/test/regression/aarch64/SystemRegisters.cc b/test/regression/aarch64/SystemRegisters.cc index 98ded12ded..869526f600 100644 --- a/test/regression/aarch64/SystemRegisters.cc +++ b/test/regression/aarch64/SystemRegisters.cc @@ -71,6 +71,20 @@ TEST_P(SystemRegister, sysreg_access) { EXPECT_EQ(getSystemRegister(0xde82), 42); } +TEST_P(SystemRegister, counter_timers) { + // Ensure that the VCT is incremented at correct rate : once per ((2.5 * 1e9) + // / (100 * 1e6)) cycles (i.e. once per 25 cycles). + RUN_AARCH64(R"( + mov x2, xzr + mov x1, #16 + # Loop of 3 instructions * 16 iterations = 48, + 2 mov instructions = 50 total instructions & ~50 cycles + sub x1, x1, #1 + cmp x1, x2 + b.ne #-8 + )"); + EXPECT_EQ(getSystemRegister(0xdf02), 2); +} + INSTANTIATE_TEST_SUITE_P( AArch64, SystemRegister, ::testing::Values(std::make_tuple(EMULATION, YAML::Load("{}")), diff --git a/test/unit/GenericPredictorTest.cc b/test/unit/GenericPredictorTest.cc index 828bc6de88..522bad3067 100644 --- a/test/unit/GenericPredictorTest.cc +++ b/test/unit/GenericPredictorTest.cc @@ -109,7 +109,7 @@ TEST_F(GenericPredictorTest, GlobalIndexing) { // Ensure default behaviour for first encounter auto prediction = predictor.predict(0x1F, BranchType::Conditional, 0); EXPECT_FALSE(prediction.taken); - EXPECT_EQ(prediction.target, 0); + EXPECT_EQ(prediction.target, 0x23); // Set entry in BTB predictor.update(0x1F, true, 0xAB, BranchType::Conditional); @@ -122,7 +122,7 @@ TEST_F(GenericPredictorTest, GlobalIndexing) { // Ensure default behaviour for re-encounter but with different global history prediction = predictor.predict(0x1F, BranchType::Conditional, 0); EXPECT_FALSE(prediction.taken); - EXPECT_EQ(prediction.target, 0); + EXPECT_EQ(prediction.target, 0x23); // Set entry in BTB predictor.update(0x1F, true, 0xBA, BranchType::Conditional); diff --git a/test/unit/ISATest.cc b/test/unit/ISATest.cc index 65e032373a..70f77edcdc 100644 --- a/test/unit/ISATest.cc +++ b/test/unit/ISATest.cc @@ -9,7 +9,8 @@ namespace { TEST(ISATest, CreateAArch64) { simeng::kernel::Linux kernel; YAML::Node config = YAML::Load( - "{Core: {Simulation-Mode: emulation, Micro-Operations: True, " + "{Core: {Simulation-Mode: emulation, Clock-Frequency: 2.5, " + "Timer-Frequency: 100, Micro-Operations: True, " "Vector-Length: 512}}"); // Pass a config file with only the options required by the aarch64 // architecture class to function diff --git a/test/unit/MockArchitecture.hh b/test/unit/MockArchitecture.hh index 609e012aef..802b9a6585 100644 --- a/test/unit/MockArchitecture.hh +++ b/test/unit/MockArchitecture.hh @@ -22,8 +22,8 @@ class MockArchitecture : public arch::Architecture { const Core& core, MemoryInterface& memory)); MOCK_CONST_METHOD0(getInitialState, arch::ProcessStateChange()); MOCK_CONST_METHOD0(getMaxInstructionSize, uint8_t()); - MOCK_CONST_METHOD0(getVCTreg, simeng::Register()); - MOCK_CONST_METHOD0(getPCCreg, simeng::Register()); + MOCK_CONST_METHOD2(updateSystemTimerRegisters, + void(RegisterFileSet* regFile, const uint64_t iterations)); }; } // namespace simeng