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