xref: /XiangShan/src/main/scala/xiangshan/backend/fu/wrapper/FCVT.scala (revision 517544cdbf9df2035c91f31798168c81d2589d65)
1package xiangshan.backend.fu.wrapper
2
3import org.chipsalliance.cde.config.Parameters
4import chisel3._
5import chisel3.util._
6import chisel3.util.experimental.decode._
7import utils.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 outIs32bits = RegNext(RegNext(outputWidth1H(2)))
64  val outIsInt = !outCtrl.fuOpType(6)
65  val outIsMvInst = outCtrl.fuOpType(8)
66
67  // modules
68  val fcvt = Module(new VectorCvt(XLEN))
69  fcvt.io.fire := fire
70  fcvt.io.src := src0
71  fcvt.io.opType := opcode(7, 0)
72  fcvt.io.sew := sew
73  fcvt.io.rm := vfcvtRm
74  fcvt.io.isFpToVecInst := true.B
75
76
77  //cycle2
78  val isNarrowCycle2 = RegEnable(RegEnable(isNarrowCvt, fire), fireReg)
79  val outputWidth1HCycle2 = RegEnable(RegEnable(outputWidth1H, fire), fireReg)
80
81  val fcvtResult = Mux(isNarrowCycle2, fcvt.io.result.tail(32), fcvt.io.result)
82
83  val fcvtFflags = Mux1H(outputWidth1HCycle2, Seq(
84    fcvt.io.fflags,
85    Mux(isNarrowCycle2, fcvt.io.fflags.tail(10), fcvt.io.fflags),
86    Mux(isNarrowCycle2, fcvt.io.fflags(4,0), fcvt.io.fflags.tail(10)),
87    fcvt.io.fflags(4,0)
88  ))
89
90  io.out.bits.res.fflags.get := Mux(outIsMvInst, 0.U, fcvtFflags)
91
92  // for scalar f2i cvt inst
93  val isFp2VecForInt = outIs32bits && outIsInt
94  // for f2i mv inst
95  val result = Mux(outIsMvInst, RegNext(RegNext(src0)), fcvtResult)
96
97  io.out.bits.res.data := Fill(32, result(31)) ## result(31, 0)
98}
99