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, FuncUnit, PipedFuncUnit} 27import xiangshan.backend.fu.vector.Bundles.VSew 28import xiangshan.IF2VectorType 29 30class IntFPToVec(cfg: FuConfig)(implicit p: Parameters) extends PipedFuncUnit(cfg) { 31 protected val in = io.in.bits 32 protected val out = io.out.bits 33 34 private val isFliH = in.ctrl.fuOpType(7) && in.ctrl.fuOpType(6) && !in.ctrl.fuOpType(5) 35 private val isFliS = in.ctrl.fuOpType(7) && !in.ctrl.fuOpType(6) && !in.ctrl.fuOpType(5) 36 private val isFliD = in.ctrl.fuOpType(7) && !in.ctrl.fuOpType(6) && in.ctrl.fuOpType(5) 37 private val isFli = isFliH || isFliS || isFliD 38 39 private val FliData = Wire(UInt(XLEN.W)) 40 41 private val FliHTable = Module(new FliHTable) 42 private val FliSTable = Module(new FliSTable) 43 private val FliDTable = Module(new FliDTable) 44 45 FliHTable.src := in.ctrl.fuOpType(4, 0) 46 FliSTable.src := in.ctrl.fuOpType(4, 0) 47 FliDTable.src := in.ctrl.fuOpType(4, 0) 48 49 FliData := Mux1H( 50 Seq( 51 isFliH, 52 isFliS, 53 isFliD 54 ), 55 Seq( 56 Cat(~0.U(48.W), FliHTable.out), 57 Cat(~0.U(32.W), FliSTable.out, 0.U(16.W)), 58 Cat(FliDTable.out, 0.U(48.W))) 59 ) 60 61 // vsew is the lowest 2 bits of fuOpType 62 private val isImm = Mux(isFli, 0.U, IF2VectorType.isImm(in.ctrl.fuOpType(4, 2))).asBool 63 // when needDup is true, the scalar data is duplicated in vector register 64 private val needDup = Mux(isFli, 0.U, IF2VectorType.needDup(in.ctrl.fuOpType(4, 2))).asBool 65 // when isFmv is true, the high bits of the scalar data is 1 66 private val isFmv = Mux(isFli, 0.U, IF2VectorType.isFmv(in.ctrl.fuOpType(4, 2))).asBool 67 68 private val isFp = Mux(isFli, 0.U, IF2VectorType.isFp(in.ctrl.fuOpType(4, 2))).asBool 69 70 // imm use src(1), scalar use src(0) 71 private val scalaData = Mux(isFli, FliData, Mux(isImm, in.data.src(1), in.data.src(0))) 72 // vsew is the lowest 2 bits of fuOpType 73 private val vsew = in.ctrl.fuOpType(1, 0) 74 private val dataWidth = cfg.destDataBits 75 76 private val outNAN = Seq( 77 Cat(0.U, Fill(3, 1.U), 1.U, 0.U(3.W)), 78 Cat(0.U, Fill(5, 1.U), 1.U, 0.U(9.W)), 79 Cat(0.U, Fill(8, 1.U), 1.U, 0.U(22.W)) 80 ) 81 private val isFpCanonicalNAN = Seq( 82 !scalaData.head(56).andR, 83 !scalaData.head(48).andR, 84 !scalaData.head(32).andR 85 ) 86 87 private val fpData = Mux1H(Seq( 88 (vsew === VSew.e8) -> Cat(Fill(56, 1.U), scalaData( 7, 0)), 89 (vsew === VSew.e16) -> Cat(Fill(48, 1.U), scalaData(15, 0)), 90 (vsew === VSew.e32) -> Cat(Fill(32, 1.U), scalaData(31, 0)), 91 (vsew === VSew.e64) -> scalaData 92 )) 93 94 private val vecE8Data = Wire(Vec(dataWidth / 8, UInt( 8.W))) 95 private val vecE16Data = Wire(Vec(dataWidth / 16, UInt(16.W))) 96 private val vecE32Data = Wire(Vec(dataWidth / 32, UInt(32.W))) 97 private val vecE64Data = Wire(Vec(dataWidth / 64, UInt(64.W))) 98 99 vecE8Data := VecInit(Seq.fill(dataWidth / 8)(Mux(isFpCanonicalNAN(0) & isFp, outNAN(0), scalaData( 7, 0)))) 100 vecE16Data := VecInit(Seq.fill(dataWidth / 16)(Mux(isFpCanonicalNAN(1) & isFp, outNAN(1), scalaData(15, 0)))) 101 vecE32Data := VecInit(Seq.fill(dataWidth / 32)(Mux(isFpCanonicalNAN(2) & isFp, outNAN(2), scalaData(31, 0)))) 102 vecE64Data := VecInit(Seq.fill(dataWidth / 64)(scalaData(63, 0))) 103 connect0LatencyCtrlSingal 104 out.res.data := Mux(needDup, Mux1H(Seq( 105 (vsew === VSew.e8) -> vecE8Data.asUInt, 106 (vsew === VSew.e16) -> vecE16Data.asUInt, 107 (vsew === VSew.e32) -> vecE32Data.asUInt, 108 (vsew === VSew.e64) -> vecE64Data.asUInt, 109 )), Mux(isFmv, fpData, scalaData)) 110} 111