Added support for a few RV64I instructions
This commit is contained in:
@@ -1,11 +1,14 @@
|
|||||||
RISCV_TOOLCHAIN_PATH ?= /opt/riscv-gnu-toolchain
|
RISCV_TOOLCHAIN_PATH ?= /opt/riscv-gnu-toolchain
|
||||||
|
# simx64
|
||||||
|
RISCV64_TOOLCHAIN_PATH ?= /nethome/ssrivatsan8/riscv64-unknown-elf-toolchain
|
||||||
|
|
||||||
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=rv32imf -mabi=ilp32f -Wstack-usage=1024 -fno-exceptions -fdata-sections -ffunction-sections
|
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
|
||||||
|
|
||||||
|
CFLAGS += -O3 -march=rv64imfd -mabi=lp64d -Wstack-usage=1024 -fno-exceptions -fdata-sections -ffunction-sections
|
||||||
CFLAGS += -I./include -I../hw
|
CFLAGS += -I./include -I../hw
|
||||||
|
|
||||||
PROJECT = libvortexrt
|
PROJECT = libvortexrt
|
||||||
|
|||||||
@@ -321,12 +321,14 @@ void Core::barrier(int bar_id, int count, int warp_id) {
|
|||||||
barrier.reset();
|
barrier.reset();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// simx64
|
||||||
Word Core::icache_fetch(Addr addr) {
|
Word Core::icache_fetch(Addr addr) {
|
||||||
Word data;
|
Word data;
|
||||||
mem_.read(&data, addr, sizeof(Word), 0);
|
mem_.read(&data, addr, sizeof(Word), 0);
|
||||||
return data;
|
return data;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// simx64
|
||||||
Word Core::dcache_read(Addr addr, Size size) {
|
Word Core::dcache_read(Addr addr, Size size) {
|
||||||
++loads_;
|
++loads_;
|
||||||
Word data = 0;
|
Word data = 0;
|
||||||
|
|||||||
@@ -66,10 +66,11 @@ public:
|
|||||||
|
|
||||||
void barrier(int bar_id, int count, int warp_id);
|
void barrier(int bar_id, int count, int warp_id);
|
||||||
|
|
||||||
|
// simx64
|
||||||
Word icache_fetch(Addr);
|
Word icache_fetch(Addr);
|
||||||
|
// simx64
|
||||||
Word dcache_read(Addr, Size);
|
Word dcache_read(Addr, Size);
|
||||||
|
// simx64
|
||||||
void dcache_write(Addr, Word, Size);
|
void dcache_write(Addr, Word, Size);
|
||||||
|
|
||||||
void trigger_ebreak();
|
void trigger_ebreak();
|
||||||
|
|||||||
@@ -41,6 +41,8 @@ static const std::unordered_map<int, struct InstTableEntry_t> sc_instTable = {
|
|||||||
{Opcode::FMNMSUB, {false, InstType::R4_TYPE}},
|
{Opcode::FMNMSUB, {false, InstType::R4_TYPE}},
|
||||||
{Opcode::VSET, {false, InstType::V_TYPE}},
|
{Opcode::VSET, {false, InstType::V_TYPE}},
|
||||||
{Opcode::GPGPU, {false, InstType::R_TYPE}},
|
{Opcode::GPGPU, {false, InstType::R_TYPE}},
|
||||||
|
{Opcode::R_INST_64, {false, InstType::R_TYPE}},
|
||||||
|
{Opcode::I_INST_64, {false, InstType::I_TYPE}},
|
||||||
};
|
};
|
||||||
|
|
||||||
static const char* op_string(const Instr &instr) {
|
static const char* op_string(const Instr &instr) {
|
||||||
@@ -118,6 +120,24 @@ static const char* op_string(const Instr &instr) {
|
|||||||
default:
|
default:
|
||||||
std::abort();
|
std::abort();
|
||||||
}
|
}
|
||||||
|
// 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();
|
||||||
|
}
|
||||||
|
// simx64
|
||||||
|
case Opcode::I_INST_64:
|
||||||
|
switch (func3) {
|
||||||
|
case 0: return "ADDIW";
|
||||||
|
case 1: return "SLLIW";
|
||||||
|
case 5: return func7 ? "SRAIW" : "SRLIW";
|
||||||
|
default:
|
||||||
|
std::abort();
|
||||||
|
}
|
||||||
case Opcode::SYS_INST:
|
case Opcode::SYS_INST:
|
||||||
switch (func3) {
|
switch (func3) {
|
||||||
case 0: return imm ? "EBREAK" : "ECALL";
|
case 0: return imm ? "EBREAK" : "ECALL";
|
||||||
|
|||||||
@@ -205,6 +205,9 @@ void Warp::execute(const Instr &instr, Pipeline *pipeline) {
|
|||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case 1:
|
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.
|
||||||
rddata = rsdata[0] << rsdata[1];
|
rddata = rsdata[0] << rsdata[1];
|
||||||
break;
|
break;
|
||||||
case 2:
|
case 2:
|
||||||
@@ -388,6 +391,71 @@ void Warp::execute(const Instr &instr, Pipeline *pipeline) {
|
|||||||
std::abort();
|
std::abort();
|
||||||
}
|
}
|
||||||
} break;
|
} break;
|
||||||
|
// simx64
|
||||||
|
case R_INST_64: {
|
||||||
|
switch (func3) {
|
||||||
|
case 0:
|
||||||
|
if (func7){
|
||||||
|
// SUBW
|
||||||
|
rddata = DoubleWord(rsdata[0] - rsdata[1]);
|
||||||
|
}
|
||||||
|
else{
|
||||||
|
// ADDW
|
||||||
|
rddata = DoubleWord(rsdata[0] + rsdata[1]);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case 1:
|
||||||
|
// SLLW
|
||||||
|
// shift amount given by rs2[4:0]
|
||||||
|
rddata = DoubleWord(rsdata[0] << rsdata[1]);
|
||||||
|
break;
|
||||||
|
case 5:
|
||||||
|
if (func7) {
|
||||||
|
// SRAW
|
||||||
|
// shift amount given by rs2[4:0]
|
||||||
|
rddata = DoubleWord(WordI(rsdata[0]) >> WordI(rsdata[1]));
|
||||||
|
} else {
|
||||||
|
// SRLW
|
||||||
|
// shift amount given by rs2[4:0]
|
||||||
|
rddata = DoubleWord(Word(rsdata[0]) >> Word(rsdata[1]));
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
std::abort();
|
||||||
|
}
|
||||||
|
} break;
|
||||||
|
// simx64
|
||||||
|
case I_INST_64: {
|
||||||
|
switch (func3) {
|
||||||
|
case 0:
|
||||||
|
// ADDIW
|
||||||
|
rddata = DoubleWord(rsdata[0] + immsrc);
|
||||||
|
break;
|
||||||
|
case 1:
|
||||||
|
// SLLIW
|
||||||
|
// rs1 shifted by lower 5 bits of imm
|
||||||
|
// Illegal exception if imm[5] != 0
|
||||||
|
rddata = DoubleWord(rsdata[0] << immsrc);
|
||||||
|
break;
|
||||||
|
case 5:
|
||||||
|
if (func7) {
|
||||||
|
// SRAI
|
||||||
|
// rs1 shifted by lower 5 bits of imm
|
||||||
|
// Illegal exception if imm[5] != 0
|
||||||
|
Word result = DoubleWord(WordI(rsdata[0]) >> immsrc);
|
||||||
|
rddata = result;
|
||||||
|
} else {
|
||||||
|
// SRLI
|
||||||
|
// rs1 shifted by lower 5 bits of imm
|
||||||
|
// Illegal exception if imm[5] != 0
|
||||||
|
Word result = DoubleWord(Word(rsdata[0]) >> immsrc);
|
||||||
|
rddata = result;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
std::abort();
|
||||||
|
}
|
||||||
|
} break;
|
||||||
case SYS_INST: {
|
case SYS_INST: {
|
||||||
Word csr_addr = immsrc & 0x00000FFF;
|
Word csr_addr = immsrc & 0x00000FFF;
|
||||||
Word csr_value = core_->get_csr(csr_addr, t, id_);
|
Word csr_value = core_->get_csr(csr_addr, t, id_);
|
||||||
|
|||||||
@@ -33,6 +33,10 @@ enum Opcode {
|
|||||||
VS = 0x27,
|
VS = 0x27,
|
||||||
// GPGPU Extension
|
// GPGPU Extension
|
||||||
GPGPU = 0x6b,
|
GPGPU = 0x6b,
|
||||||
|
// simx64
|
||||||
|
// RV64I Extension
|
||||||
|
R_INST_64 = 0x3b,
|
||||||
|
I_INST_64 = 0x1b,
|
||||||
};
|
};
|
||||||
|
|
||||||
enum InstType {
|
enum InstType {
|
||||||
|
|||||||
@@ -12,7 +12,8 @@ typedef int32_t WordI;
|
|||||||
// simx64
|
// simx64
|
||||||
typedef uint64_t DoubleWord;
|
typedef uint64_t DoubleWord;
|
||||||
|
|
||||||
typedef uint32_t Addr;
|
// simx64
|
||||||
|
typedef uint64_t Addr;
|
||||||
typedef uint32_t Size;
|
typedef uint32_t Size;
|
||||||
|
|
||||||
typedef std::bitset<32> RegMask;
|
typedef std::bitset<32> RegMask;
|
||||||
|
|||||||
@@ -13,8 +13,9 @@ using namespace vortex;
|
|||||||
Warp::Warp(Core *core, Word id)
|
Warp::Warp(Core *core, Word id)
|
||||||
: id_(id)
|
: id_(id)
|
||||||
, core_(core) {
|
, core_(core) {
|
||||||
|
// simx64
|
||||||
iRegFile_.resize(core_->arch().num_threads(), std::vector<DoubleWord>(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<Word>(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));
|
vRegFile_.resize(core_->arch().num_regs(), std::vector<Byte>(core_->arch().vsize(), 0));
|
||||||
this->clear();
|
this->clear();
|
||||||
}
|
}
|
||||||
@@ -86,7 +87,8 @@ void Warp::step(Pipeline *pipeline) {
|
|||||||
for (int i = 0; i < core_->arch().num_regs(); ++i) {
|
for (int i = 0; i < core_->arch().num_regs(); ++i) {
|
||||||
DPN(4, " %r" << std::setfill('0') << std::setw(2) << std::dec << i << ':');
|
DPN(4, " %r" << std::setfill('0') << std::setw(2) << std::dec << i << ':');
|
||||||
for (int j = 0; j < core_->arch().num_threads(); ++j) {
|
for (int j = 0; j < core_->arch().num_threads(); ++j) {
|
||||||
DPN(4, ' ' << std::setfill('0') << std::setw(8) << std::hex << iRegFile_[j][i] << std::setfill(' ') << ' ');
|
// simx64
|
||||||
|
DPN(4, ' ' << std::setfill('0') << std::setw(16) << std::hex << iRegFile_[j][i] << std::setfill(' ') << ' ');
|
||||||
}
|
}
|
||||||
DPN(4, std::endl);
|
DPN(4, std::endl);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -100,7 +100,7 @@ private:
|
|||||||
|
|
||||||
// simx64
|
// simx64
|
||||||
std::vector<std::vector<DoubleWord>> iRegFile_;
|
std::vector<std::vector<DoubleWord>> iRegFile_;
|
||||||
std::vector<std::vector<Word>> fRegFile_;
|
std::vector<std::vector<DoubleWord>> fRegFile_;
|
||||||
std::vector<std::vector<Byte>> vRegFile_;
|
std::vector<std::vector<Byte>> vRegFile_;
|
||||||
std::stack<DomStackEntry> domStack_;
|
std::stack<DomStackEntry> domStack_;
|
||||||
|
|
||||||
|
|||||||
@@ -11,10 +11,10 @@ run-simx:
|
|||||||
run-rtlsim:
|
run-rtlsim:
|
||||||
$(MAKE) -C hello run-rtlsim
|
$(MAKE) -C hello run-rtlsim
|
||||||
$(MAKE) -C fibonacci run-rtlsim
|
$(MAKE) -C fibonacci run-rtlsim
|
||||||
$(MAKE) -C simple run-rtlsim
|
$(MAKE) -C simple run-rtlsim
|
||||||
|
|
||||||
clean:
|
clean:
|
||||||
$(MAKE) -C hello clean
|
$(MAKE) -C hello clean
|
||||||
$(MAKE) -C fibonacci clean
|
$(MAKE) -C fibonacci clean
|
||||||
$(MAKE) -C simple clean
|
$(MAKE) -C simple clean
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user