FPUSubModule.scala 1.5 KB
Newer Older
1
package xiangshan.backend.fu.fpu
L
FPUv0.1  
LinJiawei 已提交
2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57

import chisel3._
import chisel3.util._


class FPUSubModuleInput extends Bundle{
  val op = UInt(3.W)
  val isDouble = Bool()
  val a, b, c = UInt(64.W)
  val rm = UInt(3.W)
}

class FPUSubModuleOutput extends Bundle{
  val fflags = new Fflags
  val result = UInt(64.W)
}

class FPUSubModuleIO extends Bundle{
  val in = Flipped(DecoupledIO(new FPUSubModuleInput))
  val out = DecoupledIO(new FPUSubModuleOutput)
}

trait HasPipelineReg { this: FPUSubModule =>
  def latency: Int

  val ready = Wire(Bool())
  val cnt = RegInit(0.U((log2Up(latency)+1).W))

  ready := (cnt < latency.U) || (cnt === latency.U && io.out.ready)
  cnt := cnt + io.in.fire() - io.out.fire()

  val valids = io.in.valid +: Array.fill(latency)(RegInit(false.B))
  for(i <- 1 to latency){
    when(ready){ valids(i) := valids(i-1) }
  }

  def PipelineReg[T<:Data](i: Int)(next: T) = RegEnable(next, enable = valids(i-1) && ready)
  def S1Reg[T<:Data](next: T):T = PipelineReg[T](1)(next)
  def S2Reg[T<:Data](next: T):T = PipelineReg[T](2)(next)
  def S3Reg[T<:Data](next: T):T = PipelineReg[T](3)(next)
  def S4Reg[T<:Data](next: T):T = PipelineReg[T](4)(next)
  def S5Reg[T<:Data](next: T):T = PipelineReg[T](5)(next)

  io.in.ready := ready
  io.out.valid := valids.last
}

trait HasUIntToSIntHelper {
  implicit class UIntToSIntHelper(x: UInt){
    def toSInt: SInt = Cat(0.U(1.W), x).asSInt()
  }
}

abstract class FPUSubModule extends Module with HasUIntToSIntHelper {
  val io = IO(new FPUSubModuleIO)
}