1
0

WIP on FPU subword recoding

This commit is contained in:
Andrew Waterman 2017-03-25 15:41:43 -07:00 committed by Andrew Waterman
parent 986e1754be
commit bb42f3bf3b

View File

@ -231,6 +231,13 @@ object IsSNaNRecFN {
IsNaNRecFN(expWidth, sigWidth, in) && !in(sigWidth - 2) IsNaNRecFN(expWidth, sigWidth, in) && !in(sigWidth - 2)
} }
class FType(val exp: Int, val sig: Int)
object FType {
val S = new FType(8, 24)
val D = new FType(11, 53)
}
/** Format conversion without rounding or NaN handling */ /** Format conversion without rounding or NaN handling */
object RecFNToRecFN_noncompliant { object RecFNToRecFN_noncompliant {
def apply(in: UInt, inExpWidth: Int, inSigWidth: Int, outExpWidth: Int, outSigWidth: Int) = { def apply(in: UInt, inExpWidth: Int, inSigWidth: Int, outExpWidth: Int, outSigWidth: Int) = {
@ -249,22 +256,23 @@ object RecFNToRecFN_noncompliant {
} }
object CanonicalNaN { object CanonicalNaN {
def apply(expWidth: Int, sigWidth: Int): UInt = def apply(t: FType): UInt =
UInt((BigInt(7) << (expWidth + sigWidth - 3)) + (BigInt(1) << (sigWidth - 2)), expWidth + sigWidth + 1) UInt((BigInt(7) << (t.exp + t.sig - 3)) + (BigInt(1) << (t.sig - 2)), t.exp + t.sig + 1)
def signaling(expWidth: Int, sigWidth: Int): UInt = def signaling(t: FType): UInt =
UInt((BigInt(7) << (expWidth + sigWidth - 3)) + (BigInt(1) << (sigWidth - 3)), expWidth + sigWidth + 1) UInt((BigInt(7) << (t.exp + t.sig - 3)) + (BigInt(1) << (t.sig - 3)), t.exp + t.sig + 1)
} }
trait HasFPUParameters { trait HasFPUParameters {
val fLen: Int val fLen: Int
val (sExpWidth, sSigWidth) = (8, 24) val (sExpWidth, sSigWidth) = (FType.S.exp, FType.S.sig)
val (dExpWidth, dSigWidth) = (11, 53) val (dExpWidth, dSigWidth) = (FType.D.exp, FType.D.sig)
val floatWidths = fLen match { val floatTypes = fLen match {
case 32 => List((sExpWidth, sSigWidth)) case 32 => List(FType.S)
case 64 => List((sExpWidth, sSigWidth), (dExpWidth, dSigWidth)) case 64 => List(FType.S, FType.D)
} }
val maxExpWidth = floatWidths.map(_._1).max val maxType = floatTypes.sortWith(_.exp > _.exp).head
val maxSigWidth = floatWidths.map(_._2).max val maxExpWidth = maxType.exp
val maxSigWidth = maxType.sig
} }
abstract class FPUModule(implicit p: Parameters) extends CoreModule()(p) with HasFPUParameters abstract class FPUModule(implicit p: Parameters) extends CoreModule()(p) with HasFPUParameters
@ -433,7 +441,7 @@ class IntToFP(val latency: Int)(implicit p: Parameters) extends FPUModule()(p) {
val issnan2 = IsSNaNRecFN(expWidth, sigWidth, in.bits.in2) val issnan2 = IsSNaNRecFN(expWidth, sigWidth, in.bits.in2)
val invalid = issnan1 || issnan2 val invalid = issnan1 || issnan2
val isNaNOut = invalid || (isnan1 && isnan2) val isNaNOut = invalid || (isnan1 && isnan2)
val cNaN = floatWidths.filter(_._1 >= expWidth).map(x => CanonicalNaN(x._1, x._2)).reduce(_+_) val cNaN = floatTypes.filter(_.exp >= expWidth).map(CanonicalNaN(_)).reduce(_+_)
(isnan2 || in.bits.rm(0) =/= io.lt && !isnan1, invalid, isNaNOut, cNaN) (isnan2 || in.bits.rm(0) =/= io.lt && !isnan1, invalid, isNaNOut, cNaN)
} }
val (isLHS, isInvalid, isNaNOut, cNaN) = fLen match { val (isLHS, isInvalid, isNaNOut, cNaN) = fLen match {
@ -530,6 +538,9 @@ class FPU(cfg: FPUParams)(implicit p: Parameters) extends FPUModule()(p) {
val mem_ctrl = RegEnable(ex_ctrl, req_valid) val mem_ctrl = RegEnable(ex_ctrl, req_valid)
val wb_ctrl = RegEnable(mem_ctrl, mem_reg_valid) val wb_ctrl = RegEnable(mem_ctrl, mem_reg_valid)
def expand(x: UInt, t: FType) = RecFNToRecFN_noncompliant(x, t.exp, t.sig, maxType.exp, maxType.sig)
def contract(x: UInt, t: FType) = RecFNToRecFN_noncompliant(x, maxType.exp, maxType.sig, t.exp, t.sig)
// load response // load response
val load_wb = Reg(next=io.dmem_resp_val) val load_wb = Reg(next=io.dmem_resp_val)
val load_wb_single = RegEnable(!io.dmem_resp_type(0), io.dmem_resp_val) val load_wb_single = RegEnable(!io.dmem_resp_type(0), io.dmem_resp_val)
@ -540,7 +551,7 @@ class FPU(cfg: FPUParams)(implicit p: Parameters) extends FPUModule()(p) {
case 32 => rec_s case 32 => rec_s
case 64 => case 64 =>
val rec_d = hardfloat.recFNFromFN(dExpWidth, dSigWidth, load_wb_data) val rec_d = hardfloat.recFNFromFN(dExpWidth, dSigWidth, load_wb_data)
Mux(load_wb_single, rec_s | CanonicalNaN.signaling(maxExpWidth, maxSigWidth), rec_d) Mux(load_wb_single, rec_s | CanonicalNaN.signaling(maxType), rec_d)
} }
// regfile // regfile
@ -670,7 +681,7 @@ class FPU(cfg: FPUParams)(implicit p: Parameters) extends FPUModule()(p) {
val wsingle = Mux(divSqrt_wen, divSqrt_single, wbInfo(0).single) val wsingle = Mux(divSqrt_wen, divSqrt_single, wbInfo(0).single)
val wdata = fLen match { val wdata = fLen match {
case 32 => wdata0 case 32 => wdata0
case 64 => Mux(wsingle, wdata0(32, 0) | CanonicalNaN.signaling(maxExpWidth, maxSigWidth), wdata0) case 64 => Mux(wsingle, wdata0(32, 0) | CanonicalNaN.signaling(maxType), wdata0)
} }
val wexc = (pipes.map(_.res.exc): Seq[UInt])(wbInfo(0).pipeid) val wexc = (pipes.map(_.res.exc): Seq[UInt])(wbInfo(0).pipeid)
when ((!wbInfo(0).cp && wen(0)) || divSqrt_wen) { when ((!wbInfo(0).cp && wen(0)) || divSqrt_wen) {