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