diff --git a/runtime/Makefile b/runtime/Makefile index e9d08b20..0c4435ca 100644 --- a/runtime/Makefile +++ b/runtime/Makefile @@ -1,6 +1,6 @@ RISCV_TOOLCHAIN_PATH ?= /opt/riscv-gnu-toolchain # simx64 -RISCV64_TOOLCHAIN_PATH ?= /nethome/ssrivatsan8/riscv64-unknown-elf-toolchain +RISCV64_TOOLCHAIN_PATH ?= /nethome/ssrivatsan8/riscv CC = $(RISCV64_TOOLCHAIN_PATH)/bin/riscv64-unknown-elf-gcc @@ -8,7 +8,7 @@ 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 += -O3 -march=rv64imfd -mabi=lp64d -Wstack-usage=1024 -fno-exceptions -fdata-sections -ffunction-sections +CFLAGS += -O3 -march=rv64i -mabi=lp64 -Wstack-usage=1024 -fno-exceptions -fdata-sections -ffunction-sections CFLAGS += -I./include -I../hw PROJECT = libvortexrt diff --git a/sim/common/util.h b/sim/common/util.h index dbaeb5fa..8077d78e 100644 --- a/sim/common/util.h +++ b/sim/common/util.h @@ -22,7 +22,14 @@ inline uint64_t align_size(uint64_t size, uint64_t alignment) { } // Apply integer sign extension -inline uint32_t signExt(uint32_t w, uint32_t bit, uint32_t mask) { +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) { if (w >> (bit - 1)) w |= ~mask; return w; diff --git a/sim/simX/archdef.h b/sim/simX/archdef.h index 75248c1a..73e28a15 100644 --- a/sim/simX/archdef.h +++ b/sim/simX/archdef.h @@ -14,8 +14,9 @@ public: ArchDef(const std::string &/*arch*/, int num_cores, int num_warps, - int num_threads) { - wsize_ = 4; + int num_threads) { + // simx64 + wsize_ = 8; vsize_ = 16; num_regs_ = 32; num_csrs_ = 4096; diff --git a/sim/simX/decode.cpp b/sim/simX/decode.cpp index 76f02456..5e9718d9 100644 --- a/sim/simX/decode.cpp +++ b/sim/simX/decode.cpp @@ -107,8 +107,12 @@ static const char* op_string(const Instr &instr) { case 0: return "LBI"; case 1: return "LHI"; case 2: return "LW"; + // simx64 + case 3: return "LD"; case 4: return "LBU"; case 5: return "LHU"; + // simx64 + case 6: return "LWU"; default: std::abort(); } @@ -117,6 +121,8 @@ static const char* op_string(const Instr &instr) { case 0: return "SB"; case 1: return "SH"; case 2: return "SW"; + // simx64 + case 3: return "SD"; default: std::abort(); } @@ -301,7 +307,7 @@ Decoder::Decoder(const ArchDef &arch) { v_imm_mask_ = 0x7ff; } -std::shared_ptr Decoder::decode(Word code, Word PC) { +std::shared_ptr Decoder::decode(uint32_t code, uint32_t PC) { auto instr = std::make_shared(); Opcode op = (Opcode)((code >> shift_opcode_) & opcode_mask_); instr->setOpcode(op); @@ -310,10 +316,11 @@ std::shared_ptr Decoder::decode(Word code, Word PC) { Word func6 = (code >> shift_func6_) & func6_mask_; Word func7 = (code >> shift_func7_) & func7_mask_; - int rd = (code >> shift_rd_) & reg_mask_; - int rs1 = (code >> shift_rs1_) & reg_mask_; - int rs2 = (code >> shift_rs2_) & reg_mask_; - int rs3 = (code >> shift_rs3_) & reg_mask_; + // simx64 + long rd = (code >> shift_rd_) & reg_mask_; + long rs1 = (code >> shift_rs1_) & reg_mask_; + long rs2 = (code >> shift_rs2_) & reg_mask_; + long rs3 = (code >> shift_rs3_) & reg_mask_; auto op_it = sc_instTable.find(op); if (op_it == sc_instTable.end()) { @@ -371,7 +378,7 @@ std::shared_ptr Decoder::decode(Word code, Word PC) { instr->setFunc3(func3); instr->setFunc7(func7); if ((func3 == 5) && (op != L_INST) && (op != Opcode::FL)) { - instr->setImm(signExt(rs2, 5, reg_mask_)); + instr->setImm(signExt(rs2, 6, 0x3F)); } else { instr->setImm(signExt(code >> shift_rs2_, 12, i_imm_mask_)); } diff --git a/sim/simX/decode.h b/sim/simX/decode.h index f8f3909c..9189439c 100644 --- a/sim/simX/decode.h +++ b/sim/simX/decode.h @@ -13,7 +13,7 @@ class Decoder { public: Decoder(const ArchDef &); - std::shared_ptr decode(Word code, Word PC); + std::shared_ptr decode(uint32_t code, uint32_t PC); private: diff --git a/sim/simX/execute.cpp b/sim/simX/execute.cpp index 4f297b32..5f3e2aa3 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; @@ -109,7 +109,8 @@ void Warp::execute(const Instr &instr, Pipeline *pipeline) { rd_write = true; break; case AUIPC_INST: - rddata = ((immsrc << 12) & 0xfffff000) + PC_; + // simx64 + rddata = signExt(((immsrc << 12) & 0xfffff000), 32, 0xFFFFFFFF) + PC_; rd_write = true; break; case R_INST: { @@ -199,8 +200,10 @@ void Warp::execute(const Instr &instr, Pipeline *pipeline) { switch (func3) { case 0: if (func7) { + // RV32I: SUB rddata = rsdata[0] - rsdata[1]; } else { + // RV32I: ADD rddata = rsdata[0] + rsdata[1]; } break; @@ -211,25 +214,32 @@ void Warp::execute(const Instr &instr, Pipeline *pipeline) { rddata = rsdata[0] << rsdata[1]; break; case 2: + // RV32I: SLT (signed) rddata = (WordI(rsdata[0]) < WordI(rsdata[1])); break; case 3: + // RV32I: SLTU (unsigned) rddata = (Word(rsdata[0]) < Word(rsdata[1])); break; case 4: + // RV32I: XOR rddata = rsdata[0] ^ rsdata[1]; break; case 5: if (func7) { + // RV32I: SRA rddata = WordI(rsdata[0]) >> WordI(rsdata[1]); } else { + // RV32I: SRL rddata = Word(rsdata[0]) >> Word(rsdata[1]); } break; case 6: + // RV32I: OR rddata = rsdata[0] | rsdata[1]; break; case 7: + // RV32I: AND rddata = rsdata[0] & rsdata[1]; break; default: @@ -241,42 +251,42 @@ void Warp::execute(const Instr &instr, Pipeline *pipeline) { case I_INST: switch (func3) { case 0: - // ADDI + // RV32I: ADDI rddata = rsdata[0] + immsrc; break; case 1: - // SLLI + // RV64I: SLLI rddata = rsdata[0] << immsrc; break; case 2: - // SLTI + // RV32I: SLTI rddata = (WordI(rsdata[0]) < WordI(immsrc)); break; case 3: { - // SLTIU + // RV32I: SLTIU rddata = (Word(rsdata[0]) < Word(immsrc)); } break; case 4: - // XORI + // RV32I: XORI rddata = rsdata[0] ^ immsrc; break; case 5: if (func7) { - // SRAI + // RV64I: SRAI Word result = WordI(rsdata[0]) >> immsrc; rddata = result; } else { - // SRLI + // RV64I: SRLI Word result = Word(rsdata[0]) >> immsrc; rddata = result; } break; case 6: - // ORI + // RV32I: ORI rddata = rsdata[0] | immsrc; break; case 7: - // ANDI + // RV32I: ANDI rddata = rsdata[0] & immsrc; break; default: @@ -287,37 +297,37 @@ void Warp::execute(const Instr &instr, Pipeline *pipeline) { case B_INST: switch (func3) { case 0: - // BEQ + // RV32I: BEQ if (rsdata[0] == rsdata[1]) { nextPC = PC_ + immsrc; } break; case 1: - // BNE + // RV32I: BNE if (rsdata[0] != rsdata[1]) { nextPC = PC_ + immsrc; } break; case 4: - // BLT + // RV32I: BLT if (WordI(rsdata[0]) < WordI(rsdata[1])) { nextPC = PC_ + immsrc; } break; case 5: - // BGE + // RV32I: BGE if (WordI(rsdata[0]) >= WordI(rsdata[1])) { nextPC = PC_ + immsrc; } break; case 6: - // BLTU + // RV32I: BLTU if (Word(rsdata[0]) < Word(rsdata[1])) { nextPC = PC_ + immsrc; } break; case 7: - // BGEU + // RV32I: BGEU if (Word(rsdata[0]) >= Word(rsdata[1])) { nextPC = PC_ + immsrc; } @@ -326,6 +336,7 @@ void Warp::execute(const Instr &instr, Pipeline *pipeline) { pipeline->stall_warp = true; runOnce = true; break; + // RV32I: JAL case JAL_INST: rddata = nextPC; nextPC = PC_ + immsrc; @@ -333,9 +344,10 @@ void Warp::execute(const Instr &instr, Pipeline *pipeline) { runOnce = true; rd_write = true; break; + // RV32I: JALR case JALR_INST: rddata = nextPC; - nextPC = rsdata[0] + immsrc; + nextPC = HalfWord(rsdata[0]) + HalfWord(immsrc); pipeline->stall_warp = true; runOnce = true; rd_write = true; @@ -343,29 +355,37 @@ void Warp::execute(const Instr &instr, Pipeline *pipeline) { 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, 4); + Word data_read = core_->dcache_read(memAddr, 8); D(3, "LOAD MEM: ADDRESS=0x" << std::hex << memAddr << ", DATA=0x" << data_read); switch (func3) { case 0: - // LBI + // RV32I: LBI rddata = signExt((data_read >> shift_by) & 0xFF, 8, 0xFF); break; case 1: - // LHI + // RV32I: LHI rddata = signExt((data_read >> shift_by) & 0xFFFF, 16, 0xFFFF); break; case 2: - // LW + // RV32I: LW + rddata = signExt((data_read >> shift_by) & 0xFFFFFFFF, 32, 0xFFFFFFFF); + break; + case 3: + // RV64I: LD rddata = data_read; break; case 4: - // LBU + // RV32I: LBU rddata = Word((data_read >> shift_by) & 0xFF); break; case 5: - // LHU + // RV32I: LHU rddata = Word((data_read >> shift_by) & 0xFFFF); break; + case 6: + // RV64I: LWU + rddata = Word((data_read >> shift_by) & 0xFFFFFFFF); + break; default: std::abort(); } @@ -376,16 +396,20 @@ void Warp::execute(const Instr &instr, Pipeline *pipeline) { D(3, "STORE MEM: ADDRESS=0x" << std::hex << memAddr); switch (func3) { case 0: - // SB + // RV32I: SB core_->dcache_write(memAddr, rsdata[1] & 0x000000FF, 1); break; case 1: - // SH - core_->dcache_write(memAddr, rsdata[1], 2); + // RV32I: SH + core_->dcache_write(memAddr, rsdata[1] & 0x0000FFFF, 2); break; case 2: - // SW - core_->dcache_write(memAddr, rsdata[1], 4); + // RV32I: SW + core_->dcache_write(memAddr, rsdata[1] & 0xFFFFFFFF, 4); + break; + case 3: + // RV64I: SD + core_ ->dcache_write(memAddr, rsdata[1], 8); break; default: std::abort(); @@ -396,65 +420,68 @@ void Warp::execute(const Instr &instr, Pipeline *pipeline) { switch (func3) { case 0: if (func7){ - // SUBW - rddata = DoubleWord(rsdata[0] - rsdata[1]); + // RV64I: SUBW + rddata = signExt((HalfWord)rsdata[0] - (HalfWord)rsdata[1], 32, 0xFFFFFFFF); } else{ - // ADDW - rddata = DoubleWord(rsdata[0] + rsdata[1]); + // RV64I: ADDW + rddata = signExt((HalfWord)rsdata[0] + (HalfWord)rsdata[1], 32, 0xFFFFFFFF); } break; case 1: - // SLLW + // RV64I: SLLW // shift amount given by rs2[4:0] - rddata = DoubleWord(rsdata[0] << rsdata[1]); + rddata = signExt((HalfWord)rsdata[0] << (HalfWord)rsdata[1], 32, 0xFFFFFFFF); break; case 5: if (func7) { - // SRAW + // RV64I: SRAW // shift amount given by rs2[4:0] - rddata = DoubleWord(WordI(rsdata[0]) >> WordI(rsdata[1])); + rddata = signExt((HalfWordI)rsdata[0] >> (HalfWordI)rsdata[1], 32, 0xFFFFFFFF); } else { - // SRLW + // RV64I: SRLW // shift amount given by rs2[4:0] - rddata = DoubleWord(Word(rsdata[0]) >> Word(rsdata[1])); + rddata = signExt((HalfWord)rsdata[0] >> (HalfWord)rsdata[1], 32, 0xFFFFFFFF); } break; default: std::abort(); } + rd_write = true; } break; // simx64 case I_INST_64: { switch (func3) { case 0: - // ADDIW - rddata = DoubleWord(rsdata[0] + immsrc); + // RV64I: ADDIW + rddata = signExt((HalfWord)rsdata[0] + (HalfWord)immsrc, 32, 0xFFFFFFFF); + printf("rddata\n"); break; case 1: - // SLLIW + // RV64I: SLLIW // rs1 shifted by lower 5 bits of imm // Illegal exception if imm[5] != 0 - rddata = DoubleWord(rsdata[0] << immsrc); + rddata = signExt((HalfWord)rsdata[0] << (HalfWord)immsrc, 32, 0xFFFFFFFF); break; case 5: if (func7) { - // SRAI + // RV64I: SRAI // rs1 shifted by lower 5 bits of imm // Illegal exception if imm[5] != 0 - Word result = DoubleWord(WordI(rsdata[0]) >> immsrc); + Word result = signExt((HalfWordI)rsdata[0] >> (HalfWordI)immsrc, 32, 0xFFFFFFFF); rddata = result; } else { - // SRLI + // RV64I: SRLI // rs1 shifted by lower 5 bits of imm // Illegal exception if imm[5] != 0 - Word result = DoubleWord(Word(rsdata[0]) >> immsrc); + Word result = signExt((HalfWord)rsdata[0] >> (HalfWord)immsrc, 32, 0xFFFFFFFF); rddata = result; } break; default: std::abort(); } + rd_write = true; } break; case SYS_INST: { Word csr_addr = immsrc & 0x00000FFF; @@ -467,37 +494,37 @@ void Warp::execute(const Instr &instr, Pipeline *pipeline) { } break; case 1: - // CSRRW + // RV32I: CSRRW rddata = csr_value; core_->set_csr(csr_addr, rsdata[0], t, id_); rd_write = true; break; case 2: - // CSRRS + // RV32I: CSRRS rddata = csr_value; core_->set_csr(csr_addr, csr_value | rsdata[0], t, id_); rd_write = true; break; case 3: - // CSRRC + // RV32I: CSRRC rddata = csr_value; core_->set_csr(csr_addr, csr_value & ~rsdata[0], t, id_); rd_write = true; break; case 5: - // CSRRWI + // RV32I: CSRRWI rddata = csr_value; core_->set_csr(csr_addr, rsrc0, t, id_); rd_write = true; break; case 6: - // CSRRSI + // RV32I: CSRRSI rddata = csr_value; core_->set_csr(csr_addr, csr_value | rsrc0, t, id_); rd_write = true; break; case 7: - // CSRRCI + // RV32I: CSRRCI rddata = csr_value; core_->set_csr(csr_addr, csr_value & ~rsrc0, t, id_); rd_write = true; @@ -506,6 +533,7 @@ void Warp::execute(const Instr &instr, Pipeline *pipeline) { break; } } break; + // RV32I: FENCE case FENCE: pipeline->stall_warp = true; runOnce = true; @@ -661,20 +689,21 @@ 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); + // 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); + // 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); + // 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); + // rddata = rv_fnmsub(rsdata[0], rsdata[1], rsdata[2], frm, &fflags); break; default: break; diff --git a/sim/simX/types.h b/sim/simX/types.h index c9bf18fb..94078e4b 100644 --- a/sim/simX/types.h +++ b/sim/simX/types.h @@ -7,13 +7,15 @@ namespace vortex { typedef uint8_t Byte; -typedef uint32_t Word; -typedef int32_t WordI; -// simx64 -typedef uint64_t DoubleWord; +typedef uint64_t Word; +typedef int64_t WordI; // simx64 -typedef uint64_t Addr; +typedef uint32_t HalfWord; +typedef int32_t HalfWordI; + +// simx64 +typedef uint32_t Addr; typedef uint32_t Size; typedef std::bitset<32> RegMask; diff --git a/sim/simX/warp.cpp b/sim/simX/warp.cpp index b5f9c203..883a09dd 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(); } diff --git a/sim/simX/warp.h b/sim/simX/warp.h index f2a33d90..2c96c95b 100644 --- a/sim/simX/warp.h +++ b/sim/simX/warp.h @@ -99,8 +99,8 @@ private: ThreadMask tmask_; // simx64 - std::vector> iRegFile_; - std::vector> fRegFile_; + std::vector> iRegFile_; + std::vector> fRegFile_; std::vector> vRegFile_; std::stack domStack_;