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