xref: /XiangShan/src/main/scala/xiangshan/backend/fu/fpu/IntToFP.scala (revision dc597826530cb6803c2396d6ab0e5eb176b732e0)
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 utils.{SignExt, ZeroExt}
26
27class IntToFPDataModule(implicit p: Parameters) extends FPUDataModule {
28
29  val in_valid, out_ready = IO(Input(Bool()))
30  val in_ready, out_valid = IO(Output(Bool()))
31  val kill_w, kill_r = IO(Input(Bool()))
32
33  val s_idle :: s_cvt :: s_finish :: Nil = Enum(3)
34  val state = RegInit(s_idle)
35
36
37  val in_fire = in_valid && in_ready
38  val out_fire = out_valid && out_ready
39  in_ready := state === s_idle
40  out_valid := state === s_finish
41
42  val src1 = RegEnable(io.in.src(0), in_fire)
43  val rmReg = RegEnable(rm, in_fire)
44  val ctrl = RegEnable(io.in.fpCtrl, in_fire)
45
46  switch(state){
47    is(s_idle){
48      when(in_fire && !kill_w){
49        state := s_cvt
50      }
51    }
52    is(s_cvt){
53      state := s_finish
54    }
55    is(s_finish){
56      when(out_fire){
57        state := s_idle
58      }
59    }
60  }
61  when(state =/= s_idle && kill_r){
62    state := s_idle
63  }
64
65  /*
66      s_cvt
67   */
68  val tag = ctrl.typeTagOut
69  val typ = ctrl.typ
70  val wflags = ctrl.wflags
71
72  val mux = Wire(new Bundle() {
73    val data = UInt(XLEN.W)
74    val exc = UInt(5.W)
75  })
76
77  // fmv
78  mux.data := src1
79  mux.exc := 0.U
80
81  val intValue = Mux(typ(1),
82    Mux(typ(0), ZeroExt(src1, XLEN), SignExt(src1, XLEN)),
83    Mux(typ(0), ZeroExt(src1(31, 0), XLEN), SignExt(src1(31, 0), XLEN))
84  )
85
86  when(wflags){
87    val i2fResults = for(t <- FPU.ftypes) yield {
88      val i2f = Module(new fudian.IntToFP(t.expWidth, t.precision))
89      i2f.io.sign := ~typ(0)
90      i2f.io.long := typ(1)
91      i2f.io.int := intValue
92      i2f.io.rm := rmReg
93      (i2f.io.result, i2f.io.fflags)
94    }
95    val (data, exc) = i2fResults.unzip
96    mux.data := VecInit(data)(tag)
97    mux.exc := VecInit(exc)(tag)
98  }
99
100  val muxReg = Reg(mux.cloneType)
101  when(state === s_cvt){
102    muxReg.data := FPU.box(mux.data, ctrl.typeTagOut)
103    muxReg.exc := mux.exc
104  }
105
106  fflags := muxReg.exc
107  io.out.data := muxReg.data
108}
109
110class IntToFP(implicit p: Parameters) extends FPUSubModule {
111  override val dataModule = Module(new IntToFPDataModule)
112  dataModule.in_valid := io.in.valid
113  dataModule.out_ready := io.out.ready
114  connectDataModule
115  val uopReg = RegEnable(io.in.bits.uop, io.in.fire())
116  dataModule.kill_w := io.in.bits.uop.roqIdx.needFlush(io.redirectIn, io.flushIn)
117  dataModule.kill_r := uopReg.roqIdx.needFlush(io.redirectIn, io.flushIn)
118  io.in.ready := dataModule.in_ready
119  io.out.valid := dataModule.out_valid
120  io.out.bits.uop := uopReg
121}
122