cleaned up vector code from simx

This commit is contained in:
Blaise Tine 2024-02-21 18:27:52 -08:00
parent fc0f5e2ca4
commit 041f573815
7 changed files with 199 additions and 1233 deletions

View file

@ -28,30 +28,29 @@
using namespace vortex;
static const std::unordered_map<Opcode, InstType> sc_instTable = {
{Opcode::R_INST, InstType::R_TYPE},
{Opcode::L_INST, InstType::I_TYPE},
{Opcode::I_INST, InstType::I_TYPE},
{Opcode::S_INST, InstType::S_TYPE},
{Opcode::B_INST, InstType::B_TYPE},
{Opcode::LUI_INST, InstType::U_TYPE},
{Opcode::AUIPC_INST, InstType::U_TYPE},
{Opcode::JAL_INST, InstType::J_TYPE},
{Opcode::JALR_INST, InstType::I_TYPE},
{Opcode::SYS_INST, InstType::I_TYPE},
{Opcode::FENCE, InstType::I_TYPE},
{Opcode::AMO, InstType::R_TYPE},
{Opcode::FL, InstType::I_TYPE},
{Opcode::FS, InstType::S_TYPE},
{Opcode::FCI, InstType::R_TYPE},
{Opcode::FMADD, InstType::R4_TYPE},
{Opcode::FMSUB, InstType::R4_TYPE},
{Opcode::FMNMADD, InstType::R4_TYPE},
{Opcode::FMNMSUB, InstType::R4_TYPE},
{Opcode::VSET, InstType::V_TYPE},
{Opcode::EXT1, InstType::R_TYPE},
{Opcode::EXT2, InstType::R4_TYPE},
{Opcode::R_INST_W, InstType::R_TYPE},
{Opcode::I_INST_W, InstType::I_TYPE},
{Opcode::R, InstType::R},
{Opcode::L, InstType::I},
{Opcode::I, InstType::I},
{Opcode::S, InstType::S},
{Opcode::B, InstType::B},
{Opcode::LUI, InstType::U},
{Opcode::AUIPC, InstType::U},
{Opcode::JAL, InstType::J},
{Opcode::JALR, InstType::I},
{Opcode::SYS, InstType::I},
{Opcode::FENCE, InstType::I},
{Opcode::AMO, InstType::R},
{Opcode::FL, InstType::I},
{Opcode::FS, InstType::S},
{Opcode::FCI, InstType::R},
{Opcode::FMADD, InstType::R4},
{Opcode::FMSUB, InstType::R4},
{Opcode::FMNMADD, InstType::R4},
{Opcode::FMNMSUB, InstType::R4},
{Opcode::EXT1, InstType::R},
{Opcode::EXT2, InstType::R4},
{Opcode::R_W, InstType::R},
{Opcode::I_W, InstType::I},
};
enum Constants {
@ -59,15 +58,9 @@ enum Constants {
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,
width_aq = 1,
width_rl = 1,
shift_opcode= 0,
shift_rd = width_opcode,
@ -77,20 +70,14 @@ enum Constants {
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) {
@ -102,9 +89,9 @@ static const char* op_string(const Instr &instr) {
auto imm = instr.getImm();
switch (opcode) {
case Opcode::LUI_INST: return "LUI";
case Opcode::AUIPC_INST: return "AUIPC";
case Opcode::R_INST:
case Opcode::LUI: return "LUI";
case Opcode::AUIPC: return "AUIPC";
case Opcode::R:
if (func7 & 0x1) {
switch (func3) {
case 0: return "MUL";
@ -132,7 +119,7 @@ static const char* op_string(const Instr &instr) {
std::abort();
}
}
case Opcode::I_INST:
case Opcode::I:
switch (func3) {
case 0: return "ADDI";
case 1: return "SLLI";
@ -145,7 +132,7 @@ static const char* op_string(const Instr &instr) {
default:
std::abort();
}
case Opcode::B_INST:
case Opcode::B:
switch (func3) {
case 0: return "BEQ";
case 1: return "BNE";
@ -156,9 +143,9 @@ static const char* op_string(const Instr &instr) {
default:
std::abort();
}
case Opcode::JAL_INST: return "JAL";
case Opcode::JALR_INST: return "JALR";
case Opcode::L_INST:
case Opcode::JAL: return "JAL";
case Opcode::JALR: return "JALR";
case Opcode::L:
switch (func3) {
case 0: return "LB";
case 1: return "LH";
@ -170,7 +157,7 @@ static const char* op_string(const Instr &instr) {
default:
std::abort();
}
case Opcode::S_INST:
case Opcode::S:
switch (func3) {
case 0: return "SB";
case 1: return "SH";
@ -179,7 +166,7 @@ static const char* op_string(const Instr &instr) {
default:
std::abort();
}
case Opcode::R_INST_W:
case Opcode::R_W:
if (func7 & 0x1){
switch (func3) {
case 0: return "MULW";
@ -199,7 +186,7 @@ static const char* op_string(const Instr &instr) {
std::abort();
}
}
case Opcode::I_INST_W:
case Opcode::I_W:
switch (func3) {
case 0: return "ADDIW";
case 1: return "SLLIW";
@ -207,7 +194,7 @@ static const char* op_string(const Instr &instr) {
default:
std::abort();
}
case Opcode::SYS_INST:
case Opcode::SYS:
switch (func3) {
case 0:
switch (imm) {
@ -391,7 +378,6 @@ static const char* op_string(const Instr &instr) {
case Opcode::FMSUB: return func2 ? "FMSUB.D" : "FMSUB.S";
case Opcode::FMNMADD: return func2 ? "FNMADD.D" : "FNMADD.S";
case Opcode::FMNMSUB: return func2 ? "FNMSUB.D" : "FNMSUB.S";
case Opcode::VSET: return "VSET";
case Opcode::EXT1:
switch (func7) {
case 0:
@ -427,31 +413,24 @@ static const char* op_string(const Instr &instr) {
namespace vortex {
std::ostream &operator<<(std::ostream &os, const Instr &instr) {
auto opcode = instr.getOpcode();
auto func3 = instr.getFunc3();
os << op_string(instr);
int sep = 0;
if (instr.getRDType() != RegType::None) {
if (sep++ != 0) { os << ", "; } else { os << " "; }
os << instr.getRDType() << std::dec << instr.getRDest();
}
for (uint32_t i = 0; i < instr.getNRSrc(); ++i) {
if (instr.getRSType(i) == RegType::None)
continue;
if (sep++ != 0) { os << ", "; } else { os << " "; }
os << instr.getRSType(i) << std::dec << instr.getRSrc(i);
if (instr.getRSType(i) != RegType::None) {
os << instr.getRSType(i) << std::dec << instr.getRSrc(i);
} else {
os << "0x" << std::hex << instr.getRSrc(0);
}
}
if (instr.hasImm()) {
if (sep++ != 0) { os << ", "; } else { os << " "; }
os << "0x" << std::hex << instr.getImm();
}
if (opcode == Opcode::SYS_INST && func3 >= 5) {
// CSRs with immediate values
if (sep++ != 0) { os << ", "; } else { os << " "; }
os << "0x" << std::hex << instr.getRSrc(0);
}
return os;
}
}
@ -465,7 +444,6 @@ std::shared_ptr<Instr> Decoder::decode(uint32_t code) const {
auto func2 = (code >> shift_func2) & mask_func2;
auto func3 = (code >> shift_func3) & mask_func3;
auto func6 = (code >> shift_func6) & mask_func6;
auto func7 = (code >> shift_func7) & mask_func7;
auto rd = (code >> shift_rd) & mask_reg;
@ -475,19 +453,13 @@ std::shared_ptr<Instr> Decoder::decode(uint32_t code) const {
auto op_it = sc_instTable.find(op);
if (op_it == sc_instTable.end()) {
std::cout << std::hex << "Error: invalid opcode: 0x" << op << std::endl;
std::cout << std::hex << "Error: invalid opcode: 0x" << static_cast<int>(op) << std::endl;
return nullptr;
}
auto iType = op_it->second;
if (op == Opcode::FL || op == Opcode::FS) {
if (func3 != 0x2 && func3 != 0x3) {
iType = InstType::V_TYPE;
}
}
switch (iType) {
case InstType::R_TYPE:
case InstType::R:
switch (op) {
case Opcode::FCI:
switch (func7) {
@ -567,73 +539,73 @@ std::shared_ptr<Instr> Decoder::decode(uint32_t code) const {
instr->setFunc7(func7);
break;
case InstType::I_TYPE: {
instr->addSrcReg(rs1, RegType::Integer);
if (op == Opcode::FL) {
instr->setDestReg(rd, RegType::Float);
} else {
instr->setDestReg(rd, RegType::Integer);
}
instr->setFunc3(func3);
instr->setFunc7(func7);
case InstType::I: {
switch (op) {
case Opcode::SYS_INST:
if (func3 != 0) {
// RV32I: CSR
if (func3 >= 5) {
// rs1 holds zimm
instr->setSrcReg(0, rs1, RegType::None);
}
} else {
instr->setDestReg(rd, RegType::None);
instr->setSrcReg(0, rs1, RegType::None);
}
// uint12
instr->setImm(code >> shift_rs2);
break;
case Opcode::FENCE:
// uint12
instr->setImm(code >> shift_rs2);
instr->setDestReg(rd, RegType::None);
instr->setSrcReg(0, rs1, RegType::None);
break;
case Opcode::I_INST:
case Opcode::I_INST_W:
case Opcode::I:
case Opcode::I_W:
case Opcode::JALR:
instr->setDestReg(rd, RegType::Integer);
instr->addSrcReg(rs1, RegType::Integer);
instr->setFunc3(func3);
if (func3 == 0x1 || func3 == 0x5) {
// Shift instructions
auto shamt = rs2; // uint5
#if (XLEN == 64)
if (op == Opcode::I_INST) {
if (op == Opcode::I) {
// uint6
shamt |= ((func7 & 0x1) << 5);
}
#endif
instr->setImm(shamt);
instr->setFunc7(func7);
} else {
// int12
auto imm = code >> shift_rs2;
instr->setImm(sext(imm, width_i_imm));
}
break;
default:
// int12
break;
case Opcode::L:
case Opcode::FL: {
instr->setDestReg(rd, (op == Opcode::FL) ? RegType::Float : RegType::Integer);
instr->addSrcReg(rs1, RegType::Integer);
instr->setFunc3(func3);
auto imm = code >> shift_rs2;
instr->setImm(sext(imm, width_i_imm));
} break;
case Opcode::FENCE:
instr->setFunc3(func3);
instr->setImm(code >> shift_rs2);
break;
case Opcode::SYS:
if (func3 != 0) {
// CSR instructions
instr->setDestReg(rd, RegType::Integer);
instr->setFunc3(func3);
if (func3 < 5) {
instr->addSrcReg(rs1, RegType::Integer);
} else {
// zimm
instr->addSrcReg(rs1, RegType::None);
}
instr->setImm(code >> shift_rs2);
} else {
// ECALL/EBREACK instructions
instr->setImm(code >> shift_rs2);
}
break;
default:
std::abort();
break;
}
} break;
case InstType::S_TYPE: {
case InstType::S: {
instr->addSrcReg(rs1, RegType::Integer);
if (op == Opcode::FS) {
instr->addSrcReg(rs2, RegType::Float);
} else {
instr->addSrcReg(rs2, RegType::Integer);
}
instr->addSrcReg(rs2, (op == Opcode::FS) ? RegType::Float : RegType::Integer);
instr->setFunc3(func3);
auto imm = (func7 << width_reg) | rd;
instr->setImm(sext(imm, width_i_imm));
} break;
case InstType::B_TYPE: {
case InstType::B: {
instr->addSrcReg(rs1, RegType::Integer);
instr->addSrcReg(rs2, RegType::Integer);
instr->setFunc3(func3);
@ -645,13 +617,13 @@ std::shared_ptr<Instr> Decoder::decode(uint32_t code) const {
instr->setImm(sext(imm, width_i_imm+1));
} break;
case InstType::U_TYPE: {
case InstType::U: {
instr->setDestReg(rd, RegType::Integer);
auto imm = code >> shift_func3;
instr->setImm(sext(imm, width_j_imm));
auto imm = (code >> shift_func3) << shift_func3;
instr->setImm(imm);
} break;
case InstType::J_TYPE: {
case InstType::J: {
instr->setDestReg(rd, RegType::Integer);
auto unordered = code >> shift_func3;
auto bits_19_12 = unordered & 0xff;
@ -661,56 +633,8 @@ std::shared_ptr<Instr> Decoder::decode(uint32_t code) const {
auto imm = (bits_10_1 << 1) | (bit_11 << 11) | (bits_19_12 << 12) | (bit_20 << 20);
instr->setImm(sext(imm, width_j_imm+1));
} break;
case InstType::V_TYPE:
switch (op) {
case Opcode::VSET: {
instr->setDestReg(rd, RegType::Vector);
instr->addSrcReg(rs1, RegType::Vector);
instr->setFunc3(func3);
if (func3 == 7) {
instr->setImm(!(code >> shift_vset));
if (instr->getImm()) {
auto immed = (code >> shift_rs2) & mask_v_imm;
instr->setImm(immed);
instr->setVlmul(immed & 0x3);
instr->setVediv((immed >> 4) & 0x3);
instr->setVsew((immed >> 2) & 0x3);
} else {
instr->addSrcReg(rs2, RegType::Vector);
}
} else {
instr->addSrcReg(rs2, RegType::Vector);
instr->setVmask((code >> shift_func7) & 0x1);
instr->setFunc6(func6);
}
} break;
case Opcode::FL:
instr->setDestReg(rd, RegType::Vector);
instr->addSrcReg(rs1, RegType::Vector);
instr->setVlsWidth(func3);
instr->addSrcReg(rs2, RegType::Vector);
instr->setVmask(code >> shift_func7);
instr->setVmop((code >> shift_vmop) & mask_func3);
instr->setVnf((code >> shift_vnf) & mask_func3);
break;
case Opcode::FS:
instr->setVs3(rd);
instr->addSrcReg(rs1, RegType::Vector);
instr->setVlsWidth(func3);
instr->addSrcReg(rs2, RegType::Vector);
instr->setVmask(code >> shift_func7);
instr->setVmop((code >> shift_vmop) & mask_func3);
instr->setVnf((code >> shift_vnf) & mask_func3);
break;
default:
std::abort();
}
break;
case R4_TYPE:
case InstType::R4:
if (op == Opcode::EXT2) {
switch (func3) {
case 1:
@ -737,6 +661,7 @@ std::shared_ptr<Instr> Decoder::decode(uint32_t code) const {
instr->setFunc2(func2);
instr->setFunc3(func3);
break;
default:
std::abort();
}

File diff suppressed because it is too large Load diff

View file

@ -19,18 +19,18 @@ namespace vortex {
class Warp;
enum Opcode {
enum class Opcode {
NONE = 0,
R_INST = 0x33,
L_INST = 0x3,
I_INST = 0x13,
S_INST = 0x23,
B_INST = 0x63,
LUI_INST = 0x37,
AUIPC_INST= 0x17,
JAL_INST = 0x6f,
JALR_INST = 0x67,
SYS_INST = 0x73,
R = 0x33,
L = 0x3,
I = 0x13,
S = 0x23,
B = 0x63,
LUI = 0x37,
AUIPC = 0x17,
JAL = 0x6f,
JALR = 0x67,
SYS = 0x73,
FENCE = 0x0f,
AMO = 0x2f,
// F Extension
@ -42,10 +42,8 @@ enum Opcode {
FMNMSUB = 0x4b,
FMNMADD = 0x4f,
// RV64 Standard Extension
R_INST_W = 0x3b,
I_INST_W = 0x1b,
// Vector Extension
VSET = 0x57,
R_W = 0x3b,
I_W = 0x1b,
// Custom Extensions
EXT1 = 0x0b,
EXT2 = 0x2b,
@ -53,15 +51,14 @@ enum Opcode {
EXT4 = 0x7b
};
enum InstType {
R_TYPE,
I_TYPE,
S_TYPE,
B_TYPE,
U_TYPE,
J_TYPE,
V_TYPE,
R4_TYPE
enum class InstType {
R,
I,
S,
B,
U,
J,
R4
};
class Instr {
@ -75,16 +72,7 @@ public:
, rdest_(0)
, func2_(0)
, func3_(0)
, func6_(0)
, func7_(0)
, vmask_(0)
, vlsWidth_(0)
, vMop_(0)
, vNf_(0)
, vs3_(0)
, vlmul_(0)
, vsew_(0)
, vediv_(0) {
, func7_(0) {
for (uint32_t i = 0; i < MAX_REG_SOURCES; ++i) {
rsrc_type_[i] = RegType::None;
rsrc_[i] = 0;
@ -110,20 +98,10 @@ public:
void setFunc3(uint32_t func3) { func3_ = func3; }
void setFunc7(uint32_t func7) { func7_ = func7; }
void setImm(uint32_t 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; }
Opcode getOpcode() const { return opcode_; }
uint32_t getFunc2() const { return func2_; }
uint32_t getFunc3() const { return func3_; }
uint32_t getFunc6() const { return func6_; }
uint32_t getFunc7() const { return func7_; }
uint32_t getNRSrc() const { return num_rsrcs_; }
uint32_t getRSrc(uint32_t i) const { return rsrc_[i]; }
@ -132,14 +110,6 @@ public:
RegType getRDType() const { return rdest_type_; }
bool hasImm() const { return has_imm_; }
uint32_t 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:
@ -157,19 +127,8 @@ private:
uint32_t rdest_;
uint32_t func2_;
uint32_t func3_;
uint32_t func6_;
uint32_t func7_;
// Vector
uint32_t vmask_;
uint32_t vlsWidth_;
uint32_t vMop_;
uint32_t vNf_;
uint32_t vs3_;
uint32_t vlmul_;
uint32_t vsew_;
uint32_t vediv_;
friend std::ostream &operator<<(std::ostream &, const Instr&);
};

View file

@ -32,7 +32,6 @@ public:
Scoreboard(const Arch &arch)
: in_use_iregs_(arch.num_warps())
, in_use_fregs_(arch.num_warps())
, in_use_vregs_(arch.num_warps())
{
this->clear();
}
@ -41,15 +40,13 @@ public:
for (uint32_t i = 0, n = in_use_iregs_.size(); i < n; ++i) {
in_use_iregs_.at(i).reset();
in_use_fregs_.at(i).reset();
in_use_vregs_.at(i).reset();
}
owners_.clear();
}
bool in_use(pipeline_trace_t* trace) const {
return (trace->used_iregs & in_use_iregs_.at(trace->wid)) != 0
|| (trace->used_fregs & in_use_fregs_.at(trace->wid)) != 0
|| (trace->used_vregs & in_use_vregs_.at(trace->wid)) != 0;
|| (trace->used_fregs & in_use_fregs_.at(trace->wid)) != 0;
}
std::vector<reg_use_t> get_uses(pipeline_trace_t* trace) const {
@ -57,7 +54,6 @@ public:
auto used_iregs = trace->used_iregs & in_use_iregs_.at(trace->wid);
auto used_fregs = trace->used_fregs & in_use_fregs_.at(trace->wid);
auto used_vregs = trace->used_vregs & in_use_vregs_.at(trace->wid);
for (uint32_t r = 0; r < MAX_NUM_REGS; ++r) {
if (used_iregs.test(r)) {
@ -75,14 +71,6 @@ public:
}
}
for (uint32_t r = 0; r < MAX_NUM_REGS; ++r) {
if (used_vregs.test(r)) {
uint32_t tag = (r << 16) | (trace->wid << 4) | (int)RegType::Vector;
auto owner = owners_.at(tag);
out.push_back({RegType::Vector, r, owner->exe_type, owner->sfu_type, owner->uuid});
}
}
return out;
}
@ -95,10 +83,8 @@ public:
case RegType::Float:
in_use_fregs_.at(trace->wid).set(trace->rdest);
break;
case RegType::Vector:
in_use_vregs_.at(trace->wid).set(trace->rdest);
break;
default: assert(false);
default:
assert(false);
}
uint32_t tag = (trace->rdest << 16) | (trace->wid << 4) | (int)trace->rdest_type;
assert(owners_.count(tag) == 0);
@ -115,10 +101,8 @@ public:
case RegType::Float:
in_use_fregs_.at(trace->wid).reset(trace->rdest);
break;
case RegType::Vector:
in_use_vregs_.at(trace->wid).reset(trace->rdest);
break;
default: assert(false);
default:
assert(false);
}
uint32_t tag = (trace->rdest << 16) | (trace->wid << 4) | (int)trace->rdest_type;
owners_.erase(tag);
@ -128,7 +112,6 @@ private:
std::vector<RegMask> in_use_iregs_;
std::vector<RegMask> in_use_fregs_;
std::vector<RegMask> in_use_vregs_;
std::unordered_map<uint32_t, pipeline_trace_t*> owners_;
};

View file

@ -60,8 +60,7 @@ typedef std::unordered_map<uint32_t, uint32_t> CSRs;
enum class RegType {
None,
Integer,
Float,
Vector
Float
};
inline std::ostream &operator<<(std::ostream &os, const RegType& type) {
@ -69,7 +68,6 @@ inline std::ostream &operator<<(std::ostream &os, const RegType& type) {
case RegType::None: break;
case RegType::Integer: os << "x"; break;
case RegType::Float: os << "f"; break;
case RegType::Vector: os << "v"; break;
default: assert(false);
}
return os;

View file

@ -29,7 +29,6 @@ Warp::Warp(Core *core, uint32_t warp_id)
, core_(core)
, ireg_file_(core->arch().num_threads(), std::vector<Word>(core->arch().num_regs()))
, freg_file_(core->arch().num_threads(), std::vector<uint64_t>(core->arch().num_regs()))
, vreg_file_(core->arch().num_threads(), std::vector<Byte>(core->arch().vsize()))
{
this->reset();
}
@ -48,9 +47,6 @@ void Warp::reset() {
for (auto& reg : freg_file_.at(i)) {
reg = 0;
}
for (auto& reg : vreg_file_.at(i)) {
reg = 0;
}
}
uui_gen_.reset();
}

View file

@ -101,7 +101,6 @@ private:
std::vector<std::vector<Word>> ireg_file_;
std::vector<std::vector<uint64_t>> freg_file_;
std::vector<std::vector<Byte>> vreg_file_;
std::stack<DomStackEntry> ipdom_stack_;
struct vtype vtype_;