From 73892c9b47984b1a1e4441ce4141aa0576147bf6 Mon Sep 17 00:00:00 2001 From: Xuan Hu Date: Tue, 21 Mar 2023 13:11:01 +0800 Subject: [PATCH] arch-riscv: Add risc-v vector regs and configs This commit add regs and configs for vector extension * Add 32 vector arch regs as spec defined and 8 internal regs for uop-based vector implementation. * Add default vector configs(VLEN = 256, ELEN = 64). These cannot be changed yet, since the vector implementation has only be tested with such configs. * Add disassamble register name v0~v31 and vtmp0~vtmp7. * Add CSR registers defined in RISCV Vector Spec v1.0. * Add vector bitfields. * Add vector operand_types and operands. Change-Id: I7bbab1ee9e0aa804d6f15ef7b77fac22d4f7212a Co-authored-by: Yang Liu Co-authored-by: Fan Yang <1209202421@qq.com> Co-authored-by: Jerin Joy arch-riscv: enable rvv flags only for RV64 Change-Id: I6586e322dfd562b598f63a18964d17326c14d4cf --- src/arch/riscv/faults.hh | 2 +- src/arch/riscv/isa.cc | 54 +++++++++++++++++-- src/arch/riscv/isa.hh | 2 + src/arch/riscv/isa/bitfields.isa | 24 +++++++++ src/arch/riscv/isa/includes.isa | 1 + src/arch/riscv/isa/operands.isa | 15 +++++- src/arch/riscv/regs/misc.hh | 31 +++++++++-- src/arch/riscv/regs/vector.hh | 90 ++++++++++++++++++++++++++++++++ src/arch/riscv/utility.hh | 10 +++- 9 files changed, 219 insertions(+), 10 deletions(-) create mode 100644 src/arch/riscv/regs/vector.hh diff --git a/src/arch/riscv/faults.hh b/src/arch/riscv/faults.hh index f687fd6f20..fa67e3b34c 100644 --- a/src/arch/riscv/faults.hh +++ b/src/arch/riscv/faults.hh @@ -173,7 +173,7 @@ class InstFault : public RiscvFault : RiscvFault(n, FaultType::OTHERS, INST_ILLEGAL), _inst(inst) {} - RegVal trap_value() const override { return bits(_inst, 31, 0); } + RegVal trap_value() const override { return _inst.instBits; } }; class UnknownInstFault : public InstFault diff --git a/src/arch/riscv/isa.cc b/src/arch/riscv/isa.cc index 94a8239bac..2f9d52e1b2 100644 --- a/src/arch/riscv/isa.cc +++ b/src/arch/riscv/isa.cc @@ -43,6 +43,7 @@ #include "arch/riscv/regs/float.hh" #include "arch/riscv/regs/int.hh" #include "arch/riscv/regs/misc.hh" +#include "arch/riscv/regs/vector.hh" #include "base/bitfield.hh" #include "base/compiler.hh" #include "base/logging.hh" @@ -52,6 +53,7 @@ #include "debug/LLSC.hh" #include "debug/MatRegs.hh" #include "debug/RiscvMisc.hh" +#include "debug/VecRegs.hh" #include "mem/packet.hh" #include "mem/request.hh" #include "params/RiscvISA.hh" @@ -189,6 +191,14 @@ namespace RiscvISA [MISCREG_FFLAGS] = "FFLAGS", [MISCREG_FRM] = "FRM", + [MISCREG_VSTART] = "VSTART", + [MISCREG_VXSAT] = "VXSAT", + [MISCREG_VXRM] = "VXRM", + [MISCREG_VCSR] = "VCSR", + [MISCREG_VL] = "VL", + [MISCREG_VTYPE] = "VTYPE", + [MISCREG_VLENB] = "VLENB", + [MISCREG_NMIVEC] = "NMIVEC", [MISCREG_NMIE] = "NMIE", [MISCREG_NMIP] = "NMIP", @@ -234,11 +244,10 @@ namespace { /* Not applicable to RISCV */ -RegClass vecRegClass(VecRegClass, VecRegClassName, 1, debug::IntRegs); -RegClass vecElemClass(VecElemClass, VecElemClassName, 2, debug::IntRegs); -RegClass vecPredRegClass(VecPredRegClass, VecPredRegClassName, 1, +RegClass vecElemClass(VecElemClass, VecElemClassName, 0, debug::IntRegs); +RegClass vecPredRegClass(VecPredRegClass, VecPredRegClassName, 0, debug::IntRegs); -RegClass matRegClass(MatRegClass, MatRegClassName, 1, debug::MatRegs); +RegClass matRegClass(MatRegClass, MatRegClassName, 0, debug::MatRegs); RegClass ccRegClass(CCRegClass, CCRegClassName, 0, debug::IntRegs); } // anonymous namespace @@ -275,6 +284,13 @@ ISA::copyRegsFrom(ThreadContext *src) for (auto &id: floatRegClass) tc->setReg(id, src->getReg(id)); + // Third loop through the vector registers. + RiscvISA::VecRegContainer vc; + for (auto &id: vecRegClass) { + src->getReg(id, &vc); + tc->setReg(id, &vc); + } + // Lastly copy PC/NPC tc->pcState(src->pcState()); } @@ -299,6 +315,7 @@ void ISA::clear() // mark FS is initial status.fs = INITIAL; + // rv_type dependent init. switch (rv_type) { case RV32: @@ -307,6 +324,8 @@ void ISA::clear() case RV64: misa.rv64_mxl = 2; status.uxl = status.sxl = 2; + status.vs = VPUStatus::INITIAL; + misa.rvv = 1; break; default: panic("%s: Unknown rv_type: %d", name(), (int)rv_type); @@ -479,6 +498,17 @@ ISA::readMiscReg(RegIndex idx) return readMiscRegNoEffect(idx); } + case MISCREG_VLENB: + { + return VLENB; + } + break; + case MISCREG_VCSR: + { + return readMiscRegNoEffect(MISCREG_VXSAT) & + (readMiscRegNoEffect(MISCREG_VXRM) << 1); + } + break; default: // Try reading HPM counters // As a placeholder, all HPM counters are just cycle counters @@ -652,6 +682,22 @@ ISA::setMiscReg(RegIndex idx, RegVal val) setMiscRegNoEffect(idx, val); } break; + case MISCREG_VXSAT: + { + setMiscRegNoEffect(idx, val & 0x1); + } + break; + case MISCREG_VXRM: + { + setMiscRegNoEffect(idx, val & 0x3); + } + break; + case MISCREG_VCSR: + { + setMiscRegNoEffect(MISCREG_VXSAT, val & 0x1); + setMiscRegNoEffect(MISCREG_VXRM, (val & 0x6) >> 1); + } + break; default: setMiscRegNoEffect(idx, val); } diff --git a/src/arch/riscv/isa.hh b/src/arch/riscv/isa.hh index 31001c04b4..d7b0a21a1f 100644 --- a/src/arch/riscv/isa.hh +++ b/src/arch/riscv/isa.hh @@ -67,6 +67,8 @@ enum FPUStatus DIRTY = 3, }; +using VPUStatus = FPUStatus; + class ISA : public BaseISA { protected: diff --git a/src/arch/riscv/isa/bitfields.isa b/src/arch/riscv/isa/bitfields.isa index 8589269949..280bcbab22 100644 --- a/src/arch/riscv/isa/bitfields.isa +++ b/src/arch/riscv/isa/bitfields.isa @@ -133,3 +133,27 @@ def bitfield BIT25 <25>; def bitfield RNUM <23:20>; def bitfield KFUNCT5 <29:25>; def bitfield BS <31:30>; + +// Vector instructions +def bitfield VFUNCT6 vfunct6; +def bitfield VFUNCT5 vfunct5; +def bitfield VFUNCT3 vfunct3; +def bitfield VFUNCT2 vfunct2; + +def bitfield VS3 vs3; +def bitfield VS2 vs2; +def bitfield VS1 vs1; +def bitfield VD vd; + +def bitfield NF nf; +def bitfield MEW mew; +def bitfield MOP mop; +def bitfield VM vm; +def bitfield LUMOP lumop; +def bitfield SUMOP sumop; +def bitfield WIDTH width; + +def bitfield BIT31 bit31; +def bitfield BIT30 bit30; +def bitfield SIMM5 uimm_vsetivli; +def bitfield SIMM3 simm3; diff --git a/src/arch/riscv/isa/includes.isa b/src/arch/riscv/isa/includes.isa index 8dddc2fb59..cb95f58f7e 100644 --- a/src/arch/riscv/isa/includes.isa +++ b/src/arch/riscv/isa/includes.isa @@ -95,6 +95,7 @@ output exec {{ #include "arch/riscv/reg_abi.hh" #include "arch/riscv/regs/float.hh" #include "arch/riscv/regs/misc.hh" +#include "arch/riscv/regs/vector.hh" #include "arch/riscv/utility.hh" #include "base/condcodes.hh" #include "cpu/base.hh" diff --git a/src/arch/riscv/isa/operands.isa b/src/arch/riscv/isa/operands.isa index 72d8f81bca..a81b28df57 100644 --- a/src/arch/riscv/isa/operands.isa +++ b/src/arch/riscv/isa/operands.isa @@ -38,7 +38,15 @@ def operand_types {{ 'sd' : 'int64_t', 'ud' : 'uint64_t', 'sf' : 'float', - 'df' : 'double' + 'df' : 'double', + + 'vi' : 'vi', + 'vu' : 'vu', + 'vwi' : 'vwi', + 'vwu' : 'vwu', + 'vext' : 'vext', + 'vextu' : 'vextu', + 'vc' : 'RiscvISA::VecRegContainer' }}; let {{ @@ -79,6 +87,11 @@ def operands {{ 'Fp2': FloatRegOp('df', 'FP2 + 8', 'IsFloating', 2), 'Fp2_bits': FloatRegOp('ud', 'FP2 + 8', 'IsFloating', 2), + 'Vd': VecRegOp('vc', 'VD', 'IsVector', 1), + 'Vs1': VecRegOp('vc', 'VS1', 'IsVector', 2), + 'Vs2': VecRegOp('vc', 'VS2', 'IsVector', 3), + 'Vs3': VecRegOp('vc', 'VS3', 'IsVector', 4), + #Memory Operand 'Mem': MemOp('ud', None, (None, 'IsLoad', 'IsStore'), 5), diff --git a/src/arch/riscv/regs/misc.hh b/src/arch/riscv/regs/misc.hh index 5ea3536141..64072c97e2 100644 --- a/src/arch/riscv/regs/misc.hh +++ b/src/arch/riscv/regs/misc.hh @@ -191,6 +191,14 @@ enum MiscRegIndex MISCREG_FFLAGS, MISCREG_FRM, + MISCREG_VSTART, + MISCREG_VXSAT, + MISCREG_VXRM, + MISCREG_VCSR, + MISCREG_VL, + MISCREG_VTYPE, + MISCREG_VLENB, + // These registers are not in the standard, hence does not exist in the // CSRData map. These are mainly used to provide a minimal implementation // for non-maskable-interrupt in our simple cpu. @@ -476,7 +484,15 @@ enum CSRIndex CSR_TDATA3 = 0x7A3, CSR_DCSR = 0x7B0, CSR_DPC = 0x7B1, - CSR_DSCRATCH = 0x7B2 + CSR_DSCRATCH = 0x7B2, + + CSR_VSTART = 0x008, + CSR_VXSAT = 0x009, + CSR_VXRM = 0x00A, + CSR_VCSR = 0x00F, + CSR_VL = 0xC20, + CSR_VTYPE = 0xC21, + CSR_VLENB = 0xC22 }; struct CSRMetadata @@ -718,7 +734,15 @@ const std::unordered_map CSRData = { {CSR_TDATA3, {"tdata3", MISCREG_TDATA3, rvTypeFlags(RV64, RV32)}}, {CSR_DCSR, {"dcsr", MISCREG_DCSR, rvTypeFlags(RV64, RV32)}}, {CSR_DPC, {"dpc", MISCREG_DPC, rvTypeFlags(RV64, RV32)}}, - {CSR_DSCRATCH, {"dscratch", MISCREG_DSCRATCH, rvTypeFlags(RV64, RV32)}} + {CSR_DSCRATCH, {"dscratch", MISCREG_DSCRATCH, rvTypeFlags(RV64, RV32)}}, + + {CSR_VSTART, {"vstart", MISCREG_VSTART, rvTypeFlags(RV64, RV32)}}, + {CSR_VXSAT, {"vxsat" , MISCREG_VXSAT, rvTypeFlags(RV64, RV32)}}, + {CSR_VXRM, {"vxrm" , MISCREG_VXRM, rvTypeFlags(RV64, RV32)}}, + {CSR_VCSR, {"vcsr" , MISCREG_VCSR, rvTypeFlags(RV64, RV32)}}, + {CSR_VL, {"vl" , MISCREG_VL, rvTypeFlags(RV64, RV32)}}, + {CSR_VTYPE, {"vtype" , MISCREG_VTYPE, rvTypeFlags(RV64, RV32)}}, + {CSR_VLENB, {"VLENB" , MISCREG_VLENB, rvTypeFlags(RV64, RV32)}} }; /** @@ -816,6 +840,7 @@ const off_t SBE_OFFSET[enums::Num_RiscvType] = { const off_t SXL_OFFSET = 34; const off_t UXL_OFFSET = 32; const off_t FS_OFFSET = 13; +const off_t VS_OFFSET = 9; const off_t FRM_OFFSET = 5; const RegVal ISA_MXL_MASKS[enums::Num_RiscvType] = { @@ -853,7 +878,7 @@ const RegVal STATUS_MPRV_MASK = 1ULL << 17; const RegVal STATUS_XS_MASK = 3ULL << 15; const RegVal STATUS_FS_MASK = 3ULL << FS_OFFSET; const RegVal STATUS_MPP_MASK = 3ULL << 11; -const RegVal STATUS_VS_MASK = 3ULL << 9; +const RegVal STATUS_VS_MASK = 3ULL << VS_OFFSET; const RegVal STATUS_SPP_MASK = 1ULL << 8; const RegVal STATUS_MPIE_MASK = 1ULL << 7; const RegVal STATUS_SPIE_MASK = 1ULL << 5; diff --git a/src/arch/riscv/regs/vector.hh b/src/arch/riscv/regs/vector.hh new file mode 100644 index 0000000000..d722c2d03a --- /dev/null +++ b/src/arch/riscv/regs/vector.hh @@ -0,0 +1,90 @@ +/* + * Copyright (c) 2022 PLCT Lab + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer; + * redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution; + * neither the name of the copyright holders nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + + +#ifndef __ARCH_RISCV_REGS_VECTOR_HH__ +#define __ARCH_RISCV_REGS_VECTOR_HH__ + +#include +#include +#include + +#include "arch/generic/vec_pred_reg.hh" +#include "arch/generic/vec_reg.hh" +#include "base/bitunion.hh" +#include "cpu/reg_class.hh" +#include "debug/VecRegs.hh" + +namespace gem5 +{ + +namespace RiscvISA +{ + +constexpr unsigned ELEN = 64; +constexpr unsigned VLEN = 256; +constexpr unsigned VLENB = VLEN / 8; + +using VecRegContainer = gem5::VecRegContainer; +using vreg_t = VecRegContainer; + +const int NumVecStandardRegs = 32; +const int NumVecInternalRegs = 8; // Used by vector uop +const int NumVecRegs = NumVecStandardRegs + NumVecInternalRegs; + +const std::vector VecRegNames = { + "v0", "v1", "v2", "v3", "v4", "v5", "v6", "v7", + "v8", "v9", "v10", "v11", "v12", "v13", "v14", "v15", + "v16", "v17", "v18", "v19", "v20", "v21", "v22", "v23", + "v24", "v25", "v26", "v27", "v28", "v29", "v30", "v31", + "vtmp0", "vtmp1", "vtmp2", "vtmp3", "vtmp4", "vtmp5", "vtmp6", "vtmp7" +}; + +// vector index +const int VecMemInternalReg0 = NumVecStandardRegs; + +static inline TypedRegClassOps vecRegClassOps; + +inline constexpr RegClass vecRegClass = + RegClass(VecRegClass, VecRegClassName, NumVecRegs, debug::VecRegs). + ops(vecRegClassOps). + regType(); + +BitUnion32(VTYPE) + Bitfield<31> vill; + Bitfield<7, 0> vtype8; + Bitfield<7> vma; + Bitfield<6> vta; + Bitfield<5, 3> vsew; + Bitfield<2, 0> vlmul; +EndBitUnion(VTYPE) + +} // namespace RiscvISA +} // namespace gem5 + +#endif // __ARCH_RISCV_REGS_VECTOR_HH__ diff --git a/src/arch/riscv/utility.hh b/src/arch/riscv/utility.hh index 5fccc84c79..e0a8494ece 100644 --- a/src/arch/riscv/utility.hh +++ b/src/arch/riscv/utility.hh @@ -51,6 +51,7 @@ #include "arch/riscv/regs/float.hh" #include "arch/riscv/regs/int.hh" +#include "arch/riscv/regs/vector.hh" #include "base/types.hh" #include "cpu/reg_class.hh" #include "cpu/static_inst.hh" @@ -130,7 +131,14 @@ registerName(RegId reg) return str.str(); } return float_reg::RegNames[reg.index()]; - } else { + } else if (reg.is(VecRegClass)) { + if (reg.index() >= NumVecRegs) { + std::stringstream str; + str << "?? (v" << reg.index() << ')'; + return str.str(); + } + return VecRegNames[reg.index()]; + } else { /* It must be an InvalidRegClass, in RISC-V we should treat it as a * zero register for the disassembler to work correctly. */