From c50af7097c6a3f171f2112bb2ba556c480d3f7b9 Mon Sep 17 00:00:00 2001 From: physics1024 <15101215652@163.com> Date: Wed, 10 Jun 2026 00:50:29 +0800 Subject: [PATCH] feat(BF16) add BF16 extensions to XSAI --- .../xiangshan/backend/decode/DecodeUnit.scala | 23 +++++++++++++------ .../backend/decode/Instructions.scala | 9 ++++++++ .../xiangshan/backend/decode/VecDecoder.scala | 5 ++++ .../backend/decode/VecExceptionGen.scala | 16 +++++++++---- .../xiangshan/backend/fu/wrapper/VCVT.scala | 14 ++++++----- .../xiangshan/backend/fu/wrapper/VFMA.scala | 3 ++- yunsuan | 2 +- 7 files changed, 52 insertions(+), 20 deletions(-) diff --git a/src/main/scala/xiangshan/backend/decode/DecodeUnit.scala b/src/main/scala/xiangshan/backend/decode/DecodeUnit.scala index 97a4a2bc3d0..a87a5ebed73 100644 --- a/src/main/scala/xiangshan/backend/decode/DecodeUnit.scala +++ b/src/main/scala/xiangshan/backend/decode/DecodeUnit.scala @@ -34,6 +34,7 @@ import xiangshan.backend.decode.isa.bitfield.{InstVType, OPCODE5Bit, XSInstBitFi import xiangshan.backend.fu.vector.Bundles.{VType, Vl} import xiangshan.backend.fu.wrapper.CSRToDecode import xiangshan.backend.decode.Zimop._ +import xiangshan.backend.decode.Zfbf._ import yunsuan.{VfaluType, VfcvtType} import xiangshan.backend.decode @@ -558,6 +559,13 @@ object ZfaDecode extends DecodeConstants { ) } +object ZfbfDecode extends DecodeConstants { + override val decodeArray: Array[(BitPat, XSDecodeBase)] = Array( + FCVT_BF16_S -> FDecode(SrcType.fp, SrcType.X, SrcType.X, FuType.fcvt, VfcvtType.fcvt_bf16_s, fWen = T, canRobCompress = T), + FCVT_S_BF16 -> FDecode(SrcType.fp, SrcType.X, SrcType.X, FuType.fcvt, VfcvtType.fcvt_s_bf16, fWen = T, canRobCompress = T), + ) +} + /** * XiangShan Debug Decode constants */ @@ -866,7 +874,8 @@ class DecodeUnit(implicit p: Parameters) extends XSModule with DecodeUnitConstan OptionWrapper(HasMatrixExtension, MatrixDecoder.table(MatrixExtension)).getOrElse(Array()) ++ ZicondDecode.table ++ ZimopDecode.table ++ - ZfaDecode.table + ZfaDecode.table ++ + ZfbfDecode.table require(decode_table.map(_._2.length == 15).reduce(_ && _), "Decode tables have different column size") // assertion for LUI: only LUI should be assigned `selImm === SelImm.IMM_U && fuType === FuType.alu` @@ -1046,7 +1055,7 @@ class DecodeUnit(implicit p: Parameters) extends XSModule with DecodeUnitConstan VFADD_VV, VFSUB_VV, VFWADD_VV, VFWSUB_VV, VFWADD_WV, VFWSUB_WV, VFMUL_VV, VFDIV_VV, VFWMUL_VV, VFMACC_VV, VFNMACC_VV, VFMSAC_VV, VFNMSAC_VV, VFMADD_VV, VFNMADD_VV, VFMSUB_VV, VFNMSUB_VV, - VFWMACC_VV, VFWNMACC_VV, VFWMSAC_VV, VFWNMSAC_VV, + VFWMACC_VV, VFWMACCBF16_VV, VFWNMACC_VV, VFWMSAC_VV, VFWNMSAC_VV, VFSQRT_V, VFMIN_VV, VFMAX_VV, VMFEQ_VV, VMFNE_VV, VMFLT_VV, VMFLE_VV, @@ -1055,7 +1064,7 @@ class DecodeUnit(implicit p: Parameters) extends XSModule with DecodeUnitConstan VFADD_VF, VFSUB_VF, VFRSUB_VF, VFWADD_VF, VFWSUB_VF, VFWADD_WF, VFWSUB_WF, VFMUL_VF, VFDIV_VF, VFRDIV_VF, VFWMUL_VF, VFMACC_VF, VFNMACC_VF, VFMSAC_VF, VFNMSAC_VF, VFMADD_VF, VFNMADD_VF, VFMSUB_VF, VFNMSUB_VF, - VFWMACC_VF, VFWNMACC_VF, VFWMSAC_VF, VFWNMSAC_VF, + VFWMACC_VF, VFWMACCBF16_VF, VFWNMACC_VF, VFWMSAC_VF, VFWNMSAC_VF, VFMIN_VF, VFMAX_VF, VMFEQ_VF, VMFNE_VF, VMFLT_VF, VMFLE_VF, VMFGT_VF, VMFGE_VF, VFSGNJ_VF, VFSGNJN_VF, VFSGNJX_VF, @@ -1066,13 +1075,13 @@ class DecodeUnit(implicit p: Parameters) extends XSModule with DecodeUnitConstan FCVT_W_S, FCVT_WU_S, FCVT_L_S, FCVT_LU_S, FCVT_D_W, FCVT_D_WU, FCVT_D_L, FCVT_D_LU, FCVT_W_D, FCVT_WU_D, FCVT_L_D, FCVT_LU_D, FCVT_S_D, FCVT_D_S, - FCVT_S_H, FCVT_H_S, FCVT_H_D, FCVT_D_H, + FCVT_S_H, FCVT_H_S, FCVT_H_D, FCVT_D_H, FCVT_BF16_S, FCVT_S_BF16, FCVT_H_W, FCVT_H_WU, FCVT_H_L, FCVT_H_LU, FCVT_W_H, FCVT_WU_H, FCVT_L_H, FCVT_LU_H, VFCVT_XU_F_V, VFCVT_X_F_V, VFCVT_RTZ_XU_F_V, VFCVT_RTZ_X_F_V, VFCVT_F_XU_V, VFCVT_F_X_V, - VFWCVT_XU_F_V, VFWCVT_X_F_V, VFWCVT_RTZ_XU_F_V, VFWCVT_RTZ_X_F_V, VFWCVT_F_XU_V, VFWCVT_F_X_V, VFWCVT_F_F_V, + VFWCVT_XU_F_V, VFWCVT_X_F_V, VFWCVT_RTZ_XU_F_V, VFWCVT_RTZ_X_F_V, VFWCVT_F_XU_V, VFWCVT_F_X_V, VFWCVT_F_F_V, VFWCVTBF16_F_F_V, VFNCVT_XU_F_W, VFNCVT_X_F_W, VFNCVT_RTZ_XU_F_W, VFNCVT_RTZ_X_F_W, VFNCVT_F_XU_W, VFNCVT_F_X_W, VFNCVT_F_F_W, - VFNCVT_ROD_F_F_W, VFRSQRT7_V, VFREC7_V, + VFNCVT_ROD_F_F_W, VFNCVTBF16_F_F_W, VFRSQRT7_V, VFREC7_V, // zfa FLEQ_H, FLEQ_S, FLEQ_D, FLTQ_H, FLTQ_S, FLTQ_D, FMINM_H, FMINM_S, FMINM_D, FMAXM_H, FMAXM_S, FMAXM_D, @@ -1085,7 +1094,7 @@ class DecodeUnit(implicit p: Parameters) extends XSModule with DecodeUnitConstan FCVT_W_S, FCVT_WU_S, FCVT_L_S, FCVT_LU_S, FCVT_W_D, FCVT_WU_D, FCVT_L_D, FCVT_LU_D, FCVT_S_D, FCVT_D_S, FCVT_W_H, FCVT_WU_H, FCVT_L_H, FCVT_LU_H, - FCVT_S_H, FCVT_H_S, FCVT_H_D, FCVT_D_H, + FCVT_S_H, FCVT_H_S, FCVT_H_D, FCVT_D_H, FCVT_BF16_S, FCVT_S_BF16, FROUND_H, FROUND_S, FROUND_D, FROUNDNX_H, FROUNDNX_S, FROUNDNX_D, ) diff --git a/src/main/scala/xiangshan/backend/decode/Instructions.scala b/src/main/scala/xiangshan/backend/decode/Instructions.scala index 0b2f535abbd..3e3afcd1256 100644 --- a/src/main/scala/xiangshan/backend/decode/Instructions.scala +++ b/src/main/scala/xiangshan/backend/decode/Instructions.scala @@ -21,6 +21,15 @@ object Zvbb { def VWSLL_VX = BitPat("b110101???????????100?????1010111") } +object Zfbf { + def FCVT_BF16_S = BitPat("b010001001000?????????????1010011") + def FCVT_S_BF16 = BitPat("b010000000110?????????????1010011") + def VFWCVTBF16_F_F_V = BitPat("b010010??????01101001?????1010111") + def VFNCVTBF16_F_F_W = BitPat("b010010??????11101001?????1010111") + def VFWMACCBF16_VV = BitPat("b111011???????????001?????1010111") + def VFWMACCBF16_VF = BitPat("b111011???????????101?????1010111") +} + object Zimop { def MOP_R = BitPat("b1?00??0111???????100?????1110011") def MOP_RR = BitPat("b1?00??1??????????100?????1110011") diff --git a/src/main/scala/xiangshan/backend/decode/VecDecoder.scala b/src/main/scala/xiangshan/backend/decode/VecDecoder.scala index 37641910797..053d3a2e866 100644 --- a/src/main/scala/xiangshan/backend/decode/VecDecoder.scala +++ b/src/main/scala/xiangshan/backend/decode/VecDecoder.scala @@ -12,6 +12,7 @@ import xiangshan.backend.fu.FuType import xiangshan._ import yunsuan.{VfpuType, VipuType, VimacType, VpermType, VialuFixType, VfaluType, VfmaType, VfdivType, VfcvtType, VidivType} import xiangshan.backend.decode.Zvbb._ +import xiangshan.backend.decode.Zfbf._ abstract class VecDecode extends XSDecodeBase { def generate() : List[BitPat] @@ -600,6 +601,7 @@ object VecDecoder extends DecodeConstants { // 13.7. Vector Widening Floating-Point Fused Multiply-Add Instructions VFWMACC_VV -> OPFVV(SrcType.vp, SrcType.vp, FuType.vfma, VfmaType.vfmacc_w , F, T, F, UopSplitType.VEC_VVW), + VFWMACCBF16_VV -> OPFVV(SrcType.vp, SrcType.vp, FuType.vfma, VfmaType.vfwmaccbf16, F, T, F, UopSplitType.VEC_VVW), VFWNMACC_VV -> OPFVV(SrcType.vp, SrcType.vp, FuType.vfma, VfmaType.vfnmacc_w, F, T, F, UopSplitType.VEC_VVW), VFWMSAC_VV -> OPFVV(SrcType.vp, SrcType.vp, FuType.vfma, VfmaType.vfmsac_w , F, T, F, UopSplitType.VEC_VVW), VFWNMSAC_VV -> OPFVV(SrcType.vp, SrcType.vp, FuType.vfma, VfmaType.vfnmsac_w, F, T, F, UopSplitType.VEC_VVW), @@ -647,6 +649,7 @@ object VecDecoder extends DecodeConstants { VFWCVT_F_XU_V -> OPFVV(SrcType.X , SrcType.vp , FuType.vfcvt, VfcvtType.vfwcvt_fxuv, F, T, F, UopSplitType.VEC_VVW), VFWCVT_F_X_V -> OPFVV(SrcType.X , SrcType.vp , FuType.vfcvt, VfcvtType.vfwcvt_fxv, F, T, F, UopSplitType.VEC_VVW), VFWCVT_F_F_V -> OPFVV(SrcType.X , SrcType.vp , FuType.vfcvt, VfcvtType.vfwcvt_ffv, F, T, F, UopSplitType.VEC_VVW), + VFWCVTBF16_F_F_V -> OPFVV(SrcType.X , SrcType.vp , FuType.vfcvt, VfcvtType.vfwcvtbf16_ffv, F, T, F, UopSplitType.VEC_VVW), // ! // 13.19. Narrowing Floating-Point/Integer Type-Convert Instructions @@ -658,6 +661,7 @@ object VecDecoder extends DecodeConstants { VFNCVT_F_X_W -> OPFVV(SrcType.X , SrcType.vp , FuType.vfcvt, VfcvtType.vfncvt_fxw, F, T, F, UopSplitType.VEC_WVV), VFNCVT_F_F_W -> OPFVV(SrcType.X , SrcType.vp , FuType.vfcvt, VfcvtType.vfncvt_ffw, F, T, F, UopSplitType.VEC_WVV), VFNCVT_ROD_F_F_W -> OPFVV(SrcType.X , SrcType.vp , FuType.vfcvt, VfcvtType.vfncvt_rod_ffw, F, T, F, UopSplitType.VEC_WVV), + VFNCVTBF16_F_F_W -> OPFVV(SrcType.X , SrcType.vp , FuType.vfcvt, VfcvtType.vfncvtbf16_ffw, F, T, F, UopSplitType.VEC_WVV), // 14.3. Vector Single-Width Floating-Point Reduction Instructions VFREDOSUM_VS -> OPFVV(SrcType.vp, SrcType.vp, FuType.vfalu, VfaluType.vfredosum, F, T, F, UopSplitType.VEC_VFREDOSUM), VFREDUSUM_VS -> OPFVV(SrcType.vp, SrcType.vp, FuType.vfalu, VfaluType.vfredusum, F, T, F, UopSplitType.VEC_VFRED), @@ -702,6 +706,7 @@ object VecDecoder extends DecodeConstants { // 13.7. Vector Widening Floating-Point Fused Multiply-Add Instructions VFWMACC_VF -> OPFVF(SrcType.fp, SrcType.vp, FuType.vfma, VfmaType.vfmacc_w , F, T, F, UopSplitType.VEC_VFW), + VFWMACCBF16_VF -> OPFVF(SrcType.fp, SrcType.vp, FuType.vfma, VfmaType.vfwmaccbf16, F, T, F, UopSplitType.VEC_VFW), VFWNMACC_VF -> OPFVF(SrcType.fp, SrcType.vp, FuType.vfma, VfmaType.vfnmacc_w, F, T, F, UopSplitType.VEC_VFW), VFWMSAC_VF -> OPFVF(SrcType.fp, SrcType.vp, FuType.vfma, VfmaType.vfmsac_w , F, T, F, UopSplitType.VEC_VFW), VFWNMSAC_VF -> OPFVF(SrcType.fp, SrcType.vp, FuType.vfma, VfmaType.vfnmsac_w, F, T, F, UopSplitType.VEC_VFW), diff --git a/src/main/scala/xiangshan/backend/decode/VecExceptionGen.scala b/src/main/scala/xiangshan/backend/decode/VecExceptionGen.scala index b885c687603..9a3783c869c 100644 --- a/src/main/scala/xiangshan/backend/decode/VecExceptionGen.scala +++ b/src/main/scala/xiangshan/backend/decode/VecExceptionGen.scala @@ -13,6 +13,7 @@ import xiangshan.backend.fu.FuType import xiangshan.backend.fu.vector.Bundles._ import xiangshan.backend.decode.isa.bitfield.{InstVType, XSInstBitFields, OPCODE7Bit} import xiangshan.backend.decode.Zvbb._ +import xiangshan.backend.decode.Zfbf._ object RegNumNotAlign { def apply(reg: UInt, emul: UInt): Bool = { @@ -89,8 +90,8 @@ class VecExceptionGen(implicit p: Parameters) extends XSModule{ //fp VFWADD_VF, VFWADD_VV, VFWADD_WF, VFWADD_WV, VFWSUB_VF, VFWSUB_VV, VFWSUB_WF, VFWSUB_WV, VFWMUL_VF, VFWMUL_VV, - VFWMACC_VF, VFWMACC_VV, VFWMSAC_VF, VFWMSAC_VV, VFWNMACC_VF, VFWNMACC_VV, VFWNMSAC_VF, VFWNMSAC_VV, - VFWCVT_F_F_V, VFWCVT_F_X_V, VFWCVT_F_XU_V, VFWCVT_RTZ_X_F_V, VFWCVT_RTZ_XU_F_V, VFWCVT_X_F_V, VFWCVT_XU_F_V, + VFWMACC_VF, VFWMACC_VV, VFWMACCBF16_VF, VFWMACCBF16_VV, VFWMSAC_VF, VFWMSAC_VV, VFWNMACC_VF, VFWNMACC_VV, VFWNMSAC_VF, VFWNMSAC_VV, + VFWCVT_F_F_V, VFWCVTBF16_F_F_V, VFWCVT_F_X_V, VFWCVT_F_XU_V, VFWCVT_RTZ_X_F_V, VFWCVT_RTZ_XU_F_V, VFWCVT_X_F_V, VFWCVT_XU_F_V, // zvbb VWSLL_VV, VWSLL_VX, VWSLL_VI, ).map(_ === inst.ALL).reduce(_ || _) @@ -108,7 +109,11 @@ class VecExceptionGen(implicit p: Parameters) extends XSModule{ VNCLIP_WI, VNCLIP_WV, VNCLIP_WX, VNCLIPU_WI, VNCLIPU_WV, VNCLIPU_WX, VNSRA_WI, VNSRA_WV, VNSRA_WX, VNSRL_WI, VNSRL_WV, VNSRL_WX, //fp - VFNCVT_F_F_W, VFNCVT_F_X_W, VFNCVT_F_XU_W, VFNCVT_ROD_F_F_W, VFNCVT_RTZ_X_F_W, VFNCVT_RTZ_XU_F_W, VFNCVT_X_F_W, VFNCVT_XU_F_W + VFNCVT_F_F_W, VFNCVTBF16_F_F_W, VFNCVT_F_X_W, VFNCVT_F_XU_W, VFNCVT_ROD_F_F_W, VFNCVT_RTZ_X_F_W, VFNCVT_RTZ_XU_F_W, VFNCVT_X_F_W, VFNCVT_XU_F_W + ).map(_ === inst.ALL).reduce(_ || _) + + private val bf16VectorInst = Seq( + VFWCVTBF16_F_F_V, VFNCVTBF16_F_F_W, VFWMACCBF16_VF, VFWMACCBF16_VV ).map(_ === inst.ALL).reduce(_ || _) private val intExtInst = Seq( @@ -191,8 +196,9 @@ class VecExceptionGen(implicit p: Parameters) extends XSModule{ intExt8 && SEW <= 2.U private val wnEewIllegal = (vdWideningInst || narrowingInst || redWideningInst) && SEW === 3.U + private val bf16EewIllegal = bf16VectorInst && SEW =/= 1.U - private val eewIllegal = fpEewIllegal || intExtEewIllegal || wnEewIllegal + private val eewIllegal = fpEewIllegal || intExtEewIllegal || wnEewIllegal || bf16EewIllegal // 4. EMUL Illegal private val lsEmulIllegal = (lsStrideInst || lsIndexInst) && (LMUL +& inst.WIDTH(1, 0) < SEW +& 1.U || LMUL +& inst.WIDTH(1, 0) > SEW +& 7.U) @@ -300,4 +306,4 @@ class VecExceptionGen(implicit p: Parameters) extends XSModule{ dontTouch(regOverlapIllegal) dontTouch(notDependVtypeInst) dontTouch(vstartIllegal) -} \ No newline at end of file +} diff --git a/src/main/scala/xiangshan/backend/fu/wrapper/VCVT.scala b/src/main/scala/xiangshan/backend/fu/wrapper/VCVT.scala index a33dc6639c7..62317d7a0c0 100644 --- a/src/main/scala/xiangshan/backend/fu/wrapper/VCVT.scala +++ b/src/main/scala/xiangshan/backend/fu/wrapper/VCVT.scala @@ -9,7 +9,7 @@ import xiangshan.backend.fu.FuConfig import xiangshan.backend.fu.vector.{Mgu, VecPipedFuncUnit} import xiangshan.ExceptionNO import xiangshan.FuOpType -import yunsuan.VfpuType +import yunsuan.{VfcvtType, VfpuType} import yunsuan.vector.VectorConvert.VectorCvt import yunsuan.util._ @@ -25,9 +25,11 @@ class VCVT(cfg: FuConfig)(implicit p: Parameters) extends VecPipedFuncUnit(cfg) // io alias private val opcode = fuOpType(8, 0) private val sew = vsew + private val isVfwCvtBf16 = opcode(7, 0) === VfcvtType.vfwcvtbf16_ffv + private val isVfnCvtBf16 = opcode(7, 0) === VfcvtType.vfncvtbf16_ffw private val isRtz = opcode(2) & opcode(1) - private val isRod = opcode(2) & !opcode(1) & opcode(0) + private val isRod = opcode(2) & !opcode(1) & opcode(0) & !isVfnCvtBf16 private val isFrm = !isRtz && !isRod private val vfcvtRm = Mux1H( Seq(isRtz, isRod, isFrm), @@ -38,14 +40,14 @@ class VCVT(cfg: FuConfig)(implicit p: Parameters) extends VecPipedFuncUnit(cfg) val widen = opcode(4, 3) // 0->single 1->widen 2->norrow => width of result val isSingleCvt = !widen(1) & !widen(0) - val isWidenCvt = !widen(1) & widen(0) - val isNarrowCvt = widen(1) & !widen(0) + val isWidenCvt = (!widen(1) & widen(0)) || isVfwCvtBf16 + val isNarrowCvt = (widen(1) & !widen(0)) || isVfnCvtBf16 val fire = io.in.valid val fireReg = GatedValidRegNext(fire) // output width 8, 16, 32, 64 val output1H = Wire(UInt(4.W)) - output1H := chisel3.util.experimental.decode.decoder( + val commonOutput1H = chisel3.util.experimental.decode.decoder( widen ## sew, TruthTable( Seq( @@ -64,6 +66,7 @@ class VCVT(cfg: FuConfig)(implicit p: Parameters) extends VecPipedFuncUnit(cfg) BitPat.N(4) ) ) + output1H := Mux(isVfnCvtBf16, "b0010".U, Mux(isVfwCvtBf16, "b0100".U, commonOutput1H)) if(backendParams.debugEn) { dontTouch(output1H) } @@ -252,4 +255,3 @@ class VectorCvtTop(vlen: Int, xlen: Int) extends Module{ )) } - diff --git a/src/main/scala/xiangshan/backend/fu/wrapper/VFMA.scala b/src/main/scala/xiangshan/backend/fu/wrapper/VFMA.scala index 9a6124c5b22..64df421e530 100644 --- a/src/main/scala/xiangshan/backend/fu/wrapper/VFMA.scala +++ b/src/main/scala/xiangshan/backend/fu/wrapper/VFMA.scala @@ -24,6 +24,7 @@ class VFMA(cfg: FuConfig)(implicit p: Parameters) extends VecPipedFuncUnit(cfg) // io alias private val opcode = fuOpType(3,0) private val resWiden = fuOpType(4) + private val isBf16Widen = fuOpType === VfmaType.vfwmaccbf16 // modules private val vfmas = Seq.fill(numVecModule)(Module(new VectorFloatFMA)) @@ -67,7 +68,7 @@ class VFMA(cfg: FuConfig)(implicit p: Parameters) extends VecPipedFuncUnit(cfg) mod.io.uop_idx := vuopIdx(0) mod.io.is_vec := true.B // Todo mod.io.round_mode := rm - mod.io.fp_format := Mux(resWiden, vsew + 1.U, vsew) + mod.io.fp_format := Mux(isBf16Widen, 0.U(2.W), Mux(resWiden, vsew + 1.U, vsew)) mod.io.res_widening := resWiden mod.io.op_code := opcode resultData(i) := mod.io.fp_result diff --git a/yunsuan b/yunsuan index 955921186e3..f04155f7344 160000 --- a/yunsuan +++ b/yunsuan @@ -1 +1 @@ -Subproject commit 955921186e34bb8915806582a238181a6dc3435c +Subproject commit f04155f734454adef5b0d99a80d19944cac0bffe