fpu fix f32 tests for f64 fpu
This commit is contained in:
parent
b6eda1ad7a
commit
82dfd10dba
|
@ -59,7 +59,7 @@ class FpuTest extends FunSuite{
|
||||||
|
|
||||||
val config = SimConfig
|
val config = SimConfig
|
||||||
config.allOptimisation
|
config.allOptimisation
|
||||||
if(p.withDouble) config.withFstWave
|
// if(p.withDouble) config.withFstWave
|
||||||
config.compile(new FpuCore(portCount, p){
|
config.compile(new FpuCore(portCount, p){
|
||||||
for(i <- 0 until portCount) out(Bits(5 bits)).setName(s"flagAcc$i") := io.port(i).completion.flag.asBits
|
for(i <- 0 until portCount) out(Bits(5 bits)).setName(s"flagAcc$i") := io.port(i).completion.flag.asBits
|
||||||
setDefinitionName("FpuCore"+ (if(p.withDouble) "Double" else ""))
|
setDefinitionName("FpuCore"+ (if(p.withDouble) "Double" else ""))
|
||||||
|
@ -420,7 +420,7 @@ class FpuTest extends FunSuite{
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
def minMax(rd : Int, rs1 : Int, rs2 : Int, arg : Int = 0): Unit ={
|
def minMax(rd : Int, rs1 : Int, rs2 : Int, arg : Int, format : FpuFormat.E): Unit ={
|
||||||
cmdAdd {cmd =>
|
cmdAdd {cmd =>
|
||||||
cmd.opcode #= cmd.opcode.spinalEnum.MIN_MAX
|
cmd.opcode #= cmd.opcode.spinalEnum.MIN_MAX
|
||||||
cmd.rs1 #= rs1
|
cmd.rs1 #= rs1
|
||||||
|
@ -428,6 +428,8 @@ class FpuTest extends FunSuite{
|
||||||
cmd.rs3.randomize()
|
cmd.rs3.randomize()
|
||||||
cmd.rd #= rd
|
cmd.rd #= rd
|
||||||
cmd.arg #= arg
|
cmd.arg #= arg
|
||||||
|
cmd.roundMode.randomize()
|
||||||
|
cmd.format #= format
|
||||||
}
|
}
|
||||||
commitQueue += {cmd =>
|
commitQueue += {cmd =>
|
||||||
cmd.write #= true
|
cmd.write #= true
|
||||||
|
@ -437,7 +439,7 @@ class FpuTest extends FunSuite{
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
def fclass(rs1 : Int)(body : Int => Unit) : Unit = {
|
def fclass(rs1 : Int, format : FpuFormat.E)(body : Int => Unit) : Unit = {
|
||||||
cmdAdd {cmd =>
|
cmdAdd {cmd =>
|
||||||
cmd.opcode #= FpuOpcode.FCLASS
|
cmd.opcode #= FpuOpcode.FCLASS
|
||||||
cmd.rs1 #= rs1
|
cmd.rs1 #= rs1
|
||||||
|
@ -445,8 +447,10 @@ class FpuTest extends FunSuite{
|
||||||
cmd.rs3.randomize()
|
cmd.rs3.randomize()
|
||||||
cmd.rd.randomize()
|
cmd.rd.randomize()
|
||||||
cmd.arg.randomize()
|
cmd.arg.randomize()
|
||||||
|
cmd.roundMode.randomize()
|
||||||
|
cmd.format #= format
|
||||||
}
|
}
|
||||||
rspQueue += {rsp => body(rsp.value.toLong.toInt)}
|
rspQueue += {rsp => body(rsp.value.toBigInt.toInt)}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -587,7 +591,7 @@ class FpuTest extends FunSuite{
|
||||||
|
|
||||||
|
|
||||||
load(rd, a)
|
load(rd, a)
|
||||||
fclass(rd){v =>
|
fclass(rd, FpuFormat.FLOAT){v =>
|
||||||
val mantissa = f2b(a) & 0x7FFFFF
|
val mantissa = f2b(a) & 0x7FFFFF
|
||||||
val exp = (f2b(a) >> 23) & 0xFF
|
val exp = (f2b(a) >> 23) & 0xFF
|
||||||
val sign = (f2b(a) >> 31) & 0x1
|
val sign = (f2b(a) >> 31) & 0x1
|
||||||
|
@ -717,23 +721,63 @@ class FpuTest extends FunSuite{
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
def testF642iExact(a : Double, ref : Int, flag : Int, signed : Boolean, rounding : FpuRoundMode.E): Unit ={
|
||||||
|
val rs = new RegAllocator()
|
||||||
|
val rs1 = rs.allocate()
|
||||||
|
val rd = Random.nextInt(32)
|
||||||
|
load(rs1, a)
|
||||||
|
f2i(rs1, signed, rounding, FpuFormat.DOUBLE){rsp =>
|
||||||
|
if(signed) {
|
||||||
|
val v = rsp.value.toBigInt.toInt
|
||||||
|
var ref2 = ref
|
||||||
|
if(a >= Int.MaxValue) ref2 = Int.MaxValue
|
||||||
|
if(a <= Int.MinValue) ref2 = Int.MinValue
|
||||||
|
if(a.isNaN) ref2 = Int.MaxValue
|
||||||
|
assert(v == (ref2), f" <= f2i($a) = $v, $ref2, $rounding, $flag")
|
||||||
|
} else {
|
||||||
|
val v = rsp.value.toBigInt.toLong & 0xFFFFFFFFl
|
||||||
|
var ref2 = ref.toLong & 0xFFFFFFFFl
|
||||||
|
if(a < 0) ref2 = 0
|
||||||
|
if(a >= 0xFFFFFFFFl) ref2 = 0xFFFFFFFFl
|
||||||
|
if(a.isNaN) ref2 = 0xFFFFFFFFl
|
||||||
|
assert(v == ref2, f" <= f2ui($a) = $v, $ref2, $rounding $flag")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
def testI2fExact(a : Int, b : Float, f : Int, signed : Boolean, rounding : FpuRoundMode.E): Unit ={
|
flagMatch(flag, ref, f" f2${if(signed) "" else "u"}i($a) $ref $flag $rounding")
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
def testI2fExact(a : Int, ref : Float, f : Int, signed : Boolean, rounding : FpuRoundMode.E): Unit ={
|
||||||
val rs = new RegAllocator()
|
val rs = new RegAllocator()
|
||||||
val rd = Random.nextInt(32)
|
val rd = Random.nextInt(32)
|
||||||
i2f(rd, a, signed, rounding, FpuFormat.FLOAT)
|
i2f(rd, a, signed, rounding, FpuFormat.FLOAT)
|
||||||
storeFloat(rd){v =>
|
storeFloat(rd){v =>
|
||||||
val aLong = if(signed) a.toLong else a.toLong & 0xFFFFFFFFl
|
val aLong = if(signed) a.toLong else a.toLong & 0xFFFFFFFFl
|
||||||
val ref = b
|
|
||||||
assert(f2b(v) == f2b(ref), f"i2f($aLong) = $v, $ref $rounding")
|
assert(f2b(v) == f2b(ref), f"i2f($aLong) = $v, $ref $rounding")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
flagMatch(f, b, f"i2f($a) = $b")
|
flagMatch(f, ref, f"i2f($a) = $ref")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
def testI2f64Exact(a : Int, ref : Double, f : Int, signed : Boolean, rounding : FpuRoundMode.E): Unit ={
|
||||||
|
val rs = new RegAllocator()
|
||||||
|
val rd = Random.nextInt(32)
|
||||||
|
i2f(rd, a, signed, rounding, FpuFormat.DOUBLE)
|
||||||
|
store(rd){v =>
|
||||||
|
val aLong = if(signed) a.toLong else a.toLong & 0xFFFFFFFFl
|
||||||
|
assert(d2b(v) == d2b(ref), f"i2f($aLong) = $v, $ref $rounding")
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
flagMatch(f, ref, f"i2f($a) = $ref")
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
def testCmpExact(a : Float, b : Float, ref : Int, flag : Int, arg : Int): Unit ={
|
def testCmpExact(a : Float, b : Float, ref : Int, flag : Int, arg : Int): Unit ={
|
||||||
val rs = new RegAllocator()
|
val rs = new RegAllocator()
|
||||||
val rs1, rs2, rs3 = rs.allocate()
|
val rs1, rs2, rs3 = rs.allocate()
|
||||||
|
@ -741,7 +785,7 @@ class FpuTest extends FunSuite{
|
||||||
load(rs1, a)
|
load(rs1, a)
|
||||||
load(rs2, b)
|
load(rs2, b)
|
||||||
cmp(rs1, rs2, arg, FpuFormat.FLOAT){rsp =>
|
cmp(rs1, rs2, arg, FpuFormat.FLOAT){rsp =>
|
||||||
val v = rsp.value.toLong
|
val v = rsp.value.toBigInt.toInt
|
||||||
assert(v === ref, f"cmp($a, $b, $arg) = $v, $ref")
|
assert(v === ref, f"cmp($a, $b, $arg) = $v, $ref")
|
||||||
}
|
}
|
||||||
flagMatch(flag,f"$a < $b $ref $flag ${f2b(a).toHexString} ${f2b(b).toHexString}")
|
flagMatch(flag,f"$a < $b $ref $flag ${f2b(a).toHexString} ${f2b(b).toHexString}")
|
||||||
|
@ -795,7 +839,7 @@ class FpuTest extends FunSuite{
|
||||||
load(rs1, a)
|
load(rs1, a)
|
||||||
load(rs2, b)
|
load(rs2, b)
|
||||||
|
|
||||||
minMax(rd,rs1,rs2, arg)
|
minMax(rd,rs1,rs2, arg, FpuFormat.FLOAT)
|
||||||
storeFloat(rd){v =>
|
storeFloat(rd){v =>
|
||||||
assert(f2b(ref) == f2b(v), f"minMax($a $b $arg) = $v, $ref")
|
assert(f2b(ref) == f2b(v), f"minMax($a $b $arg) = $v, $ref")
|
||||||
}
|
}
|
||||||
|
@ -875,6 +919,18 @@ class FpuTest extends FunSuite{
|
||||||
testF2iExact(a,b, f, true, rounding)
|
testF2iExact(a,b, f, true, rounding)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
def testF2uiF64() : Unit = {
|
||||||
|
val rounding = FpuRoundMode.elements.randomPick()
|
||||||
|
val (a,b,f) = f64.f2ui(rounding).f64_i32
|
||||||
|
testF642iExact(a,b, f, false, rounding)
|
||||||
|
}
|
||||||
|
|
||||||
|
def testF2iF64() : Unit = {
|
||||||
|
val rounding = FpuRoundMode.elements.randomPick()
|
||||||
|
val (a,b,f) = f64.f2i(rounding).f64_i32
|
||||||
|
testF642iExact(a,b, f, true, rounding)
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
def testDiv() : Unit = {
|
def testDiv() : Unit = {
|
||||||
val rounding = FpuRoundMode.elements.randomPick()
|
val rounding = FpuRoundMode.elements.randomPick()
|
||||||
|
@ -934,18 +990,30 @@ class FpuTest extends FunSuite{
|
||||||
testMaxExact(a,b)
|
testMaxExact(a,b)
|
||||||
}
|
}
|
||||||
|
|
||||||
def testUI2f() : Unit = {
|
def testUI2f32() : Unit = {
|
||||||
val rounding = FpuRoundMode.elements.randomPick()
|
val rounding = FpuRoundMode.elements.randomPick()
|
||||||
val (a,b,f) = f32.i2f(rounding).i32_f32
|
val (a,b,f) = f32.i2f(rounding).i32_f32
|
||||||
testI2fExact(a,b,f, true, rounding)
|
testI2fExact(a,b,f, true, rounding)
|
||||||
}
|
}
|
||||||
|
|
||||||
def testI2f() : Unit = {
|
def testI2f32() : Unit = {
|
||||||
val rounding = FpuRoundMode.elements.randomPick()
|
val rounding = FpuRoundMode.elements.randomPick()
|
||||||
val (a,b,f) = f32.ui2f(rounding).i32_f32
|
val (a,b,f) = f32.ui2f(rounding).i32_f32
|
||||||
testI2fExact(a,b,f, false, rounding)
|
testI2fExact(a,b,f, false, rounding)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
def testUI2f64() : Unit = {
|
||||||
|
val rounding = FpuRoundMode.elements.randomPick()
|
||||||
|
val (a,b,f) = f64.i2f(rounding).i32_f64
|
||||||
|
testI2f64Exact(a,b,f, true, rounding)
|
||||||
|
}
|
||||||
|
|
||||||
|
def testI2f64() : Unit = {
|
||||||
|
val rounding = FpuRoundMode.elements.randomPick()
|
||||||
|
val (a,b,f) = f64.ui2f(rounding).i32_f64
|
||||||
|
testI2f64Exact(a,b,f, false, rounding)
|
||||||
|
}
|
||||||
|
|
||||||
def testMulF32() : Unit = {
|
def testMulF32() : Unit = {
|
||||||
val rounding = FpuRoundMode.elements.randomPick()
|
val rounding = FpuRoundMode.elements.randomPick()
|
||||||
val (a,b,c,f) = f32.mul(rounding).f32_f32_f32
|
val (a,b,c,f) = f32.mul(rounding).f32_f32_f32
|
||||||
|
@ -964,24 +1032,45 @@ class FpuTest extends FunSuite{
|
||||||
testBinaryOp(sub,a,b,c,f, rounding,"sub")
|
testBinaryOp(sub,a,b,c,f, rounding,"sub")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
def testMulF64() : Unit = {
|
def testMulF64() : Unit = {
|
||||||
val rounding = FpuRoundMode.elements.randomPick()
|
val rounding = FpuRoundMode.elements.randomPick()
|
||||||
val (a,b,c,f) = f64.mul(rounding).f64_f64_f64
|
val (a,b,c,f) = f64.mul(rounding).f64_f64_f64
|
||||||
testBinaryOpF64(mul,a,b,c,f, rounding,"mul")
|
testBinaryOpF64(mul,a,b,c,f, rounding,"mul")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
def testAddF64() : Unit = {
|
||||||
|
val rounding = FpuRoundMode.elements.randomPick()
|
||||||
|
val (a,b,c,f) = f64.add(rounding).f64_f64_f64
|
||||||
|
testBinaryOpF64(add,a,b,c,f, rounding,"add")
|
||||||
|
}
|
||||||
|
|
||||||
val f32Tests = List[() => Unit](testSubF32, testAddF32, testMulF32, testI2f, testUI2f, testMin, testMax, testSgnj, testTransferF32, testDiv, testSqrt, testF2iF32, testF2uiF32, testLe, testEq, testLt, testClass, testFma)
|
def testSubF64() : Unit = {
|
||||||
|
val rounding = FpuRoundMode.elements.randomPick()
|
||||||
|
val (a,b,c,f) = f64.sub(rounding).f64_f64_f64
|
||||||
|
testBinaryOpF64(sub,a,b,c,f, rounding,"sub")
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
val f32Tests = List[() => Unit](testSubF32, testAddF32, testMulF32, testI2f32, testUI2f32, testMin, testMax, testSgnj, testTransferF32, testDiv, testSqrt, testF2iF32, testF2uiF32, testLe, testEq, testLt, testClass, testFma)
|
||||||
|
|
||||||
//TODO test boxing
|
//TODO test boxing
|
||||||
|
//TODO double <-> simple convertions
|
||||||
if(p.withDouble) {
|
if(p.withDouble) {
|
||||||
// for(_ <- 0 until 10000) testUI2f64()
|
|
||||||
// for(_ <- 0 until 10000) testI2f64()
|
for(_ <- 0 until 10000) testAddF64()
|
||||||
// println("f64 i2f done")
|
for(_ <- 0 until 10000) testSubF64()
|
||||||
//
|
println("Add done")
|
||||||
// for(_ <- 0 until 10000) testF2uiF64()
|
|
||||||
// for(_ <- 0 until 10000) testF2iF64()
|
|
||||||
// println("f64 f2i done")
|
// testI2f64Exact(0x7FFFFFF5, 0x7FFFFFF5, 0, true, FpuRoundMode.RNE)
|
||||||
|
for(_ <- 0 until 10000) testUI2f64()
|
||||||
|
for(_ <- 0 until 10000) testI2f64()
|
||||||
|
println("f64 i2f done")
|
||||||
|
|
||||||
|
for(_ <- 0 until 10000) testF2uiF64()
|
||||||
|
for(_ <- 0 until 10000) testF2iF64()
|
||||||
|
println("f64 f2i done")
|
||||||
|
|
||||||
// testF2iExact(1.0f,1, 0, false, FpuRoundMode.RTZ)
|
// testF2iExact(1.0f,1, 0, false, FpuRoundMode.RTZ)
|
||||||
// testF2iExact(2.0f,2, 0, false, FpuRoundMode.RTZ)
|
// testF2iExact(2.0f,2, 0, false, FpuRoundMode.RTZ)
|
||||||
|
@ -1027,8 +1116,8 @@ class FpuTest extends FunSuite{
|
||||||
println("Mul done")
|
println("Mul done")
|
||||||
|
|
||||||
|
|
||||||
for(_ <- 0 until 10000) testUI2f()
|
for(_ <- 0 until 10000) testUI2f32()
|
||||||
for(_ <- 0 until 10000) testI2f()
|
for(_ <- 0 until 10000) testI2f32()
|
||||||
println("i2f done")
|
println("i2f done")
|
||||||
|
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue