diff --git a/src/main/scala/vexriscv/ip/fpu/FpuCore.scala b/src/main/scala/vexriscv/ip/fpu/FpuCore.scala index 047eaa3..b4cf6bb 100644 --- a/src/main/scala/vexriscv/ip/fpu/FpuCore.scala +++ b/src/main/scala/vexriscv/ip/fpu/FpuCore.scala @@ -28,6 +28,7 @@ case class FpuCore( portCount : Int, p : FpuParameter) extends Component{ val rs1, rs2, rs3 = p.rfAddress() val rd = p.rfAddress() val value = Bits(32 bits) + val arg = p.Arg() } case class RfReadOutput() extends Bundle{ @@ -37,6 +38,7 @@ case class FpuCore( portCount : Int, p : FpuParameter) extends Component{ val rs1, rs2, rs3 = p.internalFloating() val rd = p.rfAddress() val value = Bits(32 bits) + val arg = p.Arg() } @@ -54,6 +56,7 @@ case class FpuCore( portCount : Int, p : FpuParameter) extends Component{ val lockId = lockIdType() val rd = p.rfAddress() val value = Bits(32 bits) + val arg = Bits(2 bits) } case class MulInput() extends Bundle{ @@ -64,7 +67,6 @@ case class FpuCore( portCount : Int, p : FpuParameter) extends Component{ val add = Bool() val divSqrt = Bool() val msb1, msb2 = Bool() //allow usage of msb bits of mul - val minus = Bool() } @@ -215,6 +217,7 @@ case class FpuCore( portCount : Int, p : FpuParameter) extends Component{ output.opcode := s1.opcode output.lockId := s1LockId output.value := s1.value + output.arg := s1.arg output.rd := s1.rd output.rs1 := rf.ram.readSync(s0.source @@ s0.rs1,enable = !output.isStall) output.rs2 := rf.ram.readSync(s0.source @@ s0.rs2,enable = !output.isStall) @@ -260,7 +263,8 @@ case class FpuCore( portCount : Int, p : FpuParameter) extends Component{ mul.divSqrt := False mul.msb1 := True mul.msb2 := True - mul.minus := False //TODO + mul.rs2.sign.allowOverride(); mul.rs2.sign := read.output.rs2.sign ^ input.arg(0) + mul.rs3.sign.allowOverride(); mul.rs3.sign := read.output.rs3.sign ^ input.arg(1) } val addHit = input.opcode === p.Opcode.ADD @@ -275,6 +279,7 @@ case class FpuCore( portCount : Int, p : FpuParameter) extends Component{ add.payload := mulToAdd.payload when(!mulToAdd.valid) { add.payload.assignSomeByName(read.output.payload) + add.rs2.sign.allowOverride; add.rs2.sign := read.output.rs2.sign ^ input.arg(0) } } @@ -316,9 +321,22 @@ case class FpuCore( portCount : Int, p : FpuParameter) extends Component{ 3 -> (!rs1AbsSmaller && !rs1Equal) ) - val minMaxResult = rs1Smaller ? input.rs1 | input.rs2 - val cmpResult = B(rs1Smaller) - val fclassResult = B(0) //TODO + val minMaxResult = (rs1Smaller ^ input.arg(0)) ? input.rs1 | input.rs2 + val cmpResult = B(rs1Smaller && !input.arg(1) || rs1Equal && !input.arg(0)) + val sgnjResult = (input.rs1.sign && input.arg(1)) ^ input.rs2.sign ^ input.arg(0) + val fclassResult = B(0, 32 bits) + val decoded = input.rs1.decode() + fclassResult(0) := input.rs1.sign && decoded.isInfinity + fclassResult(1) := input.rs1.sign && decoded.isNormal + fclassResult(2) := input.rs1.sign && decoded.isSubnormal + fclassResult(3) := input.rs1.sign && decoded.isZero + fclassResult(4) := !input.rs1.sign && decoded.isZero + fclassResult(5) := !input.rs1.sign && decoded.isSubnormal + fclassResult(6) := !input.rs1.sign && decoded.isNormal + fclassResult(7) := !input.rs1.sign && decoded.isInfinity + fclassResult(8) := decoded.isNan && !decoded.isQuiet + fclassResult(9) := decoded.isNan && decoded.isQuiet + switch(input.opcode){ is(FpuOpcode.STORE) { result := storeResult } @@ -345,7 +363,7 @@ case class FpuCore( portCount : Int, p : FpuParameter) extends Component{ rfOutput.value := minMaxResult } is(FpuOpcode.SGNJ){ - rfOutput.value.sign := input.rs2.sign + rfOutput.value.sign := sgnjResult rfOutput.value.exponent := input.rs1.exponent rfOutput.value.mantissa := input.rs1.mantissa } @@ -401,7 +419,7 @@ case class FpuCore( portCount : Int, p : FpuParameter) extends Component{ decode.mulToAdd.source := input.source decode.mulToAdd.rs1.mantissa := norm.output.mantissa decode.mulToAdd.rs1.exponent := norm.output.exponent - decode.mulToAdd.rs1.sign := norm.output.sign ^ input.minus + decode.mulToAdd.rs1.sign := norm.output.sign decode.mulToAdd.rs2 := input.rs3 decode.mulToAdd.rd := input.rd decode.mulToAdd.lockId := input.lockId @@ -434,7 +452,6 @@ case class FpuCore( portCount : Int, p : FpuParameter) extends Component{ decode.divSqrtToMul.divSqrt := True decode.divSqrtToMul.msb1 := True decode.divSqrtToMul.msb2 := True - decode.divSqrtToMul.minus := False val aprox = new Area { diff --git a/src/main/scala/vexriscv/ip/fpu/Interface.scala b/src/main/scala/vexriscv/ip/fpu/Interface.scala index 1a0405d..7b4c9cf 100644 --- a/src/main/scala/vexriscv/ip/fpu/Interface.scala +++ b/src/main/scala/vexriscv/ip/fpu/Interface.scala @@ -14,7 +14,14 @@ object Fpu{ } - +case class FpuFloatDecoded() extends Bundle{ + val isNan = Bool() + val isNormal = Bool() + val isSubnormal = Bool() + val isZero = Bool() + val isInfinity = Bool() + val isQuiet = Bool() +} case class FpuFloat(exponentSize: Int, mantissaSize: Int) extends Bundle { val mantissa = UInt(mantissaSize bits) @@ -28,6 +35,21 @@ case class FpuFloat(exponentSize: Int, ret.mantissa := mantissa ret } + + + def decode() = { + val ret = FpuFloatDecoded() + val expZero = exponent === 0 + val expOne = exponent === exponent.maxValue + val manZero = mantissa === 0 + ret.isZero := expZero && manZero + ret.isSubnormal := expZero && !manZero + ret.isNormal := !expOne && !expZero + ret.isInfinity := expOne && manZero + ret.isNan := expOne && !manZero// && !sign + ret.isQuiet := mantissa.msb + ret + } } object FpuOpcode extends SpinalEnum{ @@ -50,6 +72,8 @@ case class FpuParameter( internalMantissaSize : Int, val Opcode = FpuOpcode val Format = FpuFormat + val argWidth = 2 + val Arg = HardType(Bits(2 bits)) } case class FpuFlags() extends Bundle{ diff --git a/src/main/scala/vexriscv/plugin/FpuPlugin.scala b/src/main/scala/vexriscv/plugin/FpuPlugin.scala index b19fa82..082ddd2 100644 --- a/src/main/scala/vexriscv/plugin/FpuPlugin.scala +++ b/src/main/scala/vexriscv/plugin/FpuPlugin.scala @@ -80,10 +80,10 @@ class FpuPlugin(externalFpu : Boolean = false, FADD_S -> (addSub :+ arg(0)), FSUB_S -> (addSub :+ arg(1)), FMADD_S -> (fma :+ arg(0)), - FMSUB_S -> (fma :+ arg(1)), - FNMSUB_S -> (fma :+ arg(2)), - FNMADD_S -> (fma :+ arg(3)), - FMUL_S -> (mul), + FMSUB_S -> (fma :+ arg(2)), + FNMADD_S -> (fma :+ arg(1)), + FNMSUB_S -> (fma :+ arg(3)), + FMUL_S -> (mul :+ arg(0)), FDIV_S -> (div), FSQRT_S -> (sqrt), FLW -> (fl), @@ -94,8 +94,8 @@ class FpuPlugin(externalFpu : Boolean = false, FCVT_W_S -> (fcvtF2i :+ arg(1)), FCLASS_S -> (fclass), FLE_S -> (fcmp :+ arg(0)), - FEQ_S -> (fcmp :+ arg(1)), - FLT_S -> (fcmp :+ arg(2)), + FEQ_S -> (fcmp :+ arg(2)), + FLT_S -> (fcmp :+ arg(1)), FSGNJ_S -> (fsgnj :+ arg(0)), FSGNJN_S -> (fsgnj :+ arg(1)), FSGNJX_S -> (fsgnj :+ arg(2)), diff --git a/src/test/scala/vexriscv/ip/fpu/FpuTest.scala b/src/test/scala/vexriscv/ip/fpu/FpuTest.scala index 59b3fc9..8d96a37 100644 --- a/src/test/scala/vexriscv/ip/fpu/FpuTest.scala +++ b/src/test/scala/vexriscv/ip/fpu/FpuTest.scala @@ -64,6 +64,7 @@ class FpuTest extends FunSuite{ cmd.rs2.randomize() cmd.rs3.randomize() cmd.rd #= rd + cmd.arg.randomize() } commitQueue += {cmd => cmd.write #= true @@ -84,6 +85,7 @@ class FpuTest extends FunSuite{ cmd.rs2 #= rs cmd.rs3.randomize() cmd.rd.randomize() + cmd.arg.randomize() } rspQueue += body @@ -101,6 +103,7 @@ class FpuTest extends FunSuite{ cmd.rs2 #= rs2 cmd.rs3.randomize() cmd.rd #= rd + cmd.arg #= 0 } commitQueue += {cmd => cmd.write #= true @@ -116,6 +119,7 @@ class FpuTest extends FunSuite{ cmd.rs2 #= rs2 cmd.rs3.randomize() cmd.rd #= rd + cmd.arg #= 0 } commitQueue += {cmd => cmd.write #= true @@ -131,6 +135,7 @@ class FpuTest extends FunSuite{ cmd.rs2 #= rs2 cmd.rs3.randomize() cmd.rd #= rd + cmd.arg.randomize() } commitQueue += {cmd => cmd.write #= true @@ -146,6 +151,7 @@ class FpuTest extends FunSuite{ cmd.rs2.randomize() cmd.rs3.randomize() cmd.rd #= rd + cmd.arg.randomize() } commitQueue += {cmd => cmd.write #= true @@ -161,6 +167,7 @@ class FpuTest extends FunSuite{ cmd.rs2 #= rs2 cmd.rs3 #= rs3 cmd.rd #= rd + cmd.arg #= 0 } commitQueue += {cmd => cmd.write #= true @@ -177,6 +184,7 @@ class FpuTest extends FunSuite{ cmd.rs2 #= rs2 cmd.rs3.randomize() cmd.rd.randomize() + cmd.arg #= 1 } rspQueue += body } @@ -189,6 +197,7 @@ class FpuTest extends FunSuite{ cmd.rs2.randomize() cmd.rs3.randomize() cmd.rd.randomize() + cmd.arg.randomize() } rspQueue += body } @@ -201,6 +210,7 @@ class FpuTest extends FunSuite{ cmd.rs2.randomize() cmd.rs3.randomize() cmd.rd #= rd + cmd.arg.randomize() } commitQueue += {cmd => cmd.write #= true @@ -216,6 +226,7 @@ class FpuTest extends FunSuite{ cmd.rs2.randomize() cmd.rs3.randomize() cmd.rd.randomize() + cmd.arg #= 0 } rspQueue += body } @@ -228,6 +239,7 @@ class FpuTest extends FunSuite{ cmd.rs2.randomize() cmd.rs3.randomize() cmd.rd #= rd + cmd.arg #= 0 } commitQueue += {cmd => cmd.write #= true @@ -243,6 +255,7 @@ class FpuTest extends FunSuite{ cmd.rs2 #= rs2 cmd.rs3.randomize() cmd.rd #= rd + cmd.arg #= 0 } commitQueue += {cmd => cmd.write #= true @@ -259,6 +272,7 @@ class FpuTest extends FunSuite{ cmd.rs2 #= rs2 cmd.rs3.randomize() cmd.rd #= rd + cmd.arg #= 0 } commitQueue += {cmd => cmd.write #= true