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.wrapper 20 21import org.chipsalliance.cde.config.Parameters 22import chisel3._ 23import chisel3.util._ 24import utility._ 25import utils.XSError 26import xiangshan.{SelImm, SrcType, UopSplitType, XSCoreParamsKey, XSModule} 27import xiangshan.backend.fu.FuConfig 28import xiangshan.backend.fu.vector.Bundles.VSew 29import xiangshan.backend.fu.vector.utils.VecDataSplitModule 30import xiangshan.backend.fu.vector.{Mgu, Utils, VecPipedFuncUnit, VecSrcTypeModule} 31import xiangshan.SrcType 32import yunsuan.vector.alu.{VAluOpcode, VIAlu} 33import yunsuan.{OpType, VipuType} 34import scala.collection.Seq 35 36class VIAluDecodeResultBundle extends Bundle { 37 val opcode = UInt(6.W) 38 val srcType2 = UInt(4.W) 39 val srcType1 = UInt(4.W) 40 val vdType = UInt(4.W) 41} 42 43class VIAluDecoder (implicit p: Parameters) extends XSModule { 44 val io = IO(new Bundle{ 45 val in = Input(new Bundle{ 46 val fuOpType = UInt(8.W) 47 val sew = UInt(2.W) 48 }) 49 val out = Output(new VIAluDecodeResultBundle) 50 }) 51 52 // u 00 s 01 f 10 mask 1111 53 val uSew = Cat(0.U(2.W), io.in.sew) 54 val uSew2 = Cat(0.U(2.W), (io.in.sew+1.U)) 55 val uSewf2 = Cat(0.U(2.W), (io.in.sew-1.U)) 56 val uSewf4 = Cat(0.U(2.W), (io.in.sew-2.U)) 57 val uSewf8 = Cat(0.U(2.W), (io.in.sew-3.U)) 58 val sSew = Cat(1.U(2.W), io.in.sew) 59 val sSew2 = Cat(1.U(2.W), (io.in.sew+1.U)) 60 val sSewf2 = Cat(1.U(2.W), (io.in.sew - 1.U)) 61 val sSewf4 = Cat(1.U(2.W), (io.in.sew - 2.U)) 62 val sSewf8 = Cat(1.U(2.W), (io.in.sew - 3.U)) 63 val mask = "b1111".U(4.W) 64 65 val out = LookupTree(io.in.fuOpType, List( 66 // --------------------- opcode srcType2 1 vdType 67 VipuType.vredsum_vs -> Cat(VAluOpcode.vredsum, uSew, uSew, uSew).asUInt, 68 VipuType.vredmaxu_vs -> Cat(VAluOpcode.vredmax, uSew, uSew, uSew).asUInt, 69 VipuType.vredmax_vs -> Cat(VAluOpcode.vredmax, sSew, sSew, sSew).asUInt, 70 VipuType.vredminu_vs -> Cat(VAluOpcode.vredmin, uSew, uSew, uSew).asUInt, 71 VipuType.vredmin_vs -> Cat(VAluOpcode.vredmin, sSew, sSew, sSew).asUInt, 72 VipuType.vredand_vs -> Cat(VAluOpcode.vredand, uSew, uSew, uSew).asUInt, 73 VipuType.vredor_vs -> Cat(VAluOpcode.vredor, uSew, uSew, uSew).asUInt, 74 VipuType.vredxor_vs -> Cat(VAluOpcode.vredxor, uSew, uSew, uSew).asUInt, 75 76 VipuType.vwredsumu_vs -> Cat(VAluOpcode.vredsum, uSew, uSew, uSew2).asUInt, 77 VipuType.vwredsum_vs -> Cat(VAluOpcode.vredsum, sSew, sSew, sSew2).asUInt, 78 79 VipuType.vcpop_m -> Cat(VAluOpcode.vcpop, mask, mask, uSew).asUInt, 80 VipuType.vfirst_m -> Cat(VAluOpcode.vfirst, mask, mask, uSew).asUInt, 81 VipuType.vmsbf_m -> Cat(VAluOpcode.vmsbf, mask, mask, mask).asUInt, 82 VipuType.vmsif_m -> Cat(VAluOpcode.vmsif, mask, mask, mask).asUInt, 83 VipuType.vmsof_m -> Cat(VAluOpcode.vmsof, mask, mask, mask).asUInt, 84 85 VipuType.viota_m -> Cat(VAluOpcode.viota, uSew, uSew, uSew).asUInt, 86 VipuType.vid_v -> Cat(VAluOpcode.vid, uSew, uSew, uSew).asUInt, 87 VipuType.vmv_x_s -> Cat(VAluOpcode.vmvxs, uSew, uSew, uSew).asUInt 88 89 )).asTypeOf(new VIAluDecodeResultBundle) 90 91 io.out <> out 92} 93 94class VIPU(cfg: FuConfig)(implicit p: Parameters) extends VecPipedFuncUnit(cfg) { 95 XSError(io.in.valid && io.in.bits.ctrl.fuOpType === VipuType.dummy, "VIPU OpType not supported") 96 97 // params alias 98 private val dataWidth = cfg.dataBits 99 private val dataWidthOfDataModule = 64 100 private val numVecModule = dataWidth / dataWidthOfDataModule 101 private val needClearVs1 = (VipuType.vcpop_m === io.in.bits.ctrl.fuOpType && vuopIdx === 0.U) || 102 (VipuType.viota_m === io.in.bits.ctrl.fuOpType && vuopIdx(log2Up(MaxUopSize)-1,1) === 0.U) || 103 (VipuType.vid_v === io.in.bits.ctrl.fuOpType && vuopIdx(log2Up(MaxUopSize)-1,1) === 0.U) // dirty code TODO: inset into IAlu 104 private val lmul = MuxLookup(vlmul, 1.U(4.W))(Array( 105 "b001".U -> 2.U, 106 "b010".U -> 4.U, 107 "b011".U -> 8.U 108 )) 109 private val needShiftVs1 = (VipuType.vwredsumu_vs === io.in.bits.ctrl.fuOpType || VipuType.vwredsum_vs === io.in.bits.ctrl.fuOpType) && vuopIdx < lmul 110 111 // modules 112 private val decoder = Module(new VIAluDecoder) 113 private val vialu = Module(new VIAlu) 114 115 /** 116 * [[decoder]]'s in connection 117 */ 118 decoder.io.in.fuOpType := fuOpType 119 decoder.io.in.sew := vsew(1,0) 120 121 122 /** 123 * [[vialu]]'s in connection 124 */ 125 vialu.io match { 126 case subIO => 127 subIO.in.valid := io.in.valid 128 subIO.in.bits.opcode.op := decoder.io.out.opcode 129 subIO.in.bits.info.vm := vm 130 subIO.in.bits.info.ma := vma 131 subIO.in.bits.info.ta := vta 132 subIO.in.bits.info.vlmul := vlmul 133 subIO.in.bits.info.vl := srcVConfig.vl 134 subIO.in.bits.info.vstart := vstart 135 subIO.in.bits.info.uopIdx := vuopIdx 136 subIO.in.bits.info.vxrm := vxrm 137 subIO.in.bits.srcType(0) := decoder.io.out.srcType2 138 subIO.in.bits.srcType(1) := decoder.io.out.srcType1 139 subIO.in.bits.vdType := decoder.io.out.vdType 140 subIO.in.bits.vs1 := Mux1H(Seq(needClearVs1 -> 0.U, 141 needShiftVs1 -> ZeroExt(vs1(127,64), 128), 142 ((!needClearVs1) && (!needShiftVs1)) -> vs1)) 143 subIO.in.bits.vs2 := vs2 144 subIO.in.bits.old_vd := oldVd 145 subIO.in.bits.mask := srcMask 146 } 147 148 io.out.bits.res.data := vialu.io.out.bits.vd 149} 150