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