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 <numbksco@gmail.com>
Co-authored-by: Fan Yang <1209202421@qq.com>
Co-authored-by: Jerin Joy <joy@rivosinc.com>

arch-riscv: enable rvv flags only for RV64

Change-Id: I6586e322dfd562b598f63a18964d17326c14d4cf
This commit is contained in:
Xuan Hu
2023-03-21 13:11:01 +08:00
committed by Adrià Armejach
parent dceabe5fda
commit 73892c9b47
9 changed files with 219 additions and 10 deletions

View File

@@ -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

View File

@@ -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);
}

View File

@@ -67,6 +67,8 @@ enum FPUStatus
DIRTY = 3,
};
using VPUStatus = FPUStatus;
class ISA : public BaseISA
{
protected:

View File

@@ -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;

View File

@@ -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"

View File

@@ -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),

View File

@@ -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<int, CSRMetadata> 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;

View File

@@ -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 <cstdint>
#include <string>
#include <vector>
#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<VLENB>;
using vreg_t = VecRegContainer;
const int NumVecStandardRegs = 32;
const int NumVecInternalRegs = 8; // Used by vector uop
const int NumVecRegs = NumVecStandardRegs + NumVecInternalRegs;
const std::vector<std::string> 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<RiscvISA::VecRegContainer> vecRegClassOps;
inline constexpr RegClass vecRegClass =
RegClass(VecRegClass, VecRegClassName, NumVecRegs, debug::VecRegs).
ops(vecRegClassOps).
regType<VecRegContainer>();
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__

View File

@@ -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.
*/