xref: /XiangShan/src/main/scala/xiangshan/backend/fu/fpu/FPU.scala (revision c1b85dcecc4d46a9127a0c66fb2b841609937e7d)
1dc597826SJiawei Linpackage xiangshan.backend.fu.fpu
2dc597826SJiawei Lin
3dc597826SJiawei Linimport chisel3._
4dc597826SJiawei Linimport chisel3.util._
5dc597826SJiawei Linimport fudian.FloatPoint
6dc597826SJiawei Lin
7dc597826SJiawei Linobject FPU {
8dc597826SJiawei Lin
9dc597826SJiawei Lin  case class FType(expWidth: Int, precision: Int) {
10dc597826SJiawei Lin    val sigWidth = precision - 1
11dc597826SJiawei Lin    val len = expWidth + precision
12dc597826SJiawei Lin  }
13dc597826SJiawei Lin
14*c1b85dceSXuan Hu  val f16 = FType(5, 11)
15dc597826SJiawei Lin  val f32 = FType(8, 24)
16dc597826SJiawei Lin  val f64 = FType(11, 53)
17dc597826SJiawei Lin
18*c1b85dceSXuan Hu  // Appending f16 instead of pushing it from head to avoid potential encoding conflicts.
19*c1b85dceSXuan Hu  // Todo: use fmt field encoding in riscv FP instructions instead of customized encoding.
20*c1b85dceSXuan Hu  val ftypes = List(f32, f64, f16)
21*c1b85dceSXuan Hu  val ftypeWidth = log2Up(ftypes.length)
22dc597826SJiawei Lin
23*c1b85dceSXuan Hu  val S = ftypes.indexOf(f32).U(ftypeWidth.W)
24*c1b85dceSXuan Hu  val D = ftypes.indexOf(f64).U(ftypeWidth.W)
25*c1b85dceSXuan Hu  val H = ftypes.indexOf(f16).U(ftypeWidth.W)
26dc597826SJiawei Lin
27*c1b85dceSXuan Hu  // Produce zero-extended FPXX data
28dc597826SJiawei Lin  def unbox(x: UInt, typeTag: UInt): UInt = {
29dc597826SJiawei Lin    require(x.getWidth == 64)
30*c1b85dceSXuan Hu    require(typeTag.getWidth == ftypeWidth)
31*c1b85dceSXuan Hu    Mux1H(Seq(
32*c1b85dceSXuan Hu      (typeTag === D) -> x,
33*c1b85dceSXuan Hu      (typeTag === S) -> Mux(x.head(32).andR, x(f32.len - 1, 0), FloatPoint.defaultNaNUInt(f32.expWidth, f32.precision)),
34*c1b85dceSXuan Hu      (typeTag === H) -> Mux(x.head(48).andR, x(f16.len - 1, 0), FloatPoint.defaultNaNUInt(f16.expWidth, f16.precision)),
35*c1b85dceSXuan Hu    ))
36dc597826SJiawei Lin  }
37dc597826SJiawei Lin
38dc597826SJiawei Lin  def box(x: UInt, typeTag: UInt): UInt = {
39dc597826SJiawei Lin    require(x.getWidth == 64)
40*c1b85dceSXuan Hu    Mux1H(Seq(
41*c1b85dceSXuan Hu      (typeTag === D) -> x,
42*c1b85dceSXuan Hu      (typeTag === S) -> Cat(Fill(32, 1.U(1.W)), x(f32.len - 1, 0)),
43*c1b85dceSXuan Hu      (typeTag === H) -> Cat(Fill(48, 1.U(1.W)), x(f16.len - 1, 0)),
44*c1b85dceSXuan Hu    ))
45dc597826SJiawei Lin  }
46dc597826SJiawei Lin
47a273862eSJiawei Lin  def box(x: UInt, t: FType): UInt = {
48*c1b85dceSXuan Hu    if      (t == f64) x(63, 0)
49*c1b85dceSXuan Hu    else if (t == f32) Cat(Fill(32, 1.U(1.W)), x(31, 0))
50*c1b85dceSXuan Hu    else if (t == f16) Cat(Fill(48, 1.U(1.W)), x(15, 0))
51*c1b85dceSXuan Hu    else {
52a273862eSJiawei Lin      assert(cond = false, "Unknown ftype!")
53a273862eSJiawei Lin      0.U
54a273862eSJiawei Lin    }
55a273862eSJiawei Lin  }
56a273862eSJiawei Lin
57dc597826SJiawei Lin}
58