blob: 6f5419e624abdb25057577b4b97140de7b029b82 [file] [log] [blame]
// Copyright 2024 Google LLC
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
package kelvin
import chisel3._
import chisel3.util._
import chiseltest._
import org.scalatest.freespec.AnyFreeSpec
import chisel3.experimental.BundleLiterals._
import common.Fp32
class FpuSpec extends AnyFreeSpec with ChiselScalatestTester {
def Float2Bits(x: Float): (Boolean, Int, Int) = {
val abs = x.abs
var int = java.lang.Float.floatToIntBits(abs)
val sign: Boolean = (x < 0)
val exponent: Int = int >> 23
val mantissa: Int = int & ((1 << 23) - 1)
(sign, exponent, mantissa)
}
def EnqueueValid(fpu: Fpu, op: FpuOptype.Type, ina: Float, inb: Float, inc: Float, waddr: Int) = {
fpu.io.cmd.valid.poke(1)
fpu.io.cmd.bits.optype.poke(op)
fpu.io.cmd.bits.waddr.poke(waddr)
val ina_bits = Float2Bits(ina)
val inb_bits = Float2Bits(inb)
val inc_bits = Float2Bits(inc)
fpu.io.cmd.bits.ina.sign.poke(ina_bits._1)
fpu.io.cmd.bits.ina.exponent.poke(ina_bits._2)
fpu.io.cmd.bits.ina.mantissa.poke(ina_bits._3)
fpu.io.cmd.bits.inb.sign.poke(inb_bits._1)
fpu.io.cmd.bits.inb.exponent.poke(inb_bits._2)
fpu.io.cmd.bits.inb.mantissa.poke(inb_bits._3)
fpu.io.cmd.bits.inc.sign.poke(inc_bits._1)
fpu.io.cmd.bits.inc.exponent.poke(inc_bits._2)
fpu.io.cmd.bits.inc.mantissa.poke(inc_bits._3)
}
def GetFloat(fpu: Fpu): Float = {
val sign = fpu.io.output.bits.bits.sign.peekInt().toInt
val exponent = fpu.io.output.bits.bits.exponent.peekInt().toInt
val mantissa = fpu.io.output.bits.bits.mantissa.peekInt().toInt
val int_val = (exponent << 23) + mantissa
val negate = if (sign == 1) -1.0f else 1.0f
negate * java.lang.Float.intBitsToFloat(int_val)
}
"Pipeline" in {
test(new Fpu) { dut =>
dut.io.output.ready.poke(1)
EnqueueValid(dut, FpuOptype.FpuAdd, 1.0f, 0.0f, 1.0f, 1)
dut.clock.step()
EnqueueValid(dut, FpuOptype.FpuSub, 1.0f, 0.0f, -1.0f, 2)
dut.clock.step()
assertResult(1) { dut.io.output.valid.peekInt() }
assertResult(1) { dut.io.output.bits.addr.peekInt() }
assertResult(2.0f) { GetFloat(dut) }
EnqueueValid(dut, FpuOptype.FpuMul, 1.0f, 1.0f, 0.0f, 3)
dut.clock.step()
assertResult(1) { dut.io.output.valid.peekInt() }
assertResult(2) { dut.io.output.bits.addr.peekInt() }
assertResult(2.0f) { GetFloat(dut) }
dut.io.cmd.valid.poke(0)
dut.clock.step()
assertResult(1) { dut.io.output.valid.peekInt() }
assertResult(3) { dut.io.output.bits.addr.peekInt() }
assertResult(1.0f) { GetFloat(dut) }
dut.clock.step()
assertResult(0) { dut.io.output.valid.peekInt() }
}
}
}