fpu vex cmp/fle works

This commit is contained in:
Dolu1990 2021-01-18 15:09:30 +01:00
parent 6cb498cdb2
commit d4b877d415
8 changed files with 294 additions and 94 deletions

View File

@ -176,6 +176,12 @@ object Riscv{
def FMSUB_D = M"-----01------------------1000111"
def FNMSUB_D = M"-----01------------------1001011"
def FNMADD_D = M"-----01------------------1001111"
def FLE_S = M"1010000----------000-----1010011"
def FLT_S = M"1010000----------001-----1010011"
def FEQ_S = M"1010000----------010-----1010011"
def FLE_D = M"1010001----------000-----1010011"
def FLT_D = M"1010001----------001-----1010011"
def FEQ_D = M"1010001----------010-----1010011"
object CSR{
def MVENDORID = 0xF11 // MRO Vendor ID.

View File

@ -17,6 +17,7 @@ case class FpuCore( portCount : Int, p : FpuParameter) extends Component{
val portCountWidth = log2Up(portCount)
val Source = HardType(UInt(portCountWidth bits))
val exponentOne = (1 << p.internalExponentSize-1) - 1
// val commitPerportCount = 8
@ -51,7 +52,8 @@ case class FpuCore( portCount : Int, p : FpuParameter) extends Component{
case class StoreInput() extends Bundle{
val source = Source()
val rs2 = p.internalFloating()
val opcode = p.Opcode()
val rs1, rs2 = p.internalFloating()
}
case class MulInput() extends Bundle{
@ -184,6 +186,16 @@ case class FpuCore( portCount : Int, p : FpuParameter) extends Component{
useRs3 := True //Can be delayed to have less hazard
useRd := True
}
is(p.Opcode.I2F){
useRd := True
}
is(p.Opcode.F2I){
useRs1 := True
}
is(p.Opcode.CMP){
useRs1 := True
useRs2 := True
}
}
val hits = List((useRs1, s0.rs1), (useRs2, s0.rs2), (useRs3, s0.rs3), (useRd, s0.rd)).map{case (use, reg) => use && rf.lock.map(l => l.valid && l.source === s0.source && l.address === reg).orR}
@ -230,12 +242,14 @@ case class FpuCore( portCount : Int, p : FpuParameter) extends Component{
load.rs1 := read.output.rs1
load.lockId := read.output.lockId
val storeHit = input.opcode === p.Opcode.STORE
val store = Stream(StoreInput())
input.ready setWhen(storeHit && store.ready)
store.valid := input.valid && storeHit
store.source := read.output.source
store.rs2 := read.output.rs2
val coreRspHit = List(FpuOpcode.STORE, FpuOpcode.F2I, FpuOpcode.CMP).map(input.opcode === _).orR
val coreRsp = Stream(StoreInput())
input.ready setWhen(coreRspHit && coreRsp.ready)
coreRsp.valid := input.valid && coreRspHit
coreRsp.source := read.output.source
coreRsp.opcode := read.output.opcode
coreRsp.rs1 := read.output.rs1
coreRsp.rs2 := read.output.rs2
val divSqrtHit = input.opcode === p.Opcode.DIV || input.opcode === p.Opcode.SQRT
val divSqrt = Stream(DivSqrtInput())
@ -297,14 +311,37 @@ case class FpuCore( portCount : Int, p : FpuParameter) extends Component{
}
val rspLogic = new Area{
val input = decode.store.stage()
val coreRsp = new Area{
val input = decode.coreRsp.stage()
val result = p.storeLoadType().assignDontCare()
val storeResult = input.rs2.asBits
val f2iShift = input.rs1.exponent - U(exponentOne)
val f2iShifted = (U"1" @@ input.rs1.mantissa) << (f2iShift.resize(5 bits))
val f2iResult = f2iShifted.asBits >> p.internalMantissaSize
val rs1Equal = input.rs1 === input.rs2
val rs1AbsSmaller = (input.rs1.exponent @@ input.rs1.mantissa) < (input.rs2.exponent @@ input.rs2.mantissa)
val rs1Smaller = (input.rs1.sign ## input.rs2.sign).mux(
0 -> rs1AbsSmaller,
1 -> False,
2 -> True,
3 -> (!rs1AbsSmaller && !rs1Equal)
)
val cmpResult = B(rs1Smaller)
switch(input.opcode){
is(FpuOpcode.STORE){ result := storeResult }
is(FpuOpcode.F2I) { result := f2iResult }
is(FpuOpcode.CMP) { result := cmpResult.resized }
}
input.ready := io.port.map(_.rsp.ready).read(input.source)
for(i <- 0 until portCount){
def rsp = io.port(i).rsp
rsp.valid := input.valid && input.source === i
rsp.value := input.rs2.asBits
rsp.value := result
}
}

View File

@ -19,7 +19,15 @@ case class FpuFloat(exponentSize: Int,
mantissaSize: Int) extends Bundle {
val mantissa = UInt(mantissaSize bits)
val exponent = UInt(exponentSize bits)
val sign = Bool
val sign = Bool()
def withInvertSign : FpuFloat ={
val ret = FpuFloat(exponentSize,mantissaSize)
ret.sign := !sign
ret.exponent := exponent
ret.mantissa := mantissa
ret
}
}
object FpuOpcode extends SpinalEnum{

View File

@ -12,7 +12,7 @@ class FpuPlugin(externalFpu : Boolean = false,
object FPU_ENABLE extends Stageable(Bool())
object FPU_COMMIT extends Stageable(Bool())
object FPU_LOAD extends Stageable(Bool())
object FPU_STORE extends Stageable(Bool())
object FPU_RSP extends Stageable(Bool())
object FPU_ALU extends Stageable(Bool())
object FPU_FORKED extends Stageable(Bool())
object FPU_OPCODE extends Stageable(FpuOpcode())
@ -20,12 +20,16 @@ class FpuPlugin(externalFpu : Boolean = false,
var port : FpuPort = null
override def setup(pipeline: VexRiscv): Unit = {
import pipeline.config._
val decoderService = pipeline.service(classOf[DecoderService])
decoderService.addDefault(FPU_ENABLE, False)
decoderService.add(List(
FADD_S -> List(FPU_ENABLE -> True, FPU_OPCODE -> FpuOpcode.ADD, FPU_COMMIT -> True, FPU_ALU -> True , FPU_LOAD -> False, FPU_STORE -> False),
FLW -> List(FPU_ENABLE -> True, FPU_OPCODE -> FpuOpcode.LOAD, FPU_COMMIT -> True, FPU_ALU -> False, FPU_LOAD -> True , FPU_STORE -> False),
FSW -> List(FPU_ENABLE -> True, FPU_OPCODE -> FpuOpcode.STORE,FPU_COMMIT -> False, FPU_ALU -> False, FPU_LOAD -> False, FPU_STORE -> True)
FADD_S -> List(FPU_ENABLE -> True, FPU_OPCODE -> FpuOpcode.ADD, FPU_COMMIT -> True, FPU_ALU -> True , FPU_LOAD -> False, FPU_RSP -> False),
FLW -> List(FPU_ENABLE -> True, FPU_OPCODE -> FpuOpcode.LOAD, FPU_COMMIT -> True, FPU_ALU -> False, FPU_LOAD -> True , FPU_RSP -> False),
FSW -> List(FPU_ENABLE -> True, FPU_OPCODE -> FpuOpcode.STORE, FPU_COMMIT -> False, FPU_ALU -> False, FPU_LOAD -> False, FPU_RSP -> True),
FCVT_WU_S -> List(FPU_ENABLE -> True, FPU_OPCODE -> FpuOpcode.F2I , FPU_COMMIT -> False, FPU_ALU -> False, FPU_LOAD -> False, FPU_RSP -> True, REGFILE_WRITE_VALID -> True, BYPASSABLE_EXECUTE_STAGE -> False, BYPASSABLE_MEMORY_STAGE -> False),
FLE_S -> List(FPU_ENABLE -> True, FPU_OPCODE -> FpuOpcode.CMP , FPU_COMMIT -> False, FPU_ALU -> False, FPU_LOAD -> False, FPU_RSP -> True, REGFILE_WRITE_VALID -> True, BYPASSABLE_EXECUTE_STAGE -> False, BYPASSABLE_MEMORY_STAGE -> False)
))
port = FpuPort(p)
@ -72,15 +76,16 @@ class FpuPlugin(externalFpu : Boolean = false,
import writeBack._
val dBusEncoding = pipeline.service(classOf[DBusEncodingService])
val isStore = input(FPU_FORKED) && input(FPU_STORE)
val isRsp = input(FPU_FORKED) && input(FPU_RSP)
val isCommit = input(FPU_FORKED) && input(FPU_COMMIT)
//Manage $store and port.rsp
port.rsp.ready := False
when(isStore){
when(isRsp){
port.rsp.ready := True
when(arbitration.isValid) {
dBusEncoding.bypassStore(port.rsp.value)
output(REGFILE_WRITE_DATA) := port.rsp.value
}
when(!port.rsp.valid){
arbitration.haltByOther := True
@ -105,6 +110,4 @@ class FpuPlugin(externalFpu : Boolean = false,
pipeline.stages.tail.foreach(_.input(FPU_FORKED).init(False))
}
}
}

View File

@ -25,7 +25,7 @@ Disassembly of section .crt_section:
80000040 <test2>:
80000040: 00200e13 li t3,2
80000044: 00000097 auipc ra,0x0
80000048: 1fc0a083 lw ra,508(ra) # 80000240 <test1_data>
80000048: 2900a083 lw ra,656(ra) # 800002d4 <test1_data>
8000004c: 00107153 fadd.s ft2,ft0,ft1
80000050: 00000013 nop
80000054: 00000013 nop
@ -67,7 +67,7 @@ Disassembly of section .crt_section:
800000cc: 00000013 nop
800000d0: 00000013 nop
800000d4: 00000097 auipc ra,0x0
800000d8: 16c08093 addi ra,ra,364 # 80000240 <test1_data>
800000d8: 20008093 addi ra,ra,512 # 800002d4 <test1_data>
800000dc: 0000a107 flw ft2,0(ra)
800000e0: 00000013 nop
800000e4: 00000013 nop
@ -85,9 +85,9 @@ Disassembly of section .crt_section:
8000010c: 00000013 nop
80000110: 00000013 nop
80000114: 00000097 auipc ra,0x0
80000118: 12c08093 addi ra,ra,300 # 80000240 <test1_data>
80000118: 1c008093 addi ra,ra,448 # 800002d4 <test1_data>
8000011c: 00000117 auipc sp,0x0
80000120: 12810113 addi sp,sp,296 # 80000244 <test2_data>
80000120: 1bc10113 addi sp,sp,444 # 800002d8 <test2_data>
80000124: 0000a087 flw ft1,0(ra)
80000128: 00012107 flw ft2,0(sp)
8000012c: 0020f1d3 fadd.s ft3,ft1,ft2
@ -119,7 +119,7 @@ Disassembly of section .crt_section:
8000018c: 00000013 nop
80000190: 00000013 nop
80000194: 00000097 auipc ra,0x0
80000198: 0b408093 addi ra,ra,180 # 80000248 <test3_data>
80000198: 14808093 addi ra,ra,328 # 800002dc <test3_data>
8000019c: 0030a027 fsw ft3,0(ra)
800001a0: 00000013 nop
800001a4: 00000013 nop
@ -133,13 +133,13 @@ Disassembly of section .crt_section:
800001c0 <test7>:
800001c0: 00700e13 li t3,7
800001c4: 00000097 auipc ra,0x0
800001c8: 08408093 addi ra,ra,132 # 80000248 <test3_data>
800001c8: 11808093 addi ra,ra,280 # 800002dc <test3_data>
800001cc: 00000117 auipc sp,0x0
800001d0: 08010113 addi sp,sp,128 # 8000024c <test4_data>
800001d0: 11410113 addi sp,sp,276 # 800002e0 <test4_data>
800001d4: 00000197 auipc gp,0x0
800001d8: 07c18193 addi gp,gp,124 # 80000250 <test5_data>
800001d8: 11018193 addi gp,gp,272 # 800002e4 <test5_data>
800001dc: 00000217 auipc tp,0x0
800001e0: 07820213 addi tp,tp,120 # 80000254 <test6_data>
800001e0: 10c20213 addi tp,tp,268 # 800002e8 <test6_data>
800001e4: 0000a207 flw ft4,0(ra)
800001e8: 00427253 fadd.s ft4,ft4,ft4
800001ec: 0040f2d3 fadd.s ft5,ft1,ft4
@ -150,17 +150,13 @@ Disassembly of section .crt_section:
80000200: 00000013 nop
80000204: 00000013 nop
80000208: 00000013 nop
8000020c: 0100006f j 8000021c <pass>
80000210 <fail>:
80000210: f0100137 lui sp,0xf0100
80000214: f2410113 addi sp,sp,-220 # f00fff24 <test14_data+0x700ffcb0>
80000218: 01c12023 sw t3,0(sp)
8000021c <pass>:
8000021c: f0100137 lui sp,0xf0100
80000220: f2010113 addi sp,sp,-224 # f00fff20 <test14_data+0x700ffcac>
80000224: 00012023 sw zero,0(sp)
8000020c: 0340006f j 80000240 <test8>
80000210: 00000013 nop
80000214: 00000013 nop
80000218: 00000013 nop
8000021c: 00000013 nop
80000220: 00000013 nop
80000224: 00000013 nop
80000228: 00000013 nop
8000022c: 00000013 nop
80000230: 00000013 nop
@ -168,57 +164,101 @@ Disassembly of section .crt_section:
80000238: 00000013 nop
8000023c: 00000013 nop
80000240 <test1_data>:
80000240: 0000 unimp
80000242: 3fc0 fld fs0,184(a5)
80000240 <test8>:
80000240: 00800e13 li t3,8
80000244: c011f0d3 fcvt.wu.s ra,ft3
80000248: 00000013 nop
8000024c: 00000013 nop
80000250: 00000013 nop
80000254: 00000013 nop
80000258: 0280006f j 80000280 <test9>
8000025c: 00000013 nop
80000260: 00000013 nop
80000264: 00000013 nop
80000268: 00000013 nop
8000026c: 00000013 nop
80000270: 00000013 nop
80000274: 00000013 nop
80000278: 00000013 nop
8000027c: 00000013 nop
80000244 <test2_data>:
80000244: 0000 unimp
80000246: 40a0 lw s0,64(s1)
80000280 <test9>:
80000280: 00900e13 li t3,9
80000284: a03100d3 fle.s ra,ft2,ft3
80000288: a0218153 fle.s sp,ft3,ft2
8000028c: a03181d3 fle.s gp,ft3,ft3
80000290: 00000013 nop
80000294: 00000013 nop
80000298: 00000013 nop
8000029c: 00000013 nop
800002a0: 0100006f j 800002b0 <pass>
80000248 <test3_data>:
80000248: 0049 c.nop 18
800002a4 <fail>:
800002a4: f0100137 lui sp,0xf0100
800002a8: f2410113 addi sp,sp,-220 # f00fff24 <test14_data+0x700ffc1c>
800002ac: 01c12023 sw t3,0(sp)
800002b0 <pass>:
800002b0: f0100137 lui sp,0xf0100
800002b4: f2010113 addi sp,sp,-224 # f00fff20 <test14_data+0x700ffc18>
800002b8: 00012023 sw zero,0(sp)
800002bc: 00000013 nop
800002c0: 00000013 nop
800002c4: 00000013 nop
800002c8: 00000013 nop
800002cc: 00000013 nop
800002d0: 00000013 nop
800002d4 <test1_data>:
800002d4: 0000 unimp
800002d6: 3fc0 fld fs0,184(a5)
800002d8 <test2_data>:
800002d8: 0000 unimp
800002da: 40a0 lw s0,64(s1)
800002dc <test3_data>:
800002dc: 0049 c.nop 18
...
8000024c <test4_data>:
8000024c: 003a c.slli zero,0xe
800002e0 <test4_data>:
800002e0: 003a c.slli zero,0xe
...
80000250 <test5_data>:
80000250: 0038 addi a4,sp,8
800002e4 <test5_data>:
800002e4: 0038 addi a4,sp,8
...
80000254 <test6_data>:
80000254: 0000004b fnmsub.s ft0,ft0,ft0,ft0,rne
800002e8 <test6_data>:
800002e8: 0000004b fnmsub.s ft0,ft0,ft0,ft0,rne
80000258 <test7_data>:
80000258: 0038 addi a4,sp,8
800002ec <test7_data>:
800002ec: 0038 addi a4,sp,8
...
8000025c <test8_data>:
8000025c: 00000053 fadd.s ft0,ft0,ft0,rne
800002f0 <test8_data>:
800002f0: 00000053 fadd.s ft0,ft0,ft0,rne
80000260 <test9_data>:
80000260: 0021 c.nop 8
800002f4 <test9_data>:
800002f4: 0021 c.nop 8
...
80000264 <test10_data>:
80000264: ffffffbf 0xffffffbf
800002f8 <test10_data>:
800002f8: ffffffbf 0xffffffbf
80000268 <test11_data>:
80000268: ffa9 bnez a5,800001c2 <test7+0x2>
8000026a: ffff 0xffff
800002fc <test11_data>:
800002fc: ffa9 bnez a5,80000256 <test8+0x16>
800002fe: ffff 0xffff
8000026c <test12_data>:
8000026c: ffc9 bnez a5,80000206 <test7+0x46>
8000026e: ffff 0xffff
80000300 <test12_data>:
80000300: ffc9 bnez a5,8000029a <test9+0x1a>
80000302: ffff 0xffff
80000270 <test13_data>:
80000270: 0004 0x4
80000272: ffff 0xffff
80000304 <test13_data>:
80000304: 0004 0x4
80000306: ffff 0xffff
80000274 <test14_data>:
80000274: 0005 c.nop 1
80000276: ffff 0xffff
80000278: 0000 unimp
80000308 <test14_data>:
80000308: 0005 c.nop 1
8000030a: ffff 0xffff
...

View File

@ -3,7 +3,7 @@
:1000100013000000537110001300000013000000D3
:1000200013000000130000006F00800113000000A7
:100030001300000013000000130000001300000074
:10004000130E20009700000083A0C01F5371100002
:10004000130E20009700000083A0002953711000B8
:100050001300000013000000130000001300000054
:100060006F000002130000001300000013000000E6
:100070001300000013000000130000001300000034
@ -12,31 +12,41 @@
:1000A0001300000013000000130000001300000004
:1000B00013000000130000001300000013000000F4
:1000C000130E400013000000130000001300000096
:1000D00013000000970000009380C01607A10000E5
:1000D00013000000970000009380002007A100009B
:1000E00013000000130000001300000013000000C4
:1000F0006F00000113000000130000001300000057
:10010000130E500013000000130000001300000045
:1001100013000000970000009380C0121701000038
:100120001301811287A0000007210100D3F12000F4
:1001100013000000970000009380001C17010000EE
:100120001301C11B87A0000007210100D3F12000AB
:100130001300000013000000130000001300000073
:100140006F00000413000000130000001300000003
:100150001300000013000000130000001300000053
:100160001300000013000000130000001300000043
:100170001300000013000000130000001300000033
:10018000130E6000130000001300000013000000B5
:1001900013000000970000009380400B27A0300060
:1001900013000000970000009380801427A0300017
:1001A0001300000013000000130000001300000003
:1001B0006F00000113000000130000001300000096
:1001C000130E700097000000938040081701000094
:1001D00013010108970100009381C1071702000075
:1001E0001302820707A2000053724200D3F24000BC
:1001C000130E70009700000093808011170100004B
:1001D00013014111970100009381011117020000E2
:1001E0001302C21007A2000053724200D3F2400073
:1001F0002720410027A051002720120013000000F3
:100200001300000013000000130000006F00000145
:10021000370110F0130141F22320C101370110F022
:10022000130101F22320010013000000130000005D
:100200001300000013000000130000006F00400303
:100210001300000013000000130000001300000092
:100220001300000013000000130000001300000082
:100230001300000013000000130000001300000072
:100240000000C03F0000A040490000003A0000004C
:10025000380000004B000000380000005300000090
:1002600021000000BFFFFFFFA9FFFFFFC9FFFFFF45
:0C0270000400FFFF0500FFFF000000007D
:10024000130E8000D3F011C0130000001300000053
:1002500013000000130000006F0080021300000074
:100260001300000013000000130000001300000042
:100270001300000013000000130000001300000032
:10028000130E9000D30031A0538121A0D38131A05F
:100290001300000013000000130000001300000012
:1002A0006F000001370110F0130141F22320C1015A
:1002B000370110F0130101F22320010013000000A8
:1002C00013000000130000001300000013000000E2
:1002D000130000000000C03F0000A04049000000E3
:1002E0003A000000380000004B0000003800000019
:1002F0005300000021000000BFFFFFFFA9FFFFFF28
:10030000C9FFFFFF0400FFFF0500FFFF0000000022
:080310000000000000000000E5
:00000001FF

View File

@ -100,7 +100,6 @@ test6:
.align 6
test7:
li TEST_ID, 7
la x1, test3_data
la x2, test4_data
la x3, test5_data
@ -115,6 +114,28 @@ test7:
nop
nop
nop
j test8
.align 6
test8:
li TEST_ID, 8
fcvt.wu.s x1, f3
nop
nop
nop
nop
j test9
.align 6
test9:
li TEST_ID, 9
fle.s x1, f2, f3
fle.s x2, f3, f2
fle.s x3, f3, f3
nop
nop
nop
nop
/* la x1, test1_data
li x2, 45

View File

@ -167,6 +167,31 @@ class FpuTest extends FunSuite{
cmd.load #= false
}
}
def cmp(rs1 : Int, rs2 : Int)(body : FpuRsp => Unit): Unit ={
cmdQueue += {cmd =>
cmd.opcode #= cmd.opcode.spinalEnum.CMP
cmd.value.randomize()
cmd.rs1 #= rs1
cmd.rs2 #= rs2
cmd.rs3.randomize()
cmd.rd.randomize()
}
rspQueue += body
}
def f2i(rs1 : Int)(body : FpuRsp => Unit): Unit ={
cmdQueue += {cmd =>
cmd.opcode #= cmd.opcode.spinalEnum.F2I
cmd.value.randomize()
cmd.rs1 #= rs1
cmd.rs2.randomize()
cmd.rs3.randomize()
cmd.rd.randomize()
}
rspQueue += body
}
}
@ -243,7 +268,8 @@ class FpuTest extends FunSuite{
storeFloat(rd){v =>
val ref = a.toDouble * b.toDouble + c.toDouble
println(f"$a%.20f * $b%.20f + $c%.20f = $v%.20f, $ref%.20f")
assert(checkFloat(ref.toFloat, v))
val mul = a.toDouble * b.toDouble
if((mul.abs-c.abs)/mul.abs > 0.1) assert(checkFloat(ref.toFloat, v))
}
}
@ -279,8 +305,54 @@ class FpuTest extends FunSuite{
}
}
def testF2i(a : Float): Unit ={
val rs = new RegAllocator()
val rs1, rs2, rs3 = rs.allocate()
val rd = Random.nextInt(32)
load(rs1, a)
f2i(rs1){rsp =>
val ref = a.toInt
val v = rsp.value.toBigInt
println(f"f2i($a) = $v, $ref")
assert(v === ref)
}
}
def testCmp(a : Float, b : Float): Unit ={
val rs = new RegAllocator()
val rs1, rs2, rs3 = rs.allocate()
val rd = Random.nextInt(32)
load(rs1, a)
load(rs2, b)
cmp(rs1, rs2){rsp =>
val ref = if(a < b) 1 else 0
val v = rsp.value.toBigInt
println(f"$a < $b = $v, $ref")
assert(v === ref)
}
}
val b2f = lang.Float.intBitsToFloat(_)
//TODO Test corner cases
testCmp(1.0f, 2.0f)
testCmp(1.5f, 2.0f)
testCmp(1.5f, 3.5f)
testCmp(1.5f, 1.5f)
testCmp(1.5f, -1.5f)
testCmp(-1.5f, 1.5f)
testCmp(-1.5f, -1.5f)
testCmp(1.5f, -3.5f)
//TODO Test corner cases
testF2i(16.0f)
testF2i(18.0f)
testF2i(1200.0f)
testF2i(1.0f)
// dut.clockDomain.waitSampling(1000)
// simFailure()
testAdd(0.1f, 1.6f)
testSqrt(1.5625f)
@ -296,8 +368,7 @@ class FpuTest extends FunSuite{
testSqrt(b2f(0x3f800002))
testSqrt(b2f(0x3f800003))
// dut.clockDomain.waitSampling(1000)
// simFailure()
testMul(0.1f, 1.6f)
testFma(1.1f, 2.2f, 3.0f)
@ -324,7 +395,10 @@ class FpuTest extends FunSuite{
testDiv(randomFloat(), randomFloat())
}
for(i <- 0 until 1000){
testSqrt(Math.abs(randomFloat())) //TODO
testSqrt(Math.abs(randomFloat()))
}
for(i <- 0 until 1000){
testCmp(randomFloat(), randomFloat())
}
for(i <- 0 until 1000){
val tests = ArrayBuffer[() => Unit]()
@ -333,6 +407,7 @@ class FpuTest extends FunSuite{
tests += (() =>{testFma(randomFloat(), randomFloat(), randomFloat())})
tests += (() =>{testDiv(randomFloat(), randomFloat())})
tests += (() =>{testSqrt(randomFloat().abs)})
tests += (() =>{testCmp(randomFloat(), randomFloat())})
tests.randomPick().apply()
}
waitUntil(cpu.rspQueue.isEmpty)