xref: /XiangShan/src/main/scala/xiangshan/backend/fu/wrapper/VIMacU.scala (revision bb2f3f51dd67f6e16e0cc1ffe43368c9fc7e4aef)
12ee1e93dSXuan Hupackage xiangshan.backend.fu.wrapper
22ee1e93dSXuan Hu
383ba63b3SXuan Huimport org.chipsalliance.cde.config.Parameters
42ee1e93dSXuan Huimport chisel3._
52ee1e93dSXuan Huimport chisel3.util._
6*bb2f3f51STang Haojinimport utility.XSError
72ee1e93dSXuan Huimport xiangshan.backend.fu.FuConfig
82ee1e93dSXuan Huimport xiangshan.backend.fu.vector.Bundles.VSew
92ee1e93dSXuan Huimport xiangshan.backend.fu.vector.utils.VecDataSplitModule
102ee1e93dSXuan Huimport xiangshan.backend.fu.vector.{Mgu, Utils, VecPipedFuncUnit, VecSrcTypeModule}
11c33d4a9eSXuan Huimport xiangshan.ExceptionNO
122ee1e93dSXuan Huimport yunsuan.VialuFixType
132ee1e93dSXuan Huimport yunsuan.encoding.Opcode.VimacOpcode
142ee1e93dSXuan Huimport yunsuan.encoding.{VdType, Vs1IntType, Vs2IntType}
152ee1e93dSXuan Huimport yunsuan.{OpType, VimacType}
162ee1e93dSXuan Huimport yunsuan.vector.mac.VIMac64b
172ee1e93dSXuan Hu
182ee1e93dSXuan Huclass VIMacSrcTypeModule extends VecSrcTypeModule {
192ee1e93dSXuan Hu
202ee1e93dSXuan Hu  private val opcode  = VimacType.getOpcode(fuOpType)
212ee1e93dSXuan Hu  private val vs2Sign = VimacType.vs2Sign(fuOpType)
222ee1e93dSXuan Hu  private val vs1Sign = VimacType.vs1Sign(fuOpType)
232ee1e93dSXuan Hu  private val vdSign  = VimacType.vdSign(fuOpType)
242ee1e93dSXuan Hu  private val format  = VimacType.getFormat(fuOpType)
252ee1e93dSXuan Hu  private val widen   = format === VimacType.FMT.VVW
262ee1e93dSXuan Hu
272ee1e93dSXuan Hu  private val vs2IntType = Cat(0.U(1.W), vs2Sign)
282ee1e93dSXuan Hu  private val vs1IntType = Cat(0.U(1.W), vs1Sign)
292ee1e93dSXuan Hu  private val vdIntType  = Cat(0.U(1.W),  vdSign)
302ee1e93dSXuan Hu
312ee1e93dSXuan Hu  private val vsewX2 = vsew + 1.U
322ee1e93dSXuan Hu
332ee1e93dSXuan Hu  private val vs2Type = Cat(vs2IntType, vsew)
342ee1e93dSXuan Hu  private val vs1Type = Cat(vs1IntType, vsew)
352ee1e93dSXuan Hu  private val vdType  = Cat( vdIntType, Mux(widen, vsewX2, vsew))
362ee1e93dSXuan Hu
372ee1e93dSXuan Hu  private val widenIllegal = widen && vsewX2 === VSew.e8
382ee1e93dSXuan Hu
392ee1e93dSXuan Hu  io.out.illegal := widenIllegal
402ee1e93dSXuan Hu  io.out.vs2Type := vs2Type
412ee1e93dSXuan Hu  io.out.vs1Type := vs1Type
422ee1e93dSXuan Hu  io.out.vdType  := vdType
432ee1e93dSXuan Hu}
442ee1e93dSXuan Hu
452ee1e93dSXuan Huclass VIMacU(cfg: FuConfig)(implicit p: Parameters) extends VecPipedFuncUnit(cfg) {
462ee1e93dSXuan Hu  XSError(io.in.valid && io.in.bits.ctrl.fuOpType === VimacType.dummy, "VialuF OpType not supported")
472ee1e93dSXuan Hu
482ee1e93dSXuan Hu  // params alias
492d12882cSxiaofeibao  private val dataWidth = cfg.destDataBits
502ee1e93dSXuan Hu  private val dataWidthOfDataModule = 64
512ee1e93dSXuan Hu  private val numVecModule = dataWidth / dataWidthOfDataModule
522ee1e93dSXuan Hu
532ee1e93dSXuan Hu  // io alias
542ee1e93dSXuan Hu  private val opcode  = VimacType.getOpcode(fuOpType)
552ee1e93dSXuan Hu  private val format  = VimacType.getFormat(fuOpType)
562ee1e93dSXuan Hu  private val widen   = format === VimacType.FMT.VVW
57d16a780cSXuan Hu  private val exchangeVs2Vd = VimacOpcode.overWriteMultiplicand(opcode)
582ee1e93dSXuan Hu
592ee1e93dSXuan Hu  // modules
602ee1e93dSXuan Hu  private val typeMod = Module(new VIMacSrcTypeModule)
612ee1e93dSXuan Hu  private val vs2Split = Module(new VecDataSplitModule(dataWidth, dataWidthOfDataModule))
622ee1e93dSXuan Hu  private val vs1Split = Module(new VecDataSplitModule(dataWidth, dataWidthOfDataModule))
632ee1e93dSXuan Hu  private val oldVdSplit  = Module(new VecDataSplitModule(dataWidth, dataWidthOfDataModule))
642ee1e93dSXuan Hu  private val vimacs = Seq.fill(numVecModule)(Module(new VIMac64b))
652ee1e93dSXuan Hu  private val mgu = Module(new Mgu(dataWidth))
662ee1e93dSXuan Hu
672ee1e93dSXuan Hu  /**
682ee1e93dSXuan Hu    * [[typeMod]]'s in connection
692ee1e93dSXuan Hu    */
702ee1e93dSXuan Hu  typeMod.io.in.fuOpType := fuOpType
712ee1e93dSXuan Hu  typeMod.io.in.vsew := vsew
722ee1e93dSXuan Hu  typeMod.io.in.isReverse := isReverse
732ee1e93dSXuan Hu  typeMod.io.in.isExt := isExt
742ee1e93dSXuan Hu  typeMod.io.in.isDstMask := vecCtrl.isDstMask
752ee1e93dSXuan Hu  typeMod.io.in.isMove := isMove
762ee1e93dSXuan Hu
772ee1e93dSXuan Hu  /**
782ee1e93dSXuan Hu    * In connection of [[vs2Split]], [[vs1Split]] and [[oldVdSplit]]
792ee1e93dSXuan Hu    */
802ee1e93dSXuan Hu  vs2Split.io.inVecData := vs2
812ee1e93dSXuan Hu  vs1Split.io.inVecData := vs1
822ee1e93dSXuan Hu  oldVdSplit.io.inVecData := oldVd
832ee1e93dSXuan Hu
842ee1e93dSXuan Hu  /**
852ee1e93dSXuan Hu    * [[vimacs]]'s in connection
862ee1e93dSXuan Hu    */
8711ca0f73SXuan Hu  // Vec(vs2(31,0), vs2(63,32), vs2(95,64), vs2(127,96)) ==>
8811ca0f73SXuan Hu  // Vec(
8911ca0f73SXuan Hu  //   Cat(vs2(95,64),  vs2(31,0)),
9011ca0f73SXuan Hu  //   Cat(vs2(127,96), vs2(63,32)),
9111ca0f73SXuan Hu  // )
9211ca0f73SXuan Hu  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)
9311ca0f73SXuan Hu  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)
9411ca0f73SXuan Hu
9511ca0f73SXuan Hu  private val vs2VecUsed: Vec[UInt] = Mux(widen, vs2GroupedVec, vs2Split.io.outVec64b)
9611ca0f73SXuan Hu  private val vs1VecUsed: Vec[UInt] = Mux(widen, vs1GroupedVec, vs1Split.io.outVec64b)
972ee1e93dSXuan Hu  private val oldVdVecUsed: Vec[UInt] = WireInit(oldVdSplit.io.outVec64b)
982ee1e93dSXuan Hu
992ee1e93dSXuan Hu  vimacs.zipWithIndex.foreach {
1002ee1e93dSXuan Hu    case (mod, i) =>
101e8e02b74SsinceforYy      mod.io.fire        := io.in.valid
1022ee1e93dSXuan Hu      mod.io.info.vm     := vm
1032ee1e93dSXuan Hu      mod.io.info.ma     := vma
1042ee1e93dSXuan Hu      mod.io.info.ta     := vta
1052ee1e93dSXuan Hu      mod.io.info.vlmul  := vlmul
1062ee1e93dSXuan Hu      mod.io.info.vl     := srcVConfig.vl
1072ee1e93dSXuan Hu      mod.io.info.vstart := vstart
1082ee1e93dSXuan Hu      mod.io.info.uopIdx := vuopIdx
1092ee1e93dSXuan Hu      mod.io.info.vxrm   := vxrm
1102ee1e93dSXuan Hu      mod.io.srcType(0)  := typeMod.io.out.vs2Type
1112ee1e93dSXuan Hu      mod.io.srcType(1)  := typeMod.io.out.vs1Type
1122ee1e93dSXuan Hu      mod.io.vdType      := typeMod.io.out.vdType
1132ee1e93dSXuan Hu      mod.io.vs1         := vs1VecUsed(i)
114d16a780cSXuan Hu      mod.io.vs2         := Mux(!exchangeVs2Vd, vs2VecUsed(i), oldVdVecUsed(i))
115d16a780cSXuan Hu      mod.io.oldVd       := Mux(!exchangeVs2Vd, oldVdVecUsed(i), vs2VecUsed(i))
1162ee1e93dSXuan Hu      mod.io.highHalf    := VimacOpcode.highHalf(opcode)
1172ee1e93dSXuan Hu      mod.io.isMacc      := VimacOpcode.isMacc(opcode)
1182ee1e93dSXuan Hu      mod.io.isSub       := VimacOpcode.isSub(opcode)
1192ee1e93dSXuan Hu      mod.io.widen       := widen
1202ee1e93dSXuan Hu      mod.io.isFixP      := VimacOpcode.isFixP(opcode)
1212ee1e93dSXuan Hu  }
1222ee1e93dSXuan Hu
1232ee1e93dSXuan Hu  /**
1242ee1e93dSXuan Hu    * [[mgu]]'s in connection
1252ee1e93dSXuan Hu    */
126d16a780cSXuan Hu  private val outVd = Cat(vimacs.reverse.map(_.io.vd))
127d16a780cSXuan Hu  private val outFormat = VimacType.getFormat(outCtrl.fuOpType)
128d16a780cSXuan Hu  private val outWiden = outFormat === VimacType.FMT.VVW
129904d2184SZiyue Zhang  private val outVxsat = Cat(vimacs.reverse.map(_.io.vxsat))
130d16a780cSXuan Hu
131d16a780cSXuan Hu  private val outEew = Mux(outWiden, outVecCtrl.vsew + 1.U, outVecCtrl.vsew)
132d16a780cSXuan Hu  mgu.io.in.vd := outVd
133d16a780cSXuan Hu  mgu.io.in.oldVd := outOldVd
134d16a780cSXuan Hu  mgu.io.in.mask := outSrcMask
135d16a780cSXuan Hu  mgu.io.in.info.ta := outVecCtrl.vta
136d16a780cSXuan Hu  mgu.io.in.info.ma := outVecCtrl.vma
137d16a780cSXuan Hu  mgu.io.in.info.vl := outVl
138b3e2881cSxiaofeibao-xjtu  mgu.io.in.info.vlmul := outVecCtrl.vlmul
139b3e2881cSxiaofeibao-xjtu  mgu.io.in.info.valid := io.out.valid
140d16a780cSXuan Hu  mgu.io.in.info.vstart := outVecCtrl.vstart
141d16a780cSXuan Hu  mgu.io.in.info.eew := outEew
142b3e2881cSxiaofeibao-xjtu  mgu.io.in.info.vsew := outVecCtrl.vsew
143d16a780cSXuan Hu  mgu.io.in.info.vdIdx := outVecCtrl.vuopIdx
144cdf8c16cSxgkiri  mgu.io.in.info.narrow := 0.B
145cdf8c16cSxgkiri  mgu.io.in.info.dstMask := 0.B
14692c6b7edSzhanglinjuan  mgu.io.in.isIndexedVls := false.B
1472ee1e93dSXuan Hu
1482ee1e93dSXuan Hu  io.out.bits.res.data := mgu.io.out.vd
14981cbff07Schengguanghui  io.out.bits.res.vxsat.get := (outVxsat & mgu.io.out.active).orR
150c33d4a9eSXuan Hu  io.out.bits.ctrl.exceptionVec.get(ExceptionNO.illegalInstr) := mgu.io.out.illegal
1512ee1e93dSXuan Hu}
152