1/*************************************************************************************** 2* Copyright (c) 2020-2021 Institute of Computing Technology, Chinese Academy of Sciences 3* 4* XiangShan is licensed under Mulan PSL v2. 5* You can use this software according to the terms and conditions of the Mulan PSL v2. 6* You may obtain a copy of Mulan PSL v2 at: 7* http://license.coscl.org.cn/MulanPSL2 8* 9* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, 10* EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, 11* MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE. 12* 13* See the Mulan PSL v2 for more details. 14***************************************************************************************/ 15 16// See LICENSE.Berkeley for license details. 17// See LICENSE.SiFive for license details. 18 19package xiangshan.backend.fu.fpu 20 21import chipsalliance.rocketchip.config.Parameters 22import chisel3._ 23import chisel3.util._ 24import hardfloat.INToRecFN 25import utils.{SignExt, ZeroExt} 26import xiangshan._ 27 28class IntToFPDataModule(implicit p: Parameters) extends FPUDataModule { 29 30 val in_valid, out_ready = IO(Input(Bool())) 31 val in_ready, out_valid = IO(Output(Bool())) 32 val kill_w, kill_r = IO(Input(Bool())) 33 34 val s_idle :: s_cvt :: s_ieee :: s_finish :: Nil = Enum(4) 35 val state = RegInit(s_idle) 36 37 38 val in_fire = in_valid && in_ready 39 val out_fire = out_valid && out_ready 40 in_ready := state === s_idle 41 out_valid := state === s_finish 42 43 val src1 = RegEnable(io.in.src(0)(XLEN-1, 0), in_fire) 44 val rmReg = RegEnable(rm, in_fire) 45 val ctrl = RegEnable(io.in.fpCtrl, in_fire) 46 47 switch(state){ 48 is(s_idle){ 49 when(in_fire && !kill_w){ 50 state := s_cvt 51 } 52 } 53 is(s_cvt){ 54 state := s_ieee 55 } 56 is(s_ieee){ 57 state := s_finish 58 } 59 is(s_finish){ 60 when(out_fire){ 61 state := s_idle 62 } 63 } 64 } 65 when(state =/= s_idle && kill_r){ 66 state := s_idle 67 } 68 69 /* 70 s_cvt 71 */ 72 val tag = ctrl.typeTagIn 73 val typ = ctrl.typ 74 val wflags = ctrl.wflags 75 76 val mux = Wire(new Bundle() { 77 val data = UInt((XLEN+1).W) 78 val exc = UInt(5.W) 79 }) 80 mux.data := recode(src1, tag) 81 mux.exc := 0.U 82 83 val intValue = Mux(typ(1), 84 Mux(typ(0), ZeroExt(src1, XLEN), SignExt(src1, XLEN)), 85 Mux(typ(0), ZeroExt(src1(31, 0), XLEN), SignExt(src1(31, 0), XLEN)) 86 ) 87 88 when(wflags){ 89 val i2fResults = for(t <- floatTypes) yield { 90 val i2f = Module(new INToRecFN(XLEN, t.exp, t.sig)) 91 i2f.io.signedIn := ~typ(0) 92 i2f.io.in := intValue 93 i2f.io.roundingMode := rmReg 94 i2f.io.detectTininess := hardfloat.consts.tininess_afterRounding 95 (sanitizeNaN(i2f.io.out, t), i2f.io.exceptionFlags) 96 } 97 val (data, exc) = i2fResults.unzip 98 mux.data := VecInit(data)(tag) 99 mux.exc := VecInit(exc)(tag) 100 } 101 102 val muxReg = Reg(mux.cloneType) 103 when(state === s_cvt){ 104 muxReg := mux 105 }.elsewhen(state === s_ieee){ 106 muxReg.data := ieee(box(muxReg.data, ctrl.typeTagOut)) 107 } 108 109 fflags := muxReg.exc 110 io.out.data := muxReg.data 111} 112 113class IntToFP(implicit p: Parameters) extends FPUSubModule { 114 override val dataModule = Module(new IntToFPDataModule) 115 dataModule.in_valid := io.in.valid 116 dataModule.out_ready := io.out.ready 117 connectDataModule 118 val uopReg = RegEnable(io.in.bits.uop, io.in.fire()) 119 dataModule.kill_w := io.in.bits.uop.roqIdx.needFlush(io.redirectIn, io.flushIn) 120 dataModule.kill_r := uopReg.roqIdx.needFlush(io.redirectIn, io.flushIn) 121 io.in.ready := dataModule.in_ready 122 io.out.valid := dataModule.out_valid 123 io.out.bits.uop := uopReg 124} 125