WIP on FPU subword recoding
This commit is contained in:
parent
986e1754be
commit
bb42f3bf3b
@ -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) {
|
||||||
|
Loading…
Reference in New Issue
Block a user