From e14e066fde5516b7ab3921687248f9b74219bdf0 Mon Sep 17 00:00:00 2001 From: Xuan Hu Date: Tue, 21 Feb 2023 11:48:54 +0800 Subject: [PATCH] arch-riscv: Add risc-v vector ext v1.0 vset insts support Change-Id: I84363164ca327151101e8a1c3d8441a66338c909 Co-authored-by: Yang Liu Co-authored-by: Fan Yang <1209202421@qq.com> arch-riscv: Add a todo to fix vsetvl stall on decode Change-Id: Iafb129648fba89009345f0c0ad3710f773379bf6 --- src/arch/riscv/decoder.cc | 27 +++++ src/arch/riscv/decoder.hh | 12 +- src/arch/riscv/insts/SConscript | 1 + src/arch/riscv/insts/static_inst.hh | 1 + src/arch/riscv/insts/vector.cc | 126 +++++++++++++++++++++ src/arch/riscv/insts/vector.hh | 88 ++++++++++++++ src/arch/riscv/isa/decoder.isa | 33 ++++++ src/arch/riscv/isa/formats/formats.isa | 1 + src/arch/riscv/isa/formats/vector_conf.isa | 96 ++++++++++++++++ src/arch/riscv/isa/includes.isa | 2 + 10 files changed, 386 insertions(+), 1 deletion(-) create mode 100644 src/arch/riscv/insts/vector.cc create mode 100644 src/arch/riscv/insts/vector.hh create mode 100644 src/arch/riscv/isa/formats/vector_conf.isa diff --git a/src/arch/riscv/decoder.cc b/src/arch/riscv/decoder.cc index 7faa310b1e..ce362ad522 100644 --- a/src/arch/riscv/decoder.cc +++ b/src/arch/riscv/decoder.cc @@ -42,6 +42,7 @@ void Decoder::reset() { aligned = true; mid = false; + vConfigDone = true; machInst = 0; emi = 0; } @@ -49,6 +50,15 @@ void Decoder::reset() void Decoder::moreBytes(const PCStateBase &pc, Addr fetchPC) { + // TODO: Current vsetvl instructions stall decode. Future fixes should + // enable speculation, and this code will be removed. + if (GEM5_UNLIKELY(!this->vConfigDone)) { + DPRINTF(Decode, "Waiting for vset*vl* to be executed\n"); + instDone = false; + outOfBytes = false; + return; + } + // The MSB of the upper and lower halves of a machine instruction. constexpr size_t max_bit = sizeof(machInst) * 8 - 1; constexpr size_t mid_bit = sizeof(machInst) * 4 - 1; @@ -78,6 +88,14 @@ Decoder::moreBytes(const PCStateBase &pc, Addr fetchPC) instDone = compressed(emi); } } + if (instDone) { + emi.vl = this->machVl; + emi.vtype8 = this->machVtype & 0xff; + emi.vill = this->machVtype.vill; + if (vconf(emi)) { + this->vConfigDone = false; // set true when vconfig inst execute + } + } } StaticInstPtr @@ -116,5 +134,14 @@ Decoder::decode(PCStateBase &_next_pc) return decode(emi, next_pc.instAddr()); } +void +Decoder::setVlAndVtype(uint32_t vl, VTYPE vtype) +{ + this->machVtype = vtype; + this->machVl = vl; + + this->vConfigDone = true; +} + } // namespace RiscvISA } // namespace gem5 diff --git a/src/arch/riscv/decoder.hh b/src/arch/riscv/decoder.hh index 15cbefe39c..d1d2f3cb0c 100644 --- a/src/arch/riscv/decoder.hh +++ b/src/arch/riscv/decoder.hh @@ -32,6 +32,7 @@ #include "arch/generic/decode_cache.hh" #include "arch/generic/decoder.hh" +#include "arch/riscv/insts/vector.hh" #include "arch/riscv/types.hh" #include "base/logging.hh" #include "base/types.hh" @@ -53,12 +54,16 @@ class Decoder : public InstDecoder decode_cache::InstMap instMap; bool aligned; bool mid; + bool vConfigDone; protected: //The extended machine instruction being generated ExtMachInst emi; uint32_t machInst; + VTYPE machVtype; + uint32_t machVl; + StaticInstPtr decodeInst(ExtMachInst mach_inst); /// Decode a machine instruction. @@ -74,13 +79,18 @@ class Decoder : public InstDecoder void reset() override; - inline bool compressed(ExtMachInst inst) { return (inst & 0x3) < 0x3; } + inline bool compressed(ExtMachInst inst) { return inst.quadRant < 0x3; } + inline bool vconf(ExtMachInst inst) { + return inst.opcode == 0b1010111u && inst.funct3 == 0b111u; + } //Use this to give data to the decoder. This should be used //when there is control flow. void moreBytes(const PCStateBase &pc, Addr fetchPC) override; StaticInstPtr decode(PCStateBase &nextPC) override; + + void setVlAndVtype(uint32_t vl, VTYPE vtype); }; } // namespace RiscvISA diff --git a/src/arch/riscv/insts/SConscript b/src/arch/riscv/insts/SConscript index 704152c040..2822cf86b4 100644 --- a/src/arch/riscv/insts/SConscript +++ b/src/arch/riscv/insts/SConscript @@ -33,3 +33,4 @@ Source('compressed.cc', tags='riscv isa') Source('mem.cc', tags='riscv isa') Source('standard.cc', tags='riscv isa') Source('static_inst.cc', tags='riscv isa') +Source('vector.cc', tags='riscv isa') diff --git a/src/arch/riscv/insts/static_inst.hh b/src/arch/riscv/insts/static_inst.hh index f835713505..74f9ddb452 100644 --- a/src/arch/riscv/insts/static_inst.hh +++ b/src/arch/riscv/insts/static_inst.hh @@ -33,6 +33,7 @@ #include #include "arch/riscv/pcstate.hh" +#include "arch/riscv/regs/misc.hh" #include "arch/riscv/types.hh" #include "cpu/exec_context.hh" #include "cpu/static_inst.hh" diff --git a/src/arch/riscv/insts/vector.cc b/src/arch/riscv/insts/vector.cc new file mode 100644 index 0000000000..3965a45b26 --- /dev/null +++ b/src/arch/riscv/insts/vector.cc @@ -0,0 +1,126 @@ +/* + * 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. + */ + +#include "arch/riscv/insts/vector.hh" + +#include +#include + +#include "arch/riscv/insts/static_inst.hh" +#include "arch/riscv/utility.hh" +#include "cpu/static_inst.hh" + +namespace gem5 +{ + +namespace RiscvISA +{ + +/** + * This function translates the 3-bit value of vlmul bits to the corresponding + * lmul value as specified in RVV 1.0 spec p11-12 chapter 3.4.2. + * + * I.e., + * vlmul = -3 -> LMUL = 1/8 + * vlmul = -2 -> LMUL = 1/4 + * vlmul = -1 -> LMUL = 1/2 + * vlmul = 0 -> LMUL = 1 + * vlmul = 1 -> LMUL = 2 + * vlmul = 2 -> LMUL = 4 + * vlmul = 3 -> LMUL = 8 + * +**/ +float +getVflmul(uint32_t vlmul_encoding) { + int vlmul = sext<3>(vlmul_encoding & 7); + float vflmul = vlmul >= 0 ? 1 << vlmul : 1.0 / (1 << -vlmul); + return vflmul; +} + +uint32_t +getVlmax(VTYPE vtype, uint32_t vlen) { + uint32_t sew = getSew(vtype.vsew); + // vlmax is defined in RVV 1.0 spec p12 chapter 3.4.2. + uint32_t vlmax = (vlen/sew) * getVflmul(vtype.vlmul); + return vlmax; +} + +std::string +VConfOp::generateDisassembly(Addr pc, const loader::SymbolTable *symtab) const +{ + std::stringstream ss; + ss << mnemonic << ' ' << registerName(destRegIdx(0)) << ", "; + if (bit31 && bit30 == 0) { + ss << registerName(srcRegIdx(0)) << ", " << registerName(srcRegIdx(1)); + } else if (bit31 && bit30) { + ss << uimm << ", " << generateZimmDisassembly(); + } else { + ss << registerName(srcRegIdx(0)) << ", " << generateZimmDisassembly(); + } + return ss.str(); +} + +std::string +VConfOp::generateZimmDisassembly() const +{ + std::stringstream s; + + // VSETIVLI uses ZIMM10 and VSETVLI uses ZIMM11 + uint64_t zimm = (bit31 && bit30) ? zimm10 : zimm11; + + bool frac_lmul = bits(zimm, 2); + int sew = 1 << (bits(zimm, 5, 3) + 3); + int lmul = bits(zimm, 1, 0); + auto vta = bits(zimm, 6) == 1 ? "ta" : "tu"; + auto vma = bits(zimm, 7) == 1 ? "ma" : "mu"; + s << "e" << sew; + if (frac_lmul) { + std::string lmul_str = ""; + switch(lmul){ + case 3: + lmul_str = "f2"; + break; + case 2: + lmul_str = "f4"; + break; + case 1: + lmul_str = "f8"; + break; + default: + panic("Unsupport fractional LMUL"); + } + s << ", m" << lmul_str; + } else { + s << ", m" << (1 << lmul); + } + s << ", " << vta << ", " << vma; + return s.str(); +} + +} // namespace RiscvISA +} // namespace gem5 diff --git a/src/arch/riscv/insts/vector.hh b/src/arch/riscv/insts/vector.hh new file mode 100644 index 0000000000..cdeb48360c --- /dev/null +++ b/src/arch/riscv/insts/vector.hh @@ -0,0 +1,88 @@ +/* + * 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_INSTS_VECTOR_HH__ +#define __ARCH_RISCV_INSTS_VECTOR_HH__ + +#include + +#include "arch/riscv/insts/static_inst.hh" +#include "arch/riscv/regs/misc.hh" +#include "arch/riscv/regs/vector.hh" +#include "arch/riscv/utility.hh" +#include "cpu/exec_context.hh" +#include "cpu/static_inst.hh" + +namespace gem5 +{ + +namespace RiscvISA +{ + +float +getVflmul(uint32_t vlmul_encoding); + +inline uint32_t getSew(uint32_t vsew) { + assert(vsew <= 3); + return (8 << vsew); +} + +uint32_t +getVlmax(VTYPE vtype, uint32_t vlen); + +/** + * Base class for Vector Config operations + */ +class VConfOp : public RiscvStaticInst +{ + protected: + uint64_t bit30; + uint64_t bit31; + uint64_t zimm10; + uint64_t zimm11; + uint64_t uimm; + VConfOp(const char *mnem, ExtMachInst _extMachInst, OpClass __opClass) + : RiscvStaticInst(mnem, _extMachInst, __opClass), + bit30(_extMachInst.bit30), bit31(_extMachInst.bit31), + zimm10(_extMachInst.zimm_vsetivli), + zimm11(_extMachInst.zimm_vsetvli), + uimm(_extMachInst.uimm_vsetivli) + {} + + std::string generateDisassembly( + Addr pc, const loader::SymbolTable *symtab) const override; + + std::string generateZimmDisassembly() const; +}; + + +} // namespace RiscvISA +} // namespace gem5 + + +#endif // __ARCH_RISCV_INSTS_VECTOR_HH__ diff --git a/src/arch/riscv/isa/decoder.isa b/src/arch/riscv/isa/decoder.isa index a339c11375..2e5b52a879 100644 --- a/src/arch/riscv/isa/decoder.isa +++ b/src/arch/riscv/isa/decoder.isa @@ -2012,6 +2012,39 @@ decode QUADRANT default Unknown::unknown() { } } + 0x15: decode FUNCT3 { + 0x7: decode BIT31 { + format VConfOp { + 0x0: vsetvli({{ + uint64_t rd_bits = RD; + uint64_t rs1_bits = RS1; + uint64_t requested_vl = Rs1_ud; + uint64_t requested_vtype = zimm11; + + Rd_ud = 0; + }}, VectorConfigOp, IsDirectControl, IsCondControl); + 0x1: decode BIT30 { + 0x0: vsetvl({{ + uint64_t rd_bits = RD; + uint64_t rs1_bits = RS1; + uint64_t requested_vl = Rs1_ud; + uint64_t requested_vtype = Rs2_ud; + + Rd_ud = 0; + }}, VectorConfigOp, IsDirectControl, IsCondControl); + 0x1: vsetivli({{ + uint64_t rd_bits = RD; + uint64_t rs1_bits = -1; + uint64_t requested_vl = uimm; + uint64_t requested_vtype = zimm10; + + Rd_ud = 0; + }}, VectorConfigOp, IsDirectControl, IsCondControl); + } + } + } + } + 0x18: decode FUNCT3 { format BOp { 0x0: beq({{ diff --git a/src/arch/riscv/isa/formats/formats.isa b/src/arch/riscv/isa/formats/formats.isa index 19749438a8..0f7c94da9a 100644 --- a/src/arch/riscv/isa/formats/formats.isa +++ b/src/arch/riscv/isa/formats/formats.isa @@ -37,6 +37,7 @@ ##include "fp.isa" ##include "amo.isa" ##include "bs.isa" +##include "vector_conf.isa" // Include formats for nonstandard extensions ##include "compressed.isa" diff --git a/src/arch/riscv/isa/formats/vector_conf.isa b/src/arch/riscv/isa/formats/vector_conf.isa new file mode 100644 index 0000000000..556e230075 --- /dev/null +++ b/src/arch/riscv/isa/formats/vector_conf.isa @@ -0,0 +1,96 @@ +// -*- mode:c++ -*- + +// 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. + + +def format VConfOp(code, *flags) {{ + iop = InstObjParams(name, Name, 'VConfOp', code, flags) + header_output = BasicDeclare.subst(iop) + decoder_output = BasicConstructor.subst(iop) + decode_block = BasicDecode.subst(iop) + exec_output = VConfExecute.subst(iop) +}}; + +def template VConfExecute {{ + Fault + %(class_name)s::execute(ExecContext *xc, + trace::InstRecord *traceData) const + { + auto tc = xc->tcBase(); + + %(op_decl)s; + %(op_rd)s; + %(code)s; + + tc->setMiscReg(MISCREG_VSTART, 0); + + uint32_t vlen = xc->readMiscReg(MISCREG_VLENB) * 8; + uint32_t vlmax = getVlmax(xc->readMiscReg(MISCREG_VTYPE), vlen); + + VTYPE new_vtype = requested_vtype; + if (xc->readMiscReg(MISCREG_VTYPE) != new_vtype) { + vlmax = getVlmax(new_vtype, vlen); + + float vflmul = getVflmul(new_vtype.vlmul); + + uint32_t sew = getSew(new_vtype.vsew); + + uint32_t new_vill = + !(vflmul >= 0.125 && vflmul <= 8) || + sew > std::min(vflmul, 1.0f) * ELEN || + bits(requested_vtype, 30, 8) != 0; + if (new_vill) { + vlmax = 0; + new_vtype = 0; + new_vtype.vill = 1; + } + + xc->setMiscReg(MISCREG_VTYPE, new_vtype); + } + + uint32_t current_vl = xc->readMiscReg(MISCREG_VL); + uint32_t new_vl = 0; + if (vlmax == 0) { + new_vl = 0; + } else if (rd_bits == 0 && rs1_bits == 0) { + new_vl = current_vl > vlmax ? vlmax : current_vl; + } else if (rd_bits != 0 && rs1_bits == 0) { + new_vl = vlmax; + } else if (rs1_bits != 0) { + new_vl = requested_vl > vlmax ? vlmax : requested_vl; + } + + xc->setMiscReg(MISCREG_VL, new_vl); + + tc->getDecoderPtr()->as().setVlAndVtype(new_vl, new_vtype); + + Rd = new_vl; + + %(op_wb)s; + return NoFault; + } +}}; diff --git a/src/arch/riscv/isa/includes.isa b/src/arch/riscv/isa/includes.isa index cb95f58f7e..1d544f40ed 100644 --- a/src/arch/riscv/isa/includes.isa +++ b/src/arch/riscv/isa/includes.isa @@ -34,6 +34,7 @@ // output header {{ +#include #include #include #include @@ -45,6 +46,7 @@ output header {{ #include #include +#include "arch/riscv/decoder.hh" #include "arch/riscv/insts/amo.hh" #include "arch/riscv/insts/bs.hh" #include "arch/riscv/insts/compressed.hh"