xref: /XiangShan/src/main/scala/xiangshan/backend/fu/wrapper/VIAluFix.scala (revision 785e3bfdd39261ee799e7c6ca1a1540603b08268)
135d005dfSXuan Hupackage xiangshan.backend.fu.wrapper
235d005dfSXuan Hu
383ba63b3SXuan Huimport org.chipsalliance.cde.config.Parameters
4cdf8c16cSxgkiriimport chisel3.{VecInit, _}
535d005dfSXuan Huimport chisel3.util._
6cdf8c16cSxgkiriimport chisel3.util.experimental.decode.{QMCMinimizer, TruthTable, decoder}
7bb2f3f51STang Haojinimport utility.{DelayN, XSError}
835d005dfSXuan Huimport xiangshan.XSCoreParamsKey
9*785e3bfdSXuan Huimport xiangshan.backend.fu.vector.Bundles.{VConfig, VSew}
1030fcc710SZiyue Zhangimport xiangshan.backend.fu.vector.{Mgu, Mgtu, VecPipedFuncUnit}
1135d005dfSXuan Huimport xiangshan.backend.fu.vector.Utils.VecDataToMaskDataVec
12cdf8c16cSxgkiriimport xiangshan.backend.fu.vector.utils.VecDataSplitModule
1335d005dfSXuan Huimport xiangshan.backend.fu.{FuConfig, FuType}
14c33d4a9eSXuan Huimport xiangshan.ExceptionNO
1535d005dfSXuan Huimport yunsuan.{OpType, VialuFixType}
16cdf8c16cSxgkiriimport yunsuan.vector.alu.{VIntFixpAlu64b, VIntFixpDecode, VIntFixpTable}
1735d005dfSXuan Huimport yunsuan.encoding.{VdType, Vs1IntType, Vs2IntType}
1835d005dfSXuan Huimport yunsuan.encoding.Opcode.VialuOpcode
19cdf8c16cSxgkiriimport yunsuan.vector.SewOH
2035d005dfSXuan Hu
2135d005dfSXuan Huclass VIAluSrcTypeIO extends Bundle {
2235d005dfSXuan Hu  val in = Input(new Bundle {
2335d005dfSXuan Hu    val fuOpType: UInt = OpType()
2435d005dfSXuan Hu    val vsew: UInt = VSew()
2535d005dfSXuan Hu    val isReverse: Bool = Bool() // vrsub, vrdiv
2635d005dfSXuan Hu    val isExt: Bool = Bool()
2735d005dfSXuan Hu    val isDstMask: Bool = Bool() // vvm, vvvm, mmm
2835d005dfSXuan Hu    val isMove: Bool = Bool() // vmv.s.x, vmv.v.v, vmv.v.x, vmv.v.i
2935d005dfSXuan Hu  })
3035d005dfSXuan Hu  val out = Output(new Bundle {
3135d005dfSXuan Hu    val vs1Type: UInt = Vs1IntType()
3235d005dfSXuan Hu    val vs2Type: UInt = Vs2IntType()
3335d005dfSXuan Hu    val vdType: UInt = VdType()
3435d005dfSXuan Hu    val illegal: Bool = Bool()
35cdf8c16cSxgkiri    val isVextF2: Bool = Bool()
36cdf8c16cSxgkiri    val isVextF4: Bool = Bool()
37cdf8c16cSxgkiri    val isVextF8: Bool = Bool()
3835d005dfSXuan Hu  })
3935d005dfSXuan Hu}
4035d005dfSXuan Hu
4135d005dfSXuan Huclass VIAluSrcTypeModule extends Module {
4235d005dfSXuan Hu  val io: VIAluSrcTypeIO = IO(new VIAluSrcTypeIO)
4335d005dfSXuan Hu
4435d005dfSXuan Hu  private val vsew = io.in.vsew
4535d005dfSXuan Hu  private val isExt = io.in.isExt
4635d005dfSXuan Hu  private val isDstMask = io.in.isDstMask
4735d005dfSXuan Hu
4835d005dfSXuan Hu  private val opcode = VialuFixType.getOpcode(io.in.fuOpType)
4935d005dfSXuan Hu  private val isSign = VialuFixType.isSigned(io.in.fuOpType)
5035d005dfSXuan Hu  private val format = VialuFixType.getFormat(io.in.fuOpType)
5135d005dfSXuan Hu
5235d005dfSXuan Hu  private val vsewX2 = vsew + 1.U
5335d005dfSXuan Hu  private val vsewF2 = vsew - 1.U
5435d005dfSXuan Hu  private val vsewF4 = vsew - 2.U
5535d005dfSXuan Hu  private val vsewF8 = vsew - 3.U
5635d005dfSXuan Hu
5735d005dfSXuan Hu  private val isAddSub = opcode === VialuOpcode.vadd || opcode === VialuOpcode.vsub
5835d005dfSXuan Hu  private val isShiftRight = Seq(VialuOpcode.vsrl, VialuOpcode.vsra, VialuOpcode.vssrl, VialuOpcode.vssra).map(fmt => fmt === format).reduce(_ || _)
5935d005dfSXuan Hu  private val isVext = opcode === VialuOpcode.vext
6035d005dfSXuan Hu
6135d005dfSXuan Hu  private val isWiden = isAddSub && Seq(VialuFixType.FMT.VVW, VialuFixType.FMT.WVW).map(fmt => fmt === format).reduce(_ || _)
6235d005dfSXuan Hu  private val isNarrow = isShiftRight && format === VialuFixType.FMT.WVV
6335d005dfSXuan Hu  private val isVextF2 = isVext && format === VialuFixType.FMT.VF2
6435d005dfSXuan Hu  private val isVextF4 = isVext && format === VialuFixType.FMT.VF4
6535d005dfSXuan Hu  private val isVextF8 = isVext && format === VialuFixType.FMT.VF8
6635d005dfSXuan Hu
6735d005dfSXuan Hu  // check illegal
6835d005dfSXuan Hu  private val widenIllegal = isWiden && vsewX2 === VSew.e8
6935d005dfSXuan Hu  private val narrowIllegal = isNarrow && vsewF2 === VSew.e64
7035d005dfSXuan Hu  private val vextIllegal = (isVextF2 && (vsewF2 === VSew.e64)) ||
7135d005dfSXuan Hu    (isVextF4 && (vsewF4 === VSew.e64)) ||
7235d005dfSXuan Hu    (isVextF8 && (vsewF8 === VSew.e64))
7335d005dfSXuan Hu  // Todo: use it
7435d005dfSXuan Hu  private val illegal = widenIllegal || narrowIllegal || vextIllegal
7535d005dfSXuan Hu
7639c388b5SXuan Hu  private val intType = Cat(0.U(1.W), isSign)
7739c388b5SXuan Hu
7835d005dfSXuan Hu  private class Vs2Vs1VdSew extends Bundle {
7935d005dfSXuan Hu    val vs2 = VSew()
8035d005dfSXuan Hu    val vs1 = VSew()
8135d005dfSXuan Hu    val vd = VSew()
8235d005dfSXuan Hu  }
8335d005dfSXuan Hu
8439c388b5SXuan Hu  private class Vs2Vs1VdType extends Bundle {
8539c388b5SXuan Hu    val vs2 = Vs2IntType()
8639c388b5SXuan Hu    val vs1 = Vs1IntType()
8739c388b5SXuan Hu    val vd = VdType()
8839c388b5SXuan Hu  }
8939c388b5SXuan Hu
9035d005dfSXuan Hu  private val addSubSews = Mux1H(Seq(
9135d005dfSXuan Hu    (format === VialuFixType.FMT.VVV) -> Cat(vsew, vsew, vsew),
9235d005dfSXuan Hu    (format === VialuFixType.FMT.VVW) -> Cat(vsew, vsew, vsewX2),
9335d005dfSXuan Hu    (format === VialuFixType.FMT.WVW) -> Cat(vsewX2, vsew, vsewX2),
9435d005dfSXuan Hu    (format === VialuFixType.FMT.WVV) -> Cat(vsewX2, vsew, vsew),
9535d005dfSXuan Hu  )).asTypeOf(new Vs2Vs1VdSew)
9635d005dfSXuan Hu
9735d005dfSXuan Hu  private val vextSews = Mux1H(Seq(
9835d005dfSXuan Hu    (format === VialuFixType.FMT.VF2) -> Cat(vsewF2, vsewF2, vsew),
9935d005dfSXuan Hu    (format === VialuFixType.FMT.VF4) -> Cat(vsewF4, vsewF4, vsew),
10035d005dfSXuan Hu    (format === VialuFixType.FMT.VF8) -> Cat(vsewF8, vsewF8, vsew),
10135d005dfSXuan Hu  )).asTypeOf(new Vs2Vs1VdSew)
10235d005dfSXuan Hu
10339c388b5SXuan Hu  private val maskTypes = Mux1H(Seq(
10439c388b5SXuan Hu    (format === VialuFixType.FMT.VVM) -> Cat(Cat(intType, vsew), Cat(intType, vsew), VdType.mask),
1059eaaa75dSXuan Hu    (format === VialuFixType.FMT.VVMM) -> Cat(Cat(intType, vsew), Cat(intType, vsew), VdType.mask),
10639c388b5SXuan Hu    (format === VialuFixType.FMT.MMM) -> Cat(Vs2IntType.mask, Vs1IntType.mask, VdType.mask),
10739c388b5SXuan Hu  )).asTypeOf(new Vs2Vs1VdType)
10835d005dfSXuan Hu
10935d005dfSXuan Hu  private val vs2Type = Mux1H(Seq(
11039c388b5SXuan Hu    isDstMask -> maskTypes.vs2,
11139c388b5SXuan Hu    isExt -> Cat(intType, vextSews.vs2),
11239c388b5SXuan Hu    (!isExt && !isDstMask) -> Cat(intType, addSubSews.vs2),
11335d005dfSXuan Hu  ))
11435d005dfSXuan Hu  private val vs1Type = Mux1H(Seq(
11539c388b5SXuan Hu    isDstMask -> maskTypes.vs1,
11639c388b5SXuan Hu    isExt -> Cat(intType, vextSews.vs1),
11739c388b5SXuan Hu    (!isExt && !isDstMask) -> Cat(intType, addSubSews.vs1),
11835d005dfSXuan Hu  ))
11935d005dfSXuan Hu  private val vdType = Mux1H(Seq(
12039c388b5SXuan Hu    isDstMask -> maskTypes.vd,
12139c388b5SXuan Hu    isExt -> Cat(intType, vextSews.vd),
12239c388b5SXuan Hu    (!isExt && !isDstMask) -> Cat(intType, addSubSews.vd),
12335d005dfSXuan Hu  ))
12435d005dfSXuan Hu
12535d005dfSXuan Hu  io.out.vs2Type := vs2Type
12635d005dfSXuan Hu  io.out.vs1Type := vs1Type
12735d005dfSXuan Hu  io.out.vdType := vdType
12835d005dfSXuan Hu  io.out.illegal := illegal
129cdf8c16cSxgkiri  io.out.isVextF2 := isVextF2
130cdf8c16cSxgkiri  io.out.isVextF4 := isVextF4
131cdf8c16cSxgkiri  io.out.isVextF8 := isVextF8
13235d005dfSXuan Hu}
13335d005dfSXuan Hu
13435d005dfSXuan Huclass VIAluFix(cfg: FuConfig)(implicit p: Parameters) extends VecPipedFuncUnit(cfg) {
13535d005dfSXuan Hu  XSError(io.in.valid && io.in.bits.ctrl.fuOpType === VialuFixType.dummy, "VialuF OpType not supported")
13635d005dfSXuan Hu
137cdf8c16cSxgkiri  // config params
1382d12882cSxiaofeibao  private val dataWidth = cfg.destDataBits
139cdf8c16cSxgkiri  private val dataWidthOfDataModule = 64
140cdf8c16cSxgkiri  private val numVecModule = dataWidth / dataWidthOfDataModule
141cdf8c16cSxgkiri
14235d005dfSXuan Hu  // modules
143cdf8c16cSxgkiri  private val typeMod = Module(new VIAluSrcTypeModule)
144cdf8c16cSxgkiri  private val vs2Split = Module(new VecDataSplitModule(dataWidth, dataWidthOfDataModule))
145cdf8c16cSxgkiri  private val vs1Split = Module(new VecDataSplitModule(dataWidth, dataWidthOfDataModule))
146cdf8c16cSxgkiri  private val oldVdSplit = Module(new VecDataSplitModule(dataWidth, dataWidthOfDataModule))
147cdf8c16cSxgkiri  private val vIntFixpAlus = Seq.fill(numVecModule)(Module(new VIntFixpAlu64b))
148cdf8c16cSxgkiri  private val mgu = Module(new Mgu(dataWidth))
14930fcc710SZiyue Zhang  private val mgtu = Module(new Mgtu(dataWidth))
15035d005dfSXuan Hu
15135d005dfSXuan Hu  /**
152cdf8c16cSxgkiri   * [[typeMod]]'s in connection
15335d005dfSXuan Hu   */
154cdf8c16cSxgkiri  typeMod.io.in.fuOpType := fuOpType
155cdf8c16cSxgkiri  typeMod.io.in.vsew := vsew
156cdf8c16cSxgkiri  typeMod.io.in.isReverse := isReverse
157cdf8c16cSxgkiri  typeMod.io.in.isExt := isExt
158cdf8c16cSxgkiri  typeMod.io.in.isDstMask := vecCtrl.isDstMask
159cdf8c16cSxgkiri  typeMod.io.in.isMove := isMove
160cdf8c16cSxgkiri
161cdf8c16cSxgkiri  private val vs2GroupedVec32b: 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)
162cdf8c16cSxgkiri  private val vs2GroupedVec16b: Vec[UInt] = VecInit(vs2Split.io.outVec16b.zipWithIndex.groupBy(_._2 % 2).map(x => x._1 -> x._2.map(_._1)).values.map(x => Cat(x.reverse)).toSeq)
163cdf8c16cSxgkiri  private val vs2GroupedVec8b : Vec[UInt] = VecInit(vs2Split.io.outVec8b .zipWithIndex.groupBy(_._2 % 2).map(x => x._1 -> x._2.map(_._1)).values.map(x => Cat(x.reverse)).toSeq)
164fcd66f18SZhaoyang You  private val vs1GroupedVec32b: 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)
165fcd66f18SZhaoyang You  private val vs1GroupedVec16b: Vec[UInt] = VecInit(vs1Split.io.outVec16b.zipWithIndex.groupBy(_._2 % 2).map(x => x._1 -> x._2.map(_._1)).values.map(x => Cat(x.reverse)).toSeq)
166fcd66f18SZhaoyang You  private val vs1GroupedVec8b : Vec[UInt] = VecInit(vs1Split.io.outVec8b .zipWithIndex.groupBy(_._2 % 2).map(x => x._1 -> x._2.map(_._1)).values.map(x => Cat(x.reverse)).toSeq)
16735d005dfSXuan Hu
16835d005dfSXuan Hu  /**
169cdf8c16cSxgkiri   * In connection of [[vs2Split]], [[vs1Split]] and [[oldVdSplit]]
17035d005dfSXuan Hu   */
171cdf8c16cSxgkiri  vs2Split.io.inVecData := vs2
172cdf8c16cSxgkiri  vs1Split.io.inVecData := vs1
173cdf8c16cSxgkiri  oldVdSplit.io.inVecData := oldVd
174cdf8c16cSxgkiri
175cdf8c16cSxgkiri  /**
176cdf8c16cSxgkiri   * [[vIntFixpAlus]]'s in connection
177cdf8c16cSxgkiri   */
178cdf8c16cSxgkiri  private val opcode = VialuFixType.getOpcode(inCtrl.fuOpType).asTypeOf(vIntFixpAlus.head.io.opcode)
179cdf8c16cSxgkiri  private val vs1Type = typeMod.io.out.vs1Type
180cdf8c16cSxgkiri  private val vs2Type = typeMod.io.out.vs2Type
181cdf8c16cSxgkiri  private val vdType = typeMod.io.out.vdType
182cdf8c16cSxgkiri  private val isVextF2 = typeMod.io.out.isVextF2
183cdf8c16cSxgkiri  private val isVextF4 = typeMod.io.out.isVextF4
184cdf8c16cSxgkiri  private val isVextF8 = typeMod.io.out.isVextF8
185cdf8c16cSxgkiri
186cdf8c16cSxgkiri  private val truthTable = TruthTable(VIntFixpTable.table, VIntFixpTable.default)
187cdf8c16cSxgkiri  private val decoderOut = decoder(QMCMinimizer, Cat(opcode.op), truthTable)
188cdf8c16cSxgkiri  private val vIntFixpDecode = decoderOut.asTypeOf(new VIntFixpDecode)
189cdf8c16cSxgkiri  private val isFixp = Mux(vIntFixpDecode.misc, opcode.isScalingShift, opcode.isSatAdd || opcode.isAvgAdd)
190cdf8c16cSxgkiri  private val widen = opcode.isAddSub && vs1Type(1, 0) =/= vdType(1, 0)
191cdf8c16cSxgkiri  private val widen_vs2 = widen && vs2Type(1, 0) =/= vdType(1, 0)
192cdf8c16cSxgkiri  private val eewVs1 = SewOH(vs1Type(1, 0))
193cdf8c16cSxgkiri  private val eewVd = SewOH(vdType(1, 0))
194fcd66f18SZhaoyang You  private val isVwsll = opcode.isVwsll
195cdf8c16cSxgkiri
196cdf8c16cSxgkiri  // Extension instructions
197cdf8c16cSxgkiri  private val vf2 = isVextF2
198cdf8c16cSxgkiri  private val vf4 = isVextF4
199cdf8c16cSxgkiri  private val vf8 = isVextF8
200cdf8c16cSxgkiri
201fcd66f18SZhaoyang You  private val vs1VecUsed: Vec[UInt] = Wire(Vec(numVecModule, UInt(64.W)))
202fcd66f18SZhaoyang You  private val vs2VecUsed: Vec[UInt] = Wire(Vec(numVecModule, UInt(64.W)))
203fcd66f18SZhaoyang You  private val isVwsllEewVdIs64 = isVwsll && eewVd.is64
204fcd66f18SZhaoyang You  private val isVwsllEewVdIs32 = isVwsll && eewVd.is32
205fcd66f18SZhaoyang You  private val isVwsllEewVdIs16 = isVwsll && eewVd.is16
206fcd66f18SZhaoyang You  when(widen || isNarrow || isVwsllEewVdIs64) {
207fcd66f18SZhaoyang You    vs1VecUsed := vs1GroupedVec32b
208fcd66f18SZhaoyang You  }.elsewhen(isVwsllEewVdIs32) {
209fcd66f18SZhaoyang You    vs1VecUsed := vs1GroupedVec16b
210fcd66f18SZhaoyang You  }.elsewhen(isVwsllEewVdIs16) {
211fcd66f18SZhaoyang You    vs1VecUsed := vs1GroupedVec8b
212fcd66f18SZhaoyang You  }.otherwise {
213fcd66f18SZhaoyang You    vs1VecUsed := vs1Split.io.outVec64b
214fcd66f18SZhaoyang You  }
215fcd66f18SZhaoyang You  when(vf2 || isVwsllEewVdIs64) {
216cdf8c16cSxgkiri    vs2VecUsed := vs2GroupedVec32b
217fcd66f18SZhaoyang You  }.elsewhen(vf4 || isVwsllEewVdIs32) {
218cdf8c16cSxgkiri    vs2VecUsed := vs2GroupedVec16b
219fcd66f18SZhaoyang You  }.elsewhen(vf8 || isVwsllEewVdIs16) {
220cdf8c16cSxgkiri    vs2VecUsed := vs2GroupedVec8b
221cdf8c16cSxgkiri  }.otherwise {
222cdf8c16cSxgkiri    vs2VecUsed := vs2Split.io.outVec64b
22335d005dfSXuan Hu  }
22435d005dfSXuan Hu
225b1712600SZiyue Zhang  private val vs2Adder = Mux(widen_vs2, vs2GroupedVec32b, vs2Split.io.outVec64b)
2268f7a869bSZiyue Zhang
227cdf8c16cSxgkiri  // mask
228cdf8c16cSxgkiri  private val maskDataVec: Vec[UInt] = VecDataToMaskDataVec(srcMask, vsew)
229cdf8c16cSxgkiri  private val maskIdx = Mux(isNarrow, (vuopIdx >> 1.U).asUInt, vuopIdx)
2301a6cfb3dSxgkiri  private val eewVd_is_1b = vdType === VdType.mask
231cdf8c16cSxgkiri  private val maskUsed = splitMask(maskDataVec(maskIdx), Mux(eewVd_is_1b, eewVs1, eewVd))
232cdf8c16cSxgkiri
233cdf8c16cSxgkiri  private val oldVdUsed = splitMask(VecDataToMaskDataVec(oldVd, vs1Type(1, 0))(vuopIdx), eewVs1)
234cdf8c16cSxgkiri
235cdf8c16cSxgkiri  vIntFixpAlus.zipWithIndex.foreach {
236cdf8c16cSxgkiri    case (mod, i) =>
237e8e02b74SsinceforYy      mod.io.fire := io.in.valid
238cdf8c16cSxgkiri      mod.io.opcode := opcode
239cdf8c16cSxgkiri
240cdf8c16cSxgkiri      mod.io.info.vm := vm
241cdf8c16cSxgkiri      mod.io.info.ma := vma
242cdf8c16cSxgkiri      mod.io.info.ta := vta
243cdf8c16cSxgkiri      mod.io.info.vlmul := vlmul
244cdf8c16cSxgkiri      mod.io.info.vl := vl
245cdf8c16cSxgkiri      mod.io.info.vstart := vstart
246cdf8c16cSxgkiri      mod.io.info.uopIdx := vuopIdx
247cdf8c16cSxgkiri      mod.io.info.vxrm := vxrm
248cdf8c16cSxgkiri
249cdf8c16cSxgkiri      mod.io.srcType(0) := vs2Type
250cdf8c16cSxgkiri      mod.io.srcType(1) := vs1Type
251cdf8c16cSxgkiri      mod.io.vdType := vdType
252cdf8c16cSxgkiri      mod.io.narrow := isNarrow
253cdf8c16cSxgkiri      mod.io.isSub := vIntFixpDecode.sub
254cdf8c16cSxgkiri      mod.io.isMisc := vIntFixpDecode.misc
255cdf8c16cSxgkiri      mod.io.isFixp := isFixp
256cdf8c16cSxgkiri      mod.io.widen := widen
257cdf8c16cSxgkiri      mod.io.widen_vs2 := widen_vs2
258cdf8c16cSxgkiri      mod.io.vs1 := vs1VecUsed(i)
2598f7a869bSZiyue Zhang      mod.io.vs2_adder := vs2Adder(i)
2608f7a869bSZiyue Zhang      mod.io.vs2_misc := vs2VecUsed(i)
261cdf8c16cSxgkiri      mod.io.vmask := maskUsed(i)
262cdf8c16cSxgkiri      mod.io.oldVd := oldVdUsed(i)
263cdf8c16cSxgkiri  }
264cdf8c16cSxgkiri
265cdf8c16cSxgkiri  /**
266cdf8c16cSxgkiri   * [[mgu]]'s in connection
267cdf8c16cSxgkiri   */
268fcd66f18SZhaoyang You  private val outIsVwsll = RegEnable(isVwsll, io.in.valid)
269fcd66f18SZhaoyang You  private val outIsVwsllEewVdIs64 = RegEnable(isVwsllEewVdIs64, io.in.valid)
270fcd66f18SZhaoyang You  private val outIsVwsllEewVdIs32 = RegEnable(isVwsllEewVdIs32, io.in.valid)
271fcd66f18SZhaoyang You  private val outIsVwsllEewVdIs16 = RegEnable(isVwsllEewVdIs16, io.in.valid)
27234588aebSlewislzh  //private val outEewVs1 = DelayN(eewVs1, latency)
27334588aebSlewislzh  private val outEewVs1 = SNReg(eewVs1, latency)
274cdf8c16cSxgkiri
275fcd66f18SZhaoyang You  private val outVdTmp = Cat(vIntFixpAlus.reverse.map(_.io.vd))
276fcd66f18SZhaoyang You  private val outVd = Mux1H(Seq(
277fcd66f18SZhaoyang You    (outIsVwsllEewVdIs64 || !outIsVwsll) -> outVdTmp,
278fcd66f18SZhaoyang You    outIsVwsllEewVdIs32 -> Cat(outVdTmp(127,  96), outVdTmp(63, 32), outVdTmp( 95, 64), outVdTmp(31,  0)),
279fcd66f18SZhaoyang You    outIsVwsllEewVdIs16 -> Cat(outVdTmp(127, 112), outVdTmp(63, 48), outVdTmp(111, 96), outVdTmp(47, 32), outVdTmp(95, 80), outVdTmp(31, 16), outVdTmp(79, 64), outVdTmp(15,0)),
280fcd66f18SZhaoyang You  ))
2811a6cfb3dSxgkiri  private val outCmp = Mux1H(outEewVs1.oneHot, Seq(8, 4, 2, 1).map(
282cdf8c16cSxgkiri    k => Cat(vIntFixpAlus.reverse.map(_.io.cmpOut(k - 1, 0)))))
283cdf8c16cSxgkiri  private val outNarrow = Cat(vIntFixpAlus.reverse.map(_.io.narrowVd))
284daae8f22SZiyue Zhang  private val outOpcode = VialuFixType.getOpcode(outCtrl.fuOpType).asTypeOf(vIntFixpAlus.head.io.opcode)
285cdf8c16cSxgkiri
2860895fee6SZiyue Zhang  private val numBytes = dataWidth / 8
2870895fee6SZiyue Zhang  private val maxMaskIdx = numBytes
2880895fee6SZiyue Zhang  private val maxVdIdx = 8
2890895fee6SZiyue Zhang  private val elementsInOneUop = Mux1H(outEewVs1.oneHot, Seq(1, 2, 4, 8).map(k => (numBytes / k).U(5.W)))
2900895fee6SZiyue Zhang  private val vdIdx = outVecCtrl.vuopIdx(2, 0)
2910895fee6SZiyue Zhang  private val elementsComputed = Mux1H(Seq.tabulate(maxVdIdx)(i => (vdIdx === i.U) -> (elementsInOneUop * i.U)))
2920895fee6SZiyue Zhang  val outCmpWithTail = Wire(Vec(maxMaskIdx, UInt(1.W)))
2930895fee6SZiyue Zhang  // set the bits in vd to 1 if the index is larger than vl and vta is true
2940895fee6SZiyue Zhang  for (i <- 0 until maxMaskIdx) {
2950895fee6SZiyue Zhang    when(elementsComputed +& i.U >= outVl) {
2967ee6b881SZiyue Zhang      // always operate under a tail-agnostic policy
2977ee6b881SZiyue Zhang      outCmpWithTail(i) := 1.U
2980895fee6SZiyue Zhang    }.otherwise {
2990895fee6SZiyue Zhang      outCmpWithTail(i) := outCmp(i)
3000895fee6SZiyue Zhang    }
3010895fee6SZiyue Zhang  }
3020895fee6SZiyue Zhang
30381cbff07Schengguanghui  /* insts whose mask is not used to generate 'agnosticEn' and 'activeEn' in mgu:
304cdf8c16cSxgkiri   * vadc, vmadc...
305cdf8c16cSxgkiri   * vmerge
306cdf8c16cSxgkiri   */
307cdf8c16cSxgkiri  private val needNoMask = VialuFixType.needNoMask(outCtrl.fuOpType)
308cdf8c16cSxgkiri  private val maskToMgu = Mux(needNoMask, allMaskTrue, outSrcMask)
309cdf8c16cSxgkiri
310cdf8c16cSxgkiri  private val outFormat = VialuFixType.getFormat(outCtrl.fuOpType)
311cdf8c16cSxgkiri  private val outWiden = (outFormat === VialuFixType.FMT.VVW | outFormat === VialuFixType.FMT.WVW) & !outVecCtrl.isExt & !outVecCtrl.isDstMask
312cdf8c16cSxgkiri  private val narrow = outVecCtrl.isNarrow
313cdf8c16cSxgkiri  private val dstMask = outVecCtrl.isDstMask
314904d2184SZiyue Zhang  private val outVxsat = Mux(narrow, Cat(vIntFixpAlus.reverse.map(_.io.vxsat(3, 0))), Cat(vIntFixpAlus.reverse.map(_.io.vxsat)))
315904d2184SZiyue Zhang
316904d2184SZiyue Zhang  // the result of narrow inst which needs concat
317904d2184SZiyue Zhang  private val narrowNeedCat = outVecCtrl.vuopIdx(0).asBool && narrow
318e03e0c5bSZiyue Zhang  private val outNarrowVd = Mux(narrowNeedCat, Cat(outNarrow, outOldVd(dataWidth / 2 - 1, 0)), Cat(outOldVd(dataWidth - 1, dataWidth / 2), outNarrow))
319904d2184SZiyue Zhang  private val outVxsatReal = Mux(narrowNeedCat, Cat(outVxsat(numBytes / 2 - 1, 0), 0.U((numBytes / 2).W)), outVxsat)
320cdf8c16cSxgkiri
321cdf8c16cSxgkiri  private val outEew = Mux(outWiden, outVecCtrl.vsew + 1.U, outVecCtrl.vsew)
322cdf8c16cSxgkiri
323daae8f22SZiyue Zhang  /*
324daae8f22SZiyue Zhang   * vl of vmv.x.s is 1
325daae8f22SZiyue Zhang   */
326daae8f22SZiyue Zhang  private val outIsVmvsx = outOpcode.isVmvsx
327daae8f22SZiyue Zhang
328daae8f22SZiyue Zhang  /*
329daae8f22SZiyue Zhang   * when vstart >= vl, no need to update vd, the old value should be kept
330daae8f22SZiyue Zhang   */
331daae8f22SZiyue Zhang  private val outVstartGeVl = outVstart >= outVl
332daae8f22SZiyue Zhang
333cdf8c16cSxgkiri  mgu.io.in.vd := MuxCase(outVd, Seq(
334904d2184SZiyue Zhang    narrow -> outNarrowVd,
3350895fee6SZiyue Zhang    dstMask -> outCmpWithTail.asUInt,
336cdf8c16cSxgkiri  ))
337cdf8c16cSxgkiri  mgu.io.in.oldVd := outOldVd
338cdf8c16cSxgkiri  mgu.io.in.mask := maskToMgu
339cdf8c16cSxgkiri  mgu.io.in.info.ta := outVecCtrl.vta
340cdf8c16cSxgkiri  mgu.io.in.info.ma := outVecCtrl.vma
341daae8f22SZiyue Zhang  mgu.io.in.info.vl := Mux(outIsVmvsx, 1.U, outVl)
342b3e2881cSxiaofeibao-xjtu  mgu.io.in.info.vlmul := outVecCtrl.vlmul
34334588aebSlewislzh  mgu.io.in.info.valid := validVec.last
344cdf8c16cSxgkiri  mgu.io.in.info.vstart := outVecCtrl.vstart
345cdf8c16cSxgkiri  mgu.io.in.info.eew := outEew
346b3e2881cSxiaofeibao-xjtu  mgu.io.in.info.vsew := outVecCtrl.vsew
347cdf8c16cSxgkiri  mgu.io.in.info.vdIdx := outVecCtrl.vuopIdx
348cdf8c16cSxgkiri  mgu.io.in.info.narrow := narrow
349cdf8c16cSxgkiri  mgu.io.in.info.dstMask := dstMask
35092c6b7edSzhanglinjuan  mgu.io.in.isIndexedVls := false.B
351cdf8c16cSxgkiri
35230fcc710SZiyue Zhang  /**
35330fcc710SZiyue Zhang   * [[mgtu]]'s in connection, for vmask instructions
35430fcc710SZiyue Zhang   */
3557ee6b881SZiyue Zhang  mgtu.io.in.vd := Mux(dstMask && !outVecCtrl.isOpMask, mgu.io.out.vd, outVd)
35630fcc710SZiyue Zhang  mgtu.io.in.vl := outVl
35730fcc710SZiyue Zhang
3587ee6b881SZiyue Zhang  io.out.bits.res.data := Mux(outVstartGeVl, outOldVd, Mux(dstMask, mgtu.io.out.vd, mgu.io.out.vd))
35981cbff07Schengguanghui  io.out.bits.res.vxsat.get := Mux(outVstartGeVl, false.B, (outVxsatReal & mgu.io.out.active).orR)
360daae8f22SZiyue Zhang  io.out.bits.ctrl.exceptionVec.get(ExceptionNO.illegalInstr) := mgu.io.out.illegal && !outVstartGeVl
361cdf8c16cSxgkiri
362cdf8c16cSxgkiri  // util function
363cdf8c16cSxgkiri  def splitMask(maskIn: UInt, sew: SewOH): Vec[UInt] = {
364cdf8c16cSxgkiri    val maskWidth = maskIn.getWidth
365cdf8c16cSxgkiri    val result = Wire(Vec(maskWidth / 8, UInt(8.W)))
366cdf8c16cSxgkiri    for ((resultData, i) <- result.zipWithIndex) {
367cdf8c16cSxgkiri      resultData := Mux1H(Seq(
368cdf8c16cSxgkiri        sew.is8 -> maskIn(i * 8 + 7, i * 8),
3691a6cfb3dSxgkiri        sew.is16 -> Cat(0.U((8 - 4).W), maskIn(i * 4 + 3, i * 4)),
3701a6cfb3dSxgkiri        sew.is32 -> Cat(0.U((8 - 2).W), maskIn(i * 2 + 1, i * 2)),
3711a6cfb3dSxgkiri        sew.is64 -> Cat(0.U((8 - 1).W), maskIn(i)),
372cdf8c16cSxgkiri      ))
373cdf8c16cSxgkiri    }
374cdf8c16cSxgkiri    result
375cdf8c16cSxgkiri  }
376cdf8c16cSxgkiri
37735d005dfSXuan Hu}