fpu add signed i2f/f2i

This commit is contained in:
Dolu1990 2021-01-20 13:15:29 +01:00
parent 15d79ef330
commit ac5844f393
2 changed files with 39 additions and 23 deletions

View File

@ -307,10 +307,13 @@ case class FpuCore( portCount : Int, p : FpuParameter) extends Component{
val f2iShift = input.rs1.exponent - U(exponentOne) val f2iShift = input.rs1.exponent - U(exponentOne)
val f2iShifted = (U"1" @@ input.rs1.mantissa) << (f2iShift.resize(5 bits)) val f2iShifted = (U"1" @@ input.rs1.mantissa) << (f2iShift.resize(5 bits))
val f2iResult = f2iShifted.asBits >> p.internalMantissaSize val f2iUnsigned = f2iShifted >> p.internalMantissaSize
val f2iResult = (f2iUnsigned.twoComplement(input.arg(0) && input.rs1.sign)).asBits.resize(32 bits)
val i2fLog2 = OHToUInt(OHMasking.last(input.value)) val i2fSign = input.arg(0) && input.value.msb
val i2fShifted = (input.value << p.internalMantissaSize) >> i2fLog2 val i2fUnsigned = input.value.asUInt.twoComplement(i2fSign).resize(32 bits)
val i2fLog2 = OHToUInt(OHMasking.last(i2fUnsigned))
val i2fShifted = (i2fUnsigned << p.internalMantissaSize) >> i2fLog2
val rs1Equal = input.rs1 === input.rs2 val rs1Equal = input.rs1 === input.rs2
val rs1AbsSmaller = (input.rs1.exponent @@ input.rs1.mantissa) < (input.rs2.exponent @@ input.rs2.mantissa) val rs1AbsSmaller = (input.rs1.exponent @@ input.rs1.mantissa) < (input.rs2.exponent @@ input.rs2.mantissa)
@ -355,7 +358,7 @@ case class FpuCore( portCount : Int, p : FpuParameter) extends Component{
rfOutput.value.assignDontCare() rfOutput.value.assignDontCare()
switch(input.opcode){ switch(input.opcode){
is(FpuOpcode.I2F){ is(FpuOpcode.I2F){
rfOutput.value.sign := False rfOutput.value.sign := i2fSign
rfOutput.value.exponent := i2fLog2 +^ exponentOne rfOutput.value.exponent := i2fLog2 +^ exponentOne
rfOutput.value.mantissa := U(i2fShifted).resized rfOutput.value.mantissa := U(i2fShifted).resized
} }

View File

@ -16,7 +16,7 @@ class FpuTest extends FunSuite{
test("directed"){ test("directed"){
val portCount = 4 val portCount = 1
val p = FpuParameter( val p = FpuParameter(
internalMantissaSize = 23, internalMantissaSize = 23,
withDouble = false withDouble = false
@ -189,7 +189,7 @@ class FpuTest extends FunSuite{
rspQueue += body rspQueue += body
} }
def f2i(rs1 : Int)(body : FpuRsp => Unit): Unit ={ def f2i(rs1 : Int, signed : Boolean)(body : FpuRsp => Unit): Unit ={
cmdQueue += {cmd => cmdQueue += {cmd =>
cmd.opcode #= cmd.opcode.spinalEnum.F2I cmd.opcode #= cmd.opcode.spinalEnum.F2I
cmd.value.randomize() cmd.value.randomize()
@ -197,20 +197,20 @@ 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() cmd.arg #= (if(signed) 1 else 0)
} }
rspQueue += body rspQueue += body
} }
def i2f(rd : Int, value : Int): Unit ={ def i2f(rd : Int, value : Int, signed : Boolean): Unit ={
cmdQueue += {cmd => cmdQueue += {cmd =>
cmd.opcode #= cmd.opcode.spinalEnum.I2F cmd.opcode #= cmd.opcode.spinalEnum.I2F
cmd.value #= value cmd.value #= value.toLong & 0xFFFFFFFFl
cmd.rs1.randomize() cmd.rs1.randomize()
cmd.rs2.randomize() cmd.rs2.randomize()
cmd.rs3.randomize() cmd.rs3.randomize()
cmd.rd #= rd cmd.rd #= rd
cmd.arg.randomize() cmd.arg #= (if(signed) 1 else 0)
} }
commitQueue += {cmd => commitQueue += {cmd =>
cmd.write #= true cmd.write #= true
@ -392,23 +392,23 @@ class FpuTest extends FunSuite{
} }
} }
def testF2i(a : Float): Unit ={ def testF2i(a : Float, signed : Boolean): Unit ={
val rs = new RegAllocator() val rs = new RegAllocator()
val rs1, rs2, rs3 = rs.allocate() val rs1, rs2, rs3 = rs.allocate()
val rd = Random.nextInt(32) val rd = Random.nextInt(32)
load(rs1, a) load(rs1, a)
f2i(rs1){rsp => f2i(rs1, signed){rsp =>
val ref = a.toInt val ref = a.toInt
val v = rsp.value.toBigInt val v = (rsp.value.toBigInt & 0xFFFFFFFF).toInt
println(f"f2i($a) = $v, $ref") println(f"f2i($a) = $v, $ref")
assert(v === ref) assert(v === ref)
} }
} }
def testI2f(a : Int): Unit ={ def testI2f(a : Int, signed : Boolean): Unit ={
val rs = new RegAllocator() val rs = new RegAllocator()
val rd = Random.nextInt(32) val rd = Random.nextInt(32)
i2f(rd, a) i2f(rd, a, signed)
storeFloat(rd){v => storeFloat(rd){v =>
val ref = a.toInt val ref = a.toInt
println(f"i2f($a) = $v, $ref") println(f"i2f($a) = $v, $ref")
@ -515,10 +515,17 @@ class FpuTest extends FunSuite{
//TODO Test corner cases //TODO Test corner cases
testI2f(17) for(signed <- List(false, true)) {
testI2f(12) testI2f(17, signed)
testI2f(512) testI2f(12, signed)
testI2f(1) testI2f(512, signed)
testI2f(1, signed)
}
testI2f(-17, true)
testI2f(-12, true)
testI2f(-512, true)
testI2f(-1, true)
// dut.clockDomain.waitSampling(1000) // dut.clockDomain.waitSampling(1000)
// simFailure() // simFailure()
@ -533,11 +540,17 @@ class FpuTest extends FunSuite{
testCmp(1.5f, -3.5f) testCmp(1.5f, -3.5f)
//TODO Test corner cases //TODO Test corner cases
testF2i(16.0f) for(signed <- List(false, true)) {
testF2i(18.0f) testF2i(16.0f, signed)
testF2i(1200.0f) testF2i(18.0f, signed)
testF2i(1.0f) testF2i(1200.0f, signed)
testF2i(1.0f, signed)
}
testF2i(-16.0f, true)
testF2i(-18.0f, true)
testF2i(-1200.0f, true)
testF2i(-1.0f, true)
testAdd(0.1f, 1.6f) testAdd(0.1f, 1.6f)