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