Skip to content

Commit

Permalink
Minor Feature Fixes (#240)
Browse files Browse the repository at this point in the history
* Moved counter timer logic from main into Architecture, allowing the implementation to be architecture agnostic.

* Added test for CNTVCT register.

* Updated sveGetPattern auxiliary function to work for any instruction string.

* Ensured all necessary SVE instructions included pattern recognition.

* Changed specialFiles generation directory to be the build location.

* Fixed AArch64_LD1RQ_D_IMM's invalid increments of its index variable.

* Improved conditional branch not taken target and remove loop closing direction due to emergent bug.

* Resolved LSQ bugs for comparisons against the total req limit and forwarding operands from flushed loads.

* Updated comment in sveGetPattern Aux function.
  • Loading branch information
FinnWilkinson authored and jj16791 committed Oct 21, 2022
1 parent 38fbe91 commit 35467c0
Show file tree
Hide file tree
Showing 4 changed files with 158 additions and 11 deletions.
3 changes: 0 additions & 3 deletions src/include/simeng/arch/aarch64/Architecture.hh
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
2 changes: 0 additions & 2 deletions src/include/simeng/arch/aarch64/helpers/auxiliaryFunctions.hh
Original file line number Diff line number Diff line change
Expand Up @@ -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;
}
Expand Down
6 changes: 0 additions & 6 deletions src/lib/arch/aarch64/Architecture.cc
Original file line number Diff line number Diff line change
Expand Up @@ -289,12 +289,6 @@ void Architecture::updateSystemTimerRegisters(RegisterFileSet* regFile,
}
}

simeng::Register Architecture::getPCCreg() const {
return {
RegisterType::SYSTEM,
static_cast<uint16_t>(getSystemRegisterTag(ARM64_SYSREG_PMCCNTR_EL0))};
}

} // namespace aarch64
} // namespace arch
} // namespace simeng
158 changes: 158 additions & 0 deletions src/tools/simeng/main.cc
Original file line number Diff line number Diff line change
Expand Up @@ -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<simeng::Core> core = coreInstance->getCore();
std::shared_ptr<simeng::MemoryInterface> dataMemory =
Expand All @@ -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<simeng::kernel::LinuxProcess> process;

if (executablePath.length() > 0) {
// Attempt to create the process image from the specified command-line
std::vector<std::string> commandLine(argv + 2, argv + argc);
process =
std::make_unique<simeng::kernel::LinuxProcess>(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<int> 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::kernel::LinuxProcess>(
simeng::span<char>(reinterpret_cast<char*>(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<simeng::arch::Architecture> arch =
std::make_unique<simeng::arch::aarch64::Architecture>(kernel, config);

auto predictor = simeng::GenericPredictor(config);
auto config_ports = config["Ports"];
std::vector<std::vector<uint16_t>> 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<uint16_t>());
}
}
auto portAllocator = simeng::pipeline::BalancedPortAllocator(portArrangement);

// Configure reservation station arrangment
std::vector<std::pair<uint8_t, uint64_t>> 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<uint8_t>();
if (rsArrangement.size() < port + 1) {
rsArrangement.resize(port + 1);
}
rsArrangement[port] = {i, reservation_station["Size"].as<uint16_t>()};
}
}
>>>>>>> a0002ca3 (Minor Feature Fixes (#240))

// Run simulation
std::cout << "[SimEng] Starting...\n" << std::endl;
Expand Down

0 comments on commit 35467c0

Please sign in to comment.