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