XLEN parameterization for simx
This commit is contained in:
@@ -3,7 +3,6 @@
|
||||
#include <cstdint>
|
||||
#include <algorithm>
|
||||
#include <assert.h>
|
||||
#include "xlen.h"
|
||||
|
||||
constexpr uint32_t count_leading_zeros(uint32_t value) {
|
||||
return value ? __builtin_clz(value) : 32;
|
||||
@@ -88,9 +87,11 @@ inline uint64_t sext(uint64_t word, uint32_t width) {
|
||||
return ((word >> (width - 1)) & 0x1) ? (word | ~mask) : word;
|
||||
}
|
||||
|
||||
// change:
|
||||
// Move this to another file later
|
||||
inline uint64_t nan_box(uint32_t word) {
|
||||
uintf_t mask = uintf_t(0xffffffff00000000);
|
||||
return word | mask;
|
||||
}
|
||||
inline __uint128_t sext(__uint128_t word, uint32_t width) {
|
||||
assert(width > 1);
|
||||
assert(width <= 64);
|
||||
__uint128_t unity = 1;
|
||||
__uint128_t mask = (unity << width) - 1;
|
||||
return ((word >> (width - 1)) & 0x1) ? (word | ~mask) : word;
|
||||
}
|
||||
|
||||
|
||||
@@ -1,5 +1,4 @@
|
||||
#include "rvfloats.h"
|
||||
#include "xlen.h"
|
||||
#include <stdio.h>
|
||||
|
||||
extern "C" {
|
||||
@@ -299,14 +298,7 @@ uint64_t rv_fle_d(uint64_t a, uint64_t b, uint32_t* fflags) {
|
||||
return r;
|
||||
}
|
||||
|
||||
uint32_t rv_feq_s(uint64_t a, uint64_t b, uint32_t* fflags) {
|
||||
|
||||
#if FLEN == 64
|
||||
// Either a or b isn't NaN boxed
|
||||
if ((a >> 32 != 0xffffffff) || (b >> 32 != 0xffffffff)) {
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
uint32_t rv_feq_s(uint32_t a, uint32_t b, uint32_t* fflags) {
|
||||
|
||||
auto r = f32_eq(to_float32_t(a), to_float32_t(b));
|
||||
if (fflags) { *fflags = get_fflags(); }
|
||||
@@ -437,21 +429,7 @@ uint64_t rv_fclss_d(uint64_t a) {
|
||||
return r;
|
||||
}
|
||||
|
||||
uint32_t rv_fsgnj_s(uint64_t a, uint64_t b) {
|
||||
|
||||
#if FLEN == 64
|
||||
// Both a and b aren't NaN boxed
|
||||
if ((a >> 32 != 0xffffffff) && (b >> 32 != 0xffffffff)) {
|
||||
return 0x7fc00000;
|
||||
}
|
||||
// a is NaN boxed but b isn't
|
||||
if (b >> 32 != 0xffffffff)
|
||||
return a;
|
||||
|
||||
// b is NaN boxed but a isn't
|
||||
if(a >> 32 != 0xffffffff)
|
||||
return 0xffc00000;
|
||||
#endif
|
||||
uint32_t rv_fsgnj_s(uint32_t a, uint32_t b) {
|
||||
|
||||
int sign = b & F32_SIGN;
|
||||
int r = sign | (a & ~F32_SIGN);
|
||||
@@ -467,23 +445,7 @@ uint64_t rv_fsgnj_d(uint64_t a, uint64_t b) {
|
||||
return r;
|
||||
}
|
||||
|
||||
uint32_t rv_fsgnjn_s(uint64_t a, uint64_t b) {
|
||||
|
||||
#if FLEN == 64
|
||||
// Both a and b aren't NaN boxed
|
||||
if ((a >> 32 != 0xffffffff) && (b >> 32 != 0xffffffff)) {
|
||||
return 0x7fc00000;
|
||||
}
|
||||
// a is NaN boxed but b isn't
|
||||
if (b >> 32 != 0xffffffff)
|
||||
return a;
|
||||
|
||||
// b is NaN boxed but a isn't
|
||||
if(a >> 32 != 0xffffffff)
|
||||
return 0xffc00000;
|
||||
#endif
|
||||
|
||||
printf("XLEN=%d, FLEN=%d\n", XLEN, FLEN);
|
||||
uint32_t rv_fsgnjn_s(uint32_t a, uint32_t b) {
|
||||
|
||||
int sign = ~b & F32_SIGN;
|
||||
int r = sign | (a & ~F32_SIGN);
|
||||
@@ -499,21 +461,7 @@ uint64_t rv_fsgnjn_d(uint64_t a, uint64_t b) {
|
||||
return r;
|
||||
}
|
||||
|
||||
uint32_t rv_fsgnjx_s(uint64_t a, uint64_t b) {
|
||||
|
||||
#if FLEN == 64
|
||||
// Both a and b aren't NaN boxed
|
||||
if ((a >> 32 != 0xffffffff) && (b >> 32 != 0xffffffff)) {
|
||||
return 0x7fc00000;
|
||||
}
|
||||
// a is NaN boxed but b isn't
|
||||
if (b >> 32 != 0xffffffff)
|
||||
return a;
|
||||
|
||||
// b is NaN boxed but a isn't
|
||||
if(a >> 32 != 0xffffffff)
|
||||
return 0xffc00000;
|
||||
#endif
|
||||
uint32_t rv_fsgnjx_s(uint32_t a, uint32_t b) {
|
||||
|
||||
int sign1 = a & F32_SIGN;
|
||||
int sign2 = b & F32_SIGN;
|
||||
|
||||
@@ -27,13 +27,14 @@ 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_fclss_s(uint32_t a);
|
||||
uint32_t rv_fsgnj_s(uint64_t a, uint64_t b);
|
||||
uint32_t rv_fsgnjn_s(uint64_t a, uint64_t b);
|
||||
uint32_t rv_fsgnjx_s(uint64_t a, uint64_t b);
|
||||
|
||||
uint32_t rv_fsgnj_s(uint32_t a, uint32_t b);
|
||||
uint32_t rv_fsgnjn_s(uint32_t a, uint32_t b);
|
||||
uint32_t rv_fsgnjx_s(uint32_t a, uint32_t b);
|
||||
|
||||
uint32_t rv_flt_s(uint32_t a, uint32_t b, uint32_t* fflags);
|
||||
uint32_t rv_fle_s(uint32_t a, uint32_t b, uint32_t* fflags);
|
||||
uint32_t rv_feq_s(uint64_t a, uint64_t b, uint32_t* fflags);
|
||||
uint32_t rv_feq_s(uint32_t a, uint32_t b, uint32_t* fflags);
|
||||
uint32_t rv_fmin_s(uint32_t a, uint32_t b, uint32_t* fflags);
|
||||
uint32_t rv_fmax_s(uint32_t a, uint32_t b, uint32_t* fflags);
|
||||
|
||||
|
||||
@@ -42,7 +42,7 @@ struct params_t {
|
||||
|
||||
assert(config.ports_per_bank <= this->words_per_block);
|
||||
|
||||
// Word select
|
||||
// uint32_t select
|
||||
this->word_select_addr_start = config.W;
|
||||
this->word_select_addr_end = (this->word_select_addr_start+offset_bits-1);
|
||||
|
||||
|
||||
@@ -16,7 +16,7 @@ namespace vortex {
|
||||
|
||||
enum Constants {
|
||||
|
||||
SMEM_BANK_OFFSET = log2ceil(sizeof(Word)) + log2ceil(STACK_SIZE / sizeof(Word)),
|
||||
SMEM_BANK_OFFSET = log2ceil(sizeof(uint32_t)) + log2ceil(STACK_SIZE / sizeof(uint32_t)),
|
||||
|
||||
};
|
||||
|
||||
|
||||
@@ -13,7 +13,7 @@
|
||||
|
||||
using namespace vortex;
|
||||
|
||||
Core::Core(const SimContext& ctx, const ArchDef &arch, Word id)
|
||||
Core::Core(const SimContext& ctx, const ArchDef &arch, uint32_t id)
|
||||
: SimObject(ctx, "Core")
|
||||
, MemRspPort(this)
|
||||
, MemReqPort(this)
|
||||
@@ -400,14 +400,14 @@ WarpMask Core::barrier(int bar_id, int count, int warp_id) {
|
||||
return std::move(ret);
|
||||
}
|
||||
|
||||
Word Core::icache_read(Addr addr, Size size) {
|
||||
Word data;
|
||||
uint32_t Core::icache_read(Addr addr, Size size) {
|
||||
uint32_t data;
|
||||
mmu_.read(&data, addr, size, 0);
|
||||
return data;
|
||||
}
|
||||
|
||||
XWord Core::dcache_read(Addr addr, Size size) {
|
||||
XWord data;
|
||||
Word Core::dcache_read(Addr addr, Size size) {
|
||||
Word data;
|
||||
auto type = get_addr_type(addr, size);
|
||||
if (type == AddrType::Shared) {
|
||||
smem_.read(&data, addr & (SMEM_SIZE-1), size);
|
||||
@@ -417,7 +417,7 @@ XWord Core::dcache_read(Addr addr, Size size) {
|
||||
return data;
|
||||
}
|
||||
|
||||
void Core::dcache_write(Addr addr, XWord data, Size size) {
|
||||
void Core::dcache_write(Addr addr, Word data, Size size) {
|
||||
if (addr >= IO_COUT_ADDR
|
||||
&& addr <= (IO_COUT_ADDR + IO_COUT_SIZE - 1)) {
|
||||
this->writeToStdOut(addr, data);
|
||||
@@ -431,11 +431,11 @@ void Core::dcache_write(Addr addr, XWord data, Size size) {
|
||||
}
|
||||
}
|
||||
|
||||
Word Core::tex_read(uint32_t unit, Word u, Word v, Word lod, std::vector<mem_addr_size_t>* mem_addrs) {
|
||||
uint32_t Core::tex_read(uint32_t unit, uint32_t u, uint32_t v, uint32_t lod, std::vector<mem_addr_size_t>* mem_addrs) {
|
||||
return tex_units_.at(unit).read(u, v, lod, mem_addrs);
|
||||
}
|
||||
|
||||
void Core::writeToStdOut(Addr addr, Word data) {
|
||||
void Core::writeToStdOut(Addr addr, uint32_t data) {
|
||||
uint32_t tid = (addr - IO_COUT_ADDR) & (IO_COUT_SIZE-1);
|
||||
auto& ss_buf = print_bufs_[tid];
|
||||
char c = (char)data;
|
||||
@@ -446,7 +446,7 @@ void Core::writeToStdOut(Addr addr, Word data) {
|
||||
}
|
||||
}
|
||||
|
||||
Word Core::get_csr(Addr addr, int tid, int wid) {
|
||||
uint32_t Core::get_csr(Addr addr, int tid, int wid) {
|
||||
switch (addr) {
|
||||
case CSR_SATP:
|
||||
case CSR_PMPCFG0:
|
||||
@@ -502,13 +502,13 @@ Word Core::get_csr(Addr addr, int tid, int wid) {
|
||||
return perf_stats_.instrs & 0xffffffff;
|
||||
case CSR_MINSTRET_H:
|
||||
// NumInsts
|
||||
return (Word)(perf_stats_.instrs >> 32);
|
||||
return (uint32_t)(perf_stats_.instrs >> 32);
|
||||
case CSR_MCYCLE:
|
||||
// NumCycles
|
||||
return (Word)SimPlatform::instance().cycles();
|
||||
return (uint32_t)SimPlatform::instance().cycles();
|
||||
case CSR_MCYCLE_H:
|
||||
// NumCycles
|
||||
return (Word)(SimPlatform::instance().cycles() >> 32);
|
||||
return (uint32_t)(SimPlatform::instance().cycles() >> 32);
|
||||
case CSR_MPM_IBUF_ST:
|
||||
return perf_stats_.ibuf_stalls & 0xffffffff;
|
||||
case CSR_MPM_IBUF_ST_H:
|
||||
@@ -644,7 +644,7 @@ Word Core::get_csr(Addr addr, int tid, int wid) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
void Core::set_csr(Addr addr, Word value, int /*tid*/, int wid) {
|
||||
void Core::set_csr(Addr addr, uint32_t value, int /*tid*/, int wid) {
|
||||
if (addr == CSR_FFLAGS) {
|
||||
fcsrs_.at(wid) = (fcsrs_.at(wid) & ~0x1F) | (value & 0x1F);
|
||||
} else if (addr == CSR_FRM) {
|
||||
|
||||
@@ -68,7 +68,7 @@ public:
|
||||
SimPort<MemRsp> MemRspPort;
|
||||
SimPort<MemReq> MemReqPort;
|
||||
|
||||
Core(const SimContext& ctx, const ArchDef &arch, Word id);
|
||||
Core(const SimContext& ctx, const ArchDef &arch, uint32_t id);
|
||||
~Core();
|
||||
|
||||
void attach_ram(RAM* ram);
|
||||
@@ -79,7 +79,7 @@ public:
|
||||
|
||||
void tick();
|
||||
|
||||
Word id() const {
|
||||
uint32_t id() const {
|
||||
return id_;
|
||||
}
|
||||
|
||||
@@ -95,25 +95,25 @@ public:
|
||||
return perf_stats_;
|
||||
}
|
||||
|
||||
Word getIRegValue(int reg) const {
|
||||
uint32_t getIRegValue(int reg) const {
|
||||
return warps_.at(0)->getIRegValue(reg);
|
||||
}
|
||||
|
||||
Word get_csr(Addr addr, int tid, int wid);
|
||||
uint32_t get_csr(Addr addr, int tid, int wid);
|
||||
|
||||
void set_csr(Addr addr, Word value, int tid, int wid);
|
||||
void set_csr(Addr addr, uint32_t value, int tid, int wid);
|
||||
|
||||
WarpMask wspawn(int num_warps, int nextPC);
|
||||
|
||||
WarpMask barrier(int bar_id, int count, int warp_id);
|
||||
|
||||
Word icache_read(Addr, Size);
|
||||
uint32_t icache_read(Addr, Size);
|
||||
|
||||
XWord dcache_read(Addr, Size);
|
||||
Word dcache_read(Addr, Size);
|
||||
|
||||
void dcache_write(Addr, XWord, Size);
|
||||
void dcache_write(Addr, Word, Size);
|
||||
|
||||
Word tex_read(uint32_t unit, Word lod, Word u, Word 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);
|
||||
|
||||
void trigger_ecall();
|
||||
|
||||
@@ -129,11 +129,11 @@ private:
|
||||
void execute();
|
||||
void commit();
|
||||
|
||||
void writeToStdOut(Addr addr, Word data);
|
||||
void writeToStdOut(Addr addr, uint32_t data);
|
||||
|
||||
void cout_flush();
|
||||
|
||||
Word id_;
|
||||
uint32_t id_;
|
||||
const ArchDef arch_;
|
||||
const Decoder decoder_;
|
||||
MemoryUnit mmu_;
|
||||
@@ -142,7 +142,7 @@ private:
|
||||
|
||||
std::vector<std::shared_ptr<Warp>> warps_;
|
||||
std::vector<WarpMask> barriers_;
|
||||
std::vector<Word> csrs_;
|
||||
std::vector<uint32_t> csrs_;
|
||||
std::vector<Byte> fcsrs_;
|
||||
std::vector<IBuffer> ibuffers_;
|
||||
Scoreboard scoreboard_;
|
||||
|
||||
@@ -48,11 +48,11 @@ static const std::unordered_map<int, struct InstTableEntry_t> sc_instTable = {
|
||||
|
||||
static const char* op_string(const Instr &instr) {
|
||||
auto opcode = instr.getOpcode();
|
||||
Word func2 = instr.getFunc2();
|
||||
Word func3 = instr.getFunc3();
|
||||
Word func7 = instr.getFunc7();
|
||||
Word rs2 = instr.getRSrc(1);
|
||||
XWord imm = instr.getImm();
|
||||
uint32_t func2 = instr.getFunc2();
|
||||
uint32_t func3 = instr.getFunc3();
|
||||
uint32_t func7 = instr.getFunc7();
|
||||
uint32_t rs2 = instr.getRSrc(1);
|
||||
Word imm = instr.getImm();
|
||||
|
||||
switch (opcode) {
|
||||
case Opcode::NOP: return "NOP";
|
||||
@@ -130,21 +130,21 @@ static const char* op_string(const Instr &instr) {
|
||||
case Opcode::R_INST_64:
|
||||
if (func7 & 0x1){
|
||||
switch (func3) {
|
||||
case 0: return func7 ? "SUBW" : "ADDW";
|
||||
case 1: return "SLLW";
|
||||
case 5: return func7 ? "SRAW" : "SRLW";
|
||||
case 0: return "MULW";
|
||||
case 4: return "DIVW";
|
||||
case 5: return "DIVUW";
|
||||
case 6: return "REMW";
|
||||
case 7: return "REMUW";
|
||||
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();
|
||||
case 0: return func7 ? "SUBW" : "ADDW";
|
||||
case 1: return "SLLW";
|
||||
case 5: return func7 ? "SRAW" : "SRLW";
|
||||
default:
|
||||
std::abort();
|
||||
}
|
||||
}
|
||||
case Opcode::I_INST_64:
|
||||
@@ -333,8 +333,8 @@ static const char* op_string(const Instr &instr) {
|
||||
namespace vortex {
|
||||
std::ostream &operator<<(std::ostream &os, const Instr &instr) {
|
||||
auto opcode = instr.getOpcode();
|
||||
Word func2 = instr.getFunc2();
|
||||
Word func3 = instr.getFunc3();
|
||||
uint32_t func2 = instr.getFunc2();
|
||||
uint32_t func3 = instr.getFunc3();
|
||||
|
||||
os << op_string(instr) << ": ";
|
||||
|
||||
@@ -404,15 +404,15 @@ Decoder::Decoder(const ArchDef &arch) {
|
||||
v_imm_mask_ = 0x7ff;
|
||||
}
|
||||
|
||||
std::shared_ptr<Instr> Decoder::decode(Word code) const {
|
||||
std::shared_ptr<Instr> Decoder::decode(uint32_t code) const {
|
||||
auto instr = std::make_shared<Instr>();
|
||||
Opcode op = (Opcode)((code >> shift_opcode_) & opcode_mask_);
|
||||
instr->setOpcode(op);
|
||||
|
||||
Word func2 = (code >> shift_func2_) & func2_mask_;
|
||||
Word func3 = (code >> shift_func3_) & func3_mask_;
|
||||
Word func6 = (code >> shift_func6_) & func6_mask_;
|
||||
Word func7 = (code >> shift_func7_) & func7_mask_;
|
||||
uint32_t func2 = (code >> shift_func2_) & func2_mask_;
|
||||
uint32_t func3 = (code >> shift_func3_) & func3_mask_;
|
||||
uint32_t func6 = (code >> shift_func6_) & func6_mask_;
|
||||
uint32_t func7 = (code >> shift_func7_) & func7_mask_;
|
||||
|
||||
int rd = (code >> shift_rd_) & reg_mask_;
|
||||
int rs1 = (code >> shift_rs1_) & reg_mask_;
|
||||
@@ -488,27 +488,30 @@ std::shared_ptr<Instr> Decoder::decode(Word code) const {
|
||||
case Opcode::I_INST:
|
||||
if (func3 == 0x1 || func3 == 0x5) {
|
||||
// int5 (XLEN = 32) / int6 (XLEN = 64)
|
||||
XWord shamt_mask = (1 << log2up(XLEN)) - 1;
|
||||
XWord shamt = (((func7 & 0x1) << 5) | rs2) & shamt_mask;
|
||||
Word shamt_mask = ((Word)1 << log2up(XLEN)) - 1;
|
||||
Word shamt = (((func7 & 0x1) << 5) | rs2) & shamt_mask;
|
||||
instr->setImm(shamt);
|
||||
} else {
|
||||
// int12
|
||||
instr->setImm(sext(code >> shift_rs2_, 12));
|
||||
Word imm = code >> shift_rs2_;
|
||||
instr->setImm(sext(imm, 12));
|
||||
}
|
||||
break;
|
||||
case Opcode::I_INST_64:
|
||||
if (func3 == 0x1 || func3 == 0x5) {
|
||||
// int5
|
||||
XWord shamt = rs2;
|
||||
Word shamt = rs2;
|
||||
instr->setImm(shamt);
|
||||
} else {
|
||||
// int12
|
||||
instr->setImm(sext64(code >> shift_rs2_, 12));
|
||||
Word imm = code >> shift_rs2_;
|
||||
instr->setImm(sext(imm, 12));
|
||||
}
|
||||
break;
|
||||
default:
|
||||
// int12
|
||||
instr->setImm(sext(code >> shift_rs2_, 12));
|
||||
Word imm = code >> shift_rs2_;
|
||||
instr->setImm(sext(imm, 12));
|
||||
break;
|
||||
}
|
||||
} break;
|
||||
@@ -520,7 +523,7 @@ std::shared_ptr<Instr> Decoder::decode(Word code) const {
|
||||
instr->setSrcReg(rs2);
|
||||
}
|
||||
instr->setFunc3(func3);
|
||||
XWord imm = (func7 << reg_s_) | rd;
|
||||
Word imm = (func7 << reg_s_) | rd;
|
||||
instr->setImm(sext(imm, 12));
|
||||
} break;
|
||||
|
||||
@@ -528,27 +531,28 @@ std::shared_ptr<Instr> Decoder::decode(Word code) const {
|
||||
instr->setSrcReg(rs1);
|
||||
instr->setSrcReg(rs2);
|
||||
instr->setFunc3(func3);
|
||||
Word bit_11 = rd & 0x1;
|
||||
Word bits_4_1 = rd >> 1;
|
||||
Word bit_10_5 = func7 & 0x3f;
|
||||
Word bit_12 = func7 >> 6;
|
||||
XWord imm = (bits_4_1 << 1) | (bit_10_5 << 5) | (bit_11 << 11) | (bit_12 << 12);
|
||||
uint32_t bit_11 = rd & 0x1;
|
||||
uint32_t bits_4_1 = rd >> 1;
|
||||
uint32_t bit_10_5 = func7 & 0x3f;
|
||||
uint32_t bit_12 = func7 >> 6;
|
||||
Word imm = (bits_4_1 << 1) | (bit_10_5 << 5) | (bit_11 << 11) | (bit_12 << 12);
|
||||
instr->setImm(sext(imm, 13));
|
||||
} break;
|
||||
|
||||
case InstType::U_TYPE:
|
||||
case InstType::U_TYPE: {
|
||||
instr->setDestReg(rd);
|
||||
instr->setImm(sext(code >> shift_func3_, 20));
|
||||
break;
|
||||
Word imm = code >> shift_func3_;
|
||||
instr->setImm(sext(imm, 20));
|
||||
} break;
|
||||
|
||||
case InstType::J_TYPE: {
|
||||
instr->setDestReg(rd);
|
||||
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;
|
||||
XWord imm = (XWord) 0 | (bits_10_1 << 1) | (bit_11 << 11) | (bits_19_12 << 12) | (bit_20 << 20);
|
||||
uint32_t unordered = code >> shift_func3_;
|
||||
uint32_t bits_19_12 = unordered & 0xff;
|
||||
uint32_t bit_11 = (unordered >> 8) & 0x1;
|
||||
uint32_t bits_10_1 = (unordered >> 9) & 0x3ff;
|
||||
uint32_t bit_20 = (unordered >> 19) & 0x1;
|
||||
Word imm = (Word) 0 | (bits_10_1 << 1) | (bit_11 << 11) | (bits_19_12 << 12) | (bit_20 << 20);
|
||||
if (bit_20) {
|
||||
imm |= ~j_imm_mask_;
|
||||
}
|
||||
@@ -564,7 +568,7 @@ std::shared_ptr<Instr> Decoder::decode(Word code) const {
|
||||
if (func3 == 7) {
|
||||
instr->setImm(!(code >> shift_vset_));
|
||||
if (instr->getImm()) {
|
||||
Word immed = (code >> shift_rs2_) & v_imm_mask_;
|
||||
uint32_t immed = (code >> shift_rs2_) & v_imm_mask_;
|
||||
instr->setImm(immed);
|
||||
instr->setVlmul(immed & 0x3);
|
||||
instr->setVediv((immed >> 4) & 0x3);
|
||||
|
||||
@@ -13,49 +13,49 @@ class Decoder {
|
||||
public:
|
||||
Decoder(const ArchDef &);
|
||||
|
||||
std::shared_ptr<Instr> decode(Word code) const;
|
||||
std::shared_ptr<Instr> decode(uint32_t code) const;
|
||||
|
||||
private:
|
||||
|
||||
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_;
|
||||
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_;
|
||||
|
||||
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_;
|
||||
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
|
||||
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_;
|
||||
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_;
|
||||
};
|
||||
|
||||
}
|
||||
1133
sim/simx/execute.cpp
1133
sim/simx/execute.cpp
File diff suppressed because it is too large
Load Diff
@@ -114,8 +114,8 @@ void LsuUnit::tick() {
|
||||
// duplicates detection
|
||||
bool is_dup = false;
|
||||
if (trace->tmask.test(0)) {
|
||||
uint64_t addr_mask = sizeof(Word)-1;
|
||||
Word addr0 = trace->mem_addrs.at(0).at(0).addr & ~addr_mask;
|
||||
uint64_t addr_mask = sizeof(uint32_t)-1;
|
||||
uint32_t addr0 = trace->mem_addrs.at(0).at(0).addr & ~addr_mask;
|
||||
uint32_t matches = 1;
|
||||
for (uint32_t t = 1; t < num_threads_; ++t) {
|
||||
if (!trace->tmask.test(t))
|
||||
|
||||
@@ -72,41 +72,42 @@ public:
|
||||
void setSrcFReg(int srcReg) { rsrc_type_[num_rsrcs_] = RegType::Float; rsrc_[num_rsrcs_++] = srcReg; }
|
||||
void setDestVReg(int destReg) { rdest_type_ = RegType::Vector; rdest_ = destReg; }
|
||||
void setSrcVReg(int srcReg) { rsrc_type_[num_rsrcs_] = RegType::Vector; rsrc_[num_rsrcs_++] = srcReg; }
|
||||
void setFunc2(Word func2) { func2_ = func2; }
|
||||
void setFunc3(Word func3) { func3_ = func3; }
|
||||
void setFunc7(Word func7) { func7_ = func7; }
|
||||
void setImm(XWord 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; }
|
||||
void setFunc2(uint32_t func2) { func2_ = func2; }
|
||||
void setFunc3(uint32_t func3) { func3_ = func3; }
|
||||
void setFunc7(uint32_t func7) { func7_ = func7; }
|
||||
void setImm(Word imm) { has_imm_ = true; imm_ = imm; }
|
||||
void setVlsWidth(uint32_t width) { vlsWidth_ = width; }
|
||||
void setVmop(uint32_t mop) { vMop_ = mop; }
|
||||
void setVnf(uint32_t nf) { vNf_ = nf; }
|
||||
void setVmask(uint32_t mask) { vmask_ = mask; }
|
||||
void setVs3(uint32_t vs) { vs3_ = vs; }
|
||||
void setVlmul(uint32_t lmul) { vlmul_ = 1 << lmul; }
|
||||
void setVsew(uint32_t sew) { vsew_ = 1 << (3+sew); }
|
||||
void setVediv(uint32_t ediv) { vediv_ = 1 << ediv; }
|
||||
void setFunc6(uint32_t func6) { func6_ = func6; }
|
||||
|
||||
/* Getters used by encoders. */
|
||||
// uint32_t -> uint32
|
||||
Opcode getOpcode() const { return opcode_; }
|
||||
Word getFunc2() const { return func2_; }
|
||||
Word getFunc3() const { return func3_; }
|
||||
Word getFunc6() const { return func6_; }
|
||||
Word getFunc7() const { return func7_; }
|
||||
uint32_t getFunc2() const { return func2_; }
|
||||
uint32_t getFunc3() const { return func3_; }
|
||||
uint32_t getFunc6() const { return func6_; }
|
||||
uint32_t getFunc7() const { return func7_; }
|
||||
int getNRSrc() const { return num_rsrcs_; }
|
||||
int getRSrc(int i) const { return rsrc_[i]; }
|
||||
RegType getRSType(int i) const { return rsrc_type_[i]; }
|
||||
int getRDest() const { return rdest_; }
|
||||
RegType getRDType() const { return rdest_type_; }
|
||||
bool hasImm() const { return has_imm_; }
|
||||
XWord 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_; }
|
||||
Word getImm() const { return imm_; }
|
||||
uint32_t getVlsWidth() const { return vlsWidth_; }
|
||||
uint32_t getVmop() const { return vMop_; }
|
||||
uint32_t getvNf() const { return vNf_; }
|
||||
uint32_t getVmask() const { return vmask_; }
|
||||
uint32_t getVs3() const { return vs3_; }
|
||||
uint32_t getVlmul() const { return vlmul_; }
|
||||
uint32_t getVsew() const { return vsew_; }
|
||||
uint32_t getVediv() const { return vediv_; }
|
||||
|
||||
private:
|
||||
|
||||
@@ -118,24 +119,24 @@ private:
|
||||
int num_rsrcs_;
|
||||
bool has_imm_;
|
||||
RegType rdest_type_;
|
||||
XWord imm_;
|
||||
Word imm_;
|
||||
RegType rsrc_type_[MAX_REG_SOURCES];
|
||||
int rsrc_[MAX_REG_SOURCES];
|
||||
int rdest_;
|
||||
Word func2_;
|
||||
Word func3_;
|
||||
Word func6_;
|
||||
uint32_t func2_;
|
||||
uint32_t func3_;
|
||||
uint32_t func6_;
|
||||
|
||||
// Vector
|
||||
Word vmask_;
|
||||
Word vlsWidth_;
|
||||
Word vMop_;
|
||||
Word vNf_;
|
||||
Word vs3_;
|
||||
Word vlmul_;
|
||||
Word vsew_;
|
||||
Word vediv_;
|
||||
Word func7_;
|
||||
uint32_t vmask_;
|
||||
uint32_t vlsWidth_;
|
||||
uint32_t vMop_;
|
||||
uint32_t vNf_;
|
||||
uint32_t vs3_;
|
||||
uint32_t vlmul_;
|
||||
uint32_t vsew_;
|
||||
uint32_t vediv_;
|
||||
uint32_t func7_;
|
||||
|
||||
friend std::ostream &operator<<(std::ostream &, const Instr&);
|
||||
};
|
||||
|
||||
@@ -18,7 +18,7 @@ struct pipeline_trace_t {
|
||||
int cid;
|
||||
int wid;
|
||||
ThreadMask tmask;
|
||||
XWord PC;
|
||||
Word PC;
|
||||
|
||||
//--
|
||||
bool fetch_stall;
|
||||
|
||||
@@ -7,7 +7,6 @@
|
||||
#include <util.h>
|
||||
#include <VX_config.h>
|
||||
#include <simobject.h>
|
||||
#include <xlen.h>
|
||||
|
||||
#if XLEN == 32
|
||||
#define uintx_t uint32_t
|
||||
@@ -30,6 +29,7 @@ typedef uintx_t Word;
|
||||
typedef intx_t WordI;
|
||||
typedef uintd_t DWord;
|
||||
typedef intd_t DWordI;
|
||||
typedef uint64_t FWord;
|
||||
|
||||
typedef uintx_t Addr;
|
||||
typedef uint32_t Size;
|
||||
@@ -148,7 +148,7 @@ struct mem_addr_size_t {
|
||||
uint32_t size;
|
||||
};
|
||||
|
||||
inline AddrType get_addr_type(XWord addr, uint32_t size) {
|
||||
inline AddrType get_addr_type(Word addr, uint32_t size) {
|
||||
__unused (size);
|
||||
if (SM_ENABLE) {
|
||||
if (addr >= (SMEM_BASE_ADDR - SMEM_SIZE)
|
||||
|
||||
@@ -10,10 +10,10 @@
|
||||
|
||||
using namespace vortex;
|
||||
|
||||
Warp::Warp(Core *core, Word id)
|
||||
Warp::Warp(Core *core, uint32_t id)
|
||||
: id_(id)
|
||||
, core_(core)
|
||||
, ireg_file_(core->arch().num_threads(), std::vector<XWord>(core->arch().num_regs()))
|
||||
, ireg_file_(core->arch().num_threads(), std::vector<Word>(core->arch().num_regs()))
|
||||
, freg_file_(core->arch().num_threads(), std::vector<FWord>(core->arch().num_regs()))
|
||||
, vreg_file_(core->arch().num_threads(), std::vector<Byte>(core->arch().vsize()))
|
||||
{
|
||||
@@ -47,7 +47,7 @@ void Warp::eval(pipeline_trace_t *trace) {
|
||||
|
||||
/* Fetch and decode. */
|
||||
|
||||
Word instr_code = core_->icache_read(PC_, sizeof(Word));
|
||||
uint32_t instr_code = core_->icache_read(PC_, sizeof(uint32_t));
|
||||
auto instr = core_->decoder().decode(instr_code);
|
||||
if (!instr) {
|
||||
std::cout << std::hex << "Error: invalid instruction 0x" << instr_code << ", at PC=" << PC_ << std::endl;
|
||||
@@ -77,7 +77,7 @@ void Warp::eval(pipeline_trace_t *trace) {
|
||||
DPN(4, '|');
|
||||
// Floating point register file
|
||||
for (int j = 0; j < core_->arch().num_threads(); ++j) {
|
||||
DPN(4, ' ' << std::setfill('0') << std::setw(FLEN/4) << std::hex << freg_file_.at(j).at(i) << std::setfill(' ') << ' ');
|
||||
DPN(4, ' ' << std::setfill('0') << std::setw(16) << std::hex << freg_file_.at(j).at(i) << std::setfill(' ') << ' ');
|
||||
}
|
||||
DPN(4, std::endl);
|
||||
}
|
||||
|
||||
@@ -11,7 +11,7 @@ class Core;
|
||||
class Instr;
|
||||
class pipeline_trace_t;
|
||||
struct DomStackEntry {
|
||||
DomStackEntry(const ThreadMask &tmask, XWord PC)
|
||||
DomStackEntry(const ThreadMask &tmask, Word PC)
|
||||
: tmask(tmask)
|
||||
, PC(PC)
|
||||
, fallThrough(false)
|
||||
@@ -26,7 +26,7 @@ struct DomStackEntry {
|
||||
{}
|
||||
|
||||
ThreadMask tmask;
|
||||
XWord PC;
|
||||
Word PC;
|
||||
bool fallThrough;
|
||||
bool unanimous;
|
||||
};
|
||||
@@ -40,7 +40,7 @@ struct vtype {
|
||||
|
||||
class Warp {
|
||||
public:
|
||||
Warp(Core *core, Word id);
|
||||
Warp(Core *core, uint32_t id);
|
||||
|
||||
void clear();
|
||||
|
||||
@@ -62,15 +62,15 @@ public:
|
||||
return 0;
|
||||
}
|
||||
|
||||
Word id() const {
|
||||
uint32_t id() const {
|
||||
return id_;
|
||||
}
|
||||
|
||||
Word getPC() const {
|
||||
uint32_t getPC() const {
|
||||
return PC_;
|
||||
}
|
||||
|
||||
void setPC(Word PC) {
|
||||
void setPC(uint32_t PC) {
|
||||
PC_ = PC;
|
||||
}
|
||||
|
||||
@@ -79,13 +79,13 @@ public:
|
||||
active_ = tmask_.any();
|
||||
}
|
||||
|
||||
Word getTmask() const {
|
||||
uint32_t getTmask() const {
|
||||
if (active_)
|
||||
return tmask_.to_ulong();
|
||||
return 0;
|
||||
}
|
||||
|
||||
Word getIRegValue(int reg) const {
|
||||
uint32_t getIRegValue(int reg) const {
|
||||
return ireg_file_.at(0).at(reg);
|
||||
}
|
||||
|
||||
@@ -95,14 +95,14 @@ private:
|
||||
|
||||
void execute(const Instr &instr, pipeline_trace_t *trace);
|
||||
|
||||
Word id_;
|
||||
uint32_t id_;
|
||||
Core *core_;
|
||||
bool active_;
|
||||
|
||||
XWord PC_;
|
||||
Word PC_;
|
||||
ThreadMask tmask_;
|
||||
|
||||
std::vector<std::vector<XWord>> ireg_file_;
|
||||
std::vector<std::vector<Word>> ireg_file_;
|
||||
std::vector<std::vector<FWord>> freg_file_;
|
||||
std::vector<std::vector<Byte>> vreg_file_;
|
||||
std::stack<DomStackEntry> dom_stack_;
|
||||
|
||||
Reference in New Issue
Block a user