fpu mul sems all good excepted subnormal rounding
This commit is contained in:
parent
3c4df1e963
commit
0997592768
|
@ -624,22 +624,25 @@ case class FpuCore( portCount : Int, p : FpuParameter) extends Component{
|
|||
// val exp = math.exp + U(needShift)
|
||||
// val man = needShift ? math.mulC(p.internalMantissaSize + 1, p.internalMantissaSize bits) | math.mulC(p.internalMantissaSize, p.internalMantissaSize bits)
|
||||
|
||||
val mulRounded = (math.mulC >> p.internalMantissaSize)
|
||||
val needShift = mulRounded.msb
|
||||
val (mulHigh, mulLow) = math.mulC.splitAt(p.internalMantissaSize-1)
|
||||
val scrap = mulLow =/= 0
|
||||
val needShift = mulHigh.msb
|
||||
val exp = math.exp + U(needShift)
|
||||
val man = needShift ? mulRounded(1, p.internalMantissaSize bits) | mulRounded(0, p.internalMantissaSize bits)
|
||||
|
||||
val man = needShift ? mulHigh(1, p.internalMantissaSize+1 bits) | mulHigh(0, p.internalMantissaSize+1 bits)
|
||||
scrap setWhen(needShift && mulHigh(0))
|
||||
val forceZero = input.rs1.isZero || input.rs2.isZero
|
||||
val forceUnderflow = exp <= exponentOne + exponentOne - 127 - 23 // 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 output = FpuFloat(p.internalExponentSize, p.internalMantissaSize)
|
||||
output.sign := input.rs1.sign ^ input.rs2.sign
|
||||
output.exponent := (exp - exponentOne).resized
|
||||
output.mantissa := man
|
||||
output.mantissa := man.asUInt >> 1
|
||||
output.setNormal
|
||||
|
||||
val round = man(0) ## (scrap)
|
||||
|
||||
when(forceNan) {
|
||||
output.setNanQuiet
|
||||
} elsewhen(forceOverflow) {
|
||||
|
@ -664,7 +667,7 @@ case class FpuCore( portCount : Int, p : FpuParameter) extends Component{
|
|||
output.lockId := input.lockId
|
||||
output.rd := input.rd
|
||||
output.roundMode := input.roundMode
|
||||
output.round := 0 //TODO
|
||||
output.round := norm.round.asUInt
|
||||
output.value := norm.output
|
||||
|
||||
decode.mulToAdd.valid := input.valid && input.add
|
||||
|
|
|
@ -47,4 +47,10 @@ JNIEXPORT jfloat API JNICALL Java_vexriscv_ip_fpu_FpuMath_addF32(JNIEnv * env, j
|
|||
applyRounding(rounding);
|
||||
float32_t v = f32_add(toF32(a), toF32(b));
|
||||
return fromF32(v);
|
||||
}
|
||||
|
||||
JNIEXPORT jfloat API JNICALL Java_vexriscv_ip_fpu_FpuMath_mulF32(JNIEnv * env, jobject obj, jfloat a, jfloat b, jint rounding){
|
||||
applyRounding(rounding);
|
||||
float32_t v = f32_mul(toF32(a), toF32(b));
|
||||
return fromF32(v);
|
||||
}
|
|
@ -4,6 +4,7 @@ import java.io.File;
|
|||
|
||||
public class FpuMath {
|
||||
public native float addF32(float a, float b, int rounding);
|
||||
public native float mulF32(float a, float b, int rounding);
|
||||
|
||||
static{
|
||||
System.load(new File("src/test/cpp/fpu/math/fpu_math.so").getAbsolutePath());
|
||||
|
|
|
@ -624,12 +624,22 @@ class FpuTest extends FunSuite{
|
|||
}
|
||||
|
||||
|
||||
for(i <- 0 until 64){
|
||||
val rounding = FpuRoundMode.RMM
|
||||
val a = 24f
|
||||
val b = b2f(0x3f800000+i)
|
||||
val c = Clib.math.mulF32(a, b, rounding.position)
|
||||
val f = 0
|
||||
testMulExact(a,b,c,f, rounding)
|
||||
}
|
||||
|
||||
// for(_ <- 0 until 1000000){
|
||||
// val rounding = FpuRoundMode.RTZ
|
||||
// val (a,b,c,f) = f32.mul(rounding).f32_2
|
||||
// if(a > 0 && b > 0 && !c.isInfinity) testMulExact(a,b,c,f, rounding)
|
||||
// }
|
||||
// simSuccess()
|
||||
|
||||
for(_ <- 0 until 1000000){
|
||||
val rounding = FpuRoundMode.elements.randomPick()
|
||||
val (a,b,c,f) = f32.mul(rounding).f32_2
|
||||
if(!(c.abs < 1e-35f && c.abs > 0f)) testMulExact(a,b,c,f, rounding)
|
||||
}
|
||||
|
||||
|
||||
// roundingModes.foreach(rounding => println(Clib.math.addF32(0.0f, 0.0f, rounding.position)))
|
||||
|
|
Loading…
Reference in New Issue