IntToFP.scala 2.7 KB
Newer Older
L
LinJiawei 已提交
1 2 3
// See LICENSE.Berkeley for license details.
// See LICENSE.SiFive for license details.

4 5 6
package xiangshan.backend.fu.fpu

import chisel3._
L
LinJiawei 已提交
7
import chisel3.util._
8 9 10
import hardfloat.INToRecFN
import utils.{SignExt, ZeroExt}

L
LinJiawei 已提交
11 12 13 14 15
class IntToFPDataModule extends FPUDataModule {

  val in_valid, out_ready = IO(Input(Bool()))
  val in_ready, out_valid = IO(Output(Bool()))
  val kill_w, kill_r = IO(Input(Bool()))
16

17
  val s_idle :: s_cvt :: s_ieee :: s_finish :: Nil = Enum(4)
L
LinJiawei 已提交
18 19 20
  val state = RegInit(s_idle)


L
LinJiawei 已提交
21 22 23 24 25 26 27 28
  val in_fire = in_valid && in_ready
  val out_fire = out_valid && out_ready
  in_ready := state === s_idle
  out_valid := state === s_finish

  val src1 = RegEnable(io.in.src(0)(XLEN-1, 0), in_fire)
  val rmReg = RegEnable(rm, in_fire)
  val ctrl = RegEnable(io.in.fpCtrl, in_fire)
L
LinJiawei 已提交
29 30 31

  switch(state){
    is(s_idle){
L
LinJiawei 已提交
32
      when(in_fire && !kill_w){
L
LinJiawei 已提交
33 34 35 36
        state := s_cvt
      }
    }
    is(s_cvt){
37 38 39
      state := s_ieee
    }
    is(s_ieee){
L
LinJiawei 已提交
40 41 42
      state := s_finish
    }
    is(s_finish){
L
LinJiawei 已提交
43
      when(out_fire){
L
LinJiawei 已提交
44 45 46 47
        state := s_idle
      }
    }
  }
L
LinJiawei 已提交
48
  when(state =/= s_idle && kill_r){
L
LinJiawei 已提交
49 50 51 52 53 54
    state := s_idle
  }

  /*
      s_cvt
   */
55 56 57 58 59
  val tag = ctrl.typeTagIn
  val typ = ctrl.typ
  val wflags = ctrl.wflags

  val mux = Wire(new Bundle() {
60
    val data = UInt((XLEN+1).W)
61 62 63 64 65 66 67 68 69 70 71 72 73 74 75
    val exc = UInt(5.W)
  })
  mux.data := recode(src1, tag)
  mux.exc := 0.U

  val intValue = Mux(typ(1),
    Mux(typ(0), ZeroExt(src1, XLEN), SignExt(src1, XLEN)),
    Mux(typ(0), ZeroExt(src1(31, 0), XLEN), SignExt(src1(31, 0), XLEN))
  )

  when(wflags){
    val i2fResults = for(t <- floatTypes) yield {
      val i2f = Module(new INToRecFN(XLEN, t.exp, t.sig))
      i2f.io.signedIn := ~typ(0)
      i2f.io.in := intValue
Z
ZhangZifei 已提交
76
      i2f.io.roundingMode := rmReg
77 78 79 80 81 82 83 84
      i2f.io.detectTininess := hardfloat.consts.tininess_afterRounding
      (sanitizeNaN(i2f.io.out, t), i2f.io.exceptionFlags)
    }
    val (data, exc) = i2fResults.unzip
    mux.data := VecInit(data)(tag)
    mux.exc := VecInit(exc)(tag)
  }

85 86 87 88 89 90
  val muxReg = Reg(mux.cloneType)
  when(state === s_cvt){
    muxReg := mux
  }.elsewhen(state === s_ieee){
    muxReg.data := ieee(box(muxReg.data, ctrl.typeTagOut))
  }
L
LinJiawei 已提交
91 92

  fflags := muxReg.exc
L
LinJiawei 已提交
93 94 95 96 97 98 99 100 101 102 103 104 105
  io.out.data := muxReg.data
}

class IntToFP extends FPUSubModule {
  override val dataModule = Module(new IntToFPDataModule)
  dataModule.in_valid := io.in.valid
  dataModule.out_ready := io.out.ready
  connectDataModule
  val uopReg = RegEnable(io.in.bits.uop, io.in.fire())
  dataModule.kill_w := io.in.bits.uop.roqIdx.needFlush(io.redirectIn, io.flushIn)
  dataModule.kill_r := uopReg.roqIdx.needFlush(io.redirectIn, io.flushIn)
  io.in.ready := dataModule.in_ready
  io.out.valid := dataModule.out_valid
L
LinJiawei 已提交
106
  io.out.bits.uop := uopReg
107
}