xref: /XiangShan/src/main/scala/xiangshan/backend/fu/fpu/IntToFP.scala (revision ba64d2c927a3b9adda60d1d2dda01f35fbbb6ac7)
1// See LICENSE.Berkeley for license details.
2// See LICENSE.SiFive for license details.
3
4package xiangshan.backend.fu.fpu
5
6import chisel3._
7import chisel3.util._
8import hardfloat.INToRecFN
9import utils.{SignExt, ZeroExt}
10
11class IntToFP extends FPUSubModule {
12
13  val s_idle :: s_cvt :: s_ieee :: s_finish :: Nil = Enum(4)
14  val state = RegInit(s_idle)
15
16  io.in.ready := state === s_idle
17  io.out.valid := state === s_finish
18
19  val src1 = RegEnable(io.in.bits.src(0)(XLEN-1, 0), io.in.fire())
20  val uopReg = RegEnable(io.in.bits.uop, io.in.fire())
21  val rmReg = RegEnable(rm, io.in.fire())
22
23  switch(state){
24    is(s_idle){
25      when(io.in.fire() && !io.in.bits.uop.roqIdx.needFlush(io.redirectIn, io.flushIn)){
26        state := s_cvt
27      }
28    }
29    is(s_cvt){
30      state := s_ieee
31    }
32    is(s_ieee){
33      state := s_finish
34    }
35    is(s_finish){
36      when(io.out.fire()){
37        state := s_idle
38      }
39    }
40  }
41  when(state =/= s_idle && uopReg.roqIdx.needFlush(io.redirectIn, io.flushIn)){
42    state := s_idle
43  }
44
45  /*
46      s_cvt
47   */
48  val ctrl = uopReg.ctrl.fpu
49  val tag = ctrl.typeTagIn
50  val typ = ctrl.typ
51  val wflags = ctrl.wflags
52
53  val mux = Wire(new Bundle() {
54    val data = UInt((XLEN+1).W)
55    val exc = UInt(5.W)
56  })
57  mux.data := recode(src1, tag)
58  mux.exc := 0.U
59
60  val intValue = Mux(typ(1),
61    Mux(typ(0), ZeroExt(src1, XLEN), SignExt(src1, XLEN)),
62    Mux(typ(0), ZeroExt(src1(31, 0), XLEN), SignExt(src1(31, 0), XLEN))
63  )
64
65  when(wflags){
66    val i2fResults = for(t <- floatTypes) yield {
67      val i2f = Module(new INToRecFN(XLEN, t.exp, t.sig))
68      i2f.io.signedIn := ~typ(0)
69      i2f.io.in := intValue
70      i2f.io.roundingMode := rmReg
71      i2f.io.detectTininess := hardfloat.consts.tininess_afterRounding
72      (sanitizeNaN(i2f.io.out, t), i2f.io.exceptionFlags)
73    }
74    val (data, exc) = i2fResults.unzip
75    mux.data := VecInit(data)(tag)
76    mux.exc := VecInit(exc)(tag)
77  }
78
79  val muxReg = Reg(mux.cloneType)
80  when(state === s_cvt){
81    muxReg := mux
82  }.elsewhen(state === s_ieee){
83    muxReg.data := ieee(box(muxReg.data, ctrl.typeTagOut))
84  }
85
86  fflags := muxReg.exc
87  io.out.bits.uop := uopReg
88  io.out.bits.data := muxReg.data
89}
90