diff --git a/runtime/Makefile b/runtime/Makefile index cd5bfa74..22515f3f 100644 --- a/runtime/Makefile +++ b/runtime/Makefile @@ -1,15 +1,14 @@ -# RISCV_TOOLCHAIN_PATH ?= /opt/riscv-gnu-toolchain -RISCV_TOOLCHAIN_PATH = /nethome/ssrivatsan8/riscv32 +RISCV_TOOLCHAIN_PATH ?= /opt/riscv-gnu-toolchain # simx64 RISCV64_TOOLCHAIN_PATH ?= /nethome/ssrivatsan8/riscv -CC = $(RISCV64_TOOLCHAIN_PATH)/bin/riscv64-unknown-elf-gcc -AR = $(RISCV64_TOOLCHAIN_PATH)/bin/riscv64-unknown-elf-gcc-ar -DP = $(RISCV64_TOOLCHAIN_PATH)/bin/riscv64-unknown-elf-objdump -CP = $(RISCV64_TOOLCHAIN_PATH)/bin/riscv64-unknown-elf-objcopy +CC = $(RISCV_TOOLCHAIN_PATH)/bin/riscv32-unknown-elf-gcc +AR = $(RISCV_TOOLCHAIN_PATH)/bin/riscv32-unknown-elf-gcc-ar +DP = $(RISCV_TOOLCHAIN_PATH)/bin/riscv32-unknown-elf-objdump +CP = $(RISCV_TOOLCHAIN_PATH)/bin/riscv32-unknown-elf-objcopy -CFLAGS += -O3 -march=rv64imfd -mabi=lp64d -Wstack-usage=1024 -fno-exceptions -fdata-sections -ffunction-sections +CFLAGS += -O3 -march=rv32imf -mabi=ilp32f -Wstack-usage=1024 -fno-exceptions -fdata-sections -ffunction-sections CFLAGS += -I./include -I../hw PROJECT = libvortexrt diff --git a/runtime/src/vx_start.S b/runtime/src/vx_start.S index 0d2a0078..36be5032 100644 --- a/runtime/src/vx_start.S +++ b/runtime/src/vx_start.S @@ -23,13 +23,13 @@ _start: call memset # Register global termination functions - la a0, __libc_fini_array + # la a0, __libc_fini_array # to be called upon exit call atexit # Run global initialization functions - call __libc_init_array + # call __libc_init_array # call main program routine call main diff --git a/sim/common/rvfloats.cpp b/sim/common/rvfloats.cpp index c23cb8da..677e7605 100644 --- a/sim/common/rvfloats.cpp +++ b/sim/common/rvfloats.cpp @@ -106,6 +106,21 @@ uint32_t rv_ftou(uint32_t a, uint32_t frm, uint32_t* fflags) { return r; } +// simx64 +uint64_t rv_ftol(uint32_t a, uint32_t frm, uint32_t* fflags) { + softfloat_roundingMode = frm; + auto r = f32_to_i64(to_float32_t(a), frm, true); + if (fflags) { *fflags = get_fflags(); } + return r; +} + +uint64_t rv_ftolu(uint32_t a, uint32_t frm, uint32_t* fflags) { + softfloat_roundingMode = frm; + auto r = f32_to_ui64(to_float32_t(a), frm, true); + if (fflags) { *fflags = get_fflags(); } + return r; +} + uint32_t rv_itof(uint32_t a, uint32_t frm, uint32_t* fflags) { softfloat_roundingMode = frm; auto r = i32_to_f32(a); @@ -120,6 +135,21 @@ uint32_t rv_utof(uint32_t a, uint32_t frm, uint32_t* fflags) { return from_float32_t(r); } +// simx64 +uint32_t rv_ltof(uint64_t a, uint32_t frm, uint32_t* fflags) { + softfloat_roundingMode = frm; + auto r = i64_to_f32(a); + if (fflags) { *fflags = get_fflags(); } + return from_float32_t(r); +} + +uint32_t rv_lutof(uint64_t a, uint32_t frm, uint32_t* fflags) { + softfloat_roundingMode = frm; + auto r = ui64_to_f32(a); + if (fflags) { *fflags = get_fflags(); } + return from_float32_t(r); +} + uint32_t rv_flt(uint32_t a, uint32_t b, uint32_t* fflags) { auto r = f32_lt(to_float32_t(a), to_float32_t(b)); if (fflags) { *fflags = get_fflags(); } diff --git a/sim/common/rvfloats.h b/sim/common/rvfloats.h index 392e5b63..69609a44 100644 --- a/sim/common/rvfloats.h +++ b/sim/common/rvfloats.h @@ -20,8 +20,14 @@ uint32_t rv_fsqrt(uint32_t a, uint32_t frm, uint32_t* fflags); uint32_t rv_ftoi(uint32_t a, uint32_t frm, uint32_t* fflags); uint32_t rv_ftou(uint32_t a, uint32_t frm, uint32_t* fflags); +// simx64 +uint64_t rv_ftol(uint32_t a, uint32_t frm, uint32_t* fflags); +uint64_t rv_ftolu(uint32_t a, uint32_t frm, uint32_t* fflags); uint32_t rv_itof(uint32_t a, uint32_t frm, uint32_t* fflags); uint32_t rv_utof(uint32_t a, uint32_t frm, uint32_t* fflags); +// simx64 +uint32_t rv_ltof(uint64_t a, uint32_t frm, uint32_t* fflags); +uint32_t rv_lutof(uint64_t a, uint32_t frm, uint32_t* fflags); uint32_t rv_fclss(uint32_t a); uint32_t rv_fsgnj(uint32_t a, uint32_t b); diff --git a/sim/common/util.h b/sim/common/util.h index 8077d78e..6d26dcfb 100644 --- a/sim/common/util.h +++ b/sim/common/util.h @@ -21,15 +21,15 @@ inline uint64_t align_size(uint64_t size, uint64_t alignment) { return (size + alignment - 1) & ~(alignment - 1); } -// Apply integer sign extension +// 64-bit sign extension inline uint64_t signExt(uint64_t w, uint64_t bit, uint64_t mask) { if (w >> (bit - 1)) w |= ~mask; return w; } -// Apply integer sign extension -inline uint32_t signExt32(uint32_t w, uint32_t bit, uint32_t mask) { +// 128-bit sign extension +inline __uint128_t signExt128(__uint128_t w, uint32_t bit, __uint128_t mask) { if (w >> (bit - 1)) w |= ~mask; return w; diff --git a/sim/simX/Makefile b/sim/simX/Makefile index 88e030ac..29b53fc3 100644 --- a/sim/simX/Makefile +++ b/sim/simX/Makefile @@ -21,9 +21,7 @@ VPATH := $(sort $(dir $(SRCS))) # Debugigng ifdef DEBUG - # CXXFLAGS += -g -O0 -DDEBUG_LEVEL=$(DEBUG) - # simx64 - CXXFLAGS += -g -O0 -DDEBUG_LEVEL=4 + CXXFLAGS += -g -O0 -DDEBUG_LEVEL=$(DEBUG) else CXXFLAGS += -O2 -DNDEBUG endif diff --git a/sim/simX/core.cpp b/sim/simX/core.cpp index bea53717..688fd678 100644 --- a/sim/simX/core.cpp +++ b/sim/simX/core.cpp @@ -241,7 +241,7 @@ void Core::writeback() { inst_in_writeback_.next(NULL); } -Word Core::get_csr(Addr addr, int tid, int wid) { +DoubleWord Core::get_csr(Addr addr, int tid, int wid) { if (addr == CSR_FFLAGS) { return fcsrs_.at(wid) & 0x1F; } else if (addr == CSR_FRM) { @@ -284,19 +284,19 @@ Word Core::get_csr(Addr addr, int tid, int wid) { return insts_; } else if (addr == CSR_MINSTRET_H) { // NumInsts - return (Word)(insts_ >> 32); + return (DoubleWord)(insts_ >> 32); } else if (addr == CSR_MCYCLE) { // NumCycles - return (Word)steps_; + return (DoubleWord)steps_; } else if (addr == CSR_MCYCLE_H) { // NumCycles - return (Word)(steps_ >> 32); + return (DoubleWord)(steps_ >> 32); } else { return csrs_.at(addr); } } -void Core::set_csr(Addr addr, Word value, int /*tid*/, int wid) { +void Core::set_csr(Addr addr, DoubleWord value, int /*tid*/, int wid) { if (addr == CSR_FFLAGS) { fcsrs_.at(wid) = (fcsrs_.at(wid) & ~0x1F) | (value & 0x1F); } else if (addr == CSR_FRM) { @@ -322,16 +322,16 @@ void Core::barrier(int bar_id, int count, int warp_id) { } // simx64 -HalfWord Core::icache_fetch(Addr addr) { - HalfWord data; - mem_.read(&data, addr, sizeof(HalfWord), 0); +Word Core::icache_fetch(Addr addr) { + Word data; + mem_.read(&data, addr, sizeof(Word), 0); return data; } // simx64 -Word Core::dcache_read(Addr addr, Size size) { +DoubleWord Core::dcache_read(Addr addr, Size size) { ++loads_; - Word data = 0; + DoubleWord data = 0; #ifdef SM_ENABLE if ((addr >= (SMEM_BASE_ADDR - SMEM_SIZE)) && ((addr + 3) < SMEM_BASE_ADDR)) { @@ -343,7 +343,7 @@ Word Core::dcache_read(Addr addr, Size size) { return data; } -void Core::dcache_write(Addr addr, Word data, Size size) { +void Core::dcache_write(Addr addr, DoubleWord data, Size size) { ++stores_; #ifdef SM_ENABLE if ((addr >= (SMEM_BASE_ADDR - SMEM_SIZE)) @@ -375,7 +375,7 @@ void Core::printStats() const { << "Stores: " << stores_ << std::endl; } -void Core::writeToStdOut(Addr addr, Word data) { +void Core::writeToStdOut(Addr addr, DoubleWord data) { uint32_t tid = (addr - IO_COUT_ADDR) & (IO_COUT_SIZE-1); auto& ss_buf = print_bufs_[tid]; char c = (char)data; diff --git a/sim/simX/core.h b/sim/simX/core.h index 8940ea0d..7bfb5c41 100644 --- a/sim/simX/core.h +++ b/sim/simX/core.h @@ -60,18 +60,18 @@ public: return warps_[0]->getIRegValue(reg); } - Word get_csr(Addr addr, int tid, int wid); + DoubleWord get_csr(Addr addr, int tid, int wid); - void set_csr(Addr addr, Word value, int tid, int wid); + void set_csr(Addr addr, DoubleWord value, int tid, int wid); void barrier(int bar_id, int count, int warp_id); // simx64 - HalfWord icache_fetch(Addr); + Word icache_fetch(Addr); // simx64 - Word dcache_read(Addr, Size); + DoubleWord dcache_read(Addr, Size); // simx64 - void dcache_write(Addr, Word, Size); + void dcache_write(Addr, DoubleWord, Size); void trigger_ebreak(); bool check_ebreak() const; @@ -85,7 +85,7 @@ private: void execute(); void writeback(); - void writeToStdOut(Addr addr, Word data); + void writeToStdOut(Addr addr, DoubleWord data); std::vector in_use_iregs_; std::vector in_use_fregs_; @@ -93,7 +93,7 @@ private: WarpMask stalled_warps_; std::vector> warps_; std::vector barriers_; - std::vector csrs_; + std::vector csrs_; std::vector fcsrs_; std::unordered_map print_bufs_; diff --git a/sim/simX/decode.cpp b/sim/simX/decode.cpp index 3c8c52b0..4c755070 100644 --- a/sim/simX/decode.cpp +++ b/sim/simX/decode.cpp @@ -46,10 +46,10 @@ static const std::unordered_map sc_instTable = { }; static const char* op_string(const Instr &instr) { - HalfWord func3 = instr.getFunc3(); - HalfWord func7 = instr.getFunc7(); - HalfWord rs2 = instr.getRSrc(1); - Word imm = instr.getImm(); + Word func3 = instr.getFunc3(); + Word func7 = instr.getFunc7(); + Word rs2 = instr.getRSrc(1); + DoubleWord imm = instr.getImm(); switch (instr.getOpcode()) { case Opcode::NOP: return "NOP"; case Opcode::LUI_INST: return "LUI"; @@ -128,12 +128,24 @@ static const char* op_string(const Instr &instr) { } // simx64 case Opcode::R_INST_64: - switch (func3) { - case 0: return func7 ? "SUBW" : "ADDW"; - case 1: return "SLLW"; - case 5: return func7 ? "SRAW" : "SRLW"; - default: - std::abort(); + if (func7 & 0x1){ + switch (func3) { + case 0: return func7 ? "SUBW" : "ADDW"; + case 1: return "SLLW"; + case 5: return func7 ? "SRAW" : "SRLW"; + default: + std::abort(); + } + } else { + switch (func3) { + case 0: return "MULW"; + case 4: return "DIVW"; + case 5: return "DIVUW"; + case 6: return "REMW"; + case 7: return "REMUW"; + default: + std::abort(); + } } // simx64 case Opcode::I_INST_64: @@ -189,8 +201,25 @@ static const char* op_string(const Instr &instr) { default: std::abort(); } - case 0x60: return rs2 ? "FCVT.WU.S" : "FCVT.W.S"; - case 0x68: return rs2 ? "FCVT.S.WU" : "FCVT.S.W"; + // simx64 + case 0x60: + switch (rs2) { + case 0: return "FCVT.W.S"; + case 1: return "FCVT.WU.S"; + case 2: return "FCVT.L.S"; + case 3: return "FCVT.LU.S"; + default: + std::abort(); + } + case 0x68: + switch (rs2) { + case 0: return "FCVT.S.W"; + case 1: return "FCVT.S.WU"; + case 2: return "FCVT.S.L"; + case 3: return "FCVT.S.LU"; + default: + std::abort(); + } case 0x70: return func3 ? "FLASS" : "FMV.X.W"; case 0x78: return "FMV.W.X"; default: @@ -309,14 +338,14 @@ Decoder::Decoder(const ArchDef &arch) { } // simx64 -std::shared_ptr Decoder::decode(HalfWord code, HalfWord PC) { +std::shared_ptr Decoder::decode(Word code, Word PC) { auto instr = std::make_shared(); Opcode op = (Opcode)((code >> shift_opcode_) & opcode_mask_); instr->setOpcode(op); - HalfWord func3 = (code >> shift_func3_) & func3_mask_; - HalfWord func6 = (code >> shift_func6_) & func6_mask_; - HalfWord func7 = (code >> shift_func7_) & func7_mask_; + Word func3 = (code >> shift_func3_) & func3_mask_; + Word func6 = (code >> shift_func6_) & func6_mask_; + Word func7 = (code >> shift_func7_) & func7_mask_; // simx64 int rd = (code >> shift_rd_) & reg_mask_; @@ -394,7 +423,7 @@ std::shared_ptr Decoder::decode(HalfWord code, HalfWord PC) { instr->setSrcReg(rs2); } instr->setFunc3(func3); - Word imeed = (func7 << reg_s_) | rd; + DoubleWord imeed = (func7 << reg_s_) | rd; instr->setImm(signExt(imeed, 12, s_imm_mask_)); } break; @@ -402,11 +431,11 @@ std::shared_ptr Decoder::decode(HalfWord code, HalfWord PC) { instr->setSrcReg(rs1); instr->setSrcReg(rs2); instr->setFunc3(func3); - HalfWord bit_11 = rd & 0x1; - HalfWord bits_4_1 = rd >> 1; - HalfWord bit_10_5 = func7 & 0x3f; - HalfWord bit_12 = func7 >> 6; - Word imeed = (bits_4_1 << 1) | (bit_10_5 << 5) | (bit_11 << 11) | (bit_12 << 12); + Word bit_11 = rd & 0x1; + Word bits_4_1 = rd >> 1; + Word bit_10_5 = func7 & 0x3f; + Word bit_12 = func7 >> 6; + DoubleWord imeed = (bits_4_1 << 1) | (bit_10_5 << 5) | (bit_11 << 11) | (bit_12 << 12); instr->setImm(signExt(imeed, 13, b_imm_mask_)); } break; @@ -417,12 +446,12 @@ std::shared_ptr Decoder::decode(HalfWord code, HalfWord PC) { case InstType::J_TYPE: { instr->setDestReg(rd); - HalfWord unordered = code >> shift_func3_; - HalfWord bits_19_12 = unordered & 0xff; - HalfWord bit_11 = (unordered >> 8) & 0x1; - HalfWord bits_10_1 = (unordered >> 9) & 0x3ff; - HalfWord bit_20 = (unordered >> 19) & 0x1; - Word imeed = 0 | (bits_10_1 << 1) | (bit_11 << 11) | (bits_19_12 << 12) | (bit_20 << 20); + Word unordered = code >> shift_func3_; + Word bits_19_12 = unordered & 0xff; + Word bit_11 = (unordered >> 8) & 0x1; + Word bits_10_1 = (unordered >> 9) & 0x3ff; + Word bit_20 = (unordered >> 19) & 0x1; + DoubleWord imeed = 0 | (bits_10_1 << 1) | (bit_11 << 11) | (bits_19_12 << 12) | (bit_20 << 20); if (bit_20) { imeed |= ~j_imm_mask_; } @@ -438,7 +467,7 @@ std::shared_ptr Decoder::decode(HalfWord code, HalfWord PC) { if (func3 == 7) { instr->setImm(!(code >> shift_vset_)); if (instr->getImm()) { - HalfWord immed = (code >> shift_rs2_) & v_imm_mask_; + Word immed = (code >> shift_rs2_) & v_imm_mask_; instr->setImm(immed); instr->setVlmul(immed & 0x3); instr->setVediv((immed >> 4) & 0x3); diff --git a/sim/simX/decode.h b/sim/simX/decode.h index 27307afc..f8f3909c 100644 --- a/sim/simX/decode.h +++ b/sim/simX/decode.h @@ -13,49 +13,49 @@ class Decoder { public: Decoder(const ArchDef &); - std::shared_ptr decode(HalfWord code, HalfWord PC); + std::shared_ptr decode(Word code, Word PC); private: - HalfWord inst_s_; - HalfWord opcode_s_; - HalfWord reg_s_; - HalfWord func2_s_; - HalfWord func3_s_; - HalfWord shift_opcode_; - HalfWord shift_rd_; - HalfWord shift_rs1_; - HalfWord shift_rs2_; - HalfWord shift_rs3_; - HalfWord shift_func2_; - HalfWord shift_func3_; - HalfWord shift_func7_; - HalfWord shift_j_u_immed_; - HalfWord shift_s_b_immed_; - HalfWord shift_i_immed_; + Word inst_s_; + Word opcode_s_; + Word reg_s_; + Word func2_s_; + Word func3_s_; + Word shift_opcode_; + Word shift_rd_; + Word shift_rs1_; + Word shift_rs2_; + Word shift_rs3_; + Word shift_func2_; + Word shift_func3_; + Word shift_func7_; + Word shift_j_u_immed_; + Word shift_s_b_immed_; + Word shift_i_immed_; - HalfWord reg_mask_; - HalfWord func2_mask_; - HalfWord func3_mask_; - HalfWord func6_mask_; - HalfWord func7_mask_; - HalfWord opcode_mask_; - HalfWord i_imm_mask_; - HalfWord s_imm_mask_; - HalfWord b_imm_mask_; - HalfWord u_imm_mask_; - HalfWord j_imm_mask_; - HalfWord v_imm_mask_; + Word reg_mask_; + Word func2_mask_; + Word func3_mask_; + Word func6_mask_; + Word func7_mask_; + Word opcode_mask_; + Word i_imm_mask_; + Word s_imm_mask_; + Word b_imm_mask_; + Word u_imm_mask_; + Word j_imm_mask_; + Word v_imm_mask_; //Vector - HalfWord shift_vset_; - HalfWord shift_vset_immed_; - HalfWord shift_vmask_; - HalfWord shift_vmop_; - HalfWord shift_vnf_; - HalfWord shift_func6_; - HalfWord vmask_s_; - HalfWord mop_s_; + Word shift_vset_; + Word shift_vset_immed_; + Word shift_vmask_; + Word shift_vmop_; + Word shift_vnf_; + Word shift_func6_; + Word vmask_s_; + Word mop_s_; }; } \ No newline at end of file diff --git a/sim/simX/execute.cpp b/sim/simX/execute.cpp index cb2dc464..5a321c80 100644 --- a/sim/simX/execute.cpp +++ b/sim/simX/execute.cpp @@ -16,7 +16,7 @@ using namespace vortex; static bool HasDivergentThreads(const ThreadMask &thread_mask, - const std::vector> ®_file, + const std::vector> ®_file, unsigned reg) { bool cond; size_t thread_idx = 0; @@ -53,19 +53,19 @@ void Warp::execute(const Instr &instr, Pipeline *pipeline) { assert(tmask_.any()); // simx64 - Word nextPC = PC_ + 4; + DoubleWord nextPC = PC_ + 4; bool runOnce = false; - HalfWord func3 = instr.getFunc3(); - HalfWord func6 = instr.getFunc6(); - HalfWord func7 = instr.getFunc7(); + Word func3 = instr.getFunc3(); + Word func6 = instr.getFunc6(); + Word func7 = instr.getFunc7(); auto opcode = instr.getOpcode(); int rdest = instr.getRDest(); int rsrc0 = instr.getRSrc(0); int rsrc1 = instr.getRSrc(1); - Word immsrc= instr.getImm(); - Word vmask = instr.getVmask(); + DoubleWord immsrc= instr.getImm(); + DoubleWord vmask = instr.getVmask(); int num_threads = core_->arch().num_threads(); for (int t = 0; t < num_threads; t++) { @@ -75,8 +75,8 @@ void Warp::execute(const Instr &instr, Pipeline *pipeline) { auto &iregs = iRegFile_.at(t); auto &fregs = fRegFile_.at(t); - Word rsdata[3]; - Word rddata; + DoubleWord rsdata[3]; + DoubleWord rddata; int num_rsrcs = instr.getNRSrc(); if (num_rsrcs) { @@ -106,65 +106,57 @@ void Warp::execute(const Instr &instr, Pipeline *pipeline) { case NOP: break; case LUI_INST: - rddata = signExt(((immsrc << 12) & 0xfffff000), 32, 0xFFFFFFFF); + rddata = (immsrc << 12) & 0xfffffffffffff000; rd_write = true; break; case AUIPC_INST: // simx64 - rddata = signExt(((immsrc << 12) & 0xfffff000), 32, 0xFFFFFFFF) + PC_; + rddata = ((immsrc << 12) & 0xfffffffffffff000) + PC_; rd_write = true; break; case R_INST: { if (func7 & 0x1) { switch (func3) { case 0: - // MUL - rddata = ((WordI)rsdata[0]) * ((WordI)rsdata[1]); + // RV32M: MUL + rddata = ((DoubleWordI)rsdata[0]) * ((DoubleWordI)rsdata[1]); break; case 1: { - // MULH - int64_t first = (int64_t)rsdata[0]; - if (rsdata[0] & 0x80000000) { - first = first | 0xFFFFFFFF00000000; - } - int64_t second = (int64_t)rsdata[1]; - if (rsdata[1] & 0x80000000) { - second = second | 0xFFFFFFFF00000000; - } - uint64_t result = first * second; - rddata = (result >> 32) & 0xFFFFFFFF; + // RV32M: MULH + __int128_t first = signExt128((__int128_t)rsdata[0], 64, 0xFFFFFFFFFFFFFFFF); + __int128_t second = signExt128((__int128_t)rsdata[1], 64, 0xFFFFFFFFFFFFFFFF); + __uint128_t result = first * second; + rddata = (result >> 64) & 0xFFFFFFFFFFFFFFFF; } break; case 2: { - // MULHSU - int64_t first = (int64_t)rsdata[0]; - if (rsdata[0] & 0x80000000) { - first = first | 0xFFFFFFFF00000000; - } - int64_t second = (int64_t)rsdata[1]; - rddata = ((first * second) >> 32) & 0xFFFFFFFF; + // RV32M: MULHSU + __int128_t first = signExt128((__int128_t)rsdata[0], 64, 0xFFFFFFFFFFFFFFFF); + __int128_t second = (__int128_t)rsdata[1]; + __uint128_t result = first * second; + rddata = (result >> 64) & 0xFFFFFFFFFFFFFFFF; } break; case 3: { - // MULHU - uint64_t first = (uint64_t)rsdata[0]; - uint64_t second = (uint64_t)rsdata[1]; - rddata = ((first * second) >> 32) & 0xFFFFFFFF; + // RV32M: MULHU + __uint128_t first = (__uint128_t)rsdata[0]; + __uint128_t second = (__uint128_t)rsdata[1]; + rddata = ((first * second) >> 64) & 0xFFFFFFFFFFFFFFFF; } break; case 4: { - // DIV - WordI dividen = rsdata[0]; - WordI divisor = rsdata[1]; + // RV32M: DIV + DoubleWordI dividen = rsdata[0]; + DoubleWordI divisor = rsdata[1]; if (divisor == 0) { rddata = -1; - } else if (dividen == WordI(0x80000000) && divisor == WordI(0xffffffff)) { + } else if (dividen == DoubleWordI(0x8000000000000000) && divisor == DoubleWordI(0xFFFFFFFFFFFFFFFF)) { rddata = dividen; } else { rddata = dividen / divisor; } } break; case 5: { - // DIVU - Word dividen = rsdata[0]; - Word divisor = rsdata[1]; + // RV32M: DIVU + DoubleWord dividen = rsdata[0]; + DoubleWord divisor = rsdata[1]; if (divisor == 0) { rddata = -1; } else { @@ -172,22 +164,22 @@ void Warp::execute(const Instr &instr, Pipeline *pipeline) { } } break; case 6: { - // REM - WordI dividen = rsdata[0]; - WordI divisor = rsdata[1]; - if (rsdata[1] == 0) { + // RV32M: REM + DoubleWordI dividen = rsdata[0]; + DoubleWordI divisor = rsdata[1]; + if (divisor == 0) { rddata = dividen; - } else if (dividen == WordI(0x80000000) && divisor == WordI(0xffffffff)) { + } else if (dividen == DoubleWordI(0x8000000000000000) && divisor == DoubleWordI(0xFFFFFFFFFFFFFFFF)) { rddata = 0; } else { rddata = dividen % divisor; } } break; case 7: { - // REMU - Word dividen = rsdata[0]; - Word divisor = rsdata[1]; - if (rsdata[1] == 0) { + // RV32M: REMU + DoubleWord dividen = rsdata[0]; + DoubleWord divisor = rsdata[1]; + if (divisor == 0) { rddata = dividen; } else { rddata = dividen % divisor; @@ -205,22 +197,20 @@ void Warp::execute(const Instr &instr, Pipeline *pipeline) { rddata = rsdata[0] - rsdata[1]; } else { // RV32I: ADD - rddata = WordI(rsdata[0]) + WordI(rsdata[1]);//(WordI(rsdata[0]) > 0) && (WordI(rsdata[1]) > 0)? ((rsdata[0] + rsdata[1]) & 0xFFFFFFFF) : + rddata = rsdata[0] + rsdata[1]; } break; case 1: - // simx64 - // In RV64I, only the low 6 bits of rs2 are considered for the shift amount. - // In RV32I, the value in register rs1 is shifted by the amount held in the lower 5 bits of register rs2. + // RV32I: SLL rddata = rsdata[0] << rsdata[1]; break; case 2: // RV32I: SLT (signed) - rddata = (WordI(rsdata[0]) < WordI(rsdata[1])); + rddata = (DoubleWordI(rsdata[0]) < DoubleWordI(rsdata[1])); break; case 3: // RV32I: SLTU (unsigned) - rddata = (Word(rsdata[0]) < Word(rsdata[1])); + rddata = (DoubleWord(rsdata[0]) < DoubleWord(rsdata[1])); break; case 4: // RV32I: XOR @@ -229,10 +219,10 @@ void Warp::execute(const Instr &instr, Pipeline *pipeline) { case 5: if (func7) { // RV32I: SRA - rddata = WordI(rsdata[0]) >> WordI(rsdata[1]); + rddata = DoubleWordI(rsdata[0]) >> DoubleWordI(rsdata[1]); } else { // RV32I: SRL - rddata = Word(rsdata[0]) >> Word(rsdata[1]); + rddata = DoubleWord(rsdata[0]) >> DoubleWord(rsdata[1]); } break; case 6: @@ -253,7 +243,7 @@ void Warp::execute(const Instr &instr, Pipeline *pipeline) { switch (func3) { case 0: // RV32I: ADDI - rddata = WordI(rsdata[0]) + WordI(immsrc); + rddata = rsdata[0] + immsrc; break; case 1: // RV64I: SLLI @@ -261,11 +251,11 @@ void Warp::execute(const Instr &instr, Pipeline *pipeline) { break; case 2: // RV32I: SLTI - rddata = (WordI(rsdata[0]) < WordI(immsrc)); + rddata = (DoubleWordI(rsdata[0]) < DoubleWordI(immsrc)); break; case 3: { // RV32I: SLTIU - rddata = (Word(rsdata[0]) < Word(immsrc)); + rddata = (DoubleWord(rsdata[0]) < DoubleWord(immsrc)); } break; case 4: // RV32I: XORI @@ -274,11 +264,13 @@ void Warp::execute(const Instr &instr, Pipeline *pipeline) { case 5: if (func7) { // RV64I: SRAI - Word result = WordI(rsdata[0]) >> immsrc; + // rs1 shifted by lower 6 bits of immsrc + DoubleWord result = DoubleWordI(rsdata[0]) >> immsrc; rddata = result; } else { // RV64I: SRLI - Word result = Word(rsdata[0]) >> immsrc; + // rs1 shifted by lower 6 bits of immsrc + DoubleWord result = DoubleWord(rsdata[0]) >> immsrc; rddata = result; } break; @@ -311,25 +303,25 @@ void Warp::execute(const Instr &instr, Pipeline *pipeline) { break; case 4: // RV32I: BLT - if (WordI(rsdata[0]) < WordI(rsdata[1])) { + if (DoubleWordI(rsdata[0]) < DoubleWordI(rsdata[1])) { nextPC = PC_ + immsrc; } break; case 5: // RV32I: BGE - if (WordI(rsdata[0]) >= WordI(rsdata[1])) { + if (DoubleWordI(rsdata[0]) >= DoubleWordI(rsdata[1])) { nextPC = PC_ + immsrc; } break; case 6: // RV32I: BLTU - if (Word(rsdata[0]) < Word(rsdata[1])) { + if (DoubleWord(rsdata[0]) < DoubleWord(rsdata[1])) { nextPC = PC_ + immsrc; } break; case 7: // RV32I: BGEU - if (Word(rsdata[0]) >= Word(rsdata[1])) { + if (DoubleWord(rsdata[0]) >= DoubleWord(rsdata[1])) { nextPC = PC_ + immsrc; } break; @@ -348,15 +340,15 @@ void Warp::execute(const Instr &instr, Pipeline *pipeline) { // RV32I: JALR case JALR_INST: rddata = nextPC; - nextPC = HalfWord(rsdata[0]) + HalfWord(immsrc); + nextPC = DoubleWord(rsdata[0]) + DoubleWord(immsrc); pipeline->stall_warp = true; runOnce = true; rd_write = true; break; case L_INST: { - Word memAddr = ((rsdata[0] + immsrc) & 0xFFFFFFFC); // word aligned - Word shift_by = ((rsdata[0] + immsrc) & 0x00000003) * 8; - Word data_read = core_->dcache_read(memAddr, 8); + DoubleWord memAddr = ((rsdata[0] + immsrc) & 0xFFFFFFFC); // DoubleWord aligned + DoubleWord shift_by = ((rsdata[0] + immsrc) & 0x00000003) * 8; + DoubleWord data_read = core_->dcache_read(memAddr, 8); D(3, "LOAD MEM: ADDRESS=0x" << std::hex << memAddr << ", DATA=0x" << data_read); switch (func3) { case 0: @@ -373,19 +365,19 @@ void Warp::execute(const Instr &instr, Pipeline *pipeline) { break; case 3: // RV64I: LD - rddata = data_read; + rddata = DoubleWord(data_read); break; case 4: // RV32I: LBU - rddata = Word((data_read >> shift_by) & 0xFF); + rddata = DoubleWord((data_read >> shift_by) & 0xFF); break; case 5: // RV32I: LHU - rddata = Word((data_read >> shift_by) & 0xFFFF); + rddata = DoubleWord((data_read >> shift_by) & 0xFFFF); break; case 6: // RV64I: LWU - rddata = Word((data_read >> shift_by) & 0xFFFFFFFF); + rddata = DoubleWord((data_read >> shift_by) & 0xFFFFFFFF); break; default: std::abort(); @@ -393,7 +385,7 @@ void Warp::execute(const Instr &instr, Pipeline *pipeline) { rd_write = true; } break; case S_INST: { - Word memAddr = rsdata[0] + immsrc; + DoubleWord memAddr = rsdata[0] + immsrc; D(3, "STORE MEM: ADDRESS=0x" << std::hex << memAddr); switch (func3) { case 0: @@ -418,63 +410,110 @@ void Warp::execute(const Instr &instr, Pipeline *pipeline) { } break; // simx64 case R_INST_64: { - switch (func3) { + if (func7 & 0x1){ + switch (func3) { + case 0: + // RV64M: MULW + rddata = signExt((WordI)rsdata[0] * (WordI)rsdata[1], 32, 0xFFFFFFFF); + break; + case 4: { + // RV64M: DIVW + int32_t dividen = (WordI) rsdata[0]; + int32_t divisor = (WordI) rsdata[1]; + if (divisor == 0){ + rddata = -1; + } else if (dividen == WordI(0x80000000) && divisor == WordI(0xFFFFFFFF)) { + rddata = signExt(dividen, 32, 0xFFFFFFFF); + } else { + rddata = signExt(dividen / divisor, 32, 0xFFFFFFFF); + } + } break; + case 5: { + // RV64M: DIVUW + uint32_t dividen = (Word) rsdata[0]; + uint32_t divisor = (Word) rsdata[1]; + if (divisor == 0){ + rddata = -1; + } else { + rddata = signExt(dividen / divisor, 32, 0xFFFFFFFF); + } + } break; + case 6: { + // RV64M: REMW + int32_t dividen = (WordI) rsdata[0]; + int32_t divisor = (WordI) rsdata[1]; + if (divisor == 0){ + rddata = signExt(dividen, 32, 0xFFFFFFFF); + } else if (dividen == WordI(0x80000000) && divisor == WordI(0xFFFFFFFF)) { + rddata = 0; + } else { + rddata = signExt(dividen % divisor, 32, 0xFFFFFFFF); + } + } break; + case 7: { + // RV64M: REMUW + uint32_t dividen = (Word) rsdata[0]; + uint32_t divisor = (Word) rsdata[1]; + if (divisor == 0){ + rddata = signExt(dividen, 32, 0xFFFFFFFF); + } else { + rddata = signExt(dividen % divisor, 32, 0xFFFFFFFF); + } + } break; + default: + std::abort(); + } + } else { + switch (func3) { case 0: if (func7){ // RV64I: SUBW - rddata = signExt((HalfWord)rsdata[0] - (HalfWord)rsdata[1], 32, 0xFFFFFFFF); + rddata = signExt((Word)rsdata[0] - (Word)rsdata[1], 32, 0xFFFFFFFF); } else{ // RV64I: ADDW - rddata = signExt((HalfWord)rsdata[0] + (HalfWord)rsdata[1], 32, 0xFFFFFFFF); + rddata = signExt((Word)rsdata[0] + (Word)rsdata[1], 32, 0xFFFFFFFF); } break; case 1: // RV64I: SLLW - // shift amount given by rs2[4:0] - rddata = signExt((HalfWord)rsdata[0] << (HalfWord)rsdata[1], 32, 0xFFFFFFFF); + rddata = signExt((Word)rsdata[0] << (Word)rsdata[1], 32, 0xFFFFFFFF); break; case 5: if (func7) { // RV64I: SRAW - // shift amount given by rs2[4:0] - rddata = signExt((HalfWordI)rsdata[0] >> (HalfWordI)rsdata[1], 32, 0xFFFFFFFF); + rddata = signExt((WordI)rsdata[0] >> (WordI)rsdata[1], 32, 0xFFFFFFFF); } else { // RV64I: SRLW - // shift amount given by rs2[4:0] - rddata = signExt((HalfWord)rsdata[0] >> (HalfWord)rsdata[1], 32, 0xFFFFFFFF); + rddata = signExt((Word)rsdata[0] >> (Word)rsdata[1], 32, 0xFFFFFFFF); } break; default: std::abort(); + } } rd_write = true; } break; + // simx64 case I_INST_64: { switch (func3) { case 0: // RV64I: ADDIW - rddata = signExt((HalfWord)rsdata[0] + (HalfWord)immsrc, 32, 0xFFFFFFFF); + rddata = signExt((Word)rsdata[0] + (Word)immsrc, 32, 0xFFFFFFFF); break; case 1: // RV64I: SLLIW - // rs1 shifted by lower 5 bits of imm - // Illegal exception if imm[5] != 0 - rddata = signExt((HalfWord)rsdata[0] << (HalfWord)immsrc, 32, 0xFFFFFFFF); + rddata = signExt((Word)rsdata[0] << (Word)immsrc, 32, 0xFFFFFFFF); break; case 5: if (func7) { - // RV64I: SRAI - // rs1 shifted by lower 5 bits of imm - // Illegal exception if imm[5] != 0 - Word result = signExt((HalfWordI)rsdata[0] >> (HalfWordI)immsrc, 32, 0xFFFFFFFF); + // RV64I: SRAIW + DoubleWord result = signExt((WordI)rsdata[0] >> (WordI)immsrc, 32, 0xFFFFFFFF); rddata = result; } else { - // RV64I: SRLI - // rs1 shifted by lower 5 bits of imm - // Illegal exception if imm[5] != 0 - Word result = signExt((HalfWord)rsdata[0] >> (HalfWord)immsrc, 32, 0xFFFFFFFF); + // RV64I: SRLIW + DoubleWord result = signExt((Word)rsdata[0] >> (Word)immsrc, 32, 0xFFFFFFFF); rddata = result; } break; @@ -484,8 +523,8 @@ void Warp::execute(const Instr &instr, Pipeline *pipeline) { rd_write = true; } break; case SYS_INST: { - Word csr_addr = immsrc & 0x00000FFF; - Word csr_value = core_->get_csr(csr_addr, t, id_); + DoubleWord csr_addr = immsrc & 0x00000FFF; + DoubleWord csr_value = core_->get_csr(csr_addr, t, id_); switch (func3) { case 0: if (csr_addr < 2) { @@ -540,10 +579,12 @@ void Warp::execute(const Instr &instr, Pipeline *pipeline) { break; case (FL | VL): if (func3 == 0x2) { - Word memAddr = rsdata[0] + immsrc; - Word data_read = core_->dcache_read(memAddr, 4); + // RV32F: FLW + DoubleWord memAddr = rsdata[0] + immsrc; + DoubleWord data_read = core_->dcache_read(memAddr, 4); D(3, "LOAD MEM: ADDRESS=0x" << std::hex << memAddr << ", DATA=0x" << data_read); - rddata = data_read; + // simx64 + rddata = data_read | 0xFFFFFFFF00000000; } else { D(3, "Executing vector load"); D(3, "lmul: " << vtype_.vlmul << " VLEN:" << (core_->arch().vsize() * 8) << "sew: " << vtype_.vsew); @@ -555,11 +596,11 @@ void Warp::execute(const Instr &instr, Pipeline *pipeline) { switch (instr.getVlsWidth()) { case 6: { - //load word and unit strided (not checking for unit stride) + //load DoubleWord and unit strided (not checking for unit stride) for (int i = 0; i < vl_; i++) { - Word memAddr = ((rsdata[0]) & 0xFFFFFFFC) + (i * vtype_.vsew / 8); + DoubleWord memAddr = ((rsdata[0]) & 0xFFFFFFFC) + (i * vtype_.vsew / 8); D(3, "STORE MEM: ADDRESS=0x" << std::hex << memAddr); - Word data_read = core_->dcache_read(memAddr, 4); + DoubleWord data_read = core_->dcache_read(memAddr, 4); D(3, "Mem addr: " << std::hex << memAddr << " Data read " << data_read); int *result_ptr = (int *)(vd.data() + i); *result_ptr = data_read; @@ -574,16 +615,16 @@ void Warp::execute(const Instr &instr, Pipeline *pipeline) { break; case (FS | VS): if (func3 == 0x2) { - Word memAddr = rsdata[0] + immsrc; + DoubleWord memAddr = rsdata[0] + immsrc; core_->dcache_write(memAddr, rsdata[1], 4); D(3, "STORE MEM: ADDRESS=0x" << std::hex << memAddr); } else { for (int i = 0; i < vl_; i++) { - Word memAddr = rsdata[0] + (i * vtype_.vsew / 8); + DoubleWord memAddr = rsdata[0] + (i * vtype_.vsew / 8); D(3, "STORE MEM: ADDRESS=0x" << std::hex << memAddr); switch (instr.getVlsWidth()) { case 6: { - //store word and unit strided (not checking for unit stride) + //store DoubleWord and unit strided (not checking for unit stride) uint32_t value = *(uint32_t *)(vRegFile_[instr.getVs3()].data() + i); core_->dcache_write(memAddr, value, 4); D(3, "store: " << memAddr << " value:" << value); @@ -598,87 +639,109 @@ void Warp::execute(const Instr &instr, Pipeline *pipeline) { uint32_t frm = get_fpu_rm(func3, core_, t, id_); uint32_t fflags = 0; switch (func7) { - case 0x00: //FADD + case 0x00: // RV32F: FADD rddata = rv_fadd(rsdata[0], rsdata[1], frm, &fflags); break; - case 0x04: //FSUB + case 0x04: // RV32F: FSUB rddata = rv_fsub(rsdata[0], rsdata[1], frm, &fflags); break; - case 0x08: //FMUL + case 0x08: // RV32F: FMUL rddata = rv_fmul(rsdata[0], rsdata[1], frm, &fflags); break; - case 0x0c: //FDIV + case 0x0c: // RV32F: FDIV rddata = rv_fdiv(rsdata[0], rsdata[1], frm, &fflags); break; - case 0x2c: //FSQRT + case 0x2c: // RV32F: FSQRT rddata = rv_fsqrt(rsdata[0], frm, &fflags); break; case 0x10: switch (func3) { - case 0: // FSGNJ.S + case 0: // RV32F: FSGNJ.S rddata = rv_fsgnj(rsdata[0], rsdata[1]); break; - case 1: // FSGNJN.S + case 1: // RV32F: FSGNJN.S rddata = rv_fsgnjn(rsdata[0], rsdata[1]); break; - case 2: // FSGNJX.S + case 2: // RV32F: FSGNJX.S rddata = rv_fsgnjx(rsdata[0], rsdata[1]); break; } break; case 0x14: if (func3) { - // FMAX.S + // RV32F: FMAX.S rddata = rv_fmax(rsdata[0], rsdata[1], &fflags); } else { - // FMIN.S + // RV32F: FMIN.S rddata = rv_fmin(rsdata[0], rsdata[1], &fflags); } break; case 0x60: - if (rsrc1 == 0) { - // FCVT.W.S - rddata = rv_ftoi(rsdata[0], frm, &fflags); - } else { - // FCVT.WU.S - rddata = rv_ftou(rsdata[0], frm, &fflags); + switch(rsrc1) { + case 0: + // RV32F: FCVT.W.S + rddata = signExt(rv_ftoi(rsdata[0], frm, &fflags), 32, 0xFFFFFFFF); + break; + case 1: + // RV32F: FCVT.WU.S + rddata = signExt(rv_ftou(rsdata[0], frm, &fflags), 32, 0xFFFFFFFF); + break; + case 2: + // RV64F: FCVT.L.S + rddata = rv_ftol(rsdata[0], frm, &fflags); + break; + case 3: + // RV64F: FCVT.LU.S + rddata = rv_ftolu(rsdata[0], frm, &fflags); + break; } break; case 0x70: if (func3) { - // FCLASS.S + // RV32F: FCLASS.S rddata = rv_fclss(rsdata[0]); } else { - // FMV.X.W - rddata = rsdata[0]; + // RV32F: FMV.X.W + rddata = signExt((Word)rsdata[0], 32, 0xFFFFFFFF); } break; case 0x50: switch(func3) { case 0: - // FLE.S + // RV32F: FLE.S rddata = rv_fle(rsdata[0], rsdata[1], &fflags); break; case 1: - // FLT.S + // RV32F: FLT.S rddata = rv_flt(rsdata[0], rsdata[1], &fflags); break; case 2: - // FEQ.S + // RV32F: FEQ.S rddata = rv_feq(rsdata[0], rsdata[1], &fflags); break; } break; case 0x68: - if (rsrc1) { - // FCVT.S.WU: - rddata = rv_utof(rsdata[0], frm, &fflags); - } else { - // FCVT.S.W: - rddata = rv_itof(rsdata[0], frm, &fflags); + switch(rsrc1) { + case 0: + // RV32F: FCVT.S.W + rddata = rv_itof(rsdata[0], frm, &fflags); + break; + case 1: + // RV32F: FCVT.S.WU + rddata = rv_utof(rsdata[0], frm, &fflags); + break; + case 2: + // RV64F: FCVT.S.L + rddata = rv_ltof(rsdata[0], frm, &fflags); + break; + case 3: + // RV64F: FCVT.S.LU + rddata = rv_lutof(rsdata[0], frm, &fflags); + break; } break; case 0x78: - // FMV.W.X + // RV32F: FMV.W.X rddata = rsdata[0]; break; } @@ -689,21 +752,25 @@ void Warp::execute(const Instr &instr, Pipeline *pipeline) { case FMSUB: case FMNMADD: case FMNMSUB: { - // int frm = get_fpu_rm(func3, core_, t, id_); + int frm = get_fpu_rm(func3, core_, t, id_); // simx64 Word fflags = 0; switch (opcode) { case FMADD: - // rddata = rv_fmadd(rsdata[0], rsdata[1], rsdata[2], frm, &fflags); + // RV32F: FMADD + rddata = rv_fmadd(rsdata[0], rsdata[1], rsdata[2], frm, &fflags); break; case FMSUB: - // rddata = rv_fmsub(rsdata[0], rsdata[1], rsdata[2], frm, &fflags); + // RV32F: FMSUB + rddata = rv_fmsub(rsdata[0], rsdata[1], rsdata[2], frm, &fflags); break; case FMNMADD: - // rddata = rv_fnmadd(rsdata[0], rsdata[1], rsdata[2], frm, &fflags); + // RV32F: FNMADD + rddata = rv_fnmadd(rsdata[0], rsdata[1], rsdata[2], frm, &fflags); break; case FMNMSUB: - // rddata = rv_fnmsub(rsdata[0], rsdata[1], rsdata[2], frm, &fflags); + // RV32F: FNMSUB + rddata = rv_fnmsub(rsdata[0], rsdata[1], rsdata[2], frm, &fflags); break; default: break; diff --git a/sim/simX/instr.h b/sim/simX/instr.h index ad05eef1..824ce5b2 100644 --- a/sim/simX/instr.h +++ b/sim/simX/instr.h @@ -34,7 +34,7 @@ enum Opcode { // GPGPU Extension GPGPU = 0x6b, // simx64 - // RV64I Extension + // RV64 Standard Extensions R_INST_64 = 0x3b, I_INST_64 = 0x1b, }; @@ -73,39 +73,39 @@ public: void setSrcFReg(int srcReg) { rsrc_type_[num_rsrcs_] = 2; rsrc_[num_rsrcs_++] = srcReg; } void setDestVReg(int destReg) { rdest_type_ = 3; rdest_ = destReg; } void setSrcVReg(int srcReg) { rsrc_type_[num_rsrcs_] = 3; rsrc_[num_rsrcs_++] = srcReg; } - void setFunc3(HalfWord func3) { func3_ = func3; } - void setFunc7(HalfWord func7) { func7_ = func7; } - void setImm(Word imm) { has_imm_ = true; imm_ = imm; } - void setVlsWidth(HalfWord width) { vlsWidth_ = width; } - void setVmop(HalfWord mop) { vMop_ = mop; } - void setVnf(HalfWord nf) { vNf_ = nf; } - void setVmask(HalfWord mask) { vmask_ = mask; } - void setVs3(HalfWord vs) { vs3_ = vs; } - void setVlmul(HalfWord lmul) { vlmul_ = 1 << lmul; } - void setVsew(HalfWord sew) { vsew_ = 1 << (3+sew); } - void setVediv(HalfWord ediv) { vediv_ = 1 << ediv; } - void setFunc6(HalfWord func6) { func6_ = func6; } + void setFunc3(Word func3) { func3_ = func3; } + void setFunc7(Word func7) { func7_ = func7; } + void setImm(DoubleWord imm) { has_imm_ = true; imm_ = imm; } + void setVlsWidth(Word width) { vlsWidth_ = width; } + void setVmop(Word mop) { vMop_ = mop; } + void setVnf(Word nf) { vNf_ = nf; } + void setVmask(Word mask) { vmask_ = mask; } + void setVs3(Word vs) { vs3_ = vs; } + void setVlmul(Word lmul) { vlmul_ = 1 << lmul; } + void setVsew(Word sew) { vsew_ = 1 << (3+sew); } + void setVediv(Word ediv) { vediv_ = 1 << ediv; } + void setFunc6(Word func6) { func6_ = func6; } /* Getters used by encoders. */ Opcode getOpcode() const { return opcode_; } - HalfWord getFunc3() const { return func3_; } - HalfWord getFunc6() const { return func6_; } - HalfWord getFunc7() const { return func7_; } + Word getFunc3() const { return func3_; } + Word getFunc6() const { return func6_; } + Word getFunc7() const { return func7_; } int getNRSrc() const { return num_rsrcs_; } int getRSrc(int i) const { return rsrc_[i]; } int getRSType(int i) const { return rsrc_type_[i]; } int getRDest() const { return rdest_; } int getRDType() const { return rdest_type_; } bool hasImm() const { return has_imm_; } - Word getImm() const { return imm_; } - HalfWord getVlsWidth() const { return vlsWidth_; } - HalfWord getVmop() const { return vMop_; } - HalfWord getvNf() const { return vNf_; } - HalfWord getVmask() const { return vmask_; } - HalfWord getVs3() const { return vs3_; } - HalfWord getVlmul() const { return vlmul_; } - HalfWord getVsew() const { return vsew_; } - HalfWord getVediv() const { return vediv_; } + DoubleWord getImm() const { return imm_; } + Word getVlsWidth() const { return vlsWidth_; } + Word getVmop() const { return vMop_; } + Word getvNf() const { return vNf_; } + Word getVmask() const { return vmask_; } + Word getVs3() const { return vs3_; } + Word getVlmul() const { return vlmul_; } + Word getVsew() const { return vsew_; } + Word getVediv() const { return vediv_; } private: @@ -120,23 +120,23 @@ private: int isrc_mask_; int fsrc_mask_; int vsrc_mask_; - Word imm_; + DoubleWord imm_; int rsrc_type_[MAX_REG_SOURCES]; int rsrc_[MAX_REG_SOURCES]; int rdest_; - HalfWord func3_; - HalfWord func7_; + Word func3_; + Word func7_; //Vector - HalfWord vmask_; - HalfWord vlsWidth_; - HalfWord vMop_; - HalfWord vNf_; - HalfWord vs3_; - HalfWord vlmul_; - HalfWord vsew_; - HalfWord vediv_; - HalfWord func6_; + Word vmask_; + Word vlsWidth_; + Word vMop_; + Word vNf_; + Word vs3_; + Word vlmul_; + Word vsew_; + Word vediv_; + Word func6_; friend std::ostream &operator<<(std::ostream &, const Instr&); }; diff --git a/sim/simX/pipeline.h b/sim/simX/pipeline.h index f8899a63..8d6034e6 100644 --- a/sim/simX/pipeline.h +++ b/sim/simX/pipeline.h @@ -29,7 +29,7 @@ public: //-- int wid; - Word PC; + DoubleWord PC; //-- int rdest_type; diff --git a/sim/simX/types.h b/sim/simX/types.h index f5729303..55d1dcea 100644 --- a/sim/simX/types.h +++ b/sim/simX/types.h @@ -7,13 +7,12 @@ namespace vortex { typedef uint8_t Byte; -// simx64 -typedef uint64_t Word; -typedef int64_t WordI; +typedef uint32_t Word; +typedef int32_t WordI; // simx64 -typedef uint32_t HalfWord; -typedef int32_t HalfWordI; +typedef uint64_t DoubleWord; +typedef int64_t DoubleWordI; // simx64 typedef uint64_t Addr; diff --git a/sim/simX/warp.cpp b/sim/simX/warp.cpp index 754b1561..a1191dd7 100644 --- a/sim/simX/warp.cpp +++ b/sim/simX/warp.cpp @@ -14,8 +14,8 @@ Warp::Warp(Core *core, Word id) : id_(id) , core_(core) { // simx64 - iRegFile_.resize(core_->arch().num_threads(), std::vector(core_->arch().num_regs(), 0)); - fRegFile_.resize(core_->arch().num_threads(), std::vector(core_->arch().num_regs(), 0)); + iRegFile_.resize(core_->arch().num_threads(), std::vector(core_->arch().num_regs(), 0)); + fRegFile_.resize(core_->arch().num_threads(), std::vector(core_->arch().num_regs(), 0)); vRegFile_.resize(core_->arch().num_regs(), std::vector(core_->arch().vsize(), 0)); this->clear(); } @@ -36,7 +36,7 @@ void Warp::step(Pipeline *pipeline) { /* Fetch and decode. */ - HalfWord fetched = core_->icache_fetch(PC_); + Word fetched = core_->icache_fetch(PC_); auto instr = core_->decoder().decode(fetched, PC_); // Update pipeline @@ -86,10 +86,12 @@ void Warp::step(Pipeline *pipeline) { D(4, "Register state:"); for (int i = 0; i < core_->arch().num_regs(); ++i) { DPN(4, " %r" << std::setfill('0') << std::setw(2) << std::dec << i << ':'); - for (int j = 0; j < core_->arch().num_threads(); ++j) { - // simx64 - DPN(4, ' ' << std::setfill('0') << std::setw(16) << std::hex << iRegFile_[j][i] << std::setfill(' ') << ' '); - } + // for (int j = 0; j < core_->arch().num_threads(); ++j) { + // // simx64 + // DPN(4, ' ' << std::setfill('0') << std::setw(16) << std::hex << iRegFile_[j][i] << std::setfill(' ') << ' '); + // } + DPN(4, ' ' << std::setfill('0') << std::setw(16) << std::hex << iRegFile_[0][i] << std::setfill(' ') << ' '); + DPN(4, ' ' << std::setfill('0') << std::setw(16) << std::hex << fRegFile_[0][i] << std::setfill(' ') << ' '); DPN(4, std::endl); } } \ No newline at end of file diff --git a/sim/simX/warp.h b/sim/simX/warp.h index 2c96c95b..181ed973 100644 --- a/sim/simX/warp.h +++ b/sim/simX/warp.h @@ -11,7 +11,7 @@ class Core; class Instr; class Pipeline; struct DomStackEntry { - DomStackEntry(const ThreadMask &tmask, Word PC) + DomStackEntry(const ThreadMask &tmask, DoubleWord PC) : tmask(tmask) , PC(PC) , fallThrough(false) @@ -26,7 +26,7 @@ struct DomStackEntry { {} ThreadMask tmask; - Word PC; + DoubleWord PC; bool fallThrough; bool unanimous; }; @@ -62,11 +62,11 @@ public: return id_; } - Word getPC() const { + DoubleWord getPC() const { return PC_; } - void setPC(Word PC) { + void setPC(DoubleWord PC) { PC_ = PC; } @@ -95,12 +95,12 @@ private: bool active_; Core *core_; - Word PC_; + DoubleWord PC_; ThreadMask tmask_; // simx64 - std::vector> iRegFile_; - std::vector> fRegFile_; + std::vector> iRegFile_; + std::vector> fRegFile_; std::vector> vRegFile_; std::stack domStack_; diff --git a/tests/riscv/isa64/Makefile b/tests/riscv/isa64/Makefile index ea4bf00c..e72d7df5 100644 --- a/tests/riscv/isa64/Makefile +++ b/tests/riscv/isa64/Makefile @@ -1,16 +1,30 @@ -ALL_TESTS := $(wildcard *.hex) +# ALL_TESTS := $(wildcard *.hex) -D_TESTS := $(wildcard *ud-p-*.hex) -V_TESTS := $(wildcard *-v-*.hex) -M_TESTS := $(wildcard *um-*.hex) -A_TESTS := $(wildcard *ua-*.hex) +# D_TESTS := $(wildcard *ud-p-*.hex) +# V_TESTS := $(wildcard *-v-*.hex) +# M_TESTS := $(wildcard *um-*.hex) +# A_TESTS := $(wildcard *ua-*.hex) -EXCLUDED_TESTS := $(V_TESTS) $(D_TESTS) $(M_TESTS) $(A_TESTS) rv32si-p-scall.hex rv32si-p-sbreak.hex rv32mi-p-breakpoint.hex rv32ua-p-amomax_w.hex rv32ua-p-amoxor_w.hex rv32ua-p-amoor_w.hex rv32mi-p-ma_addr.hex rv32mi-p-mcsr.hex rv32ua-p-amoswap_w.hex rv32mi-p-ma_fetch.hex rv32mi-p-csr.hex rv32ua-p-amoadd_w.hex rv32si-p-dirty.hex rv32ui-p-fence_i.hex rv32si-p-csr.hex rv32mi-p-shamt.hex rv32ua-p-amomin_w.hex rv32ua-p-lrsc.hex rv32si-p-wfi.hex rv32ua-p-amomaxu_w.hex rv32si-p-ma_fetch.hex rv32mi-p-illegal.hex rv32uc-p-rvc.hex rv32mi-p-sbreak.hex rv32ua-p-amominu_w.hex rv32ua-p-amoand_w.hex +# EXCLUDED_TESTS := $(V_TESTS) $(D_TESTS) $(M_TESTS) $(A_TESTS) rv32si-p-scall.hex rv32si-p-sbreak.hex rv32mi-p-breakpoint.hex rv32ua-p-amomax_w.hex rv32ua-p-amoxor_w.hex rv32ua-p-amoor_w.hex rv32mi-p-ma_addr.hex rv32mi-p-mcsr.hex rv32ua-p-amoswap_w.hex rv32mi-p-ma_fetch.hex rv32mi-p-csr.hex rv32ua-p-amoadd_w.hex rv32si-p-dirty.hex rv32ui-p-fence_i.hex rv32si-p-csr.hex rv32mi-p-shamt.hex rv32ua-p-amomin_w.hex rv32ua-p-lrsc.hex rv32si-p-wfi.hex rv32ua-p-amomaxu_w.hex rv32si-p-ma_fetch.hex rv32mi-p-illegal.hex rv32uc-p-rvc.hex rv32mi-p-sbreak.hex rv32ua-p-amominu_w.hex rv32ua-p-amoand_w.hex -TESTS := $(filter-out $(EXCLUDED_TESTS), $(ALL_TESTS)) +# TESTS := $(filter-out $(EXCLUDED_TESTS), $(ALL_TESTS)) + +I_TESTS := $(wildcard *ui-p-*.hex) +M_TESTS := $(wildcard *um-p-*.hex) +F_TESTS := $(wildcard *uf-p-*.hex) +TESTS := $(I_TESTS) $(M_TESTS) $(F_TESTS) all: +run-simx-i: + $(foreach test, $(I_TESTS), ../../../sim/simX/simX -r -a rv64i -c 1 -i $(test) || exit;) + +run-simx-m: + $(foreach test, $(M_TESTS), ../../../sim/simX/simX -r -a rv64i -c 1 -i $(test) || exit;) + +run-simx-f: + $(foreach test, $(F_TESTS), ../../../sim/simX/simX -r -a rv64i -c 1 -i $(test) || exit;) + run-simx: $(foreach test, $(TESTS), ../../../sim/simX/simX -r -a rv64i -c 1 -i $(test) || exit;) diff --git a/tests/runtime/hello/Makefile b/tests/runtime/hello/Makefile index 9d568e71..43e768b6 100644 --- a/tests/runtime/hello/Makefile +++ b/tests/runtime/hello/Makefile @@ -1,5 +1,4 @@ -# RISCV_TOOLCHAIN_PATH ?= /opt/riscv-gnu-toolchain -RISCV_TOOLCHAIN_PATH = /nethome/ssrivatsan8/riscv32 +RISCV_TOOLCHAIN_PATH ?= /opt/riscv-gnu-toolchain VORTEX_RT_PATH ?= $(realpath ../../../runtime) CC = $(RISCV_TOOLCHAIN_PATH)/bin/riscv32-unknown-elf-gcc @@ -10,7 +9,7 @@ CP = $(RISCV_TOOLCHAIN_PATH)/bin/riscv32-unknown-elf-objcopy CFLAGS += -march=rv32imf -mabi=ilp32f -O3 -Wstack-usage=1024 -ffreestanding -nostartfiles -fdata-sections -ffunction-sections CFLAGS += -I$(VORTEX_RT_PATH)/include -I$(VORTEX_RT_PATH)/../hw -LDFLAGS += -Wl,-Bstatic,-T,$(VORTEX_RT_PATH)/linker/vx_link.ld -Wl,--noinhibit-exec,--gc-sections $(VORTEX_RT_PATH)/libvortexrt.a +LDFLAGS += -Wl,-Bstatic,-T,$(VORTEX_RT_PATH)/linker/vx_link.ld -Wl,--gc-sections $(VORTEX_RT_PATH)/libvortexrt.a PROJECT = hello diff --git a/tests/runtime/hello64/Makefile b/tests/runtime/hello64/Makefile index 4f8812ca..dbf04c83 100644 --- a/tests/runtime/hello64/Makefile +++ b/tests/runtime/hello64/Makefile @@ -7,14 +7,16 @@ AR = $(RISCV64_TOOLCHAIN_PATH)/bin/riscv64-unknown-elf-gcc-ar DP = $(RISCV64_TOOLCHAIN_PATH)/bin/riscv64-unknown-elf-objdump CP = $(RISCV64_TOOLCHAIN_PATH)/bin/riscv64-unknown-elf-objcopy -CFLAGS += -march=rv64i -mabi=lp64 -O3 -Wstack-usage=1024 -ffreestanding -nostartfiles -fdata-sections -ffunction-sections +CFLAGS += -march=rv64imfd -mabi=lp64d -O3 -Wstack-usage=1024 -ffreestanding -nostartfiles -fdata-sections -ffunction-sections CFLAGS += -I$(VORTEX_RT_PATH)/include -I$(VORTEX_RT_PATH)/../hw -LDFLAGS += -Wl,-Bstatic,-T,$(VORTEX_RT_PATH)/linker/vx_link64.ld -Wl,--noinhibit-exec,--gc-sections $(VORTEX_RT_PATH)/libvortexrt.a +LDFLAGS += -Wl,-Bstatic,-T,$(VORTEX_RT_PATH)/linker/vx_link64.ld -Wl,--gc-sections + +# $(VORTEX_RT_PATH)/libvortexrt.a PROJECT = hello64 -SRCS = main.cpp +SRCS = main.cpp $(VORTEX_RT_PATH)/src/vx_start.S $(VORTEX_RT_PATH)/src/vx_syscalls.c all: $(PROJECT).elf $(PROJECT).bin $(PROJECT).dump diff --git a/tests/runtime/hello64/main.cpp b/tests/runtime/hello64/main.cpp index 69904cfd..d9ad0537 100644 --- a/tests/runtime/hello64/main.cpp +++ b/tests/runtime/hello64/main.cpp @@ -2,7 +2,5 @@ int main() { - printf("Hello World!\n"); - return 0; } \ No newline at end of file diff --git a/tests/runtime/simple64/Makefile b/tests/runtime/simple64/Makefile index 2078b238..1ccf20cf 100644 --- a/tests/runtime/simple64/Makefile +++ b/tests/runtime/simple64/Makefile @@ -10,7 +10,7 @@ CP = $(RISCV64_TOOLCHAIN_PATH)/bin/riscv64-unknown-elf-objcopy CFLAGS += -march=rv64imfd -mabi=lp64d -O3 -Wstack-usage=1024 -ffreestanding -nostartfiles -fdata-sections -ffunction-sections CFLAGS += -I$(VORTEX_RT_PATH)/include -I$(VORTEX_RT_PATH)/../hw -LDFLAGS += -Wl,-Bstatic,-T,$(VORTEX_RT_PATH)/linker/vx_link64.ld -Wl,--noinhibit-exec,--gc-sections $(VORTEX_RT_PATH)/libvortexrt.a +LDFLAGS += -Wl,-Bstatic,-T,$(VORTEX_RT_PATH)/linker/vx_link64.ld -Wl,--gc-sections $(VORTEX_RT_PATH)/libvortexrt.a PROJECT = simple64