FmiscExeUnit.scala 2.6 KB
Newer Older
1 2 3 4
package xiangshan.backend.exu


import chisel3._
L
LinJiawei 已提交
5
import chisel3.util._
L
linjiawei 已提交
6
import chisel3.util.experimental.BoringUtils
L
linjiawei 已提交
7
import utils._
8
import xiangshan.backend.exu.Exu.fmiscExeUnitCfg
L
LinJiawei 已提交
9 10 11
import xiangshan.backend.fu.fpu.{F32toF64, F64toF32, FCMP, FMV, FPUSubModuleOutput, FloatToInt}
import xiangshan.backend.fu.fpu.divsqrt.DivSqrt
import xiangshan.backend.fu.fpu.FPUOpType._
L
linjiawei 已提交
12
import xiangshan.backend.fu.fpu._
13 14

class FmiscExeUnit extends Exu(fmiscExeUnitCfg){
L
LinJiawei 已提交
15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32

  val fcmp = Module(new FCMP)
  val fmv = Module(new FMV(XLEN))
  val f2i = Module(new FloatToInt)
  val f32toF64 = Module(new F32toF64)
  val f64toF32 = Module(new F64toF32)
  val fdivSqrt = Module(new DivSqrt)

  val subModules = Array(
    (fcmp, FU_FCMP),
    (fmv, FU_FMV),
    (f2i, FU_F2I),
    (f32toF64, FU_S2D),
    (f64toF32, FU_D2S),
    (fdivSqrt, FU_DIVSQRT)
  ).map(x => (x._1, ("b" + x._2).U))

  val fuOp = io.in.bits.uop.ctrl.fuOpType
L
linjiawei 已提交
33 34 35
  assert(fuOp.getWidth == 7) // when fuOp's WIDTH change, here must change too
  val fu = fuOp.head(4)
  val op = fuOp.tail(4)
L
linjiawei 已提交
36 37
  val frm = WireInit(0.U(3.W))
  BoringUtils.addSink(frm, "Frm")
L
linjiawei 已提交
38 39
  val isRVF = io.in.bits.uop.ctrl.isRVF
  val (src1, src2) = (io.in.bits.src1, io.in.bits.src2)
L
LinJiawei 已提交
40 41 42

  io.in.ready := Cat(subModules.map(x => fu===x._2 && x._1.io.in.ready)).orR()

L
linjiawei 已提交
43
  val instr_rm = io.in.bits.uop.cf.instr(14, 12)
L
LinJiawei 已提交
44 45 46 47
  subModules.foreach{
    case (module, fuSel) =>
      module.io.in.valid := io.in.valid && fu===fuSel
      module.io.in.bits.uop := io.in.bits.uop
L
linjiawei 已提交
48 49 50 51 52
      module.io.in.bits.src(0) := Mux(
        (isRVF && fuOp=/=d2s && fuOp=/=fmv_f2i) || fuOp===s2d, 
        unboxF64ToF32(src1), 
        src1
      )
L
linjiawei 已提交
53
      module.io.in.bits.src(1) := Mux(isRVF, unboxF64ToF32(src2), src2)
L
LinJiawei 已提交
54
      val extraInput = module.io.in.bits.ext.get
L
linjiawei 已提交
55
      extraInput.rm := Mux(instr_rm =/= 7.U, instr_rm, frm)
L
linjiawei 已提交
56
      extraInput.isDouble := !isRVF
L
LinJiawei 已提交
57 58 59 60 61 62 63
      extraInput.op := op
      module.io.redirectIn := io.redirect
  }

  val wbArb = Module(new Arbiter(chiselTypeOf(subModules(0)._1.io.out.bits), subModules.length))

  wbArb.io.in <> VecInit(subModules.map(_._1.io.out))
L
linjiawei 已提交
64
  
L
LinJiawei 已提交
65 66 67 68 69
  val out = wbArb.io.out

  out.ready := io.out.ready
  io.out.valid := out.valid
  io.out.bits.uop := out.bits.uop
L
linjiawei 已提交
70 71 72 73
  io.out.bits.fflags := out.bits.ext.get
  val outCtrl = out.bits.uop.ctrl
  io.out.bits.data := Mux(outCtrl.isRVF && outCtrl.fpWen, 
    boxF32ToF64(out.bits.data), 
L
linjiawei 已提交
74
    Mux( (outCtrl.isRVF && outCtrl.fuOpType===fmv_f2i) || outCtrl.fuOpType===f2w || outCtrl.fuOpType===f2wu,
L
linjiawei 已提交
75 76 77 78
      SignExt(out.bits.data(31, 0), XLEN),
      out.bits.data
    )
  )
L
LinJiawei 已提交
79 80
  io.out.bits.redirectValid := DontCare
  io.out.bits.redirect := DontCare
81
  io.csrOnly <> DontCare
82
}