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 val rmReg = RegEnable(rm, io.in.fire()) 22 23 switch(state){ 24 is(s_idle){ 25 when(io.in.fire() && !io.in.bits.uop.roqIdx.needFlush(io.redirectIn, io.flushIn)){ 26 state := s_cvt 27 } 28 } 29 is(s_cvt){ 30 state := s_finish 31 } 32 is(s_finish){ 33 when(io.out.fire()){ 34 state := s_idle 35 } 36 } 37 } 38 when(state =/= s_idle && uopReg.roqIdx.needFlush(io.redirectIn, io.flushIn)){ 39 state := s_idle 40 } 41 42 /* 43 s_cvt 44 */ 45 val ctrl = uopReg.ctrl.fpu 46 val tag = ctrl.typeTagIn 47 val typ = ctrl.typ 48 val wflags = ctrl.wflags 49 50 val mux = Wire(new Bundle() { 51 val data = UInt((XLEN+1).W) 52 val exc = UInt(5.W) 53 }) 54 mux.data := recode(src1, tag) 55 mux.exc := 0.U 56 57 val intValue = Mux(typ(1), 58 Mux(typ(0), ZeroExt(src1, XLEN), SignExt(src1, XLEN)), 59 Mux(typ(0), ZeroExt(src1(31, 0), XLEN), SignExt(src1(31, 0), XLEN)) 60 ) 61 62 when(wflags){ 63 val i2fResults = for(t <- floatTypes) yield { 64 val i2f = Module(new INToRecFN(XLEN, t.exp, t.sig)) 65 i2f.io.signedIn := ~typ(0) 66 i2f.io.in := intValue 67 i2f.io.roundingMode := rmReg 68 i2f.io.detectTininess := hardfloat.consts.tininess_afterRounding 69 (sanitizeNaN(i2f.io.out, t), i2f.io.exceptionFlags) 70 } 71 val (data, exc) = i2fResults.unzip 72 mux.data := VecInit(data)(tag) 73 mux.exc := VecInit(exc)(tag) 74 } 75 76 val muxReg = RegEnable(mux, enable = state === s_cvt) 77 78 fflags := muxReg.exc 79 io.out.bits.uop := uopReg 80 io.out.bits.data := box(muxReg.data, ctrl.typeTagOut) 81} 82