diff --git a/src/include/simeng/arch/aarch64/Architecture.hh b/src/include/simeng/arch/aarch64/Architecture.hh index f58835dca1..d44abf250a 100644 --- a/src/include/simeng/arch/aarch64/Architecture.hh +++ b/src/include/simeng/arch/aarch64/Architecture.hh @@ -58,9 +58,6 @@ class Architecture : public arch::Architecture { void updateSystemTimerRegisters(RegisterFileSet* regFile, const uint64_t iterations) const override; - /** Returns the system register for the Processor Cycle Counter. */ - simeng::Register getPCCreg() const override; - /** Retrieve an ExecutionInfo object for the requested instruction. If a * opcode-based override has been defined for the latency and/or * port information, return that instead of the group-defined execution diff --git a/src/include/simeng/arch/aarch64/helpers/auxiliaryFunctions.hh b/src/include/simeng/arch/aarch64/helpers/auxiliaryFunctions.hh index ce772bcaf1..036df3f061 100644 --- a/src/include/simeng/arch/aarch64/helpers/auxiliaryFunctions.hh +++ b/src/include/simeng/arch/aarch64/helpers/auxiliaryFunctions.hh @@ -316,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/lib/arch/aarch64/Architecture.cc b/src/lib/arch/aarch64/Architecture.cc index a056786255..60fd17de68 100644 --- a/src/lib/arch/aarch64/Architecture.cc +++ b/src/lib/arch/aarch64/Architecture.cc @@ -289,12 +289,6 @@ void Architecture::updateSystemTimerRegisters(RegisterFileSet* regFile, } } -simeng::Register Architecture::getPCCreg() const { - return { - RegisterType::SYSTEM, - static_cast(getSystemRegisterTag(ARM64_SYSREG_PMCCNTR_EL0))}; -} - } // namespace aarch64 } // namespace arch } // namespace simeng diff --git a/src/tools/simeng/main.cc b/src/tools/simeng/main.cc index c920b4afdd..e8506b488d 100644 --- a/src/tools/simeng/main.cc +++ b/src/tools/simeng/main.cc @@ -76,6 +76,7 @@ int main(int argc, char** argv) { // outputting if (executablePath == "") executablePath = "Default"; +<<<<<<< HEAD // Get simulation objects needed to forward simulation std::shared_ptr core = coreInstance->getCore(); std::shared_ptr dataMemory = @@ -90,6 +91,163 @@ int main(int argc, char** argv) { for (const auto& arg : executableArgs) std::cout << " " << arg; std::cout << std::endl; std::cout << "[SimEng] Config file: " << configFilePath << std::endl; +======= + if (argc > 2) { + executablePath = std::string(argv[2]); + } + + // Create the process image + std::unique_ptr process; + + if (executablePath.length() > 0) { + // Attempt to create the process image from the specified command-line + std::vector commandLine(argv + 2, argv + argc); + process = + std::make_unique(commandLine, config); + if (!process->isValid()) { + std::cerr << "Could not read/parse " << argv[2] << std::endl; + exit(1); + } + } else { + // Create the process image directly + + // char* memory = new char[1024](); + + // Simple program demonstrating various instructions + // uint32_t hex[] = { + // 0x320003E0, // orr w0, wzr, #1 + // 0x321F0001, // orr w1, w0, #2 + // 0xB90003E1, // str w1, [sp] + // 0xB94003E0, // ldr w0, [sp] + // 0xF94003E0, // ldr x0, [sp] + // 0x14000002, // b #8 + // 0x320003E0, // orr w0, wzr, #1 + // 0x32000002, // orr w2, w0, #1 + // 0x71000420, // subs w0, w1, #1 + // }; + + // Simple loop; counts down from 1024*1024 + // uint32_t hex[] = { + // // 0x321E03E0, // orr w0, wzr, #4 + // 0x320C03E0, // orr w0, wzr, #1048576 + // // 0x321603E0, // orr w0, wzr, #1024 + // 0x71000400, // subs w0, w0, #1 + // // 0x320003E0, // orr w0, wzr, #1 + // // 0x71000400, // subs w0, w0, #1 + // 0x54FFFFE1, // b.ne -4 + // }; + + // Out-of-order test; counts down from 1024*1024, with an independent `orr` + // at the start of each branch. With an instruction latency of 2 or greater, + // the `orr` at the start of the next loop should issue/execute while the + // preceding branch is waiting on the result from the `subs`. + uint32_t hex[] = { + // 0x321E03E0, // orr w0, wzr, #4 + // 0x321603E0, // orr w0, wzr, #1024 + 0x320C03E0, // orr w0, wzr, #1048576 + 0x320003E1, // orr w0, wzr, #1 + 0x71000400, // subs w0, w0, #1 + // 0x00000000, // invalid + 0x54FFFFC1, // b.ne -8 + // .exit: + 0xD2800000, // mov x0, #0 + 0xD2800BC8, // mov x8, #94 + 0xD4000001, // svc #0 + }; + + // Load/store consistency test; a simple bubble sort algorithm + // uint32_t hex[] = { + // 0x320003E0, // orr w0, wzr, #1 + // 0x51000400, // sub w0, w0, #1 + + // 0x11013001, // add w1, w0, #76 + // // .start: + // 0x11000002, // add w2, w0, #0 + // // .compare: + // 0xB9400044, // ldr w4, [x2, 0] + // 0xB9400445, // ldr w5, [x2, 4] + // 0x4B0400A6, // sub w6, w5, w4 + // 0x37F80046, // tbnz w6, #31, #8 (.swap) + // 0x14000003, // b #12 (.next) + // // .swap: + // 0xB9000444, // str w4, [x2, 4] + // 0xB9000045, // str w5, [x2, 0] + // // .next: + // 0x11001042, // add w2, w2, #4 + // 0x4B010046, // sub w6, w2, w1 + // 0x37FFFEE6, // tbnz w6, #31, #-36 (.compare) + // 0x51001021, // sub w1, w1, #4 + // 0x4B010006, // sub w6, w0, w1 + // 0x37FFFE66, // tbnz w6, #31, #-52 (.start) + // }; + + // Force a load/store ordering violation + // uint32_t hex[] = { + // 0x320003E0, // orr w0, wzr, #1 + // 0x51000400, // sub w0, w0, #1 + + // 0x11000002, // add w2, w0, #0 + // 0x11013001, // add w1, w0, #76 + + // 0xB9000041, // str w1, [x2] + // 0xB9400043, // ldr w3, [x2] + // 0xB9000443, // str w3, [x2, 4] + // }; + + // Some arbitrary values to sort + // std::vector memoryValues = {9, 6, 7, 20, 5, 0, 80, 2, 1, 6, + // 17, 4, 3, 22, 117, 11, 4, 12, 10, 18}; + // memcpy(memory, memoryValues.data(), memoryValues.size() * sizeof(int)); + + process = std::make_unique( + simeng::span(reinterpret_cast(hex), sizeof(hex)), config); + } + + // Read the process image and copy to memory + auto processImage = process->getProcessImage(); + size_t processMemorySize = processImage.size(); + char* processMemory = new char[processMemorySize](); + std::copy(processImage.begin(), processImage.end(), processMemory); + + uint64_t entryPoint = process->getEntryPoint(); + + // Create the OS kernel with the process + simeng::kernel::Linux kernel; + kernel.createProcess(*process.get()); + + simeng::FlatMemoryInterface instructionMemory(processMemory, + processMemorySize); + + // Create the architecture, with knowledge of the kernel + std::unique_ptr arch = + std::make_unique(kernel, config); + + auto predictor = simeng::GenericPredictor(config); + auto config_ports = config["Ports"]; + std::vector> portArrangement(config_ports.size()); + // Extract number of ports + for (size_t i = 0; i < config_ports.size(); i++) { + auto config_groups = config_ports[i]["Instruction-Group-Support"]; + // Extract number of groups in port + for (size_t j = 0; j < config_groups.size(); j++) { + portArrangement[i].push_back(config_groups[j].as()); + } + } + auto portAllocator = simeng::pipeline::BalancedPortAllocator(portArrangement); + + // Configure reservation station arrangment + std::vector> rsArrangement; + for (size_t i = 0; i < config["Reservation-Stations"].size(); i++) { + auto reservation_station = config["Reservation-Stations"][i]; + for (size_t j = 0; j < reservation_station["Ports"].size(); j++) { + uint8_t port = reservation_station["Ports"][j].as(); + if (rsArrangement.size() < port + 1) { + rsArrangement.resize(port + 1); + } + rsArrangement[port] = {i, reservation_station["Size"].as()}; + } + } +>>>>>>> a0002ca3 (Minor Feature Fixes (#240)) // Run simulation std::cout << "[SimEng] Starting...\n" << std::endl;