FDivSqrt.scala 2.4 KB
Newer Older
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
package xiangshan.backend.fu.fpu

import chisel3._
import chisel3.util._
import freechips.rocketchip.tile.FType
import hardfloat.{DivSqrtRecFNToRaw_small, RoundAnyRawFNToRecFN}

class FDivSqrt extends FPUSubModule {

  val s_idle :: s_div :: s_finish :: Nil = Enum(3)
  val state = RegInit(s_idle)

  val divSqrt = Module(new DivSqrtRecFNToRaw_small(FType.D.exp, FType.D.sig, 0))
  val divSqrtRawValid = divSqrt.io.rawOutValid_sqrt || divSqrt.io.rawOutValid_div

  val fpCtrl = io.in.bits.uop.ctrl.fpu
  val tag = fpCtrl.typeTagIn
  val uopReg = RegEnable(io.in.bits.uop, io.in.fire())
  val single = RegEnable(tag === S, io.in.fire())
L
LinJiawei 已提交
20
  val rmReg = RegEnable(rm, io.in.fire())
21
  val kill = uopReg.roqIdx.needFlush(io.redirectIn, io.flushIn)
22 23 24 25
  val killReg = RegInit(false.B)

  switch(state){
    is(s_idle){
26
      when(io.in.fire() && !io.in.bits.uop.roqIdx.needFlush(io.redirectIn, io.flushIn)){ state := s_div }
27 28 29 30 31
    }
    is(s_div){
      when(divSqrtRawValid){
        when(kill || killReg){
          state := s_idle
Fa_wang's avatar
Fa_wang 已提交
32
          killReg := false.B
33 34 35 36 37 38 39 40
        }.otherwise({
          state := s_finish
        })
      }.elsewhen(kill){
        killReg := true.B
      }
    }
    is(s_finish){
Fa_wang's avatar
Fa_wang 已提交
41 42 43
      when(io.out.fire() || kill){
        state := s_idle
      }
44 45 46 47 48 49
    }
  }


  val src1 = unbox(io.in.bits.src(0), tag, None)
  val src2 = unbox(io.in.bits.src(1), tag, None)
Y
Yinan Xu 已提交
50
  divSqrt.io.inValid := io.in.fire() && !io.in.bits.uop.roqIdx.needFlush(io.redirectIn, io.flushIn)
51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68
  divSqrt.io.sqrtOp := fpCtrl.sqrt
  divSqrt.io.a := src1
  divSqrt.io.b := src2
  divSqrt.io.roundingMode := rm



  val round32 = Module(new RoundAnyRawFNToRecFN(
    FType.D.exp, FType.D.sig+2, FType.S.exp, FType.S.sig, 0
  ))
  val round64 = Module(new RoundAnyRawFNToRecFN(
    FType.D.exp, FType.D.sig+2, FType.D.exp, FType.D.sig, 0
  ))

  for(rounder <- Seq(round32, round64)){
    rounder.io.invalidExc := divSqrt.io.invalidExc
    rounder.io.infiniteExc := divSqrt.io.infiniteExc
    rounder.io.in := divSqrt.io.rawOut
L
LinJiawei 已提交
69
    rounder.io.roundingMode := rmReg
70 71 72 73 74 75 76
    rounder.io.detectTininess := hardfloat.consts.tininess_afterRounding
  }

  val data = Mux(single, round32.io.out, round64.io.out)
  val flags = Mux(single, round32.io.exceptionFlags, round64.io.exceptionFlags)

  io.in.ready := state===s_idle
L
LinJiawei 已提交
77
  io.out.valid := state===s_finish && !killReg
78 79 80 81
  io.out.bits.uop := uopReg
  io.out.bits.data := RegNext(data, divSqrtRawValid)
  fflags := RegNext(flags, divSqrtRawValid)
}