From 51673665b555b80821141911be994392eb134de3 Mon Sep 17 00:00:00 2001 From: Blaise Tine Date: Thu, 7 Oct 2021 13:59:26 -0400 Subject: [PATCH] simX updates --- hw/simulate/main.cpp | 19 ++++++++- simX/execute.cpp | 51 ++++++++++++++++------- simX/main.cpp | 15 +++++-- simX/mem.cpp | 99 ++++++++++++++++++++++++-------------------- simX/mem.h | 4 +- simX/util.cpp | 8 ++++ simX/util.h | 3 ++ simX/warp.cpp | 2 +- simX/warp.h | 1 + 9 files changed, 136 insertions(+), 66 deletions(-) diff --git a/hw/simulate/main.cpp b/hw/simulate/main.cpp index bf332a19..e8c089de 100644 --- a/hw/simulate/main.cpp +++ b/hw/simulate/main.cpp @@ -33,6 +33,13 @@ static void parse_args(int argc, char **argv) { } } +inline const char* fileExtension(const char* filepath) { + const char *ext = strrchr(filepath, '.'); + if (ext == NULL || ext == filepath) + return ""; + return ext + 1; +} + int main(int argc, char **argv) { int exitcode = 0; @@ -46,7 +53,17 @@ int main(int argc, char **argv) { RAM ram; Simulator simulator; simulator.attach_ram(&ram); - simulator.load_ihex(program); + + std::string program_ext(fileExtension(program)); + if (program_ext == "bin") { + simulator.load_bin(program); + } else if (program_ext == "hex") { + simulator.load_ihex(program); + } else { + std::cout << "*** error: only *.bin or *.hex images supported." << std::endl; + return -1; + } + exitcode = simulator.run(); if (riscv_test) { diff --git a/simX/execute.cpp b/simX/execute.cpp index f29ea150..8a1c00db 100644 --- a/simX/execute.cpp +++ b/simX/execute.cpp @@ -114,15 +114,19 @@ void Warp::execute(const Instr &instr, Pipeline *pipeline) { } DPN(2, std::endl); } + + bool rd_write = false; switch (opcode) { case NOP: break; case LUI_INST: rddata = (immsrc << 12) & 0xfffff000; + rd_write = true; break; case AUIPC_INST: rddata = ((immsrc << 12) & 0xfffff000) + PC_; + rd_write = true; break; case R_INST: { if (func7 & 0x1) { @@ -245,6 +249,7 @@ void Warp::execute(const Instr &instr, Pipeline *pipeline) { std::abort(); } } + rd_write = true; } break; case I_INST: switch (func3) { @@ -290,6 +295,7 @@ void Warp::execute(const Instr &instr, Pipeline *pipeline) { default: std::abort(); } + rd_write = true; break; case B_INST: switch (func3) { @@ -338,12 +344,14 @@ void Warp::execute(const Instr &instr, Pipeline *pipeline) { nextPC = PC_ + immsrc; pipeline->stall_warp = true; runOnce = true; + rd_write = true; break; case JALR_INST: rddata = nextPC; nextPC = rsdata[0] + immsrc; pipeline->stall_warp = true; runOnce = true; + rd_write = true; break; case L_INST: { Word memAddr = ((rsdata[0] + immsrc) & 0xFFFFFFFC); // word aligned @@ -374,6 +382,7 @@ void Warp::execute(const Instr &instr, Pipeline *pipeline) { default: std::abort(); } + rd_write = true; } break; case S_INST: { Word memAddr = rsdata[0] + immsrc; @@ -409,31 +418,37 @@ void Warp::execute(const Instr &instr, Pipeline *pipeline) { // CSRRW rddata = csr_value; core_->set_csr(csr_addr, rsdata[0], t, id_); + rd_write = true; break; case 2: // CSRRS rddata = csr_value; core_->set_csr(csr_addr, csr_value | rsdata[0], t, id_); + rd_write = true; break; case 3: // CSRRC rddata = csr_value; core_->set_csr(csr_addr, csr_value & ~rsdata[0], t, id_); + rd_write = true; break; case 5: // CSRRWI rddata = csr_value; core_->set_csr(csr_addr, rsrc0, t, id_); + rd_write = true; break; case 6: // CSRRSI rddata = csr_value; core_->set_csr(csr_addr, csr_value | rsrc0, t, id_); + rd_write = true; break; case 7: // CSRRCI rddata = csr_value; core_->set_csr(csr_addr, csr_value & ~rsrc0, t, id_); + rd_write = true; break; default: break; @@ -475,6 +490,7 @@ void Warp::execute(const Instr &instr, Pipeline *pipeline) { } break; } + rd_write = true; break; case (FS | VS): if (func3 == 0x2) { @@ -764,7 +780,8 @@ void Warp::execute(const Instr &instr, Pipeline *pipeline) { } break; } - break; + rd_write = true; + break; case FMADD: case FMSUB: @@ -811,8 +828,8 @@ void Warp::execute(const Instr &instr, Pipeline *pipeline) { rddata = floatToBin(fpDest); } - } - break; + rd_write = true; + } break; case GPGPU: switch (func3) { case 0: { @@ -1767,20 +1784,22 @@ void Warp::execute(const Instr &instr, Pipeline *pipeline) { std::abort(); } - int rdt = instr.getRDType(); - switch (rdt) { - case 1: - if (rdest) { - D(2, "[" << std::dec << t << "] Dest Regs: r" << rdest << "=0x" << std::hex << std::hex << rddata); - iregs[rdest] = rddata; + if (rd_write) { + int rdt = instr.getRDType(); + switch (rdt) { + case 1: + if (rdest) { + D(2, "[" << std::dec << t << "] Dest Regs: r" << rdest << "=0x" << std::hex << std::hex << rddata); + iregs[rdest] = rddata; + } + break; + case 2: + D(2, "[" << std::dec << t << "] Dest Regs: fr" << rdest << "=0x" << std::hex << std::hex << rddata); + fregs[rdest] = rddata; + break; + default: + break; } - break; - case 2: - D(2, "[" << std::dec << t << "] Dest Regs: fr" << rdest << "=0x" << std::hex << std::hex << rddata); - fregs[rdest] = rddata; - break; - default: - break; } } diff --git a/simX/main.cpp b/simX/main.cpp index 21660d91..07d34129 100644 --- a/simX/main.cpp +++ b/simX/main.cpp @@ -53,10 +53,19 @@ int main(int argc, char **argv) { Decoder decoder(arch); MemoryUnit mu(0, arch.wsize(), true); - RAM old_ram((1<<12), (1<<20)); - old_ram.loadHexImage(imgFileName.c_str()); + RAM ram((1<<12), (1<<20)); - mu.attach(old_ram, 0, 0xFFFFFFFF); + std::string program_ext(fileExtension(imgFileName.c_str())); + if (program_ext == "bin") { + ram.loadBinImage(imgFileName.c_str()); + } else if (program_ext == "hex") { + ram.loadHexImage(imgFileName.c_str()); + } else { + std::cout << "*** error: only *.bin or *.hex images supported." << std::endl; + return -1; + } + + mu.attach(ram, 0, 0xFFFFFFFF); struct stat hello; fstat(0, &hello); diff --git a/simX/mem.cpp b/simX/mem.cpp index cb33bb1f..4ce4841e 100644 --- a/simX/mem.cpp +++ b/simX/mem.cpp @@ -232,74 +232,85 @@ void RAM::write(Addr addr, const void *data, Size size) { } } -static uint32_t hti_old(char c) { - if (c >= 'A' && c <= 'F') - return c - 'A' + 10; - if (c >= 'a' && c <= 'f') - return c - 'a' + 10; - return c - '0'; -} - -static uint32_t hToI_old(char *c, uint32_t size) { - uint32_t value = 0; - for (uint32_t i = 0; i < size; i++) { - value += hti_old(c[i]) << ((size - i - 1) * 4); +void RAM::loadBinImage(const char* path) { + std::ifstream ifs(path); + if (!ifs) { + std::cout << "error: " << path << " not found" << std::endl; } - return value; -} -void RAM::loadHexImage(std::string path) { + ifs.seekg(0, ifs.end); + auto size = ifs.tellg(); + std::vector content(size); + ifs.seekg(0, ifs.beg); + ifs.read((char*)content.data(), size); + this->clear(); - FILE *fp = fopen(&path[0], "r"); - if (fp == 0) { - std::cout << path << " not found" << std::endl; + this->write(STARTUP_ADDR, content.data(), size); +} + +void RAM::loadHexImage(const char* path) { + auto hti = [&](char c)->uint32_t { + if (c >= 'A' && c <= 'F') + return c - 'A' + 10; + if (c >= 'a' && c <= 'f') + return c - 'a' + 10; + return c - '0'; + }; + + auto hToI = [&](const char *c, uint32_t size)->uint32_t { + uint32_t value = 0; + for (uint32_t i = 0; i < size; i++) { + value += hti(c[i]) << ((size - i - 1) * 4); + } + return value; + }; + + std::ifstream ifs(path); + if (!ifs) { + std::cout << "error: " << path << " not found" << std::endl; } - fseek(fp, 0, SEEK_END); - uint32_t size = ftell(fp); - fseek(fp, 0, SEEK_SET); - char *content = new char[size]; - int x = fread(content, 1, size, fp); - if (!x) { - std::cout << "COULD NOT READ FILE\n"; - std::abort(); - } + ifs.seekg(0, ifs.end); + uint32_t size = ifs.tellg(); + std::vector content(size); + ifs.seekg(0, ifs.beg); + ifs.read(content.data(), size); int offset = 0; - char *line = content; - - while (1) { + char *line = content.data(); + + this->clear(); + + while (true) { if (line[0] == ':') { - uint32_t byteCount = hToI_old(line + 1, 2); - uint32_t nextAddr = hToI_old(line + 3, 4) + offset; - uint32_t key = hToI_old(line + 7, 2); + uint32_t byteCount = hToI(line + 1, 2); + uint32_t nextAddr = hToI(line + 3, 4) + offset; + uint32_t key = hToI(line + 7, 2); switch (key) { case 0: for (uint32_t i = 0; i < byteCount; i++) { - unsigned add = nextAddr + i; - *this->get(add) = hToI_old(line + 9 + i * 2, 2); + uint32_t addr = nextAddr + i; + uint32_t value = hToI(line + 9 + i * 2, 2); + *this->get(addr) = value; } break; case 2: - offset = hToI_old(line + 9, 4) << 4; + offset = hToI(line + 9, 4) << 4; break; case 4: - offset = hToI_old(line + 9, 4) << 16; + offset = hToI(line + 9, 4) << 16; break; default: break; } } while (*line != '\n' && size != 0) { - line++; - size--; + ++line; + --size; } if (size <= 1) break; - line++; - size--; + ++line; + --size; } - - if (content) - delete[] content; } \ No newline at end of file diff --git a/simX/mem.h b/simX/mem.h index d7426b41..5c3e3211 100644 --- a/simX/mem.h +++ b/simX/mem.h @@ -143,7 +143,9 @@ public: void read(Addr addr, void *data, Size size) override; void write(Addr addr, const void *data, Size size) override; - void loadHexImage(std::string path); + void loadBinImage(const char* path); + + void loadHexImage(const char* path); private: diff --git a/simX/util.cpp b/simX/util.cpp index 95628917..7f78eb7b 100644 --- a/simX/util.cpp +++ b/simX/util.cpp @@ -3,6 +3,7 @@ #include #include #include +#include #include #include "types.h" #include "util.h" @@ -177,4 +178,11 @@ uint8_t vortex::fpBinIsInf(uint32_t din) { return 2; // positive infinity } return 0; // not infinity +} + +const char* vortex::fileExtension(const char* filepath) { + const char *ext = strrchr(filepath, '.'); + if (ext == NULL || ext == filepath) + return ""; + return ext + 1; } \ No newline at end of file diff --git a/simX/util.h b/simX/util.h index b50db756..85b64127 100644 --- a/simX/util.h +++ b/simX/util.h @@ -45,4 +45,7 @@ uint8_t fpBinIsZero(uint32_t din); // check floating-point number in binary format is infinity uint8_t fpBinIsInf(uint32_t din); +// return file extension +const char* fileExtension(const char* filepath); + } \ No newline at end of file diff --git a/simX/warp.cpp b/simX/warp.cpp index 05df1837..bc6ff242 100644 --- a/simX/warp.cpp +++ b/simX/warp.cpp @@ -36,7 +36,7 @@ void Warp::step(Pipeline *pipeline) { /* Fetch and decode. */ Word fetched = core_->icache_fetch(PC_); - auto instr = core_->decoder().decode(fetched); + auto instr = core_->decoder().decode(fetched, PC_); // Update pipeline pipeline->valid = true; diff --git a/simX/warp.h b/simX/warp.h index fbf80e53..7473d858 100644 --- a/simX/warp.h +++ b/simX/warp.h @@ -37,6 +37,7 @@ struct vtype { int vsew; int vlmul; }; + class Warp { public: Warp(Core *core, Word id);