1517544cdSsinsanctionpackage xiangshan.backend.fu.wrapper 2517544cdSsinsanction 3517544cdSsinsanctionimport org.chipsalliance.cde.config.Parameters 4517544cdSsinsanctionimport chisel3._ 5517544cdSsinsanctionimport chisel3.util._ 6517544cdSsinsanctionimport chisel3.util.experimental.decode._ 7bb2f3f51STang Haojinimport utility.XSError 8517544cdSsinsanctionimport xiangshan.backend.fu.FuConfig 9517544cdSsinsanctionimport xiangshan.backend.fu.fpu.FpPipedFuncUnit 10b189aafaSzmximport xiangshan.backend.fu.vector.Bundles.VSew 11*20b2b626SsinceforYyimport xiangshan.FuOpType 12*20b2b626SsinceforYyimport yunsuan.{VfcvtType, VfpuType} 13b189aafaSzmximport yunsuan.scalar.FPCVT 14517544cdSsinsanctionimport yunsuan.util._ 15517544cdSsinsanction 16517544cdSsinsanction 17517544cdSsinsanctionclass FCVT(cfg: FuConfig)(implicit p: Parameters) extends FpPipedFuncUnit(cfg) { 18517544cdSsinsanction XSError(io.in.valid && io.in.bits.ctrl.fuOpType === VfpuType.dummy, "Vfcvt OpType not supported") 19517544cdSsinsanction 20517544cdSsinsanction // io alias 21517544cdSsinsanction private val opcode = fuOpType(8, 0) 22517544cdSsinsanction private val src0 = inData.src(0) 23517544cdSsinsanction private val sew = fp_fmt 24517544cdSsinsanction 25*20b2b626SsinceforYy private val isFround = opcode === VfcvtType.fround 26*20b2b626SsinceforYy private val isFoundnx = opcode === VfcvtType.froundnx 27*20b2b626SsinceforYy private val isFcvtmod = opcode === VfcvtType.fcvtmod_w_d 28*20b2b626SsinceforYy 29*20b2b626SsinceforYy private val isRtz = opcode(2) & opcode(1) | isFcvtmod 30517544cdSsinsanction private val isRod = opcode(2) & !opcode(1) & opcode(0) 31517544cdSsinsanction private val isFrm = !isRtz && !isRod 32517544cdSsinsanction private val vfcvtRm = Mux1H( 33517544cdSsinsanction Seq(isRtz, isRod, isFrm), 34517544cdSsinsanction Seq(1.U, 6.U, rm) 35517544cdSsinsanction ) 36517544cdSsinsanction 37517544cdSsinsanction val widen = opcode(4, 3) // 0->single 1->widen 2->norrow => width of result 38517544cdSsinsanction val isSingleCvt = !widen(1) & !widen(0) 39517544cdSsinsanction val isWidenCvt = !widen(1) & widen(0) 40517544cdSsinsanction val isNarrowCvt = widen(1) & !widen(0) 41517544cdSsinsanction val fire = io.in.valid 42517544cdSsinsanction val fireReg = GatedValidRegNext(fire) 43517544cdSsinsanction 44517544cdSsinsanction // output width 8, 16, 32, 64 45517544cdSsinsanction val output1H = Wire(UInt(4.W)) 46517544cdSsinsanction output1H := chisel3.util.experimental.decode.decoder( 47517544cdSsinsanction widen ## sew, 48517544cdSsinsanction TruthTable( 49517544cdSsinsanction Seq( 50517544cdSsinsanction BitPat("b00_01") -> BitPat("b0010"), // 16 51517544cdSsinsanction BitPat("b00_10") -> BitPat("b0100"), // 32 52517544cdSsinsanction BitPat("b00_11") -> BitPat("b1000"), // 64 53517544cdSsinsanction 54517544cdSsinsanction BitPat("b01_00") -> BitPat("b0010"), // 16 55517544cdSsinsanction BitPat("b01_01") -> BitPat("b0100"), // 32 56517544cdSsinsanction BitPat("b01_10") -> BitPat("b1000"), // 64 57517544cdSsinsanction 58517544cdSsinsanction BitPat("b10_00") -> BitPat("b0001"), // 8 59517544cdSsinsanction BitPat("b10_01") -> BitPat("b0010"), // 16 60517544cdSsinsanction BitPat("b10_10") -> BitPat("b0100"), // 32 61b189aafaSzmx 62b189aafaSzmx BitPat("b11_01") -> BitPat("b1000"), // f16->f64/i64/ui64 63b189aafaSzmx BitPat("b11_11") -> BitPat("b0010"), // f64->f16 64517544cdSsinsanction ), 65517544cdSsinsanction BitPat.N(4) 66517544cdSsinsanction ) 67517544cdSsinsanction ) 68517544cdSsinsanction if(backendParams.debugEn) { 69517544cdSsinsanction dontTouch(output1H) 70517544cdSsinsanction } 71517544cdSsinsanction val outputWidth1H = output1H 725b2e2174Sxiaofeibao val outIs16bits = RegNext(RegNext(outputWidth1H(1))) 73517544cdSsinsanction val outIs32bits = RegNext(RegNext(outputWidth1H(2))) 74517544cdSsinsanction val outIsInt = !outCtrl.fuOpType(6) 75*20b2b626SsinceforYy val outIsMvInst = outCtrl.fuOpType === FuOpType.FMVXF 76517544cdSsinsanction 77517544cdSsinsanction // modules 78b189aafaSzmx val fcvt = Module(new FPCVT(XLEN)) 79517544cdSsinsanction fcvt.io.fire := fire 80517544cdSsinsanction fcvt.io.src := src0 81517544cdSsinsanction fcvt.io.opType := opcode(7, 0) 82517544cdSsinsanction fcvt.io.sew := sew 83517544cdSsinsanction fcvt.io.rm := vfcvtRm 84517544cdSsinsanction fcvt.io.isFpToVecInst := true.B 85*20b2b626SsinceforYy fcvt.io.isFround := Cat(isFoundnx, isFround) 86*20b2b626SsinceforYy fcvt.io.isFcvtmod := isFcvtmod 87517544cdSsinsanction 88517544cdSsinsanction 89517544cdSsinsanction //cycle2 90517544cdSsinsanction val isNarrowCycle2 = RegEnable(RegEnable(isNarrowCvt, fire), fireReg) 91517544cdSsinsanction val outputWidth1HCycle2 = RegEnable(RegEnable(outputWidth1H, fire), fireReg) 92517544cdSsinsanction 93b189aafaSzmx val fcvtResult = fcvt.io.result 94b189aafaSzmx io.out.bits.res.fflags.get := Mux(outIsMvInst, 0.U, fcvt.io.fflags) 95517544cdSsinsanction 96b189aafaSzmx //fmv box 97b189aafaSzmx val result_fmv = Mux1H(Seq( 98b189aafaSzmx (sew === VSew.e8) -> Fill(56, src0(7)) ## src0(7, 0), 99b189aafaSzmx (sew === VSew.e16) -> Fill(48, src0(15)) ## src0(15, 0), 100b189aafaSzmx (sew === VSew.e32) -> Fill(32, src0(31)) ## src0(31, 0), 101b189aafaSzmx (sew === VSew.e64) -> src0, 102517544cdSsinsanction )) 103517544cdSsinsanction // for scalar f2i cvt inst 104446ae837Sxiaofeibao val isFpToInt32 = outIs32bits && outIsInt 105517544cdSsinsanction // for f2i mv inst 106b189aafaSzmx val result = Mux(outIsMvInst, RegEnable(RegEnable(result_fmv, fire), fireReg), 1075b2e2174Sxiaofeibao // for scalar fp32 fp16 result 1085b2e2174Sxiaofeibao Mux( 1095b2e2174Sxiaofeibao outIs32bits && !outIsInt, 1105b2e2174Sxiaofeibao Cat(Fill(32, 1.U), fcvtResult(31,0)), 1115b2e2174Sxiaofeibao Mux(outIs16bits && !outIsInt, Cat(Fill(48, 1.U), fcvtResult(15,0)), fcvtResult) 1125b2e2174Sxiaofeibao ) 1135b2e2174Sxiaofeibao ) 114517544cdSsinsanction 115446ae837Sxiaofeibao io.out.bits.res.data := Mux(isFpToInt32, 116446ae837Sxiaofeibao Fill(32, result(31)) ## result(31, 0), 117446ae837Sxiaofeibao result 118446ae837Sxiaofeibao ) 119517544cdSsinsanction} 120