fpu mul now pass all roundings
This commit is contained in:
parent
0997592768
commit
c51b0fcafe
|
@ -631,7 +631,7 @@ case class FpuCore( portCount : Int, p : FpuParameter) extends Component{
|
||||||
val man = needShift ? mulHigh(1, p.internalMantissaSize+1 bits) | mulHigh(0, p.internalMantissaSize+1 bits)
|
val man = needShift ? mulHigh(1, p.internalMantissaSize+1 bits) | mulHigh(0, p.internalMantissaSize+1 bits)
|
||||||
scrap setWhen(needShift && mulHigh(0))
|
scrap setWhen(needShift && mulHigh(0))
|
||||||
val forceZero = input.rs1.isZero || input.rs2.isZero
|
val forceZero = input.rs1.isZero || input.rs2.isZero
|
||||||
val forceUnderflow = exp <= exponentOne + exponentOne - 127 - 23 // 0x6A //TODO
|
val forceUnderflow = exp < exponentOne + exponentOne - 127 - 24 // 0x6A //TODO
|
||||||
val forceOverflow = /*exp > exponentOne + exponentOne + 127 || */input.rs1.isInfinity || input.rs2.isInfinity
|
val forceOverflow = /*exp > exponentOne + exponentOne + 127 || */input.rs1.isInfinity || input.rs2.isInfinity
|
||||||
val forceNan = input.rs1.isNan || input.rs2.isNan || ((input.rs1.isInfinity || input.rs2.isInfinity) && (input.rs1.isZero || input.rs2.isZero))
|
val forceNan = input.rs1.isNan || input.rs2.isNan || ((input.rs1.isInfinity || input.rs2.isInfinity) && (input.rs1.isZero || input.rs2.isZero))
|
||||||
|
|
||||||
|
@ -650,7 +650,7 @@ case class FpuCore( portCount : Int, p : FpuParameter) extends Component{
|
||||||
} elsewhen(forceZero) {
|
} elsewhen(forceZero) {
|
||||||
output.setZero
|
output.setZero
|
||||||
} elsewhen(forceUnderflow) {
|
} elsewhen(forceUnderflow) {
|
||||||
output.setZero
|
output.exponent := exponentOne - 127 - 25
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -968,6 +968,7 @@ case class FpuCore( portCount : Int, p : FpuParameter) extends Component{
|
||||||
|
|
||||||
|
|
||||||
val merge = new Area {
|
val merge = new Area {
|
||||||
|
//TODO maybe load can bypass merge and round.
|
||||||
val arbitrated = StreamArbiterFactory.lowerFirst.noLock.on(List(load.s1.output, add.output, mul.output, shortPip.rfOutput))
|
val arbitrated = StreamArbiterFactory.lowerFirst.noLock.on(List(load.s1.output, add.output, mul.output, shortPip.rfOutput))
|
||||||
val isCommited = rf.lock.map(_.commited).read(arbitrated.lockId)
|
val isCommited = rf.lock.map(_.commited).read(arbitrated.lockId)
|
||||||
val commited = arbitrated.haltWhen(!isCommited).toFlow
|
val commited = arbitrated.haltWhen(!isCommited).toFlow
|
||||||
|
@ -976,16 +977,25 @@ case class FpuCore( portCount : Int, p : FpuParameter) extends Component{
|
||||||
val round = new Area{
|
val round = new Area{
|
||||||
val input = merge.commited.combStage
|
val input = merge.commited.combStage
|
||||||
|
|
||||||
|
//TODO do not break NAN payload
|
||||||
|
val manAggregate = input.value.mantissa @@ input.round
|
||||||
|
val expDif = (exponentOne-126) - input.value.exponent
|
||||||
|
val discardCount = expDif.msb ? U(0) | expDif.resize(log2Up(p.internalMantissaSize) bits)
|
||||||
|
val exactMask = (List(True) ++ (0 until p.internalMantissaSize+1).map(_ < discardCount)).asBits.asUInt
|
||||||
|
val roundAdjusted = (True ## (manAggregate>>1))(discardCount) ## ((manAggregate & exactMask) =/= 0)
|
||||||
|
|
||||||
val mantissaIncrement = !input.value.special && input.roundMode.mux(
|
val mantissaIncrement = !input.value.special && input.roundMode.mux(
|
||||||
FpuRoundMode.RNE -> (input.round(1) && (input.round(0) || input.value.mantissa.lsb)),
|
FpuRoundMode.RNE -> (roundAdjusted(1) && (roundAdjusted(0) || (U"01" ## (manAggregate>>2))(discardCount))),
|
||||||
FpuRoundMode.RTZ -> False,
|
FpuRoundMode.RTZ -> False,
|
||||||
FpuRoundMode.RDN -> (input.round =/= 0 && input.value.sign),
|
FpuRoundMode.RDN -> (roundAdjusted =/= 0 && input.value.sign),
|
||||||
FpuRoundMode.RUP -> (input.round =/= 0 && !input.value.sign),
|
FpuRoundMode.RUP -> (roundAdjusted =/= 0 && !input.value.sign),
|
||||||
FpuRoundMode.RMM -> (input.round(1))
|
FpuRoundMode.RMM -> (roundAdjusted(1))
|
||||||
)
|
)
|
||||||
|
|
||||||
val math = p.internalFloating()
|
val math = p.internalFloating()
|
||||||
val adder = (input.value.exponent @@ input.value.mantissa) + U(mantissaIncrement)
|
val adderMantissa = input.value.mantissa & (mantissaIncrement ? ~(exactMask.trim(1) >> 1) | input.value.mantissa.maxValue)
|
||||||
|
val adderRightOp = (mantissaIncrement ? (exactMask >> 1)| U(0)).resize(p.internalMantissaSize bits)
|
||||||
|
val adder = (input.value.exponent @@ adderMantissa) + adderRightOp + U(mantissaIncrement)
|
||||||
math.special := input.value.special
|
math.special := input.value.special
|
||||||
math.sign := input.value.sign
|
math.sign := input.value.sign
|
||||||
math.exponent := adder(p.internalMantissaSize, p.internalExponentSize bits)
|
math.exponent := adder(p.internalMantissaSize, p.internalExponentSize bits)
|
||||||
|
@ -1010,6 +1020,21 @@ case class FpuCore( portCount : Int, p : FpuParameter) extends Component{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
when(!math.special && math.exponent <= exponentOne - 127-23){
|
||||||
|
val doMin = input.roundMode.mux(
|
||||||
|
FpuRoundMode.RNE -> (False),
|
||||||
|
FpuRoundMode.RTZ -> (False),
|
||||||
|
FpuRoundMode.RDN -> (math.sign),
|
||||||
|
FpuRoundMode.RUP -> (!math.sign),
|
||||||
|
FpuRoundMode.RMM -> (False)
|
||||||
|
)
|
||||||
|
when(doMin){
|
||||||
|
patched.exponent := exponentOne - 127-23+1
|
||||||
|
patched.mantissa := 0
|
||||||
|
} otherwise {
|
||||||
|
patched.setZero
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
val output = input.swapPayload(RoundOutput())
|
val output = input.swapPayload(RoundOutput())
|
||||||
output.source := input.source
|
output.source := input.source
|
||||||
|
|
|
@ -638,7 +638,8 @@ class FpuTest extends FunSuite{
|
||||||
for(_ <- 0 until 1000000){
|
for(_ <- 0 until 1000000){
|
||||||
val rounding = FpuRoundMode.elements.randomPick()
|
val rounding = FpuRoundMode.elements.randomPick()
|
||||||
val (a,b,c,f) = f32.mul(rounding).f32_2
|
val (a,b,c,f) = f32.mul(rounding).f32_2
|
||||||
if(!(c.abs < 1e-35f && c.abs > 0f)) testMulExact(a,b,c,f, rounding)
|
// if(!(c.abs < 1e-35f && c.abs > 0f)) testMulExact(a,b,c,f, rounding)
|
||||||
|
/*if(! (a.toDouble*b.toDouble.abs <= 2E-45)) */testMulExact(a,b,c,f, rounding)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue