xref: /XiangShan/src/main/scala/xiangshan/backend/fu/fpu/IntToFP.scala (revision 5c5bd416ce761d956348a8e2fbbf268922371d8b)
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 IntToFPDataModule extends FPUDataModule {
12
13  val in_valid, out_ready = IO(Input(Bool()))
14  val in_ready, out_valid = IO(Output(Bool()))
15  val kill_w, kill_r = IO(Input(Bool()))
16
17  val s_idle :: s_cvt :: s_ieee :: s_finish :: Nil = Enum(4)
18  val state = RegInit(s_idle)
19
20
21  val in_fire = in_valid && in_ready
22  val out_fire = out_valid && out_ready
23  in_ready := state === s_idle
24  out_valid := state === s_finish
25
26  val src1 = RegEnable(io.in.src(0)(XLEN-1, 0), in_fire)
27  val rmReg = RegEnable(rm, in_fire)
28  val ctrl = RegEnable(io.in.fpCtrl, in_fire)
29
30  switch(state){
31    is(s_idle){
32      when(in_fire && !kill_w){
33        state := s_cvt
34      }
35    }
36    is(s_cvt){
37      state := s_ieee
38    }
39    is(s_ieee){
40      state := s_finish
41    }
42    is(s_finish){
43      when(out_fire){
44        state := s_idle
45      }
46    }
47  }
48  when(state =/= s_idle && kill_r){
49    state := s_idle
50  }
51
52  /*
53      s_cvt
54   */
55  val tag = ctrl.typeTagIn
56  val typ = ctrl.typ
57  val wflags = ctrl.wflags
58
59  val mux = Wire(new Bundle() {
60    val data = UInt((XLEN+1).W)
61    val exc = UInt(5.W)
62  })
63  mux.data := recode(src1, tag)
64  mux.exc := 0.U
65
66  val intValue = Mux(typ(1),
67    Mux(typ(0), ZeroExt(src1, XLEN), SignExt(src1, XLEN)),
68    Mux(typ(0), ZeroExt(src1(31, 0), XLEN), SignExt(src1(31, 0), XLEN))
69  )
70
71  when(wflags){
72    val i2fResults = for(t <- floatTypes) yield {
73      val i2f = Module(new INToRecFN(XLEN, t.exp, t.sig))
74      i2f.io.signedIn := ~typ(0)
75      i2f.io.in := intValue
76      i2f.io.roundingMode := rmReg
77      i2f.io.detectTininess := hardfloat.consts.tininess_afterRounding
78      (sanitizeNaN(i2f.io.out, t), i2f.io.exceptionFlags)
79    }
80    val (data, exc) = i2fResults.unzip
81    mux.data := VecInit(data)(tag)
82    mux.exc := VecInit(exc)(tag)
83  }
84
85  val muxReg = Reg(mux.cloneType)
86  when(state === s_cvt){
87    muxReg := mux
88  }.elsewhen(state === s_ieee){
89    muxReg.data := ieee(box(muxReg.data, ctrl.typeTagOut))
90  }
91
92  fflags := muxReg.exc
93  io.out.data := muxReg.data
94}
95
96class IntToFP extends FPUSubModule {
97  override val dataModule = Module(new IntToFPDataModule)
98  dataModule.in_valid := io.in.valid
99  dataModule.out_ready := io.out.ready
100  connectDataModule
101  val uopReg = RegEnable(io.in.bits.uop, io.in.fire())
102  dataModule.kill_w := io.in.bits.uop.roqIdx.needFlush(io.redirectIn, io.flushIn)
103  dataModule.kill_r := uopReg.roqIdx.needFlush(io.redirectIn, io.flushIn)
104  io.in.ready := dataModule.in_ready
105  io.out.valid := dataModule.out_valid
106  io.out.bits.uop := uopReg
107}
108