xref: /XiangShan/src/main/scala/xiangshan/backend/fu/fpu/IntToFP.scala (revision 614d2bc6eead7bc6e6e71c4d6dc850d2d5ad3aef)
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 org.chipsalliance.cde.config.Parameters
23import chisel3._
24import chisel3.util._
25import utility.{SignExt, ZeroExt}
26import xiangshan.backend.fu.FuConfig
27import yunsuan.scalar
28
29class IntToFPDataModule(latency: Int)(implicit p: Parameters) extends FPUDataModule {
30  val regEnables = IO(Input(Vec(latency, Bool())))
31
32  //  stage1
33  val ctrl = io.in.fpCtrl
34  val in = io.in.src(0)
35  val typ = ctrl.typ
36  val intValue = RegEnable(Mux(ctrl.wflags,
37    Mux(typ(1),
38      Mux(typ(0), ZeroExt(in, XLEN), SignExt(in, XLEN)),
39      Mux(typ(0), ZeroExt(in(31, 0), XLEN), SignExt(in(31, 0), XLEN))
40    ),
41    in
42  ), regEnables(0))
43  val ctrlReg = RegEnable(ctrl, regEnables(0))
44  val rmReg = RegEnable(rm, regEnables(0))
45
46  // stage2
47  val s2_tag = ctrlReg.typeTagOut
48  val s2_wflags = ctrlReg.wflags
49  val s2_typ = ctrlReg.typ
50
51  val mux = Wire(new Bundle() {
52    val data = UInt(XLEN.W)
53    val exc = UInt(5.W)
54  })
55
56  mux.data := intValue
57  mux.exc := 0.U
58
59  when(s2_wflags){
60    val i2fResults = for(t <- FPU.ftypes.take(3)) yield {
61      val i2f = Module(new scalar.IntToFP(t.expWidth, t.precision))
62      i2f.io.sign := ~s2_typ(0)
63      i2f.io.long := s2_typ(1)
64      i2f.io.int := intValue
65      i2f.io.rm := rmReg
66      (i2f.io.result, i2f.io.fflags)
67    }
68    val (data, exc) = i2fResults.unzip
69    mux.data := VecInit(data)(s2_tag)
70    mux.exc := VecInit(exc)(s2_tag)
71  }
72
73  // stage3
74  val s3_out = RegEnable(mux, regEnables(1))
75  val s3_tag = RegEnable(s2_tag, regEnables(1))
76
77  io.out.fflags := s3_out.exc
78  io.out.data := FPU.box(s3_out.data, s3_tag)
79}
80
81class IntToFP(cfg: FuConfig)(implicit p: Parameters) extends FPUPipelineModule(cfg) {
82  override def latency: Int = cfg.latency.latencyVal.get
83  override val dataModule = Module(new IntToFPDataModule(latency))
84  connectDataModule
85  dataModule.regEnables <> VecInit((1 to latency) map (i => regEnable(i)))
86}
87