1package xiangshan.backend.fu.wrapper 2 3import org.chipsalliance.cde.config.Parameters 4import chisel3._ 5import chisel3.util._ 6import chisel3.util.experimental.decode._ 7import utility.XSError 8import xiangshan.backend.fu.FuConfig 9import xiangshan.backend.fu.fpu.FpPipedFuncUnit 10import xiangshan.backend.fu.vector.Bundles.VSew 11import xiangshan.FuOpType 12import yunsuan.{VfcvtType, VfpuType} 13import yunsuan.scalar.FPCVT 14import yunsuan.util._ 15 16 17class FCVT(cfg: FuConfig)(implicit p: Parameters) extends FpPipedFuncUnit(cfg) { 18 XSError(io.in.valid && io.in.bits.ctrl.fuOpType === VfpuType.dummy, "Vfcvt OpType not supported") 19 20 // io alias 21 private val opcode = fuOpType(8, 0) 22 private val src0 = inData.src(0) 23 private val sew = fp_fmt 24 25 private val isFround = opcode === VfcvtType.fround 26 private val isFoundnx = opcode === VfcvtType.froundnx 27 private val isFcvtmod = opcode === VfcvtType.fcvtmod_w_d 28 29 private val isRtz = opcode(2) & opcode(1) | isFcvtmod 30 private val isRod = opcode(2) & !opcode(1) & opcode(0) 31 private val isFrm = !isRtz && !isRod 32 private val vfcvtRm = Mux1H( 33 Seq(isRtz, isRod, isFrm), 34 Seq(1.U, 6.U, rm) 35 ) 36 37 val widen = opcode(4, 3) // 0->single 1->widen 2->norrow => width of result 38 val isSingleCvt = !widen(1) & !widen(0) 39 val isWidenCvt = !widen(1) & widen(0) 40 val isNarrowCvt = widen(1) & !widen(0) 41 val fire = io.in.valid 42 val fireReg = GatedValidRegNext(fire) 43 44 // output width 8, 16, 32, 64 45 val output1H = Wire(UInt(4.W)) 46 output1H := chisel3.util.experimental.decode.decoder( 47 widen ## sew, 48 TruthTable( 49 Seq( 50 BitPat("b00_01") -> BitPat("b0010"), // 16 51 BitPat("b00_10") -> BitPat("b0100"), // 32 52 BitPat("b00_11") -> BitPat("b1000"), // 64 53 54 BitPat("b01_00") -> BitPat("b0010"), // 16 55 BitPat("b01_01") -> BitPat("b0100"), // 32 56 BitPat("b01_10") -> BitPat("b1000"), // 64 57 58 BitPat("b10_00") -> BitPat("b0001"), // 8 59 BitPat("b10_01") -> BitPat("b0010"), // 16 60 BitPat("b10_10") -> BitPat("b0100"), // 32 61 62 BitPat("b11_01") -> BitPat("b1000"), // f16->f64/i64/ui64 63 BitPat("b11_11") -> BitPat("b0010"), // f64->f16 64 ), 65 BitPat.N(4) 66 ) 67 ) 68 if(backendParams.debugEn) { 69 dontTouch(output1H) 70 } 71 val outputWidth1H = output1H 72 val outIs16bits = RegNext(RegNext(outputWidth1H(1))) 73 val outIs32bits = RegNext(RegNext(outputWidth1H(2))) 74 val outIsInt = !outCtrl.fuOpType(6) 75 val outIsMvInst = outCtrl.fuOpType === FuOpType.FMVXF 76 77 // modules 78 val fcvt = Module(new FPCVT(XLEN)) 79 fcvt.io.fire := fire 80 fcvt.io.src := src0 81 fcvt.io.opType := opcode(7, 0) 82 fcvt.io.sew := sew 83 fcvt.io.rm := vfcvtRm 84 fcvt.io.isFpToVecInst := true.B 85 fcvt.io.isFround := Cat(isFoundnx, isFround) 86 fcvt.io.isFcvtmod := isFcvtmod 87 88 89 //cycle2 90 val isNarrowCycle2 = RegEnable(RegEnable(isNarrowCvt, fire), fireReg) 91 val outputWidth1HCycle2 = RegEnable(RegEnable(outputWidth1H, fire), fireReg) 92 93 val fcvtResult = fcvt.io.result 94 io.out.bits.res.fflags.get := Mux(outIsMvInst, 0.U, fcvt.io.fflags) 95 96 //fmv box 97 val result_fmv = Mux1H(Seq( 98 (sew === VSew.e8) -> Fill(56, src0(7)) ## src0(7, 0), 99 (sew === VSew.e16) -> Fill(48, src0(15)) ## src0(15, 0), 100 (sew === VSew.e32) -> Fill(32, src0(31)) ## src0(31, 0), 101 (sew === VSew.e64) -> src0, 102 )) 103 // for scalar f2i cvt inst 104 val isFpToInt32 = outIs32bits && outIsInt 105 // for f2i mv inst 106 val result = Mux(outIsMvInst, RegEnable(RegEnable(result_fmv, fire), fireReg), 107 // for scalar fp32 fp16 result 108 Mux( 109 outIs32bits && !outIsInt, 110 Cat(Fill(32, 1.U), fcvtResult(31,0)), 111 Mux(outIs16bits && !outIsInt, Cat(Fill(48, 1.U), fcvtResult(15,0)), fcvtResult) 112 ) 113 ) 114 115 io.out.bits.res.data := Mux(isFpToInt32, 116 Fill(32, result(31)) ## result(31, 0), 117 result 118 ) 119} 120