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