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