xref: /XiangShan/src/main/scala/xiangshan/backend/fu/wrapper/FCVT.scala (revision 8a020714df826c6ac860308700137855ecd6ba07)
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