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