blob: 7f639e4b875d68787bf2e37bca99e736820ced8a [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.experimental.BundleLiterals._
import chisel3.util._
import common.Fp32
import common.Fma
import common.FmaCmd
object FpuOptype extends ChiselEnum {
val FpuAdd = Value
val FpuSub = Value
val FpuMul = Value
val FpuFma = Value
val FpuFms = Value
val FpuFnma = Value
val FpuFnms = Value
}
class FpuCmd extends Bundle {
val optype = FpuOptype()
val ina = new Fp32
val inb = new Fp32
val inc = new Fp32
val waddr = UInt(5.W)
}
object FpuCmd {
def ToFmaCmd(fpuCmd: FpuCmd): WithAddr[FmaCmd] = {
val invert_ab = (fpuCmd.optype === FpuOptype.FpuFnma) ||
(fpuCmd.optype === FpuOptype.FpuFnms)
val invert_c = (fpuCmd.optype === FpuOptype.FpuSub) ||
(fpuCmd.optype === FpuOptype.FpuFms) ||
(fpuCmd.optype === FpuOptype.FpuFnms)
val fmaCmd = Wire(WithAddr(5, new FmaCmd))
fmaCmd.bits.ina := Mux(invert_ab, fpuCmd.ina.negate(), fpuCmd.ina)
fmaCmd.bits.inb := Mux((fpuCmd.optype === FpuOptype.FpuAdd) ||
(fpuCmd.optype === FpuOptype.FpuSub),
Fp32(false.B, 127.U(8.W), 0.U(23.W)),
fpuCmd.inb)
fmaCmd.bits.inc := Mux((fpuCmd.optype === FpuOptype.FpuMul),
Fp32.fromWord(0.U(32.W)),
Mux(invert_c, fpuCmd.inc.negate(), fpuCmd.inc))
fmaCmd.addr := fpuCmd.waddr
fmaCmd
}
}
class Fpu extends Module {
val io = IO(new Bundle {
val cmd = Flipped(Decoupled(new FpuCmd))
val output = Decoupled(WithAddr(5, new Fp32))
})
val fmaCmd = io.cmd.map(FpuCmd.ToFmaCmd)
val state1 = fmaCmd.map(LiftAddr(5, Fma.FmaStage1))
val state2 = Queue(state1, 1, true).map(LiftAddr(5, Fma.FmaStage2))
io.output <> Queue(state2, 1, true).map(LiftAddr(5, Fma.FmaStage3))
}