FCMP.scala 2.1 KB
Newer Older
1
package xiangshan.backend.fu.fpu
L
FPUv0.1  
LinJiawei 已提交
2 3 4

import chisel3._
import chisel3.util._
L
LinJiawei 已提交
5
import xiangshan.FuType
6
import xiangshan.backend.fu.{CertainLatency, FuConfig, FunctionUnit}
7
import xiangshan.backend.fu.FunctionUnit._
L
FPUv0.1  
LinJiawei 已提交
8

9 10 11
class FCMP extends FPUPipelineModule {

  override val latency = FunctionUnit.fcmpCfg.latency.latencyVal.get
L
FPUv0.1  
LinJiawei 已提交
12

13
  val src = io.in.bits.src.map(x => Mux(isDouble, x, extF32ToF64(x)))
L
FPUv0.1  
LinJiawei 已提交
14 15 16 17 18 19 20 21 22 23 24 25
  val sign = src.map(_(63))
  val aSign = sign(0)

  val subRes = src(0).toSInt - src(1).toSInt

  val classify = Array.fill(2)(Module(new Classify(Float64.expWidth, Float64.mantWidth)).io)
  classify.zip(src).foreach({case (c, s) => c.in := s})

  val srcIsNaN = classify.map(_.isNaN)
  val srcIsSNaN = classify.map(_.isSNaN)

  val isDoubleReg = S1Reg(isDouble)
26 27
  val opReg = S1Reg(op)
  val srcReg = io.in.bits.src.map(S1Reg)
L
FPUv0.1  
LinJiawei 已提交
28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55
  val (aSignReg, bSignReg) = (S1Reg(sign(0)), S1Reg(sign(1)))

  val hasNaNReg = S1Reg(srcIsNaN(0) || srcIsNaN(1))
  val bothNaNReg = S1Reg(srcIsNaN(0) && srcIsNaN(1))
  val hasSNaNReg = S1Reg(srcIsSNaN(0) || srcIsSNaN(1))
  val aIsNaNReg = S1Reg(srcIsNaN(0))
  val bothZeroReg = S1Reg(src(0).tail(1)===0.U && src(1).tail(1)===0.U)

  val uintEqReg = S1Reg(subRes===0.S)
  val uintLessReg = S1Reg(aSign ^ (subRes < 0.S))


  val invalid = Mux(opReg(2) || !opReg(1), hasSNaNReg, hasNaNReg)

  val le,lt,eq = Wire(Bool())
  eq := uintEqReg || bothZeroReg
  le := Mux(aSignReg =/= bSignReg, aSignReg || bothZeroReg, uintEqReg || uintLessReg)
  lt := Mux(aSignReg =/= bSignReg, aSignReg && !bothZeroReg, !uintEqReg && uintLessReg)
  val fcmpResult = Mux(hasNaNReg,
    false.B,
    Mux(opReg(2), eq, Mux(opReg(0), lt, le))
  )

  val sel_a = lt || (eq && aSignReg)
  val defaultNaN = Mux(isDoubleReg, Float64.defaultNaN, Float32.defaultNaN)
  val min = Mux(bothNaNReg, defaultNaN, Mux(sel_a && !aIsNaNReg, srcReg(0), srcReg(1)))
  val max = Mux(bothNaNReg, defaultNaN, Mux(!sel_a && !aIsNaNReg, srcReg(0), srcReg(1)))

56 57 58 59 60 61
  fflags.inexact := false.B
  fflags.underflow := false.B
  fflags.overflow := false.B
  fflags.infinite := false.B
  fflags.invalid := S2Reg(invalid)
  io.out.bits.data := S2Reg(Mux(opReg===0.U, min, Mux(opReg===1.U, max, fcmpResult)))
L
FPUv0.1  
LinJiawei 已提交
62
}