1/**************************************************************************************** 2 * Copyright (c) 2020-2021 Institute of Computing Technology, Chinese Academy of Sciences 3 * Copyright (c) 2020-2021 Peng Cheng Laboratory 4 * 5 * XiangShan is licensed under Mulan PSL v2. 6 * You can use this software according to the terms and conditions of the Mulan PSL v2. 7 * You may obtain a copy of Mulan PSL v2 at: 8 * http://license.coscl.org.cn/MulanPSL2 9 * 10 * THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, 11 * EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, 12 * MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE. 13 * 14 * See the Mulan PSL v2 for more details. 15 **************************************************************************************** 16 */ 17 18 19package xiangshan.backend.fu.vector 20 21import chipsalliance.rocketchip.config.Parameters 22import chisel3._ 23import chisel3.util._ 24import utils._ 25import utility._ 26import yunsuan.vector.VectorIntAdder 27import yunsuan.vector.alu.{VAluOpcode, VIAlu} 28import yunsuan.{VectorElementFormat, VipuType} 29import xiangshan.{SelImm, SrcType, UopDivType, XSCoreParamsKey, XSModule} 30 31import scala.collection.Seq 32 33class VIPU(implicit p: Parameters) extends VPUSubModule(p(XSCoreParamsKey).VLEN) { 34 XSError(io.in.valid && io.in.bits.uop.ctrl.fuOpType === VipuType.dummy, "VIPU OpType not supported") 35 36// extra io 37 val vxrm = IO(Input(UInt(2.W))) 38 39// def some signal 40 val dataReg = Reg(io.out.bits.data.cloneType) 41 val dataWire = Wire(dataReg.cloneType) 42 val s_idle :: s_compute :: s_finish :: Nil = Enum(3) 43 val state = RegInit(s_idle) 44 val vialu = Module(new VIAluWrapper) 45 val outValid = vialu.io.out.valid 46 val outFire = vialu.io.out.fire() 47 48// reg input signal 49 val s0_uopReg = Reg(io.in.bits.uop.cloneType) 50 val inHs = io.in.fire() 51 when(inHs && state === s_idle){ 52 s0_uopReg := io.in.bits.uop 53 } 54 dataReg := Mux(outValid, dataWire, dataReg) 55 56// fsm 57 switch (state) { 58 is (s_idle) { 59 state := Mux(inHs, s_compute, s_idle) 60 } 61 is (s_compute) { 62 state := Mux(outValid, Mux(outFire, s_idle, s_finish), 63 s_compute) 64 } 65 is (s_finish) { 66 state := Mux(io.out.fire(), s_idle, s_finish) 67 } 68 } 69 70// connect VIAlu 71 dataWire := vialu.io.out.bits.data 72 vialu.io.in.bits <> io.in.bits 73 vialu.io.redirectIn := DontCare // TODO : 74 vialu.vxrm := vxrm 75 io.out.bits.data := Mux(state === s_compute && outFire, dataWire, dataReg) 76 io.out.bits.uop := s0_uopReg 77 78 vialu.io.in.valid := io.in.valid && state === s_idle 79 io.out.valid := state === s_compute && outValid || state === s_finish 80 vialu.io.out.ready := io.out.ready 81 io.in.ready := state === s_idle 82} 83 84class VIAluDecodeResultBundle extends Bundle { 85 val opcode = UInt(6.W) 86 val srcType = Vec(2, UInt(4.W)) 87 val vdType = UInt(4.W) 88} 89 90class VIAluDecoder (implicit p: Parameters) extends XSModule { 91 val io = IO(new Bundle{ 92 val in = Input(new Bundle{ 93 val fuOpType = UInt(8.W) 94 val sew = UInt(2.W) 95 }) 96 val out = Output(new VIAluDecodeResultBundle) 97 }) 98 99// val DecodeDefault = List(VAluOpcode.dummy, VpuDataType.dummy, VpuDataType.dummy, VpuDataType.dummy) 100// val DecodeTable = Array( 101// BitPat("b" + Cat(VipuType.add, "b00".U).litValue().toString()) -> List(VAluOpcode.vadd, VpuDataType.s8, VpuDataType.s8, VpuDataType.s8), 102// BitPat("b" + Cat(VipuType.add, "b01".U).litValue().toString()) -> List(VAluOpcode.vadd, VpuDataType.s16, VpuDataType.s16, VpuDataType.s16), 103// BitPat("b" + Cat(VipuType.add, "b10".U).litValue().toString()) -> List(VAluOpcode.vadd, VpuDataType.s32, VpuDataType.s32, VpuDataType.s32), 104// BitPat("b" + Cat(VipuType.add, "b11".U).litValue().toString()) -> List(VAluOpcode.vadd, VpuDataType.s64, VpuDataType.s64, VpuDataType.s64), 105// ) 106// val opcode :: srcType1 :: srcType2 :: vdType :: Nil = ListLookup(Cat(io.in.fuOpType, io.in.sew), DecodeDefault, DecodeTable) 107 108 109 val out = LookupTree(io.in.fuOpType, List( 110 VipuType.add -> Cat(VAluOpcode.vadd, Cat(0.U(2.W), io.in.sew), Cat(0.U(2.W), io.in.sew), Cat(0.U(2.W), io.in.sew)).asUInt() 111 )).asTypeOf(new VIAluDecodeResultBundle) 112 113 io.out <> out 114} 115 116class VIAluWrapper(implicit p: Parameters) extends VPUSubModule(p(XSCoreParamsKey).VLEN) { 117 XSError(io.in.valid && io.in.bits.uop.ctrl.fuOpType === VipuType.dummy, "VIPU OpType not supported") 118 119// extra io 120 val vxrm = IO(Input(UInt(2.W))) 121 122// rename signal 123 val in = io.in.bits 124 val ctrl = in.uop.ctrl 125 val vtype = ctrl.vconfig.vtype 126 127// generate src1 and src2 128 val imm = VecInit(Seq.fill(VLEN/XLEN)(VecImmExtractor(ctrl.selImm, vtype.vsew, ctrl.imm))).asUInt 129 val _src1 = Mux(SrcType.isImm(ctrl.srcType(0)), imm, Mux(ctrl.uopDivType === UopDivType.VEC_MV_LMUL, VecExtractor(vtype.vsew, io.in.bits.src(0)), io.in.bits.src(0))) 130 val _src2 = in.src(1) 131 val src1 = Mux(VipuType.needReverse(ctrl.fuOpType), _src2, _src1) 132 val src2 = Mux(VipuType.needReverse(ctrl.fuOpType), _src1, _src2) 133 134// connect VIAlu 135 val decoder = Module(new VIAluDecoder) 136 val vialu = Module(new VIAlu) 137 decoder.io.in.fuOpType := in.uop.ctrl.fuType 138 decoder.io.in.sew := in.uop.ctrl.vconfig.vtype.vsew(1,0) 139 140 vialu.io.in.bits.opcode := decoder.io.out.opcode 141 vialu.io.in.bits.info.vm := in.uop.ctrl.vm 142 vialu.io.in.bits.info.ma := in.uop.ctrl.vconfig.vtype.vma 143 vialu.io.in.bits.info.ta := in.uop.ctrl.vconfig.vtype.vta 144 vialu.io.in.bits.info.vlmul := in.uop.ctrl.vconfig.vtype.vlmul 145 vialu.io.in.bits.info.vl := in.uop.ctrl.vconfig.vl 146// vialu.io.in.bits.info.vstart := 0.U // TODO : 147 vialu.io.in.bits.info.uopIdx := in.uop.ctrl.uopIdx 148 vialu.io.in.bits.info.vxrm := vxrm 149 vialu.io.in.bits.srcType(0) := decoder.io.out.srcType(0) 150 vialu.io.in.bits.srcType(1) := decoder.io.out.srcType(1) 151 vialu.io.in.bits.vdType := decoder.io.out.vdType 152 vialu.io.in.bits.vs1 := src1 153 vialu.io.in.bits.vs2 := src2 154 vialu.io.in.bits.old_vd := in.src(2) 155 vialu.io.in.bits.mask := in.src(3) 156 157 val vdOut = vialu.io.out.bits.vd 158 val vxsatOut = vialu.io.out.bits.vxsat 159 160 vialu.io.in.valid := io.in.valid 161 162// connect io 163 io.out.bits.data := vdOut 164 io.out.bits.uop := DontCare 165 io.out.valid := vialu.io.out.valid 166 io.in.ready := DontCare 167} 168 169object VecImmExtractor { 170 def Imm_OPIVIS(imm: UInt): UInt = { 171 SignExt(imm(4,0), 8) 172 } 173 def Imm_OPIVIU(imm: UInt): UInt = { 174 ZeroExt(imm(4,0), 8) 175 } 176 177 def imm_sew(sew: UInt, imm: UInt): UInt = { 178 val _imm = SignExt(imm(7,0), 64) 179 LookupTree(sew(1,0), List( 180 "b00".U -> VecInit(Seq.fill(8)(_imm(7,0))).asUInt, 181 "b01".U -> VecInit(Seq.fill(4)(_imm(15,0))).asUInt, 182 "b10".U -> VecInit(Seq.fill(2)(_imm(31,0))).asUInt, 183 "b11".U -> _imm(63,0), 184 )) 185 } 186 187 def apply(immType: UInt, sew: UInt, imm: UInt): UInt = { 188 val _imm = Mux(immType === SelImm.IMM_OPIVIS, Imm_OPIVIS(imm), Imm_OPIVIU(imm)) 189 imm_sew(sew, _imm(7,0)) 190 } 191} 192