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