fixed several bugs and refactor memory access
This commit is contained in:
@@ -74,24 +74,27 @@ inline uint64_t bit_getw(uint64_t bits, uint32_t start, uint32_t end) {
|
|||||||
inline uint32_t sext(uint32_t word, uint32_t width) {
|
inline uint32_t sext(uint32_t word, uint32_t width) {
|
||||||
assert(width > 1);
|
assert(width > 1);
|
||||||
assert(width <= 32);
|
assert(width <= 32);
|
||||||
uint64_t unity = 1;
|
if (width == 32)
|
||||||
uint32_t mask = (unity << width) - 1;
|
return word;
|
||||||
|
uint32_t mask = (uint32_t(1) << width) - 1;
|
||||||
return ((word >> (width - 1)) & 0x1) ? (word | ~mask) : word;
|
return ((word >> (width - 1)) & 0x1) ? (word | ~mask) : word;
|
||||||
}
|
}
|
||||||
|
|
||||||
inline uint64_t sext(uint64_t word, uint32_t width) {
|
inline uint64_t sext(uint64_t word, uint32_t width) {
|
||||||
assert(width > 1);
|
assert(width > 1);
|
||||||
assert(width <= 64);
|
assert(width <= 64);
|
||||||
__uint128_t unity = 1;
|
if (width == 64)
|
||||||
uint64_t mask = (unity << width) - 1;
|
return word;
|
||||||
|
uint64_t mask = (uint64_t(1) << width) - 1;
|
||||||
return ((word >> (width - 1)) & 0x1) ? (word | ~mask) : word;
|
return ((word >> (width - 1)) & 0x1) ? (word | ~mask) : word;
|
||||||
}
|
}
|
||||||
|
|
||||||
inline __uint128_t sext(__uint128_t word, uint32_t width) {
|
inline __uint128_t sext(__uint128_t word, uint32_t width) {
|
||||||
assert(width > 1);
|
assert(width > 1);
|
||||||
assert(width <= 64);
|
assert(width <= 128);
|
||||||
__uint128_t unity = 1;
|
if (width == 128)
|
||||||
__uint128_t mask = (unity << width) - 1;
|
return word;
|
||||||
|
__uint128_t mask = (__uint128_t(1) << width) - 1;
|
||||||
return ((word >> (width - 1)) & 0x1) ? (word | ~mask) : word;
|
return ((word >> (width - 1)) & 0x1) ? (word | ~mask) : word;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -226,9 +226,9 @@ void RAM::read(void *data, uint64_t addr, uint64_t size) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void RAM::write(const void *data, uint64_t addr, uint64_t size) {
|
void RAM::write(const void *data, uint64_t addr, uint64_t size) {
|
||||||
const uint8_t* s = (const uint8_t*)data;
|
const uint8_t* d = (const uint8_t*)data;
|
||||||
for (uint64_t i = 0; i < size; i++) {
|
for (uint64_t i = 0; i < size; i++) {
|
||||||
*this->get(addr + i) = s[i];
|
*this->get(addr + i) = d[i];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -19,10 +19,11 @@ uint32_t rv_fsqrt_s(uint32_t a, uint32_t frm, uint32_t* fflags);
|
|||||||
|
|
||||||
uint32_t rv_ftoi_s(uint32_t a, uint32_t frm, uint32_t* fflags);
|
uint32_t rv_ftoi_s(uint32_t a, uint32_t frm, uint32_t* fflags);
|
||||||
uint32_t rv_ftou_s(uint32_t a, uint32_t frm, uint32_t* fflags);
|
uint32_t rv_ftou_s(uint32_t a, uint32_t frm, uint32_t* fflags);
|
||||||
uint64_t rv_ftol_s(uint32_t a, uint32_t frm, uint32_t* fflags);
|
|
||||||
uint64_t rv_ftolu_s(uint32_t a, uint32_t frm, uint32_t* fflags);
|
|
||||||
uint32_t rv_itof_s(uint32_t a, uint32_t frm, uint32_t* fflags);
|
uint32_t rv_itof_s(uint32_t a, uint32_t frm, uint32_t* fflags);
|
||||||
uint32_t rv_utof_s(uint32_t a, uint32_t frm, uint32_t* fflags);
|
uint32_t rv_utof_s(uint32_t a, uint32_t frm, uint32_t* fflags);
|
||||||
|
|
||||||
|
uint64_t rv_ftol_s(uint32_t a, uint32_t frm, uint32_t* fflags);
|
||||||
|
uint64_t rv_ftolu_s(uint32_t a, uint32_t frm, uint32_t* fflags);
|
||||||
uint32_t rv_ltof_s(uint64_t a, uint32_t frm, uint32_t* fflags);
|
uint32_t rv_ltof_s(uint64_t a, uint32_t frm, uint32_t* fflags);
|
||||||
uint32_t rv_lutof_s(uint64_t a, uint32_t frm, uint32_t* fflags);
|
uint32_t rv_lutof_s(uint64_t a, uint32_t frm, uint32_t* fflags);
|
||||||
|
|
||||||
|
|||||||
@@ -400,33 +400,31 @@ WarpMask Core::barrier(uint32_t bar_id, uint32_t count, uint32_t warp_id) {
|
|||||||
return std::move(ret);
|
return std::move(ret);
|
||||||
}
|
}
|
||||||
|
|
||||||
uint32_t Core::icache_read(Addr addr, Size size) {
|
void Core::icache_read(void *data, uint64_t addr, uint32_t size) {
|
||||||
uint32_t data;
|
mmu_.read(data, addr, size, 0);
|
||||||
mmu_.read(&data, addr, size, 0);
|
|
||||||
return data;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Word Core::dcache_read(Addr addr, Size size) {
|
void Core::dcache_read(void *data, uint64_t addr, uint32_t size) {
|
||||||
Word data;
|
|
||||||
auto type = get_addr_type(addr, size);
|
auto type = get_addr_type(addr, size);
|
||||||
if (type == AddrType::Shared) {
|
if (type == AddrType::Shared) {
|
||||||
smem_.read(&data, addr & (SMEM_SIZE-1), size);
|
addr &= (SMEM_SIZE-1);
|
||||||
|
smem_.read(data, addr, size);
|
||||||
} else {
|
} else {
|
||||||
mmu_.read(&data, addr, size, 0);
|
mmu_.read(data, addr, size, 0);
|
||||||
}
|
}
|
||||||
return data;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void Core::dcache_write(Addr addr, Word data, Size size) {
|
void Core::dcache_write(const void* data, uint64_t addr, uint32_t size) {
|
||||||
if (addr >= IO_COUT_ADDR
|
if (addr >= IO_COUT_ADDR
|
||||||
&& addr <= (IO_COUT_ADDR + IO_COUT_SIZE - 1)) {
|
&& addr <= (IO_COUT_ADDR + IO_COUT_SIZE - 1)) {
|
||||||
this->writeToStdOut(addr, data);
|
this->writeToStdOut(data, addr, size);
|
||||||
} else {
|
} else {
|
||||||
auto type = get_addr_type(addr, size);
|
auto type = get_addr_type(addr, size);
|
||||||
if (type == AddrType::Shared) {
|
if (type == AddrType::Shared) {
|
||||||
smem_.write(&data, addr & (SMEM_SIZE-1), size);
|
addr &= (SMEM_SIZE-1);
|
||||||
|
smem_.write(data, addr, size);
|
||||||
} else {
|
} else {
|
||||||
mmu_.write(&data, addr, size, 0);
|
mmu_.write(data, addr, size, 0);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -435,10 +433,12 @@ uint32_t Core::tex_read(uint32_t unit, uint32_t u, uint32_t v, uint32_t lod, std
|
|||||||
return tex_units_.at(unit).read(u, v, lod, mem_addrs);
|
return tex_units_.at(unit).read(u, v, lod, mem_addrs);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Core::writeToStdOut(Addr addr, uint32_t data) {
|
void Core::writeToStdOut(const void* data, uint64_t addr, uint32_t size) {
|
||||||
|
if (size != 1)
|
||||||
|
std::abort();
|
||||||
uint32_t tid = (addr - IO_COUT_ADDR) & (IO_COUT_SIZE-1);
|
uint32_t tid = (addr - IO_COUT_ADDR) & (IO_COUT_SIZE-1);
|
||||||
auto& ss_buf = print_bufs_[tid];
|
auto& ss_buf = print_bufs_[tid];
|
||||||
char c = (char)data;
|
char c = *(char*)data;
|
||||||
ss_buf << c;
|
ss_buf << c;
|
||||||
if (c == '\n') {
|
if (c == '\n') {
|
||||||
std::cout << std::dec << "#" << tid << ": " << ss_buf.str() << std::flush;
|
std::cout << std::dec << "#" << tid << ": " << ss_buf.str() << std::flush;
|
||||||
@@ -446,7 +446,7 @@ void Core::writeToStdOut(Addr addr, uint32_t data) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
uint32_t Core::get_csr(Addr addr, uint32_t tid, uint32_t wid) {
|
uint32_t Core::get_csr(uint32_t addr, uint32_t tid, uint32_t wid) {
|
||||||
switch (addr) {
|
switch (addr) {
|
||||||
case CSR_SATP:
|
case CSR_SATP:
|
||||||
case CSR_PMPCFG0:
|
case CSR_PMPCFG0:
|
||||||
@@ -644,7 +644,7 @@ uint32_t Core::get_csr(Addr addr, uint32_t tid, uint32_t wid) {
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
void Core::set_csr(Addr addr, uint32_t value, uint32_t /*tid*/, uint32_t wid) {
|
void Core::set_csr(uint32_t addr, uint32_t value, uint32_t /*tid*/, uint32_t wid) {
|
||||||
if (addr == CSR_FFLAGS) {
|
if (addr == CSR_FFLAGS) {
|
||||||
fcsrs_.at(wid) = (fcsrs_.at(wid) & ~0x1F) | (value & 0x1F);
|
fcsrs_.at(wid) = (fcsrs_.at(wid) & ~0x1F) | (value & 0x1F);
|
||||||
} else if (addr == CSR_FRM) {
|
} else if (addr == CSR_FRM) {
|
||||||
|
|||||||
@@ -99,19 +99,19 @@ public:
|
|||||||
return warps_.at(0)->getIRegValue(reg);
|
return warps_.at(0)->getIRegValue(reg);
|
||||||
}
|
}
|
||||||
|
|
||||||
uint32_t get_csr(Addr addr, uint32_t tid, uint32_t wid);
|
uint32_t get_csr(uint32_t addr, uint32_t tid, uint32_t wid);
|
||||||
|
|
||||||
void set_csr(Addr addr, uint32_t value, uint32_t tid, uint32_t wid);
|
void set_csr(uint32_t addr, uint32_t value, uint32_t tid, uint32_t wid);
|
||||||
|
|
||||||
WarpMask wspawn(uint32_t num_warps, uint32_t nextPC);
|
WarpMask wspawn(uint32_t num_warps, uint32_t nextPC);
|
||||||
|
|
||||||
WarpMask barrier(uint32_t bar_id, uint32_t count, uint32_t warp_id);
|
WarpMask barrier(uint32_t bar_id, uint32_t count, uint32_t warp_id);
|
||||||
|
|
||||||
uint32_t icache_read(Addr, Size);
|
void icache_read(void* data, uint64_t addr, uint32_t size);
|
||||||
|
|
||||||
Word dcache_read(Addr, Size);
|
void dcache_read(void* data, uint64_t addr, uint32_t size);
|
||||||
|
|
||||||
void dcache_write(Addr, Word, Size);
|
void dcache_write(const void* data, uint64_t addr, uint32_t size);
|
||||||
|
|
||||||
uint32_t tex_read(uint32_t unit, uint32_t lod, uint32_t u, uint32_t v, std::vector<mem_addr_size_t>* mem_addrs);
|
uint32_t tex_read(uint32_t unit, uint32_t lod, uint32_t u, uint32_t v, std::vector<mem_addr_size_t>* mem_addrs);
|
||||||
|
|
||||||
@@ -129,7 +129,7 @@ private:
|
|||||||
void execute();
|
void execute();
|
||||||
void commit();
|
void commit();
|
||||||
|
|
||||||
void writeToStdOut(Addr addr, uint32_t data);
|
void writeToStdOut(const void* data, uint64_t addr, uint32_t size);
|
||||||
|
|
||||||
void cout_flush();
|
void cout_flush();
|
||||||
|
|
||||||
|
|||||||
@@ -19,7 +19,7 @@ struct InstTableEntry_t {
|
|||||||
InstType iType;
|
InstType iType;
|
||||||
};
|
};
|
||||||
|
|
||||||
static const std::unordered_map<int, struct InstTableEntry_t> sc_instTable = {
|
static const std::unordered_map<Opcode, struct InstTableEntry_t> sc_instTable = {
|
||||||
{Opcode::NOP, {false, InstType::N_TYPE}},
|
{Opcode::NOP, {false, InstType::N_TYPE}},
|
||||||
{Opcode::R_INST, {false, InstType::R_TYPE}},
|
{Opcode::R_INST, {false, InstType::R_TYPE}},
|
||||||
{Opcode::L_INST, {false, InstType::I_TYPE}},
|
{Opcode::L_INST, {false, InstType::I_TYPE}},
|
||||||
@@ -42,17 +42,54 @@ static const std::unordered_map<int, struct InstTableEntry_t> sc_instTable = {
|
|||||||
{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::GPU, {false, InstType::R4_TYPE}},
|
{Opcode::GPU, {false, InstType::R4_TYPE}},
|
||||||
{Opcode::R_INST_64, {false, InstType::R_TYPE}},
|
{Opcode::R_INST_W, {false, InstType::R_TYPE}},
|
||||||
{Opcode::I_INST_64, {false, InstType::I_TYPE}},
|
{Opcode::I_INST_W, {false, InstType::I_TYPE}},
|
||||||
|
};
|
||||||
|
|
||||||
|
enum Constants {
|
||||||
|
width_opcode= 7,
|
||||||
|
width_reg = 5,
|
||||||
|
width_func2 = 2,
|
||||||
|
width_func3 = 3,
|
||||||
|
width_func6 = 6,
|
||||||
|
width_func7 = 7,
|
||||||
|
width_mop = 3,
|
||||||
|
width_vmask = 1,
|
||||||
|
width_i_imm = 12,
|
||||||
|
width_j_imm = 20,
|
||||||
|
width_v_imm = 11,
|
||||||
|
|
||||||
|
shift_opcode= 0,
|
||||||
|
shift_rd = width_opcode,
|
||||||
|
shift_func3 = shift_rd + width_reg,
|
||||||
|
shift_rs1 = shift_func3 + width_func3,
|
||||||
|
shift_rs2 = shift_rs1 + width_reg,
|
||||||
|
shift_func2 = shift_rs2 + width_reg,
|
||||||
|
shift_func7 = shift_rs2 + width_reg,
|
||||||
|
shift_rs3 = shift_func7 + width_func2,
|
||||||
|
shift_vmop = shift_func7 + width_vmask,
|
||||||
|
shift_vnf = shift_vmop + width_mop,
|
||||||
|
shift_func6 = shift_func7 + width_vmask,
|
||||||
|
shift_vset = shift_func7 + width_func6,
|
||||||
|
|
||||||
|
mask_opcode = (1<<width_opcode)-1,
|
||||||
|
mask_reg = (1<<width_reg)-1,
|
||||||
|
mask_func2 = (1<<width_func2)-1,
|
||||||
|
mask_func3 = (1<<width_func3)-1,
|
||||||
|
mask_func6 = (1<<width_func6)-1,
|
||||||
|
mask_func7 = (1<<width_func7)-1,
|
||||||
|
mask_i_imm = (1<<width_i_imm)-1,
|
||||||
|
mask_j_imm = (1<<width_j_imm)-1,
|
||||||
|
mask_v_imm = (1<<width_v_imm)-1,
|
||||||
};
|
};
|
||||||
|
|
||||||
static const char* op_string(const Instr &instr) {
|
static const char* op_string(const Instr &instr) {
|
||||||
auto opcode = instr.getOpcode();
|
auto opcode = instr.getOpcode();
|
||||||
uint32_t func2 = instr.getFunc2();
|
auto func2 = instr.getFunc2();
|
||||||
uint32_t func3 = instr.getFunc3();
|
auto func3 = instr.getFunc3();
|
||||||
uint32_t func7 = instr.getFunc7();
|
auto func7 = instr.getFunc7();
|
||||||
uint32_t rs2 = instr.getRSrc(1);
|
auto rs2 = instr.getRSrc(1);
|
||||||
Word imm = instr.getImm();
|
auto imm = instr.getImm();
|
||||||
|
|
||||||
switch (opcode) {
|
switch (opcode) {
|
||||||
case Opcode::NOP: return "NOP";
|
case Opcode::NOP: return "NOP";
|
||||||
@@ -127,7 +164,7 @@ static const char* op_string(const Instr &instr) {
|
|||||||
default:
|
default:
|
||||||
std::abort();
|
std::abort();
|
||||||
}
|
}
|
||||||
case Opcode::R_INST_64:
|
case Opcode::R_INST_W:
|
||||||
if (func7 & 0x1){
|
if (func7 & 0x1){
|
||||||
switch (func3) {
|
switch (func3) {
|
||||||
case 0: return "MULW";
|
case 0: return "MULW";
|
||||||
@@ -147,7 +184,7 @@ static const char* op_string(const Instr &instr) {
|
|||||||
std::abort();
|
std::abort();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
case Opcode::I_INST_64:
|
case Opcode::I_INST_W:
|
||||||
switch (func3) {
|
switch (func3) {
|
||||||
case 0: return "ADDIW";
|
case 0: return "ADDIW";
|
||||||
case 1: return "SLLIW";
|
case 1: return "SLLIW";
|
||||||
@@ -333,8 +370,8 @@ static const char* op_string(const Instr &instr) {
|
|||||||
namespace vortex {
|
namespace vortex {
|
||||||
std::ostream &operator<<(std::ostream &os, const Instr &instr) {
|
std::ostream &operator<<(std::ostream &os, const Instr &instr) {
|
||||||
auto opcode = instr.getOpcode();
|
auto opcode = instr.getOpcode();
|
||||||
uint32_t func2 = instr.getFunc2();
|
auto func2 = instr.getFunc2();
|
||||||
uint32_t func3 = instr.getFunc3();
|
auto func3 = instr.getFunc3();
|
||||||
|
|
||||||
os << op_string(instr) << ": ";
|
os << op_string(instr) << ": ";
|
||||||
|
|
||||||
@@ -368,56 +405,22 @@ std::ostream &operator<<(std::ostream &os, const Instr &instr) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Decoder::Decoder(const ArchDef &arch) {
|
Decoder::Decoder(const ArchDef&) {}
|
||||||
inst_s_ = arch.wsize() * 8;
|
|
||||||
opcode_s_ = 7;
|
|
||||||
reg_s_ = 5;
|
|
||||||
func2_s_ = 2;
|
|
||||||
func3_s_ = 3;
|
|
||||||
mop_s_ = 3;
|
|
||||||
vmask_s_ = 1;
|
|
||||||
|
|
||||||
shift_opcode_ = 0;
|
|
||||||
shift_rd_ = opcode_s_;
|
|
||||||
shift_func3_ = shift_rd_ + reg_s_;
|
|
||||||
shift_rs1_ = shift_func3_ + func3_s_;
|
|
||||||
shift_rs2_ = shift_rs1_ + reg_s_;
|
|
||||||
shift_func2_ = shift_rs2_ + reg_s_;
|
|
||||||
shift_func7_ = shift_rs2_ + reg_s_;
|
|
||||||
shift_rs3_ = shift_func7_ + func2_s_;
|
|
||||||
shift_vmop_ = shift_func7_ + vmask_s_;
|
|
||||||
shift_vnf_ = shift_vmop_ + mop_s_;
|
|
||||||
shift_func6_ = shift_func7_ + 1;
|
|
||||||
shift_vset_ = shift_func7_ + 6;
|
|
||||||
|
|
||||||
reg_mask_ = 0x1f;
|
|
||||||
func2_mask_ = 0x3;
|
|
||||||
func3_mask_ = 0x7;
|
|
||||||
func6_mask_ = 0x3f;
|
|
||||||
func7_mask_ = 0x7f;
|
|
||||||
opcode_mask_ = 0x7f;
|
|
||||||
i_imm_mask_ = 0xfff;
|
|
||||||
s_imm_mask_ = 0xfff;
|
|
||||||
b_imm_mask_ = 0x1fff;
|
|
||||||
u_imm_mask_ = 0xfffff;
|
|
||||||
j_imm_mask_ = 0xfffff;
|
|
||||||
v_imm_mask_ = 0x7ff;
|
|
||||||
}
|
|
||||||
|
|
||||||
std::shared_ptr<Instr> Decoder::decode(uint32_t code) const {
|
std::shared_ptr<Instr> Decoder::decode(uint32_t code) const {
|
||||||
auto instr = std::make_shared<Instr>();
|
auto instr = std::make_shared<Instr>();
|
||||||
Opcode op = (Opcode)((code >> shift_opcode_) & opcode_mask_);
|
auto op = Opcode((code >> shift_opcode) & mask_opcode);
|
||||||
instr->setOpcode(op);
|
instr->setOpcode(op);
|
||||||
|
|
||||||
uint32_t func2 = (code >> shift_func2_) & func2_mask_;
|
auto func2 = (code >> shift_func2) & mask_func2;
|
||||||
uint32_t func3 = (code >> shift_func3_) & func3_mask_;
|
auto func3 = (code >> shift_func3) & mask_func3;
|
||||||
uint32_t func6 = (code >> shift_func6_) & func6_mask_;
|
auto func6 = (code >> shift_func6) & mask_func6;
|
||||||
uint32_t func7 = (code >> shift_func7_) & func7_mask_;
|
auto func7 = (code >> shift_func7) & mask_func7;
|
||||||
|
|
||||||
int rd = (code >> shift_rd_) & reg_mask_;
|
auto rd = (code >> shift_rd) & mask_reg;
|
||||||
int rs1 = (code >> shift_rs1_) & reg_mask_;
|
auto rs1 = (code >> shift_rs1) & mask_reg;
|
||||||
int rs2 = (code >> shift_rs2_) & reg_mask_;
|
auto rs2 = (code >> shift_rs2) & mask_reg;
|
||||||
int rs3 = (code >> shift_rs3_) & reg_mask_;
|
auto rs3 = (code >> shift_rs3) & mask_reg;
|
||||||
|
|
||||||
auto op_it = sc_instTable.find(op);
|
auto op_it = sc_instTable.find(op);
|
||||||
if (op_it == sc_instTable.end()) {
|
if (op_it == sc_instTable.end()) {
|
||||||
@@ -439,43 +442,43 @@ std::shared_ptr<Instr> Decoder::decode(uint32_t code) const {
|
|||||||
case InstType::R_TYPE:
|
case InstType::R_TYPE:
|
||||||
if (op == Opcode::FCI) {
|
if (op == Opcode::FCI) {
|
||||||
switch (func7) {
|
switch (func7) {
|
||||||
|
case 0x50: // FLE.S, FLT.S, FEQ.S
|
||||||
|
case 0x51: // FLE.D, FLT.D, FEQ.D
|
||||||
|
case 0x60: // FCVT.W.D, FCVT.WU.D, FCVT.L.D, FCVT.LU.D
|
||||||
|
case 0x61: // FCVT.WU.S, FCVT.W.S, FCVT.L.S, FCVT.LU.S
|
||||||
|
case 0x70: // FCLASS.S, FMV.X.W
|
||||||
|
case 0x71: // FCLASS.D, FMV.X.D
|
||||||
|
instr->setDestReg(rd, RegType::Integer);
|
||||||
|
instr->setSrcReg(rs1, RegType::Float);
|
||||||
|
break;
|
||||||
case 0x68: // FCVT.S.W, FCVT.S.WU, FCVT.S.L, FCVT.S.LU
|
case 0x68: // FCVT.S.W, FCVT.S.WU, FCVT.S.L, FCVT.S.LU
|
||||||
case 0x69: // FCVT.D.W, FCVT.D.WU, FCVT.D.L, FCVT.D.LU
|
case 0x69: // FCVT.D.W, FCVT.D.WU, FCVT.D.L, FCVT.D.LU
|
||||||
case 0x78: // FMV.W.X
|
case 0x78: // FMV.W.X
|
||||||
case 0x79: // FMV.D.X
|
case 0x79: // FMV.D.X
|
||||||
instr->setSrcReg(rs1);
|
instr->setDestReg(rd, RegType::Float);
|
||||||
|
instr->setSrcReg(rs1, RegType::Integer);
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
instr->setSrcFReg(rs1);
|
instr->setDestReg(rd, RegType::Float);
|
||||||
}
|
instr->setSrcReg(rs1, RegType::Float);
|
||||||
instr->setSrcFReg(rs2);
|
instr->setSrcReg(rs2, RegType::Float);
|
||||||
switch (func7) {
|
|
||||||
case 0x50: // FLE.S, FLT.S, FEQ.S
|
|
||||||
case 0x51: // FLE.D, FLT.D, FEQ.D
|
|
||||||
case 0x60: // FCVT.WU.S, FCVT.W.S, FCVT.L.S, FCVT.LU.S
|
|
||||||
case 0x61: // FCVT.W.D, FCVT.WU.D, FCVT.L.D, FCVT.LU.D
|
|
||||||
case 0x70: // FLASS.S, FMV.X.W
|
|
||||||
case 0x71: // FCLASS.D, FMV.X.D
|
|
||||||
instr->setDestReg(rd);
|
|
||||||
break;
|
break;
|
||||||
default:
|
|
||||||
instr->setDestFReg(rd);
|
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
instr->setDestReg(rd);
|
instr->setDestReg(rd, RegType::Integer);
|
||||||
instr->setSrcReg(rs1);
|
instr->setSrcReg(rs1, RegType::Integer);
|
||||||
instr->setSrcReg(rs2);
|
instr->setSrcReg(rs2, RegType::Integer);
|
||||||
}
|
}
|
||||||
instr->setFunc3(func3);
|
instr->setFunc3(func3);
|
||||||
instr->setFunc7(func7);
|
instr->setFunc7(func7);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case InstType::I_TYPE: {
|
case InstType::I_TYPE: {
|
||||||
instr->setSrcReg(rs1);
|
instr->setSrcReg(rs1, RegType::Integer);
|
||||||
if (op == Opcode::FL) {
|
if (op == Opcode::FL) {
|
||||||
instr->setDestFReg(rd);
|
instr->setDestReg(rd, RegType::Float);
|
||||||
} else {
|
} else {
|
||||||
instr->setDestReg(rd);
|
instr->setDestReg(rd, RegType::Integer);
|
||||||
}
|
}
|
||||||
instr->setFunc3(func3);
|
instr->setFunc3(func3);
|
||||||
instr->setFunc7(func7);
|
instr->setFunc7(func7);
|
||||||
@@ -483,80 +486,71 @@ std::shared_ptr<Instr> Decoder::decode(uint32_t code) const {
|
|||||||
case Opcode::SYS_INST:
|
case Opcode::SYS_INST:
|
||||||
case Opcode::FENCE:
|
case Opcode::FENCE:
|
||||||
// uint12
|
// uint12
|
||||||
instr->setImm(code >> shift_rs2_);
|
instr->setImm(code >> shift_rs2);
|
||||||
break;
|
break;
|
||||||
case Opcode::I_INST:
|
case Opcode::I_INST:
|
||||||
|
case Opcode::I_INST_W:
|
||||||
if (func3 == 0x1 || func3 == 0x5) {
|
if (func3 == 0x1 || func3 == 0x5) {
|
||||||
// int5 (XLEN = 32) / int6 (XLEN = 64)
|
auto shamt = rs2; // uint5
|
||||||
Word shamt_mask = ((Word)1 << log2up(XLEN)) - 1;
|
#if (XLEN == 64)
|
||||||
Word shamt = (((func7 & 0x1) << 5) | rs2) & shamt_mask;
|
if (op == Opcode::I_INST) {
|
||||||
|
// uint6
|
||||||
|
shamt |= ((func7 & 0x1) << 5);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
instr->setImm(shamt);
|
instr->setImm(shamt);
|
||||||
} else {
|
} else {
|
||||||
// int12
|
// int12
|
||||||
Word imm = code >> shift_rs2_;
|
auto imm = code >> shift_rs2;
|
||||||
instr->setImm(sext(imm, 12));
|
instr->setImm(sext(imm, width_i_imm));
|
||||||
}
|
|
||||||
break;
|
|
||||||
case Opcode::I_INST_64:
|
|
||||||
if (func3 == 0x1 || func3 == 0x5) {
|
|
||||||
// int5
|
|
||||||
Word shamt = rs2;
|
|
||||||
instr->setImm(shamt);
|
|
||||||
} else {
|
|
||||||
// int12
|
|
||||||
Word imm = code >> shift_rs2_;
|
|
||||||
instr->setImm(sext(imm, 12));
|
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
// int12
|
// int12
|
||||||
Word imm = code >> shift_rs2_;
|
auto imm = code >> shift_rs2;
|
||||||
instr->setImm(sext(imm, 12));
|
instr->setImm(sext(imm, width_i_imm));
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
} break;
|
} break;
|
||||||
case InstType::S_TYPE: {
|
case InstType::S_TYPE: {
|
||||||
instr->setSrcReg(rs1);
|
instr->setSrcReg(rs1, RegType::Integer);
|
||||||
if (op == Opcode::FS) {
|
if (op == Opcode::FS) {
|
||||||
instr->setSrcFReg(rs2);
|
instr->setSrcReg(rs2, RegType::Float);
|
||||||
} else {
|
} else {
|
||||||
instr->setSrcReg(rs2);
|
instr->setSrcReg(rs2, RegType::Integer);
|
||||||
}
|
}
|
||||||
instr->setFunc3(func3);
|
instr->setFunc3(func3);
|
||||||
Word imm = (func7 << reg_s_) | rd;
|
auto imm = (func7 << width_reg) | rd;
|
||||||
instr->setImm(sext(imm, 12));
|
instr->setImm(sext(imm, width_i_imm));
|
||||||
} break;
|
} break;
|
||||||
|
|
||||||
case InstType::B_TYPE: {
|
case InstType::B_TYPE: {
|
||||||
instr->setSrcReg(rs1);
|
instr->setSrcReg(rs1, RegType::Integer);
|
||||||
instr->setSrcReg(rs2);
|
instr->setSrcReg(rs2, RegType::Integer);
|
||||||
instr->setFunc3(func3);
|
instr->setFunc3(func3);
|
||||||
uint32_t bit_11 = rd & 0x1;
|
auto bit_11 = rd & 0x1;
|
||||||
uint32_t bits_4_1 = rd >> 1;
|
auto bits_4_1 = rd >> 1;
|
||||||
uint32_t bit_10_5 = func7 & 0x3f;
|
auto bit_10_5 = func7 & 0x3f;
|
||||||
uint32_t bit_12 = func7 >> 6;
|
auto bit_12 = func7 >> 6;
|
||||||
Word imm = (bits_4_1 << 1) | (bit_10_5 << 5) | (bit_11 << 11) | (bit_12 << 12);
|
auto imm = (bits_4_1 << 1) | (bit_10_5 << 5) | (bit_11 << 11) | (bit_12 << 12);
|
||||||
instr->setImm(sext(imm, 13));
|
instr->setImm(sext(imm, width_i_imm+1));
|
||||||
} break;
|
} break;
|
||||||
|
|
||||||
case InstType::U_TYPE: {
|
case InstType::U_TYPE: {
|
||||||
instr->setDestReg(rd);
|
instr->setDestReg(rd, RegType::Integer);
|
||||||
Word imm = code >> shift_func3_;
|
auto imm = code >> shift_func3;
|
||||||
instr->setImm(sext(imm, 20));
|
instr->setImm(sext(imm, width_j_imm));
|
||||||
} break;
|
} break;
|
||||||
|
|
||||||
case InstType::J_TYPE: {
|
case InstType::J_TYPE: {
|
||||||
instr->setDestReg(rd);
|
instr->setDestReg(rd, RegType::Integer);
|
||||||
uint32_t unordered = code >> shift_func3_;
|
auto unordered = code >> shift_func3;
|
||||||
uint32_t bits_19_12 = unordered & 0xff;
|
auto bits_19_12 = unordered & 0xff;
|
||||||
uint32_t bit_11 = (unordered >> 8) & 0x1;
|
auto bit_11 = (unordered >> 8) & 0x1;
|
||||||
uint32_t bits_10_1 = (unordered >> 9) & 0x3ff;
|
auto bits_10_1 = (unordered >> 9) & 0x3ff;
|
||||||
uint32_t bit_20 = (unordered >> 19) & 0x1;
|
auto bit_20 = (unordered >> 19) & 0x1;
|
||||||
Word imm = (bits_10_1 << 1) | (bit_11 << 11) | (bits_19_12 << 12) | (bit_20 << 20);
|
auto imm = (bits_10_1 << 1) | (bit_11 << 11) | (bits_19_12 << 12) | (bit_20 << 20);
|
||||||
if (bit_20) {
|
instr->setImm(sext(imm, width_j_imm+1));
|
||||||
imm |= ~j_imm_mask_;
|
|
||||||
}
|
|
||||||
instr->setImm(imm);
|
|
||||||
} break;
|
} break;
|
||||||
|
|
||||||
case InstType::V_TYPE:
|
case InstType::V_TYPE:
|
||||||
@@ -566,9 +560,9 @@ std::shared_ptr<Instr> Decoder::decode(uint32_t code) const {
|
|||||||
instr->setSrcVReg(rs1);
|
instr->setSrcVReg(rs1);
|
||||||
instr->setFunc3(func3);
|
instr->setFunc3(func3);
|
||||||
if (func3 == 7) {
|
if (func3 == 7) {
|
||||||
instr->setImm(!(code >> shift_vset_));
|
instr->setImm(!(code >> shift_vset));
|
||||||
if (instr->getImm()) {
|
if (instr->getImm()) {
|
||||||
uint32_t immed = (code >> shift_rs2_) & v_imm_mask_;
|
auto immed = (code >> shift_rs2) & mask_v_imm;
|
||||||
instr->setImm(immed);
|
instr->setImm(immed);
|
||||||
instr->setVlmul(immed & 0x3);
|
instr->setVlmul(immed & 0x3);
|
||||||
instr->setVediv((immed >> 4) & 0x3);
|
instr->setVediv((immed >> 4) & 0x3);
|
||||||
@@ -578,7 +572,7 @@ std::shared_ptr<Instr> Decoder::decode(uint32_t code) const {
|
|||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
instr->setSrcVReg(rs2);
|
instr->setSrcVReg(rs2);
|
||||||
instr->setVmask((code >> shift_func7_) & 0x1);
|
instr->setVmask((code >> shift_func7) & 0x1);
|
||||||
instr->setFunc6(func6);
|
instr->setFunc6(func6);
|
||||||
}
|
}
|
||||||
} break;
|
} break;
|
||||||
@@ -588,9 +582,9 @@ std::shared_ptr<Instr> Decoder::decode(uint32_t code) const {
|
|||||||
instr->setSrcVReg(rs1);
|
instr->setSrcVReg(rs1);
|
||||||
instr->setVlsWidth(func3);
|
instr->setVlsWidth(func3);
|
||||||
instr->setSrcVReg(rs2);
|
instr->setSrcVReg(rs2);
|
||||||
instr->setVmask(code >> shift_func7_);
|
instr->setVmask(code >> shift_func7);
|
||||||
instr->setVmop((code >> shift_vmop_) & func3_mask_);
|
instr->setVmop((code >> shift_vmop) & mask_func3);
|
||||||
instr->setVnf((code >> shift_vnf_) & func3_mask_);
|
instr->setVnf((code >> shift_vnf) & mask_func3);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case Opcode::FS:
|
case Opcode::FS:
|
||||||
@@ -598,9 +592,9 @@ std::shared_ptr<Instr> Decoder::decode(uint32_t code) const {
|
|||||||
instr->setSrcVReg(rs1);
|
instr->setSrcVReg(rs1);
|
||||||
instr->setVlsWidth(func3);
|
instr->setVlsWidth(func3);
|
||||||
instr->setSrcVReg(rs2);
|
instr->setSrcVReg(rs2);
|
||||||
instr->setVmask(code >> shift_func7_);
|
instr->setVmask(code >> shift_func7);
|
||||||
instr->setVmop((code >> shift_vmop_) & func3_mask_);
|
instr->setVmop((code >> shift_vmop) & mask_func3);
|
||||||
instr->setVnf((code >> shift_vnf_) & func3_mask_);
|
instr->setVnf((code >> shift_vnf) & mask_func3);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
@@ -609,15 +603,15 @@ std::shared_ptr<Instr> Decoder::decode(uint32_t code) const {
|
|||||||
break;
|
break;
|
||||||
case R4_TYPE:
|
case R4_TYPE:
|
||||||
if (op == Opcode::GPU) {
|
if (op == Opcode::GPU) {
|
||||||
instr->setDestReg(rd);
|
instr->setDestReg(rd, RegType::Integer);
|
||||||
instr->setSrcReg(rs1);
|
instr->setSrcReg(rs1, RegType::Integer);
|
||||||
instr->setSrcReg(rs2);
|
instr->setSrcReg(rs2, RegType::Integer);
|
||||||
instr->setSrcReg(rs3);
|
instr->setSrcReg(rs3, RegType::Integer);
|
||||||
} else {
|
} else {
|
||||||
instr->setDestFReg(rd);
|
instr->setDestReg(rd, RegType::Float);
|
||||||
instr->setSrcFReg(rs1);
|
instr->setSrcReg(rs1, RegType::Float);
|
||||||
instr->setSrcFReg(rs2);
|
instr->setSrcReg(rs2, RegType::Float);
|
||||||
instr->setSrcFReg(rs3);
|
instr->setSrcReg(rs3, RegType::Float);
|
||||||
}
|
}
|
||||||
instr->setFunc2(func2);
|
instr->setFunc2(func2);
|
||||||
instr->setFunc3(func3);
|
instr->setFunc3(func3);
|
||||||
|
|||||||
@@ -7,55 +7,12 @@ namespace vortex {
|
|||||||
|
|
||||||
class ArchDef;
|
class ArchDef;
|
||||||
class Instr;
|
class Instr;
|
||||||
class Pipeline;
|
|
||||||
|
|
||||||
class Decoder {
|
class Decoder {
|
||||||
public:
|
public:
|
||||||
Decoder(const ArchDef &);
|
Decoder(const ArchDef &);
|
||||||
|
|
||||||
std::shared_ptr<Instr> decode(uint32_t code) const;
|
std::shared_ptr<Instr> decode(uint32_t code) const;
|
||||||
|
|
||||||
private:
|
|
||||||
|
|
||||||
uint32_t inst_s_;
|
|
||||||
uint32_t opcode_s_;
|
|
||||||
uint32_t reg_s_;
|
|
||||||
uint32_t func2_s_;
|
|
||||||
uint32_t func3_s_;
|
|
||||||
uint32_t shift_opcode_;
|
|
||||||
uint32_t shift_rd_;
|
|
||||||
uint32_t shift_rs1_;
|
|
||||||
uint32_t shift_rs2_;
|
|
||||||
uint32_t shift_rs3_;
|
|
||||||
uint32_t shift_func2_;
|
|
||||||
uint32_t shift_func3_;
|
|
||||||
uint32_t shift_func7_;
|
|
||||||
uint32_t shift_j_u_immed_;
|
|
||||||
uint32_t shift_s_b_immed_;
|
|
||||||
uint32_t shift_i_immed_;
|
|
||||||
|
|
||||||
uint32_t reg_mask_;
|
|
||||||
uint32_t func2_mask_;
|
|
||||||
uint32_t func3_mask_;
|
|
||||||
uint32_t func6_mask_;
|
|
||||||
uint32_t func7_mask_;
|
|
||||||
uint32_t opcode_mask_;
|
|
||||||
uint32_t i_imm_mask_;
|
|
||||||
uint32_t s_imm_mask_;
|
|
||||||
uint32_t b_imm_mask_;
|
|
||||||
uint32_t u_imm_mask_;
|
|
||||||
uint32_t j_imm_mask_;
|
|
||||||
uint32_t v_imm_mask_;
|
|
||||||
|
|
||||||
//Vector
|
|
||||||
uint32_t shift_vset_;
|
|
||||||
uint32_t shift_vset_immed_;
|
|
||||||
uint32_t shift_vmask_;
|
|
||||||
uint32_t shift_vmop_;
|
|
||||||
uint32_t shift_vnf_;
|
|
||||||
uint32_t shift_func6_;
|
|
||||||
uint32_t vmask_s_;
|
|
||||||
uint32_t mop_s_;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
}
|
}
|
||||||
File diff suppressed because it is too large
Load Diff
@@ -33,8 +33,8 @@ enum Opcode {
|
|||||||
GPGPU = 0x6b,
|
GPGPU = 0x6b,
|
||||||
GPU = 0x5b,
|
GPU = 0x5b,
|
||||||
// RV64 Standard Extensions
|
// RV64 Standard Extensions
|
||||||
R_INST_64 = 0x3b,
|
R_INST_W = 0x3b,
|
||||||
I_INST_64 = 0x1b,
|
I_INST_W = 0x1b,
|
||||||
};
|
};
|
||||||
|
|
||||||
enum InstType {
|
enum InstType {
|
||||||
@@ -64,18 +64,15 @@ public:
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Setters used to "craft" the instruction. */
|
|
||||||
void setOpcode(Opcode opcode) { opcode_ = opcode; }
|
void setOpcode(Opcode opcode) { opcode_ = opcode; }
|
||||||
void setDestReg(uint32_t destReg) { rdest_type_ = RegType::Integer; rdest_ = destReg; }
|
void setDestReg(uint32_t destReg, RegType type) { rdest_type_ = type; rdest_ = destReg; }
|
||||||
void setSrcReg(uint32_t srcReg) { rsrc_type_[num_rsrcs_] = RegType::Integer; rsrc_[num_rsrcs_++] = srcReg; }
|
void setSrcReg(uint32_t srcReg, RegType type) { rsrc_type_[num_rsrcs_] = type; rsrc_[num_rsrcs_++] = srcReg; }
|
||||||
void setDestFReg(uint32_t destReg) { rdest_type_ = RegType::Float; rdest_ = destReg; }
|
|
||||||
void setSrcFReg(uint32_t srcReg) { rsrc_type_[num_rsrcs_] = RegType::Float; rsrc_[num_rsrcs_++] = srcReg; }
|
|
||||||
void setDestVReg(uint32_t destReg) { rdest_type_ = RegType::Vector; rdest_ = destReg; }
|
void setDestVReg(uint32_t destReg) { rdest_type_ = RegType::Vector; rdest_ = destReg; }
|
||||||
void setSrcVReg(uint32_t srcReg) { rsrc_type_[num_rsrcs_] = RegType::Vector; rsrc_[num_rsrcs_++] = srcReg; }
|
void setSrcVReg(uint32_t srcReg) { rsrc_type_[num_rsrcs_] = RegType::Vector; rsrc_[num_rsrcs_++] = srcReg; }
|
||||||
void setFunc2(uint32_t func2) { func2_ = func2; }
|
void setFunc2(uint32_t func2) { func2_ = func2; }
|
||||||
void setFunc3(uint32_t func3) { func3_ = func3; }
|
void setFunc3(uint32_t func3) { func3_ = func3; }
|
||||||
void setFunc7(uint32_t func7) { func7_ = func7; }
|
void setFunc7(uint32_t func7) { func7_ = func7; }
|
||||||
void setImm(Word imm) { has_imm_ = true; imm_ = imm; }
|
void setImm(uint32_t imm) { has_imm_ = true; imm_ = imm; }
|
||||||
void setVlsWidth(uint32_t width) { vlsWidth_ = width; }
|
void setVlsWidth(uint32_t width) { vlsWidth_ = width; }
|
||||||
void setVmop(uint32_t mop) { vMop_ = mop; }
|
void setVmop(uint32_t mop) { vMop_ = mop; }
|
||||||
void setVnf(uint32_t nf) { vNf_ = nf; }
|
void setVnf(uint32_t nf) { vNf_ = nf; }
|
||||||
@@ -86,8 +83,6 @@ public:
|
|||||||
void setVediv(uint32_t ediv) { vediv_ = 1 << ediv; }
|
void setVediv(uint32_t ediv) { vediv_ = 1 << ediv; }
|
||||||
void setFunc6(uint32_t func6) { func6_ = func6; }
|
void setFunc6(uint32_t func6) { func6_ = func6; }
|
||||||
|
|
||||||
/* Getters used by encoders. */
|
|
||||||
// uint32_t -> uint32
|
|
||||||
Opcode getOpcode() const { return opcode_; }
|
Opcode getOpcode() const { return opcode_; }
|
||||||
uint32_t getFunc2() const { return func2_; }
|
uint32_t getFunc2() const { return func2_; }
|
||||||
uint32_t getFunc3() const { return func3_; }
|
uint32_t getFunc3() const { return func3_; }
|
||||||
@@ -99,7 +94,7 @@ public:
|
|||||||
uint32_t getRDest() const { return rdest_; }
|
uint32_t getRDest() const { return rdest_; }
|
||||||
RegType getRDType() const { return rdest_type_; }
|
RegType getRDType() const { return rdest_type_; }
|
||||||
bool hasImm() const { return has_imm_; }
|
bool hasImm() const { return has_imm_; }
|
||||||
Word getImm() const { return imm_; }
|
uint32_t getImm() const { return imm_; }
|
||||||
uint32_t getVlsWidth() const { return vlsWidth_; }
|
uint32_t getVlsWidth() const { return vlsWidth_; }
|
||||||
uint32_t getVmop() const { return vMop_; }
|
uint32_t getVmop() const { return vMop_; }
|
||||||
uint32_t getvNf() const { return vNf_; }
|
uint32_t getvNf() const { return vNf_; }
|
||||||
@@ -119,7 +114,7 @@ private:
|
|||||||
uint32_t num_rsrcs_;
|
uint32_t num_rsrcs_;
|
||||||
bool has_imm_;
|
bool has_imm_;
|
||||||
RegType rdest_type_;
|
RegType rdest_type_;
|
||||||
Word imm_;
|
uint32_t imm_;
|
||||||
RegType rsrc_type_[MAX_REG_SOURCES];
|
RegType rsrc_type_[MAX_REG_SOURCES];
|
||||||
uint32_t rsrc_[MAX_REG_SOURCES];
|
uint32_t rsrc_[MAX_REG_SOURCES];
|
||||||
uint32_t rdest_;
|
uint32_t rdest_;
|
||||||
|
|||||||
@@ -26,14 +26,14 @@ int main(int argc, char **argv) {
|
|||||||
bool showStats(false);
|
bool showStats(false);
|
||||||
bool riscv_test(false);
|
bool riscv_test(false);
|
||||||
|
|
||||||
/* Read the command line arguments. */
|
// parse the command line arguments
|
||||||
CommandLineArgFlag fh("-h", "--help", "", showHelp);
|
CommandLineArgFlag fh("-h", "--help", "show command line options", showHelp);
|
||||||
CommandLineArgSetter<std::string> fi("-i", "--image", "", imgFileName);
|
CommandLineArgSetter<std::string> fi("-i", "--image", "program binary", imgFileName);
|
||||||
CommandLineArgSetter<int> fc("-c", "--cores", "", num_cores);
|
CommandLineArgSetter<int> fc("-c", "--cores", "number of cores", num_cores);
|
||||||
CommandLineArgSetter<int> fw("-w", "--warps", "", num_warps);
|
CommandLineArgSetter<int> fw("-w", "--warps", "number of warps", num_warps);
|
||||||
CommandLineArgSetter<int> ft("-t", "--threads", "", num_threads);
|
CommandLineArgSetter<int> ft("-t", "--threads", "number of threads", num_threads);
|
||||||
CommandLineArgFlag fr("-r", "--riscv", "", riscv_test);
|
CommandLineArgFlag fr("-r", "--riscv", "enable riscv tests", riscv_test);
|
||||||
CommandLineArgFlag fs("-s", "--stats", "", showStats);
|
CommandLineArgFlag fs("-s", "--stats", "show stats", showStats);
|
||||||
|
|
||||||
CommandLineArg::readArgs(argc - 1, argv + 1);
|
CommandLineArg::readArgs(argc - 1, argv + 1);
|
||||||
|
|
||||||
|
|||||||
@@ -61,10 +61,11 @@ uint32_t TexUnit::read(int32_t u,
|
|||||||
uint32_t addr11 = base_addr + offset11 * stride;
|
uint32_t addr11 = base_addr + offset11 * stride;
|
||||||
|
|
||||||
// memory lookup
|
// memory lookup
|
||||||
uint32_t texel00 = core_->dcache_read(addr00, stride);
|
uint32_t texel00(0), texel01(0), texel10(0), texel11(0);
|
||||||
uint32_t texel01 = core_->dcache_read(addr01, stride);
|
core_->dcache_read(&texel00, addr00, stride);
|
||||||
uint32_t texel10 = core_->dcache_read(addr10, stride);
|
core_->dcache_read(&texel01, addr01, stride);
|
||||||
uint32_t texel11 = core_->dcache_read(addr11, stride);
|
core_->dcache_read(&texel10, addr10, stride);
|
||||||
|
core_->dcache_read(&texel11, addr11, stride);
|
||||||
|
|
||||||
mem_addrs->push_back({addr00, stride});
|
mem_addrs->push_back({addr00, stride});
|
||||||
mem_addrs->push_back({addr01, stride});
|
mem_addrs->push_back({addr01, stride});
|
||||||
@@ -84,7 +85,8 @@ uint32_t TexUnit::read(int32_t u,
|
|||||||
uint32_t addr = base_addr + offset * stride;
|
uint32_t addr = base_addr + offset * stride;
|
||||||
|
|
||||||
// memory lookup
|
// memory lookup
|
||||||
uint32_t texel = core_->dcache_read(addr, stride);
|
uint32_t texel(0);
|
||||||
|
core_->dcache_read(&texel, addr, stride);
|
||||||
mem_addrs->push_back({addr, stride});
|
mem_addrs->push_back({addr, stride});
|
||||||
|
|
||||||
// filtering
|
// filtering
|
||||||
|
|||||||
@@ -16,21 +16,17 @@ typedef uint32_t Word;
|
|||||||
typedef int32_t WordI;
|
typedef int32_t WordI;
|
||||||
typedef uint64_t DWord;
|
typedef uint64_t DWord;
|
||||||
typedef int64_t DWordI;
|
typedef int64_t DWordI;
|
||||||
typedef uint32_t Addr;
|
|
||||||
typedef uint32_t Size;
|
|
||||||
typedef uint32_t FWord;
|
|
||||||
#elif XLEN == 64
|
#elif XLEN == 64
|
||||||
typedef uint64_t Word;
|
typedef uint64_t Word;
|
||||||
typedef int64_t WordI;
|
typedef int64_t WordI;
|
||||||
typedef __uint128_t DWord;
|
typedef __uint128_t DWord;
|
||||||
typedef __int128_t DWordI;
|
typedef __int128_t DWordI;
|
||||||
typedef uint64_t Addr;
|
|
||||||
typedef uint64_t Size;
|
|
||||||
typedef uint64_t FWord;
|
|
||||||
#else
|
#else
|
||||||
#error unsupported XLEN
|
#error unsupported XLEN
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
typedef uint64_t FWord;
|
||||||
|
|
||||||
typedef std::bitset<32> RegMask;
|
typedef std::bitset<32> RegMask;
|
||||||
typedef std::bitset<32> ThreadMask;
|
typedef std::bitset<32> ThreadMask;
|
||||||
typedef std::bitset<32> WarpMask;
|
typedef std::bitset<32> WarpMask;
|
||||||
@@ -44,12 +40,12 @@ enum class RegType {
|
|||||||
Vector
|
Vector
|
||||||
};
|
};
|
||||||
|
|
||||||
inline std::ostream &operator<<(std::ostream &os, const RegType& type) {
|
inline std::ostream &operator<<(std::ostream &os, const RegType& clss) {
|
||||||
switch (type) {
|
switch (clss) {
|
||||||
case RegType::None: break;
|
case RegType::None: break;
|
||||||
case RegType::Integer: os << "r"; break;
|
case RegType::Integer: os << "x"; break;
|
||||||
case RegType::Float: os << "fr"; break;
|
case RegType::Float: os << "f"; break;
|
||||||
case RegType::Vector: os << "vr"; break;
|
case RegType::Vector: os << "v"; break;
|
||||||
}
|
}
|
||||||
return os;
|
return os;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -47,7 +47,8 @@ void Warp::eval(pipeline_trace_t *trace) {
|
|||||||
|
|
||||||
/* Fetch and decode. */
|
/* Fetch and decode. */
|
||||||
|
|
||||||
uint32_t instr_code = core_->icache_read(PC_, sizeof(uint32_t));
|
uint32_t instr_code = 0;
|
||||||
|
core_->icache_read(&instr_code, PC_, sizeof(uint32_t));
|
||||||
auto instr = core_->decoder().decode(instr_code);
|
auto instr = core_->decoder().decode(instr_code);
|
||||||
if (!instr) {
|
if (!instr) {
|
||||||
std::cout << std::hex << "Error: invalid instruction 0x" << instr_code << ", at PC=" << PC_ << std::endl;
|
std::cout << std::hex << "Error: invalid instruction 0x" << instr_code << ", at PC=" << PC_ << std::endl;
|
||||||
|
|||||||
Reference in New Issue
Block a user