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 hardfloat.INToRecFN 26import utils.{SignExt, ZeroExt} 27import xiangshan._ 28 29class IntToFPDataModule(implicit p: Parameters) extends FPUDataModule { 30 31 val in_valid, out_ready = IO(Input(Bool())) 32 val in_ready, out_valid = IO(Output(Bool())) 33 val kill_w, kill_r = IO(Input(Bool())) 34 35 val s_idle :: s_cvt :: s_ieee :: s_finish :: Nil = Enum(4) 36 val state = RegInit(s_idle) 37 38 39 val in_fire = in_valid && in_ready 40 val out_fire = out_valid && out_ready 41 in_ready := state === s_idle 42 out_valid := state === s_finish 43 44 val src1 = RegEnable(io.in.src(0)(XLEN-1, 0), in_fire) 45 val rmReg = RegEnable(rm, in_fire) 46 val ctrl = RegEnable(io.in.fpCtrl, in_fire) 47 48 switch(state){ 49 is(s_idle){ 50 when(in_fire && !kill_w){ 51 state := s_cvt 52 } 53 } 54 is(s_cvt){ 55 state := s_ieee 56 } 57 is(s_ieee){ 58 state := s_finish 59 } 60 is(s_finish){ 61 when(out_fire){ 62 state := s_idle 63 } 64 } 65 } 66 when(state =/= s_idle && kill_r){ 67 state := s_idle 68 } 69 70 /* 71 s_cvt 72 */ 73 val tag = ctrl.typeTagIn 74 val typ = ctrl.typ 75 val wflags = ctrl.wflags 76 77 val mux = Wire(new Bundle() { 78 val data = UInt((XLEN+1).W) 79 val exc = UInt(5.W) 80 }) 81 mux.data := recode(src1, tag) 82 mux.exc := 0.U 83 84 val intValue = Mux(typ(1), 85 Mux(typ(0), ZeroExt(src1, XLEN), SignExt(src1, XLEN)), 86 Mux(typ(0), ZeroExt(src1(31, 0), XLEN), SignExt(src1(31, 0), XLEN)) 87 ) 88 89 when(wflags){ 90 val i2fResults = for(t <- floatTypes) yield { 91 val i2f = Module(new INToRecFN(XLEN, t.exp, t.sig)) 92 i2f.io.signedIn := ~typ(0) 93 i2f.io.in := intValue 94 i2f.io.roundingMode := rmReg 95 i2f.io.detectTininess := hardfloat.consts.tininess_afterRounding 96 (sanitizeNaN(i2f.io.out, t), i2f.io.exceptionFlags) 97 } 98 val (data, exc) = i2fResults.unzip 99 mux.data := VecInit(data)(tag) 100 mux.exc := VecInit(exc)(tag) 101 } 102 103 val muxReg = Reg(mux.cloneType) 104 when(state === s_cvt){ 105 muxReg := mux 106 }.elsewhen(state === s_ieee){ 107 muxReg.data := ieee(box(muxReg.data, ctrl.typeTagOut)) 108 } 109 110 fflags := muxReg.exc 111 io.out.data := muxReg.data 112} 113 114class IntToFP(implicit p: Parameters) extends FPUSubModule { 115 override val dataModule = Module(new IntToFPDataModule) 116 dataModule.in_valid := io.in.valid 117 dataModule.out_ready := io.out.ready 118 connectDataModule 119 val uopReg = RegEnable(io.in.bits.uop, io.in.fire()) 120 dataModule.kill_w := io.in.bits.uop.roqIdx.needFlush(io.redirectIn, io.flushIn) 121 dataModule.kill_r := uopReg.roqIdx.needFlush(io.redirectIn, io.flushIn) 122 io.in.ready := dataModule.in_ready 123 io.out.valid := dataModule.out_valid 124 io.out.bits.uop := uopReg 125} 126