Added support for a few RV64I instructions

This commit is contained in:
Santosh Raghav Srivatsan 2021-11-11 13:35:14 -05:00
parent 9cd8dec397
commit d1892bd6ec
10 changed files with 114 additions and 13 deletions

View file

@ -1,11 +1,14 @@
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
PROJECT = libvortexrt

View file

@ -321,12 +321,14 @@ void Core::barrier(int bar_id, int count, int warp_id) {
barrier.reset();
}
// simx64
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) {
++loads_;
Word data = 0;

View file

@ -66,10 +66,11 @@ public:
void barrier(int bar_id, int count, int warp_id);
// simx64
Word icache_fetch(Addr);
// simx64
Word dcache_read(Addr, Size);
// simx64
void dcache_write(Addr, Word, Size);
void trigger_ebreak();

View file

@ -41,6 +41,8 @@ static const std::unordered_map<int, struct InstTableEntry_t> sc_instTable = {
{Opcode::FMNMSUB, {false, InstType::R4_TYPE}},
{Opcode::VSET, {false, InstType::V_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) {
@ -118,6 +120,24 @@ static const char* op_string(const Instr &instr) {
default:
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:
switch (func3) {
case 0: return imm ? "EBREAK" : "ECALL";

View file

@ -205,6 +205,9 @@ void Warp::execute(const Instr &instr, Pipeline *pipeline) {
}
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.
rddata = rsdata[0] << rsdata[1];
break;
case 2:
@ -388,6 +391,71 @@ void Warp::execute(const Instr &instr, Pipeline *pipeline) {
std::abort();
}
} 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: {
Word csr_addr = immsrc & 0x00000FFF;
Word csr_value = core_->get_csr(csr_addr, t, id_);

View file

@ -33,6 +33,10 @@ enum Opcode {
VS = 0x27,
// GPGPU Extension
GPGPU = 0x6b,
// simx64
// RV64I Extension
R_INST_64 = 0x3b,
I_INST_64 = 0x1b,
};
enum InstType {

View file

@ -12,7 +12,8 @@ typedef int32_t WordI;
// simx64
typedef uint64_t DoubleWord;
typedef uint32_t Addr;
// simx64
typedef uint64_t Addr;
typedef uint32_t Size;
typedef std::bitset<32> RegMask;

View file

@ -13,8 +13,9 @@ using namespace vortex;
Warp::Warp(Core *core, Word id)
: id_(id)
, core_(core) {
// simx64
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));
this->clear();
}
@ -86,7 +87,8 @@ void Warp::step(Pipeline *pipeline) {
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) {
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);
}

View file

@ -100,7 +100,7 @@ private:
// simx64
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::stack<DomStackEntry> domStack_;

View file

@ -11,10 +11,10 @@ run-simx:
run-rtlsim:
$(MAKE) -C hello run-rtlsim
$(MAKE) -C fibonacci run-rtlsim
$(MAKE) -C simple run-rtlsim
$(MAKE) -C simple run-rtlsim
clean:
$(MAKE) -C hello clean
$(MAKE) -C fibonacci clean
$(MAKE) -C simple clean
$(MAKE) -C simple clean