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 val vxsat = IO(Output(UInt(1.W))) 39 40// def some signal 41 val dataReg = Reg(io.out.bits.data.cloneType) 42 val dataWire = Wire(dataReg.cloneType) 43 val s_idle :: s_compute :: s_finish :: Nil = Enum(3) 44 val state = RegInit(s_idle) 45 val vialu = Module(new VIAluWrapper) 46 val outValid = vialu.io.out.valid 47 val outFire = vialu.io.out.fire() 48 49// reg input signal 50 val s0_uopReg = Reg(io.in.bits.uop.cloneType) 51 val inHs = io.in.fire() 52 when(inHs && state === s_idle){ 53 s0_uopReg := io.in.bits.uop 54 } 55 dataReg := Mux(outValid, dataWire, dataReg) 56 57// fsm 58 switch (state) { 59 is (s_idle) { 60 state := Mux(inHs, s_compute, s_idle) 61 } 62 is (s_compute) { 63 state := Mux(outValid, Mux(outFire, s_idle, s_finish), 64 s_compute) 65 } 66 is (s_finish) { 67 state := Mux(io.out.fire(), s_idle, s_finish) 68 } 69 } 70 71// connect VIAlu 72 dataWire := vialu.io.out.bits.data 73 vialu.io.in.bits <> io.in.bits 74 vialu.io.redirectIn := DontCare // TODO : 75 vialu.vxrm := vxrm 76 io.out.bits.data := Mux(state === s_compute && outFire, dataWire, dataReg) 77 io.out.bits.uop := s0_uopReg 78 vxsat := vialu.vxsat 79 80 vialu.io.in.valid := io.in.valid && state === s_idle 81 io.out.valid := state === s_compute && outValid || state === s_finish 82 vialu.io.out.ready := io.out.ready 83 io.in.ready := state === s_idle 84} 85 86class VIAluDecodeResultBundle extends Bundle { 87 val opcode = UInt(6.W) 88 val srcType = Vec(2, UInt(4.W)) 89 val vdType = UInt(4.W) 90} 91 92class VIAluDecoder (implicit p: Parameters) extends XSModule { 93 val io = IO(new Bundle{ 94 val in = Input(new Bundle{ 95 val fuOpType = UInt(8.W) 96 val sew = UInt(2.W) 97 }) 98 val out = Output(new VIAluDecodeResultBundle) 99 }) 100 101// val DecodeDefault = List(VAluOpcode.dummy, VpuDataType.dummy, VpuDataType.dummy, VpuDataType.dummy) 102// val DecodeTable = Array( 103// BitPat("b" + Cat(VipuType.add, "b00".U).litValue().toString()) -> List(VAluOpcode.vadd, VpuDataType.s8, VpuDataType.s8, VpuDataType.s8), 104// BitPat("b" + Cat(VipuType.add, "b01".U).litValue().toString()) -> List(VAluOpcode.vadd, VpuDataType.s16, VpuDataType.s16, VpuDataType.s16), 105// BitPat("b" + Cat(VipuType.add, "b10".U).litValue().toString()) -> List(VAluOpcode.vadd, VpuDataType.s32, VpuDataType.s32, VpuDataType.s32), 106// BitPat("b" + Cat(VipuType.add, "b11".U).litValue().toString()) -> List(VAluOpcode.vadd, VpuDataType.s64, VpuDataType.s64, VpuDataType.s64), 107// ) 108// val opcode :: srcType1 :: srcType2 :: vdType :: Nil = ListLookup(Cat(io.in.fuOpType, io.in.sew), DecodeDefault, DecodeTable) 109 110// u 00 s 01 f 10 mask 1111 111 val out = LookupTree(io.in.fuOpType, List( 112 VipuType.add -> Cat(VAluOpcode.vadd, Cat(1.U(2.W), io.in.sew), Cat(1.U(2.W), io.in.sew), Cat(1.U(2.W), io.in.sew)).asUInt() 113 )).asTypeOf(new VIAluDecodeResultBundle) 114 115 io.out <> out 116} 117 118class VIAluWrapper(implicit p: Parameters) extends VPUSubModule(p(XSCoreParamsKey).VLEN) { 119 XSError(io.in.valid && io.in.bits.uop.ctrl.fuOpType === VipuType.dummy, "VIPU OpType not supported") 120 121// extra io 122 val vxrm = IO(Input(UInt(2.W))) 123 val vxsat = IO(Output(UInt(1.W))) 124 125// rename signal 126 val in = io.in.bits 127 val ctrl = in.uop.ctrl 128 val vtype = ctrl.vconfig.vtype 129 130// generate src1 and src2 131 val imm = VecInit(Seq.fill(VLEN/XLEN)(VecImmExtractor(ctrl.selImm, vtype.vsew, ctrl.imm))).asUInt 132 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))) 133 val _src2 = in.src(1) 134 val src1 = Mux(VipuType.needReverse(ctrl.fuOpType), _src2, _src1) 135 val src2 = Mux(VipuType.needReverse(ctrl.fuOpType), _src1, _src2) 136 137// connect VIAlu 138 val decoder = Module(new VIAluDecoder) 139 val vialu = Module(new VIAlu) 140 decoder.io.in.fuOpType := in.uop.ctrl.fuType 141 decoder.io.in.sew := in.uop.ctrl.vconfig.vtype.vsew(1,0) 142 143 vialu.io.in.bits.opcode := decoder.io.out.opcode 144 vialu.io.in.bits.info.vm := in.uop.ctrl.vm 145 vialu.io.in.bits.info.ma := in.uop.ctrl.vconfig.vtype.vma 146 vialu.io.in.bits.info.ta := in.uop.ctrl.vconfig.vtype.vta 147 vialu.io.in.bits.info.vlmul := in.uop.ctrl.vconfig.vtype.vlmul 148 vialu.io.in.bits.info.vl := in.uop.ctrl.vconfig.vl 149 vialu.io.in.bits.info.vstart := 0.U // TODO : 150 vialu.io.in.bits.info.uopIdx := in.uop.ctrl.uopIdx.value 151 vialu.io.in.bits.info.vxrm := vxrm 152 vialu.io.in.bits.srcType(0) := decoder.io.out.srcType(0) 153 vialu.io.in.bits.srcType(1) := decoder.io.out.srcType(1) 154 vialu.io.in.bits.vdType := decoder.io.out.vdType 155 vialu.io.in.bits.vs1 := src1 156 vialu.io.in.bits.vs2 := src2 157 vialu.io.in.bits.old_vd := in.src(2) 158 vialu.io.in.bits.mask := in.src(3) 159 160 val vdOut = vialu.io.out.bits.vd 161 val vxsatOut = vialu.io.out.bits.vxsat 162 163 vialu.io.in.valid := io.in.valid 164 165// connect io 166 io.out.bits.data := vdOut 167 io.out.bits.uop := DontCare 168 vxsat := vxsatOut 169 io.out.valid := vialu.io.out.valid 170 io.in.ready := DontCare 171} 172 173object VecImmExtractor { 174 def Imm_OPIVIS(imm: UInt): UInt = { 175 SignExt(imm(4,0), 8) 176 } 177 def Imm_OPIVIU(imm: UInt): UInt = { 178 ZeroExt(imm(4,0), 8) 179 } 180 181 def imm_sew(sew: UInt, imm: UInt): UInt = { 182 val _imm = SignExt(imm(7,0), 64) 183 LookupTree(sew(1,0), List( 184 "b00".U -> VecInit(Seq.fill(8)(_imm(7,0))).asUInt, 185 "b01".U -> VecInit(Seq.fill(4)(_imm(15,0))).asUInt, 186 "b10".U -> VecInit(Seq.fill(2)(_imm(31,0))).asUInt, 187 "b11".U -> _imm(63,0), 188 )) 189 } 190 191 def apply(immType: UInt, sew: UInt, imm: UInt): UInt = { 192 val _imm = Mux(immType === SelImm.IMM_OPIVIS, Imm_OPIVIS(imm), Imm_OPIVIU(imm)) 193 imm_sew(sew, _imm(7,0)) 194 } 195} 196