1// See LICENSE.Berkeley for license details. 2// See LICENSE.SiFive for license details. 3 4package xiangshan.backend.fu.fpu 5 6import chisel3._ 7import chisel3.util._ 8import hardfloat.INToRecFN 9import utils.{SignExt, ZeroExt} 10 11class IntToFP extends FPUSubModule { 12 13 val s_idle :: s_cvt :: s_finish :: Nil = Enum(3) 14 val state = RegInit(s_idle) 15 16 io.in.ready := state === s_idle 17 io.out.valid := state === s_finish 18 19 val src1 = RegEnable(io.in.bits.src(0)(XLEN-1, 0), io.in.fire()) 20 val uopReg = RegEnable(io.in.bits.uop, io.in.fire()) 21 22 switch(state){ 23 is(s_idle){ 24 when(io.in.fire() && !io.in.bits.uop.roqIdx.needFlush(io.redirectIn, io.flushIn)){ 25 state := s_cvt 26 } 27 } 28 is(s_cvt){ 29 state := s_finish 30 } 31 is(s_finish){ 32 when(io.out.fire()){ 33 state := s_idle 34 } 35 } 36 } 37 when(state =/= s_idle && uopReg.roqIdx.needFlush(io.redirectIn, io.flushIn)){ 38 state := s_idle 39 } 40 41 /* 42 s_cvt 43 */ 44 val ctrl = uopReg.ctrl.fpu 45 val tag = ctrl.typeTagIn 46 val typ = ctrl.typ 47 val wflags = ctrl.wflags 48 49 val mux = Wire(new Bundle() { 50 val data = UInt((XLEN+1).W) 51 val exc = UInt(5.W) 52 }) 53 mux.data := recode(src1, tag) 54 mux.exc := 0.U 55 56 val intValue = Mux(typ(1), 57 Mux(typ(0), ZeroExt(src1, XLEN), SignExt(src1, XLEN)), 58 Mux(typ(0), ZeroExt(src1(31, 0), XLEN), SignExt(src1(31, 0), XLEN)) 59 ) 60 61 when(wflags){ 62 val i2fResults = for(t <- floatTypes) yield { 63 val i2f = Module(new INToRecFN(XLEN, t.exp, t.sig)) 64 i2f.io.signedIn := ~typ(0) 65 i2f.io.in := intValue 66 i2f.io.roundingMode := rm 67 i2f.io.detectTininess := hardfloat.consts.tininess_afterRounding 68 (sanitizeNaN(i2f.io.out, t), i2f.io.exceptionFlags) 69 } 70 val (data, exc) = i2fResults.unzip 71 mux.data := VecInit(data)(tag) 72 mux.exc := VecInit(exc)(tag) 73 } 74 75 val muxReg = RegEnable(mux, enable = state === s_cvt) 76 77 fflags := muxReg.exc 78 io.out.bits.uop := uopReg 79 io.out.bits.data := box(muxReg.data, ctrl.typeTagOut) 80} 81