diff --git a/src/main/scala/vexriscv/Riscv.scala b/src/main/scala/vexriscv/Riscv.scala index ae64bff..df49682 100644 --- a/src/main/scala/vexriscv/Riscv.scala +++ b/src/main/scala/vexriscv/Riscv.scala @@ -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. diff --git a/src/main/scala/vexriscv/ip/fpu/FpuCore.scala b/src/main/scala/vexriscv/ip/fpu/FpuCore.scala index d7ffddf..5d31fe9 100644 --- a/src/main/scala/vexriscv/ip/fpu/FpuCore.scala +++ b/src/main/scala/vexriscv/ip/fpu/FpuCore.scala @@ -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 } } diff --git a/src/main/scala/vexriscv/ip/fpu/Interface.scala b/src/main/scala/vexriscv/ip/fpu/Interface.scala index 27f3482..0719bff 100644 --- a/src/main/scala/vexriscv/ip/fpu/Interface.scala +++ b/src/main/scala/vexriscv/ip/fpu/Interface.scala @@ -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{ diff --git a/src/main/scala/vexriscv/plugin/FpuPlugin.scala b/src/main/scala/vexriscv/plugin/FpuPlugin.scala index 635d1ec..e61d224 100644 --- a/src/main/scala/vexriscv/plugin/FpuPlugin.scala +++ b/src/main/scala/vexriscv/plugin/FpuPlugin.scala @@ -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)) } } - - } diff --git a/src/test/cpp/raw/fpu/build/fpu.asm b/src/test/cpp/raw/fpu/build/fpu.asm index 4c0a26f..f65b2ab 100644 --- a/src/test/cpp/raw/fpu/build/fpu.asm +++ b/src/test/cpp/raw/fpu/build/fpu.asm @@ -25,7 +25,7 @@ Disassembly of section .crt_section: 80000040 : 80000040: 00200e13 li t3,2 80000044: 00000097 auipc ra,0x0 -80000048: 1fc0a083 lw ra,508(ra) # 80000240 +80000048: 2900a083 lw ra,656(ra) # 800002d4 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 +800000d8: 20008093 addi ra,ra,512 # 800002d4 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 +80000118: 1c008093 addi ra,ra,448 # 800002d4 8000011c: 00000117 auipc sp,0x0 -80000120: 12810113 addi sp,sp,296 # 80000244 +80000120: 1bc10113 addi sp,sp,444 # 800002d8 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 +80000198: 14808093 addi ra,ra,328 # 800002dc 8000019c: 0030a027 fsw ft3,0(ra) 800001a0: 00000013 nop 800001a4: 00000013 nop @@ -133,13 +133,13 @@ Disassembly of section .crt_section: 800001c0 : 800001c0: 00700e13 li t3,7 800001c4: 00000097 auipc ra,0x0 -800001c8: 08408093 addi ra,ra,132 # 80000248 +800001c8: 11808093 addi ra,ra,280 # 800002dc 800001cc: 00000117 auipc sp,0x0 -800001d0: 08010113 addi sp,sp,128 # 8000024c +800001d0: 11410113 addi sp,sp,276 # 800002e0 800001d4: 00000197 auipc gp,0x0 -800001d8: 07c18193 addi gp,gp,124 # 80000250 +800001d8: 11018193 addi gp,gp,272 # 800002e4 800001dc: 00000217 auipc tp,0x0 -800001e0: 07820213 addi tp,tp,120 # 80000254 +800001e0: 10c20213 addi tp,tp,268 # 800002e8 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 - -80000210 : -80000210: f0100137 lui sp,0xf0100 -80000214: f2410113 addi sp,sp,-220 # f00fff24 -80000218: 01c12023 sw t3,0(sp) - -8000021c : -8000021c: f0100137 lui sp,0xf0100 -80000220: f2010113 addi sp,sp,-224 # f00fff20 -80000224: 00012023 sw zero,0(sp) +8000020c: 0340006f j 80000240 +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 : -80000240: 0000 unimp -80000242: 3fc0 fld fs0,184(a5) +80000240 : +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 +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 : -80000244: 0000 unimp -80000246: 40a0 lw s0,64(s1) +80000280 : +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 -80000248 : -80000248: 0049 c.nop 18 +800002a4 : +800002a4: f0100137 lui sp,0xf0100 +800002a8: f2410113 addi sp,sp,-220 # f00fff24 +800002ac: 01c12023 sw t3,0(sp) + +800002b0 : +800002b0: f0100137 lui sp,0xf0100 +800002b4: f2010113 addi sp,sp,-224 # f00fff20 +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 : +800002d4: 0000 unimp +800002d6: 3fc0 fld fs0,184(a5) + +800002d8 : +800002d8: 0000 unimp +800002da: 40a0 lw s0,64(s1) + +800002dc : +800002dc: 0049 c.nop 18 ... -8000024c : -8000024c: 003a c.slli zero,0xe +800002e0 : +800002e0: 003a c.slli zero,0xe ... -80000250 : -80000250: 0038 addi a4,sp,8 +800002e4 : +800002e4: 0038 addi a4,sp,8 ... -80000254 : -80000254: 0000004b fnmsub.s ft0,ft0,ft0,ft0,rne +800002e8 : +800002e8: 0000004b fnmsub.s ft0,ft0,ft0,ft0,rne -80000258 : -80000258: 0038 addi a4,sp,8 +800002ec : +800002ec: 0038 addi a4,sp,8 ... -8000025c : -8000025c: 00000053 fadd.s ft0,ft0,ft0,rne +800002f0 : +800002f0: 00000053 fadd.s ft0,ft0,ft0,rne -80000260 : -80000260: 0021 c.nop 8 +800002f4 : +800002f4: 0021 c.nop 8 ... -80000264 : -80000264: ffffffbf 0xffffffbf +800002f8 : +800002f8: ffffffbf 0xffffffbf -80000268 : -80000268: ffa9 bnez a5,800001c2 -8000026a: ffff 0xffff +800002fc : +800002fc: ffa9 bnez a5,80000256 +800002fe: ffff 0xffff -8000026c : -8000026c: ffc9 bnez a5,80000206 -8000026e: ffff 0xffff +80000300 : +80000300: ffc9 bnez a5,8000029a +80000302: ffff 0xffff -80000270 : -80000270: 0004 0x4 -80000272: ffff 0xffff +80000304 : +80000304: 0004 0x4 +80000306: ffff 0xffff -80000274 : -80000274: 0005 c.nop 1 -80000276: ffff 0xffff -80000278: 0000 unimp +80000308 : +80000308: 0005 c.nop 1 +8000030a: ffff 0xffff ... diff --git a/src/test/cpp/raw/fpu/build/fpu.hex b/src/test/cpp/raw/fpu/build/fpu.hex index 58fefe0..a182b0e 100644 --- a/src/test/cpp/raw/fpu/build/fpu.hex +++ b/src/test/cpp/raw/fpu/build/fpu.hex @@ -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 diff --git a/src/test/cpp/raw/fpu/src/crt.S b/src/test/cpp/raw/fpu/src/crt.S index e0ed765..0a3183f 100644 --- a/src/test/cpp/raw/fpu/src/crt.S +++ b/src/test/cpp/raw/fpu/src/crt.S @@ -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 diff --git a/src/test/scala/vexriscv/ip/fpu/FpuTest.scala b/src/test/scala/vexriscv/ip/fpu/FpuTest.scala index 0a2f665..7b3dafb 100644 --- a/src/test/scala/vexriscv/ip/fpu/FpuTest.scala +++ b/src/test/scala/vexriscv/ip/fpu/FpuTest.scala @@ -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)