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 rs1, rs2, rs3 = p.rfAddress()
val rd = p.rfAddress() val rd = p.rfAddress()
val value = Bits(32 bits) val value = Bits(32 bits)
val arg = p.Arg()
} }
case class RfReadOutput() extends Bundle{ 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 rs1, rs2, rs3 = p.internalFloating()
val rd = p.rfAddress() val rd = p.rfAddress()
val value = Bits(32 bits) 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 lockId = lockIdType()
val rd = p.rfAddress() val rd = p.rfAddress()
val value = Bits(32 bits) val value = Bits(32 bits)
val arg = Bits(2 bits)
} }
case class MulInput() extends Bundle{ case class MulInput() extends Bundle{
@ -64,7 +67,6 @@ case class FpuCore( portCount : Int, p : FpuParameter) extends Component{
val add = Bool() val add = Bool()
val divSqrt = Bool() val divSqrt = Bool()
val msb1, msb2 = Bool() //allow usage of msb bits of mul 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.opcode := s1.opcode
output.lockId := s1LockId output.lockId := s1LockId
output.value := s1.value output.value := s1.value
output.arg := s1.arg
output.rd := s1.rd output.rd := s1.rd
output.rs1 := rf.ram.readSync(s0.source @@ s0.rs1,enable = !output.isStall) output.rs1 := rf.ram.readSync(s0.source @@ s0.rs1,enable = !output.isStall)
output.rs2 := rf.ram.readSync(s0.source @@ s0.rs2,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.divSqrt := False
mul.msb1 := True mul.msb1 := True
mul.msb2 := 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 val addHit = input.opcode === p.Opcode.ADD
@ -275,6 +279,7 @@ case class FpuCore( portCount : Int, p : FpuParameter) extends Component{
add.payload := mulToAdd.payload add.payload := mulToAdd.payload
when(!mulToAdd.valid) { when(!mulToAdd.valid) {
add.payload.assignSomeByName(read.output.payload) 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) 3 -> (!rs1AbsSmaller && !rs1Equal)
) )
val minMaxResult = rs1Smaller ? input.rs1 | input.rs2 val minMaxResult = (rs1Smaller ^ input.arg(0)) ? input.rs1 | input.rs2
val cmpResult = B(rs1Smaller) val cmpResult = B(rs1Smaller && !input.arg(1) || rs1Equal && !input.arg(0))
val fclassResult = B(0) //TODO 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){ switch(input.opcode){
is(FpuOpcode.STORE) { result := storeResult } is(FpuOpcode.STORE) { result := storeResult }
@ -345,7 +363,7 @@ case class FpuCore( portCount : Int, p : FpuParameter) extends Component{
rfOutput.value := minMaxResult rfOutput.value := minMaxResult
} }
is(FpuOpcode.SGNJ){ is(FpuOpcode.SGNJ){
rfOutput.value.sign := input.rs2.sign rfOutput.value.sign := sgnjResult
rfOutput.value.exponent := input.rs1.exponent rfOutput.value.exponent := input.rs1.exponent
rfOutput.value.mantissa := input.rs1.mantissa 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.source := input.source
decode.mulToAdd.rs1.mantissa := norm.output.mantissa decode.mulToAdd.rs1.mantissa := norm.output.mantissa
decode.mulToAdd.rs1.exponent := norm.output.exponent 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.rs2 := input.rs3
decode.mulToAdd.rd := input.rd decode.mulToAdd.rd := input.rd
decode.mulToAdd.lockId := input.lockId decode.mulToAdd.lockId := input.lockId
@ -434,7 +452,6 @@ case class FpuCore( portCount : Int, p : FpuParameter) extends Component{
decode.divSqrtToMul.divSqrt := True decode.divSqrtToMul.divSqrt := True
decode.divSqrtToMul.msb1 := True decode.divSqrtToMul.msb1 := True
decode.divSqrtToMul.msb2 := True decode.divSqrtToMul.msb2 := True
decode.divSqrtToMul.minus := False
val aprox = new Area { 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, case class FpuFloat(exponentSize: Int,
mantissaSize: Int) extends Bundle { mantissaSize: Int) extends Bundle {
val mantissa = UInt(mantissaSize bits) val mantissa = UInt(mantissaSize bits)
@ -28,6 +35,21 @@ case class FpuFloat(exponentSize: Int,
ret.mantissa := mantissa ret.mantissa := mantissa
ret 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{ object FpuOpcode extends SpinalEnum{
@ -50,6 +72,8 @@ case class FpuParameter( internalMantissaSize : Int,
val Opcode = FpuOpcode val Opcode = FpuOpcode
val Format = FpuFormat val Format = FpuFormat
val argWidth = 2
val Arg = HardType(Bits(2 bits))
} }
case class FpuFlags() extends Bundle{ case class FpuFlags() extends Bundle{

View File

@ -80,10 +80,10 @@ class FpuPlugin(externalFpu : Boolean = false,
FADD_S -> (addSub :+ arg(0)), FADD_S -> (addSub :+ arg(0)),
FSUB_S -> (addSub :+ arg(1)), FSUB_S -> (addSub :+ arg(1)),
FMADD_S -> (fma :+ arg(0)), FMADD_S -> (fma :+ arg(0)),
FMSUB_S -> (fma :+ arg(1)), FMSUB_S -> (fma :+ arg(2)),
FNMSUB_S -> (fma :+ arg(2)), FNMADD_S -> (fma :+ arg(1)),
FNMADD_S -> (fma :+ arg(3)), FNMSUB_S -> (fma :+ arg(3)),
FMUL_S -> (mul), FMUL_S -> (mul :+ arg(0)),
FDIV_S -> (div), FDIV_S -> (div),
FSQRT_S -> (sqrt), FSQRT_S -> (sqrt),
FLW -> (fl), FLW -> (fl),
@ -94,8 +94,8 @@ class FpuPlugin(externalFpu : Boolean = false,
FCVT_W_S -> (fcvtF2i :+ arg(1)), FCVT_W_S -> (fcvtF2i :+ arg(1)),
FCLASS_S -> (fclass), FCLASS_S -> (fclass),
FLE_S -> (fcmp :+ arg(0)), FLE_S -> (fcmp :+ arg(0)),
FEQ_S -> (fcmp :+ arg(1)), FEQ_S -> (fcmp :+ arg(2)),
FLT_S -> (fcmp :+ arg(2)), FLT_S -> (fcmp :+ arg(1)),
FSGNJ_S -> (fsgnj :+ arg(0)), FSGNJ_S -> (fsgnj :+ arg(0)),
FSGNJN_S -> (fsgnj :+ arg(1)), FSGNJN_S -> (fsgnj :+ arg(1)),
FSGNJX_S -> (fsgnj :+ arg(2)), FSGNJX_S -> (fsgnj :+ arg(2)),

View File

@ -64,6 +64,7 @@ class FpuTest extends FunSuite{
cmd.rs2.randomize() cmd.rs2.randomize()
cmd.rs3.randomize() cmd.rs3.randomize()
cmd.rd #= rd cmd.rd #= rd
cmd.arg.randomize()
} }
commitQueue += {cmd => commitQueue += {cmd =>
cmd.write #= true cmd.write #= true
@ -84,6 +85,7 @@ class FpuTest extends FunSuite{
cmd.rs2 #= rs cmd.rs2 #= rs
cmd.rs3.randomize() cmd.rs3.randomize()
cmd.rd.randomize() cmd.rd.randomize()
cmd.arg.randomize()
} }
rspQueue += body rspQueue += body
@ -101,6 +103,7 @@ class FpuTest extends FunSuite{
cmd.rs2 #= rs2 cmd.rs2 #= rs2
cmd.rs3.randomize() cmd.rs3.randomize()
cmd.rd #= rd cmd.rd #= rd
cmd.arg #= 0
} }
commitQueue += {cmd => commitQueue += {cmd =>
cmd.write #= true cmd.write #= true
@ -116,6 +119,7 @@ class FpuTest extends FunSuite{
cmd.rs2 #= rs2 cmd.rs2 #= rs2
cmd.rs3.randomize() cmd.rs3.randomize()
cmd.rd #= rd cmd.rd #= rd
cmd.arg #= 0
} }
commitQueue += {cmd => commitQueue += {cmd =>
cmd.write #= true cmd.write #= true
@ -131,6 +135,7 @@ class FpuTest extends FunSuite{
cmd.rs2 #= rs2 cmd.rs2 #= rs2
cmd.rs3.randomize() cmd.rs3.randomize()
cmd.rd #= rd cmd.rd #= rd
cmd.arg.randomize()
} }
commitQueue += {cmd => commitQueue += {cmd =>
cmd.write #= true cmd.write #= true
@ -146,6 +151,7 @@ class FpuTest extends FunSuite{
cmd.rs2.randomize() cmd.rs2.randomize()
cmd.rs3.randomize() cmd.rs3.randomize()
cmd.rd #= rd cmd.rd #= rd
cmd.arg.randomize()
} }
commitQueue += {cmd => commitQueue += {cmd =>
cmd.write #= true cmd.write #= true
@ -161,6 +167,7 @@ class FpuTest extends FunSuite{
cmd.rs2 #= rs2 cmd.rs2 #= rs2
cmd.rs3 #= rs3 cmd.rs3 #= rs3
cmd.rd #= rd cmd.rd #= rd
cmd.arg #= 0
} }
commitQueue += {cmd => commitQueue += {cmd =>
cmd.write #= true cmd.write #= true
@ -177,6 +184,7 @@ class FpuTest extends FunSuite{
cmd.rs2 #= rs2 cmd.rs2 #= rs2
cmd.rs3.randomize() cmd.rs3.randomize()
cmd.rd.randomize() cmd.rd.randomize()
cmd.arg #= 1
} }
rspQueue += body rspQueue += body
} }
@ -189,6 +197,7 @@ class FpuTest extends FunSuite{
cmd.rs2.randomize() cmd.rs2.randomize()
cmd.rs3.randomize() cmd.rs3.randomize()
cmd.rd.randomize() cmd.rd.randomize()
cmd.arg.randomize()
} }
rspQueue += body rspQueue += body
} }
@ -201,6 +210,7 @@ class FpuTest extends FunSuite{
cmd.rs2.randomize() cmd.rs2.randomize()
cmd.rs3.randomize() cmd.rs3.randomize()
cmd.rd #= rd cmd.rd #= rd
cmd.arg.randomize()
} }
commitQueue += {cmd => commitQueue += {cmd =>
cmd.write #= true cmd.write #= true
@ -216,6 +226,7 @@ class FpuTest extends FunSuite{
cmd.rs2.randomize() cmd.rs2.randomize()
cmd.rs3.randomize() cmd.rs3.randomize()
cmd.rd.randomize() cmd.rd.randomize()
cmd.arg #= 0
} }
rspQueue += body rspQueue += body
} }
@ -228,6 +239,7 @@ class FpuTest extends FunSuite{
cmd.rs2.randomize() cmd.rs2.randomize()
cmd.rs3.randomize() cmd.rs3.randomize()
cmd.rd #= rd cmd.rd #= rd
cmd.arg #= 0
} }
commitQueue += {cmd => commitQueue += {cmd =>
cmd.write #= true cmd.write #= true
@ -243,6 +255,7 @@ class FpuTest extends FunSuite{
cmd.rs2 #= rs2 cmd.rs2 #= rs2
cmd.rs3.randomize() cmd.rs3.randomize()
cmd.rd #= rd cmd.rd #= rd
cmd.arg #= 0
} }
commitQueue += {cmd => commitQueue += {cmd =>
cmd.write #= true cmd.write #= true
@ -259,6 +272,7 @@ class FpuTest extends FunSuite{
cmd.rs2 #= rs2 cmd.rs2 #= rs2
cmd.rs3.randomize() cmd.rs3.randomize()
cmd.rd #= rd cmd.rd #= rd
cmd.arg #= 0
} }
commitQueue += {cmd => commitQueue += {cmd =>
cmd.write #= true cmd.write #= true