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