Modified RV32F instructions to support 64-bit register file and added RV64F ISA extension

This commit is contained in:
Santosh Raghav Srivatsan 2021-12-06 18:55:13 -05:00
parent 30a0d34151
commit e6eda67d0c
21 changed files with 459 additions and 316 deletions

View file

@ -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

View file

@ -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

View file

@ -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(); }

View file

@ -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);

View file

@ -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;

View file

@ -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

View file

@ -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;

View file

@ -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<RegMask> in_use_iregs_;
std::vector<RegMask> in_use_fregs_;
@ -93,7 +93,7 @@ private:
WarpMask stalled_warps_;
std::vector<std::shared_ptr<Warp>> warps_;
std::vector<WarpMask> barriers_;
std::vector<Word> csrs_;
std::vector<DoubleWord> csrs_;
std::vector<Byte> fcsrs_;
std::unordered_map<int, std::stringstream> print_bufs_;

View file

@ -46,10 +46,10 @@ static const std::unordered_map<int, struct InstTableEntry_t> 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<Instr> Decoder::decode(HalfWord code, HalfWord PC) {
std::shared_ptr<Instr> Decoder::decode(Word code, Word PC) {
auto instr = std::make_shared<Instr>();
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<Instr> 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<Instr> 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<Instr> 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<Instr> 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);

View file

@ -13,49 +13,49 @@ class Decoder {
public:
Decoder(const ArchDef &);
std::shared_ptr<Instr> decode(HalfWord code, HalfWord PC);
std::shared_ptr<Instr> 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_;
};
}

View file

@ -16,7 +16,7 @@
using namespace vortex;
static bool HasDivergentThreads(const ThreadMask &thread_mask,
const std::vector<std::vector<Word>> &reg_file,
const std::vector<std::vector<DoubleWord>> &reg_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;

View file

@ -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&);
};

View file

@ -29,7 +29,7 @@ public:
//--
int wid;
Word PC;
DoubleWord PC;
//--
int rdest_type;

View file

@ -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;

View file

@ -14,8 +14,8 @@ Warp::Warp(Core *core, Word id)
: id_(id)
, core_(core) {
// simx64
iRegFile_.resize(core_->arch().num_threads(), std::vector<Word>(core_->arch().num_regs(), 0));
fRegFile_.resize(core_->arch().num_threads(), std::vector<Word>(core_->arch().num_regs(), 0));
iRegFile_.resize(core_->arch().num_threads(), std::vector<DoubleWord>(core_->arch().num_regs(), 0));
fRegFile_.resize(core_->arch().num_threads(), std::vector<DoubleWord>(core_->arch().num_regs(), 0));
vRegFile_.resize(core_->arch().num_regs(), std::vector<Byte>(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);
}
}

View file

@ -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<std::vector<Word>> iRegFile_;
std::vector<std::vector<Word>> fRegFile_;
std::vector<std::vector<DoubleWord>> iRegFile_;
std::vector<std::vector<DoubleWord>> fRegFile_;
std::vector<std::vector<Byte>> vRegFile_;
std::stack<DomStackEntry> domStack_;

View file

@ -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;)

View file

@ -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

View file

@ -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

View file

@ -2,7 +2,5 @@
int main()
{
printf("Hello World!\n");
return 0;
}

View file

@ -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