fpu implement fclass and args for sub, fma, max, fcmp, fsgnj

This commit is contained in:
Dolu1990 2021-01-20 12:01:08 +01:00
parent 11349a71fa
commit 15d79ef330
4 changed files with 70 additions and 15 deletions

View File

@ -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 {

View File

@ -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{

View File

@ -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)),

View File

@ -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