xref: /XiangShan/src/main/scala/xiangshan/backend/fu/fpu/IntToFP.scala (revision f320e0f01bd645f0a3045a8a740e60dd770734a9)
1/***************************************************************************************
2* Copyright (c) 2020-2021 Institute of Computing Technology, Chinese Academy of Sciences
3* Copyright (c) 2020-2021 Peng Cheng Laboratory
4*
5* XiangShan is licensed under Mulan PSL v2.
6* You can use this software according to the terms and conditions of the Mulan PSL v2.
7* You may obtain a copy of Mulan PSL v2 at:
8*          http://license.coscl.org.cn/MulanPSL2
9*
10* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
11* EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
12* MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
13*
14* See the Mulan PSL v2 for more details.
15***************************************************************************************/
16
17// See LICENSE.Berkeley for license details.
18// See LICENSE.SiFive for license details.
19
20package xiangshan.backend.fu.fpu
21
22import chipsalliance.rocketchip.config.Parameters
23import chisel3._
24import chisel3.util._
25import hardfloat.INToRecFN
26import utils.{SignExt, ZeroExt}
27import xiangshan._
28
29class IntToFPDataModule(implicit p: Parameters) extends FPUDataModule {
30
31  val in_valid, out_ready = IO(Input(Bool()))
32  val in_ready, out_valid = IO(Output(Bool()))
33  val kill_w, kill_r = IO(Input(Bool()))
34
35  val s_idle :: s_cvt :: s_ieee :: s_finish :: Nil = Enum(4)
36  val state = RegInit(s_idle)
37
38
39  val in_fire = in_valid && in_ready
40  val out_fire = out_valid && out_ready
41  in_ready := state === s_idle
42  out_valid := state === s_finish
43
44  val src1 = RegEnable(io.in.src(0)(XLEN-1, 0), in_fire)
45  val rmReg = RegEnable(rm, in_fire)
46  val ctrl = RegEnable(io.in.fpCtrl, in_fire)
47
48  switch(state){
49    is(s_idle){
50      when(in_fire && !kill_w){
51        state := s_cvt
52      }
53    }
54    is(s_cvt){
55      state := s_ieee
56    }
57    is(s_ieee){
58      state := s_finish
59    }
60    is(s_finish){
61      when(out_fire){
62        state := s_idle
63      }
64    }
65  }
66  when(state =/= s_idle && kill_r){
67    state := s_idle
68  }
69
70  /*
71      s_cvt
72   */
73  val tag = ctrl.typeTagIn
74  val typ = ctrl.typ
75  val wflags = ctrl.wflags
76
77  val mux = Wire(new Bundle() {
78    val data = UInt((XLEN+1).W)
79    val exc = UInt(5.W)
80  })
81  mux.data := recode(src1, tag)
82  mux.exc := 0.U
83
84  val intValue = Mux(typ(1),
85    Mux(typ(0), ZeroExt(src1, XLEN), SignExt(src1, XLEN)),
86    Mux(typ(0), ZeroExt(src1(31, 0), XLEN), SignExt(src1(31, 0), XLEN))
87  )
88
89  when(wflags){
90    val i2fResults = for(t <- floatTypes) yield {
91      val i2f = Module(new INToRecFN(XLEN, t.exp, t.sig))
92      i2f.io.signedIn := ~typ(0)
93      i2f.io.in := intValue
94      i2f.io.roundingMode := rmReg
95      i2f.io.detectTininess := hardfloat.consts.tininess_afterRounding
96      (sanitizeNaN(i2f.io.out, t), i2f.io.exceptionFlags)
97    }
98    val (data, exc) = i2fResults.unzip
99    mux.data := VecInit(data)(tag)
100    mux.exc := VecInit(exc)(tag)
101  }
102
103  val muxReg = Reg(mux.cloneType)
104  when(state === s_cvt){
105    muxReg := mux
106  }.elsewhen(state === s_ieee){
107    muxReg.data := ieee(box(muxReg.data, ctrl.typeTagOut))
108  }
109
110  fflags := muxReg.exc
111  io.out.data := muxReg.data
112}
113
114class IntToFP(implicit p: Parameters) extends FPUSubModule {
115  override val dataModule = Module(new IntToFPDataModule)
116  dataModule.in_valid := io.in.valid
117  dataModule.out_ready := io.out.ready
118  connectDataModule
119  val uopReg = RegEnable(io.in.bits.uop, io.in.fire())
120  dataModule.kill_w := io.in.bits.uop.roqIdx.needFlush(io.redirectIn, io.flushIn)
121  dataModule.kill_r := uopReg.roqIdx.needFlush(io.redirectIn, io.flushIn)
122  io.in.ready := dataModule.in_ready
123  io.out.valid := dataModule.out_valid
124  io.out.bits.uop := uopReg
125}
126