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