From d16a780cf74d65405ed0aa88b3627c0aa804c1be Mon Sep 17 00:00:00 2001 From: Xuan Hu Date: Mon, 29 May 2023 12:52:33 +0800 Subject: [PATCH] vector: fix source data of vmadd and vnmsub * The input of VIMac data module should be exchanged when opcode is vmadd or vnmsub, since source data are not exchanged in data module. --- .../backend/fu/vector/VecPipedFuncUnit.scala | 27 +++++++++++++++-- .../xiangshan/backend/fu/wrapper/VIMacU.scala | 30 +++++++++++-------- 2 files changed, 42 insertions(+), 15 deletions(-) diff --git a/src/main/scala/xiangshan/backend/fu/vector/VecPipedFuncUnit.scala b/src/main/scala/xiangshan/backend/fu/vector/VecPipedFuncUnit.scala index a63d8e3d7..f3c4faf89 100644 --- a/src/main/scala/xiangshan/backend/fu/vector/VecPipedFuncUnit.scala +++ b/src/main/scala/xiangshan/backend/fu/vector/VecPipedFuncUnit.scala @@ -33,8 +33,8 @@ trait VecFuncUnitAlias { this: FuncUnit => // swap vs1 and vs2, used by vrsub, etc protected val isReverse = vecCtrl.isReverse - private val allMaskTrue = VecInit(Seq.fill(VLEN)(true.B)).asUInt - private val allMaskFalse = VecInit(Seq.fill(VLEN)(false.B)).asUInt + protected val allMaskTrue = VecInit(Seq.fill(VLEN)(true.B)).asUInt + protected val allMaskFalse = VecInit(Seq.fill(VLEN)(false.B)).asUInt // vadc.vv, vsbc.vv need this protected val needClearMask: Bool = VialuFixType.needClearMask(inCtrl.fuOpType) @@ -71,6 +71,29 @@ class VecPipedFuncUnit(cfg: FuConfig)(implicit p: Parameters) extends FuncUnit(c protected val vs1 = Mux(isReverse, src1, src0) protected val oldVd = inData.src(2) + protected val outCtrl = ctrlVec.last + protected val outData = dataVec.last + + protected val outVecCtrl = outCtrl.vpu.get + protected val outVm = outVecCtrl.vm + + // vadc.vv, vsbc.vv need this + protected val outNeedClearMask: Bool = VialuFixType.needClearMask(outCtrl.fuOpType) + + protected val outVConfig = if(!cfg.vconfigWakeUp) outCtrl.vpu.get.vconfig else outData.getSrcVConfig.asTypeOf(new VConfig) + protected val outVl = outVConfig.vl + protected val outOldVd = outData.src(2) + // There is no difference between control-dependency or data-dependency for function unit, + // but spliting these in ctrl or data bundles is easy to coding. + protected val outSrcMask: UInt = if (!cfg.maskWakeUp) outCtrl.vpu.get.vmask else { + MuxCase( + outData.getSrcMask, Seq( + outNeedClearMask -> allMaskFalse, + outVm -> allMaskTrue + ) + ) + } + override def latency: Int = cfg.latency.latencyVal.get } diff --git a/src/main/scala/xiangshan/backend/fu/wrapper/VIMacU.scala b/src/main/scala/xiangshan/backend/fu/wrapper/VIMacU.scala index 1fb2e331d..07e5961ef 100644 --- a/src/main/scala/xiangshan/backend/fu/wrapper/VIMacU.scala +++ b/src/main/scala/xiangshan/backend/fu/wrapper/VIMacU.scala @@ -53,6 +53,7 @@ class VIMacU(cfg: FuConfig)(implicit p: Parameters) extends VecPipedFuncUnit(cfg private val opcode = VimacType.getOpcode(fuOpType) private val format = VimacType.getFormat(fuOpType) private val widen = format === VimacType.FMT.VVW + private val exchangeVs2Vd = VimacOpcode.overWriteMultiplicand(opcode) // modules private val typeMod = Module(new VIMacSrcTypeModule) @@ -108,8 +109,8 @@ class VIMacU(cfg: FuConfig)(implicit p: Parameters) extends VecPipedFuncUnit(cfg mod.io.srcType(1) := typeMod.io.out.vs1Type mod.io.vdType := typeMod.io.out.vdType mod.io.vs1 := vs1VecUsed(i) - mod.io.vs2 := vs2VecUsed(i) - mod.io.oldVd := oldVdVecUsed(i) + mod.io.vs2 := Mux(!exchangeVs2Vd, vs2VecUsed(i), oldVdVecUsed(i)) + mod.io.oldVd := Mux(!exchangeVs2Vd, oldVdVecUsed(i), vs2VecUsed(i)) mod.io.highHalf := VimacOpcode.highHalf(opcode) mod.io.isMacc := VimacOpcode.isMacc(opcode) mod.io.isSub := VimacOpcode.isSub(opcode) @@ -120,17 +121,20 @@ class VIMacU(cfg: FuConfig)(implicit p: Parameters) extends VecPipedFuncUnit(cfg /** * [[mgu]]'s in connection */ - private val vd = Cat(vimacs.reverse.map(_.io.vd)) - private val eew = Mux(widen, vsew + 1.U, vsew) - mgu.io.in.vd := vd - mgu.io.in.oldVd := oldVd - mgu.io.in.mask := srcMask - mgu.io.in.info.ta := vta - mgu.io.in.info.ma := vma - mgu.io.in.info.vl := vl - mgu.io.in.info.vstart := vstart - mgu.io.in.info.eew := eew - mgu.io.in.info.vdIdx := vuopIdx + private val outVd = Cat(vimacs.reverse.map(_.io.vd)) + private val outFormat = VimacType.getFormat(outCtrl.fuOpType) + private val outWiden = outFormat === VimacType.FMT.VVW + + private val outEew = Mux(outWiden, outVecCtrl.vsew + 1.U, outVecCtrl.vsew) + mgu.io.in.vd := outVd + mgu.io.in.oldVd := outOldVd + mgu.io.in.mask := outSrcMask + mgu.io.in.info.ta := outVecCtrl.vta + mgu.io.in.info.ma := outVecCtrl.vma + mgu.io.in.info.vl := outVl + mgu.io.in.info.vstart := outVecCtrl.vstart + mgu.io.in.info.eew := outEew + mgu.io.in.info.vdIdx := outVecCtrl.vuopIdx io.out.bits.res.data := mgu.io.out.vd io.out.bits.res.vxsat.get := vimacs.map(_.io.vxsat).reduce(_ | _).orR -- GitLab