xref: /XiangShan/src/main/scala/xiangshan/backend/fu/fpu/IntFPToVec.scala (revision 20b2b626df334d81ef257109d46d530f01639020)
1395c8649SZiyue-Zhang/***************************************************************************************
2395c8649SZiyue-Zhang* Copyright (c) 2020-2021 Institute of Computing Technology, Chinese Academy of Sciences
3395c8649SZiyue-Zhang* Copyright (c) 2020-2021 Peng Cheng Laboratory
4395c8649SZiyue-Zhang*
5395c8649SZiyue-Zhang* XiangShan is licensed under Mulan PSL v2.
6395c8649SZiyue-Zhang* You can use this software according to the terms and conditions of the Mulan PSL v2.
7395c8649SZiyue-Zhang* You may obtain a copy of Mulan PSL v2 at:
8395c8649SZiyue-Zhang*          http://license.coscl.org.cn/MulanPSL2
9395c8649SZiyue-Zhang*
10395c8649SZiyue-Zhang* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
11395c8649SZiyue-Zhang* EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
12395c8649SZiyue-Zhang* MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
13395c8649SZiyue-Zhang*
14395c8649SZiyue-Zhang* See the Mulan PSL v2 for more details.
15395c8649SZiyue-Zhang***************************************************************************************/
16395c8649SZiyue-Zhang
17395c8649SZiyue-Zhang// See LICENSE.Berkeley for license details.
18395c8649SZiyue-Zhang// See LICENSE.SiFive for license details.
19395c8649SZiyue-Zhang
20395c8649SZiyue-Zhangpackage xiangshan.backend.fu.fpu
21395c8649SZiyue-Zhang
22395c8649SZiyue-Zhangimport org.chipsalliance.cde.config.Parameters
23395c8649SZiyue-Zhangimport chisel3._
24395c8649SZiyue-Zhangimport chisel3.util._
25395c8649SZiyue-Zhangimport utility.{SignExt, ZeroExt}
26395c8649SZiyue-Zhangimport xiangshan.backend.fu.{FuConfig, FuncUnit, PipedFuncUnit}
27395c8649SZiyue-Zhangimport xiangshan.backend.fu.vector.Bundles.VSew
28395c8649SZiyue-Zhangimport xiangshan.IF2VectorType
29395c8649SZiyue-Zhang
30395c8649SZiyue-Zhangclass IntFPToVec(cfg: FuConfig)(implicit p: Parameters) extends PipedFuncUnit(cfg) {
31395c8649SZiyue-Zhang  protected val in = io.in.bits
32395c8649SZiyue-Zhang  protected val out = io.out.bits
33395c8649SZiyue-Zhang
34*20b2b626SsinceforYy  private val isFliH = in.ctrl.fuOpType(7) &&  in.ctrl.fuOpType(6) && !in.ctrl.fuOpType(5)
35*20b2b626SsinceforYy  private val isFliS = in.ctrl.fuOpType(7) && !in.ctrl.fuOpType(6) && !in.ctrl.fuOpType(5)
36*20b2b626SsinceforYy  private val isFliD = in.ctrl.fuOpType(7) && !in.ctrl.fuOpType(6) &&  in.ctrl.fuOpType(5)
37*20b2b626SsinceforYy  private val isFli = isFliH || isFliS || isFliD
38395c8649SZiyue-Zhang
39*20b2b626SsinceforYy  private val FliData = Wire(UInt(XLEN.W))
40*20b2b626SsinceforYy
41*20b2b626SsinceforYy  private val FliHTable = Module(new FliHTable)
42*20b2b626SsinceforYy  private val FliSTable = Module(new FliSTable)
43*20b2b626SsinceforYy  private val FliDTable = Module(new FliDTable)
44*20b2b626SsinceforYy
45*20b2b626SsinceforYy  FliHTable.src := in.ctrl.fuOpType(4, 0)
46*20b2b626SsinceforYy  FliSTable.src := in.ctrl.fuOpType(4, 0)
47*20b2b626SsinceforYy  FliDTable.src := in.ctrl.fuOpType(4, 0)
48*20b2b626SsinceforYy
49*20b2b626SsinceforYy  FliData := Mux1H(
50*20b2b626SsinceforYy    Seq(
51*20b2b626SsinceforYy      isFliH,
52*20b2b626SsinceforYy      isFliS,
53*20b2b626SsinceforYy      isFliD
54*20b2b626SsinceforYy    ),
55*20b2b626SsinceforYy    Seq(
56*20b2b626SsinceforYy      Cat(~0.U(48.W), FliHTable.out),
57*20b2b626SsinceforYy      Cat(~0.U(32.W), FliSTable.out, 0.U(16.W)),
58*20b2b626SsinceforYy      Cat(FliDTable.out, 0.U(48.W)))
59*20b2b626SsinceforYy  )
60*20b2b626SsinceforYy
61*20b2b626SsinceforYy  // vsew is the lowest 2 bits of fuOpType
62*20b2b626SsinceforYy  private val isImm = Mux(isFli, 0.U, IF2VectorType.isImm(in.ctrl.fuOpType(4, 2))).asBool
63*20b2b626SsinceforYy  // when needDup is true, the scalar data is duplicated in vector register
64*20b2b626SsinceforYy  private val needDup = Mux(isFli, 0.U, IF2VectorType.needDup(in.ctrl.fuOpType(4, 2))).asBool
65*20b2b626SsinceforYy  // when isFmv is true, the high bits of the scalar data is 1
66*20b2b626SsinceforYy  private val isFmv = Mux(isFli, 0.U, IF2VectorType.isFmv(in.ctrl.fuOpType(4, 2))).asBool
67*20b2b626SsinceforYy
68*20b2b626SsinceforYy  private val isFp = Mux(isFli, 0.U, IF2VectorType.isFp(in.ctrl.fuOpType(4, 2))).asBool
695820cff8Slewislzh
70395c8649SZiyue-Zhang  // imm use src(1), scalar use src(0)
71*20b2b626SsinceforYy  private val scalaData = Mux(isFli, FliData, Mux(isImm, in.data.src(1), in.data.src(0)))
72395c8649SZiyue-Zhang  // vsew is the lowest 2 bits of fuOpType
73395c8649SZiyue-Zhang  private val vsew = in.ctrl.fuOpType(1, 0)
742d12882cSxiaofeibao  private val dataWidth = cfg.destDataBits
75395c8649SZiyue-Zhang
765820cff8Slewislzh  private val outNAN = Seq(
775820cff8Slewislzh    Cat(0.U, Fill(3, 1.U), 1.U, 0.U(3.W)),
785820cff8Slewislzh    Cat(0.U, Fill(5, 1.U), 1.U, 0.U(9.W)),
795820cff8Slewislzh    Cat(0.U, Fill(8, 1.U), 1.U, 0.U(22.W))
805820cff8Slewislzh  )
815820cff8Slewislzh  private val isFpCanonicalNAN = Seq(
825820cff8Slewislzh    !scalaData.head(56).andR,
835820cff8Slewislzh    !scalaData.head(48).andR,
845820cff8Slewislzh    !scalaData.head(32).andR
855820cff8Slewislzh  )
865820cff8Slewislzh
8723ea5b5eSZiyue Zhang  private val fpData = Mux1H(Seq(
8823ea5b5eSZiyue Zhang    (vsew === VSew.e8)  -> Cat(Fill(56, 1.U), scalaData( 7, 0)),
8923ea5b5eSZiyue Zhang    (vsew === VSew.e16) -> Cat(Fill(48, 1.U), scalaData(15, 0)),
9023ea5b5eSZiyue Zhang    (vsew === VSew.e32) -> Cat(Fill(32, 1.U), scalaData(31, 0)),
9123ea5b5eSZiyue Zhang    (vsew === VSew.e64) -> scalaData
9223ea5b5eSZiyue Zhang  ))
9323ea5b5eSZiyue Zhang
94395c8649SZiyue-Zhang  private val vecE8Data  = Wire(Vec(dataWidth /  8, UInt( 8.W)))
95395c8649SZiyue-Zhang  private val vecE16Data = Wire(Vec(dataWidth / 16, UInt(16.W)))
96395c8649SZiyue-Zhang  private val vecE32Data = Wire(Vec(dataWidth / 32, UInt(32.W)))
97395c8649SZiyue-Zhang  private val vecE64Data = Wire(Vec(dataWidth / 64, UInt(64.W)))
98395c8649SZiyue-Zhang
995820cff8Slewislzh  vecE8Data   := VecInit(Seq.fill(dataWidth /  8)(Mux(isFpCanonicalNAN(0) & isFp, outNAN(0), scalaData( 7, 0))))
1005820cff8Slewislzh  vecE16Data  := VecInit(Seq.fill(dataWidth / 16)(Mux(isFpCanonicalNAN(1) & isFp, outNAN(1), scalaData(15, 0))))
1015820cff8Slewislzh  vecE32Data  := VecInit(Seq.fill(dataWidth / 32)(Mux(isFpCanonicalNAN(2) & isFp, outNAN(2), scalaData(31, 0))))
102395c8649SZiyue-Zhang  vecE64Data  := VecInit(Seq.fill(dataWidth / 64)(scalaData(63, 0)))
103db7becb6Sxiaofeibao  connect0LatencyCtrlSingal
104395c8649SZiyue-Zhang  out.res.data := Mux(needDup, Mux1H(Seq(
105395c8649SZiyue-Zhang    (vsew === VSew.e8)  -> vecE8Data.asUInt,
106395c8649SZiyue-Zhang    (vsew === VSew.e16) -> vecE16Data.asUInt,
107395c8649SZiyue-Zhang    (vsew === VSew.e32) -> vecE32Data.asUInt,
108395c8649SZiyue-Zhang    (vsew === VSew.e64) -> vecE64Data.asUInt,
10923ea5b5eSZiyue Zhang  )), Mux(isFmv, fpData, scalaData))
110395c8649SZiyue-Zhang}
111