1package xiangshan.backend.fu.wrapper 2 3import chipsalliance.rocketchip.config.Parameters 4import chisel3._ 5import chisel3.util._ 6import utils.XSError 7import xiangshan.backend.fu.FuConfig 8import xiangshan.backend.fu.vector.Bundles.VSew 9import xiangshan.backend.fu.vector.utils.VecDataSplitModule 10import xiangshan.backend.fu.vector.{Mgu, Utils, VecPipedFuncUnit, VecSrcTypeModule} 11import yunsuan.VialuFixType 12import yunsuan.encoding.Opcode.VimacOpcode 13import yunsuan.encoding.{VdType, Vs1IntType, Vs2IntType} 14import yunsuan.{OpType, VimacType} 15import yunsuan.vector.mac.VIMac64b 16 17class VIMacSrcTypeModule extends VecSrcTypeModule { 18 19 private val opcode = VimacType.getOpcode(fuOpType) 20 private val vs2Sign = VimacType.vs2Sign(fuOpType) 21 private val vs1Sign = VimacType.vs1Sign(fuOpType) 22 private val vdSign = VimacType.vdSign(fuOpType) 23 private val format = VimacType.getFormat(fuOpType) 24 private val widen = format === VimacType.FMT.VVW 25 26 private val vs2IntType = Cat(0.U(1.W), vs2Sign) 27 private val vs1IntType = Cat(0.U(1.W), vs1Sign) 28 private val vdIntType = Cat(0.U(1.W), vdSign) 29 30 private val vsewX2 = vsew + 1.U 31 32 private val vs2Type = Cat(vs2IntType, vsew) 33 private val vs1Type = Cat(vs1IntType, vsew) 34 private val vdType = Cat( vdIntType, Mux(widen, vsewX2, vsew)) 35 36 private val widenIllegal = widen && vsewX2 === VSew.e8 37 38 io.out.illegal := widenIllegal 39 io.out.vs2Type := vs2Type 40 io.out.vs1Type := vs1Type 41 io.out.vdType := vdType 42} 43 44class VIMacU(cfg: FuConfig)(implicit p: Parameters) extends VecPipedFuncUnit(cfg) { 45 XSError(io.in.valid && io.in.bits.ctrl.fuOpType === VimacType.dummy, "VialuF OpType not supported") 46 47 // params alias 48 private val dataWidth = cfg.dataBits 49 private val dataWidthOfDataModule = 64 50 private val numVecModule = dataWidth / dataWidthOfDataModule 51 52 // io alias 53 private val opcode = VimacType.getOpcode(fuOpType) 54 private val format = VimacType.getFormat(fuOpType) 55 private val widen = format === VimacType.FMT.VVW 56 private val exchangeVs2Vd = VimacOpcode.overWriteMultiplicand(opcode) 57 58 // modules 59 private val typeMod = Module(new VIMacSrcTypeModule) 60 private val vs2Split = Module(new VecDataSplitModule(dataWidth, dataWidthOfDataModule)) 61 private val vs1Split = Module(new VecDataSplitModule(dataWidth, dataWidthOfDataModule)) 62 private val oldVdSplit = Module(new VecDataSplitModule(dataWidth, dataWidthOfDataModule)) 63 private val vimacs = Seq.fill(numVecModule)(Module(new VIMac64b)) 64 private val mgu = Module(new Mgu(dataWidth)) 65 66 /** 67 * [[typeMod]]'s in connection 68 */ 69 typeMod.io.in.fuOpType := fuOpType 70 typeMod.io.in.vsew := vsew 71 typeMod.io.in.isReverse := isReverse 72 typeMod.io.in.isExt := isExt 73 typeMod.io.in.isDstMask := vecCtrl.isDstMask 74 typeMod.io.in.isMove := isMove 75 76 /** 77 * In connection of [[vs2Split]], [[vs1Split]] and [[oldVdSplit]] 78 */ 79 vs2Split.io.inVecData := vs2 80 vs1Split.io.inVecData := vs1 81 oldVdSplit.io.inVecData := oldVd 82 83 /** 84 * [[vimacs]]'s in connection 85 */ 86 // Vec(vs2(31,0), vs2(63,32), vs2(95,64), vs2(127,96)) ==> 87 // Vec( 88 // Cat(vs2(95,64), vs2(31,0)), 89 // Cat(vs2(127,96), vs2(63,32)), 90 // ) 91 private val vs2GroupedVec: Vec[UInt] = VecInit(vs2Split.io.outVec32b.zipWithIndex.groupBy(_._2 % 2).map(x => x._1 -> x._2.map(_._1)).values.map(x => Cat(x.reverse)).toSeq) 92 private val vs1GroupedVec: Vec[UInt] = VecInit(vs1Split.io.outVec32b.zipWithIndex.groupBy(_._2 % 2).map(x => x._1 -> x._2.map(_._1)).values.map(x => Cat(x.reverse)).toSeq) 93 94 private val vs2VecUsed: Vec[UInt] = Mux(widen, vs2GroupedVec, vs2Split.io.outVec64b) 95 private val vs1VecUsed: Vec[UInt] = Mux(widen, vs1GroupedVec, vs1Split.io.outVec64b) 96 private val oldVdVecUsed: Vec[UInt] = WireInit(oldVdSplit.io.outVec64b) 97 98 vimacs.zipWithIndex.foreach { 99 case (mod, i) => 100 mod.io.info.vm := vm 101 mod.io.info.ma := vma 102 mod.io.info.ta := vta 103 mod.io.info.vlmul := vlmul 104 mod.io.info.vl := srcVConfig.vl 105 mod.io.info.vstart := vstart 106 mod.io.info.uopIdx := vuopIdx 107 mod.io.info.vxrm := vxrm 108 mod.io.srcType(0) := typeMod.io.out.vs2Type 109 mod.io.srcType(1) := typeMod.io.out.vs1Type 110 mod.io.vdType := typeMod.io.out.vdType 111 mod.io.vs1 := vs1VecUsed(i) 112 mod.io.vs2 := Mux(!exchangeVs2Vd, vs2VecUsed(i), oldVdVecUsed(i)) 113 mod.io.oldVd := Mux(!exchangeVs2Vd, oldVdVecUsed(i), vs2VecUsed(i)) 114 mod.io.highHalf := VimacOpcode.highHalf(opcode) 115 mod.io.isMacc := VimacOpcode.isMacc(opcode) 116 mod.io.isSub := VimacOpcode.isSub(opcode) 117 mod.io.widen := widen 118 mod.io.isFixP := VimacOpcode.isFixP(opcode) 119 } 120 121 /** 122 * [[mgu]]'s in connection 123 */ 124 private val outVd = Cat(vimacs.reverse.map(_.io.vd)) 125 private val outFormat = VimacType.getFormat(outCtrl.fuOpType) 126 private val outWiden = outFormat === VimacType.FMT.VVW 127 128 private val outEew = Mux(outWiden, outVecCtrl.vsew + 1.U, outVecCtrl.vsew) 129 mgu.io.in.vd := outVd 130 mgu.io.in.oldVd := outOldVd 131 mgu.io.in.mask := outSrcMask 132 mgu.io.in.info.ta := outVecCtrl.vta 133 mgu.io.in.info.ma := outVecCtrl.vma 134 mgu.io.in.info.vl := outVl 135 mgu.io.in.info.vstart := outVecCtrl.vstart 136 mgu.io.in.info.eew := outEew 137 mgu.io.in.info.vdIdx := outVecCtrl.vuopIdx 138 mgu.io.in.info.narrow := 0.B 139 mgu.io.in.info.dstMask := 0.B 140 141 io.out.bits.res.data := mgu.io.out.vd 142 io.out.bits.res.vxsat.get := (Cat(vimacs.map(_.io.vxsat)) & mgu.io.out.keep).orR 143} 144