From bdb5bc118051860ac8e1fed6a485205f5eb8e86c Mon Sep 17 00:00:00 2001 From: Dolu1990 Date: Fri, 22 Jan 2021 20:47:31 +0100 Subject: [PATCH] fpu div implement some special values handeling --- src/main/scala/vexriscv/ip/fpu/FpuCore.scala | 55 ++++++++++++++++---- src/test/scala/vexriscv/ip/fpu/FpuTest.scala | 12 ++++- 2 files changed, 57 insertions(+), 10 deletions(-) diff --git a/src/main/scala/vexriscv/ip/fpu/FpuCore.scala b/src/main/scala/vexriscv/ip/fpu/FpuCore.scala index 606f8fc..33a792e 100644 --- a/src/main/scala/vexriscv/ip/fpu/FpuCore.scala +++ b/src/main/scala/vexriscv/ip/fpu/FpuCore.scala @@ -643,6 +643,14 @@ case class FpuCore( portCount : Int, p : FpuParameter) extends Component{ decode.divSqrtToMul.rs2.sign := input.rs2.sign decode.divSqrtToMul.rs2.exponent := divExp.value + iterationValue.msb.asUInt decode.divSqrtToMul.rs2.mantissa := (iterationValue << 1).resized + val overflow = input.rs2.isZeroOrSubnormal + val nan = input.rs2.isNan || (input.rs1.isZeroOrSubnormal && input.rs2.isZeroOrSubnormal) + + when(nan){ + decode.divSqrtToMul.rs2.setNanQuiet + } elsewhen(overflow) { + decode.divSqrtToMul.rs2.setInfinity + } when(decode.divSqrtToMul.ready) { state := IDLE input.ready := True @@ -806,17 +814,37 @@ object FpuSynthesisBench extends App{ }) } + class Shifter(width : Int) extends Rtl{ + override def getName(): String = "shifter_" + width + override def getRtlPath(): String = getName() + ".v" + SpinalVerilog(new Component{ + val a = in UInt(width bits) + val sel = in UInt(log2Up(width) bits) + val result = out(a >> sel) + setDefinitionName(Shifter.this.getName()) + }) + } + class Rotate(width : Int) extends Rtl{ + override def getName(): String = "rotate_" + width + override def getRtlPath(): String = getName() + ".v" + SpinalVerilog(new Component{ + val a = in UInt(width bits) + val sel = in UInt(log2Up(width) bits) + val result = out(a.rotateLeft(sel)) + setDefinitionName(Rotate.this.getName()) + }) + } - val rtls = ArrayBuffer[Fpu]() - rtls += new Fpu( - "32", - portCount = 1, - FpuParameter( - internalMantissaSize = 23, - withDouble = false - ) - ) + val rtls = ArrayBuffer[Rtl]() +// rtls += new Fpu( +// "32", +// portCount = 1, +// FpuParameter( +// internalMantissaSize = 23, +// withDouble = false +// ) +// ) // rtls += new Fpu( // "64", // portCount = 1, @@ -826,6 +854,15 @@ object FpuSynthesisBench extends App{ // ) // ) +// rtls += new Shifter(24) +// rtls += new Shifter(32) +// rtls += new Shifter(52) +// rtls += new Shifter(64) + rtls += new Rotate(24) + rtls += new Rotate(32) + rtls += new Rotate(52) + rtls += new Rotate(64) + val targets = XilinxStdTargets()// ++ AlteraStdTargets() diff --git a/src/test/scala/vexriscv/ip/fpu/FpuTest.scala b/src/test/scala/vexriscv/ip/fpu/FpuTest.scala index b30b411..17dafff 100644 --- a/src/test/scala/vexriscv/ip/fpu/FpuTest.scala +++ b/src/test/scala/vexriscv/ip/fpu/FpuTest.scala @@ -393,7 +393,9 @@ class FpuTest extends FunSuite{ div(rd,rs1,rs2) storeFloat(rd){v => - val ref = a/b + val refUnclamped = a/b + val refClamped = clamp(clamp(a)/clamp(b)) + val ref = refClamped val error = Math.abs(ref-v)/ref println(f"$a / $b = $v, $ref $error") assert(checkFloat(ref, v)) @@ -522,6 +524,14 @@ class FpuTest extends FunSuite{ val fAll = fZeros ++ fSubnormals ++ fExpSmall ++ fExpNormal ++ fExpBig ++ fInfinity ++ fNan +// testDiv(0.0f, 1.2f ) +// testDiv(1.2f, 0.0f ) +// testDiv(0.0f, 0.0f ) +// for(a <- fAll; _ <- 0 until 50) testDiv(a, randomFloat()) +// for(a <- fAll; b <- fAll) testDiv(a, b) +// for(_ <- 0 until 1000) testDiv(randomFloat(), randomFloat()) + + testMul(1.2f, 0f) for(a <- fAll; _ <- 0 until 50) testMul(a, randomFloat())