xref: /XiangShan/src/main/scala/xiangshan/backend/fu/FunctionUnit.scala (revision 8a4dc19a5e2f0e8738191c5d75a9cf98f58c36dd)
1cafb3558SLinJiaweipackage xiangshan.backend.fu
2cafb3558SLinJiawei
3cafb3558SLinJiaweiimport chisel3._
4cafb3558SLinJiaweiimport chisel3.util._
5cafb3558SLinJiaweiimport xiangshan._
6e18c367fSLinJiaweiimport xiangshan.backend.fu.fpu.divsqrt.DivSqrt
7e18c367fSLinJiaweiimport xiangshan.backend.fu.fpu._
8e18c367fSLinJiaweiimport xiangshan.backend.fu.fpu.fma.FMA
9cafb3558SLinJiawei
10cafb3558SLinJiawei/*
11cafb3558SLinJiawei    XiangShan Function Unit
12cafb3558SLinJiawei    A Exu can have one or more function units
13cafb3558SLinJiawei */
14cafb3558SLinJiawei
153e60a357SLinJiaweitrait HasFuLatency {
163e60a357SLinJiawei  val latencyVal: Option[Int]
173e60a357SLinJiawei}
183e60a357SLinJiawei
193e60a357SLinJiaweicase class CertainLatency(value: Int) extends HasFuLatency{
203e60a357SLinJiawei  override val latencyVal: Option[Int] = Some(value)
213e60a357SLinJiawei}
223e60a357SLinJiawei
233e60a357SLinJiaweicase class UncertainLatency() extends HasFuLatency {
243e60a357SLinJiawei  override val latencyVal: Option[Int] = None
253e60a357SLinJiawei}
263e60a357SLinJiawei
2716df83adSZhangZifei
2816df83adSZhangZifei
29cafb3558SLinJiaweicase class FuConfig
30cafb3558SLinJiawei(
31cafb3558SLinJiawei  fuType: UInt,
32cafb3558SLinJiawei  numIntSrc: Int,
33cafb3558SLinJiawei  numFpSrc: Int,
34cafb3558SLinJiawei  writeIntRf: Boolean,
35cafb3558SLinJiawei  writeFpRf: Boolean,
363e60a357SLinJiawei  hasRedirect: Boolean,
373e60a357SLinJiawei  latency: HasFuLatency = CertainLatency(0)
3814521086SLinJiawei) {
3914521086SLinJiawei  def srcCnt: Int = math.max(numIntSrc, numFpSrc)
40c84054caSLinJiawei}
41c84054caSLinJiawei
42e18c367fSLinJiawei
43e18c367fSLinJiawei
44e18c367fSLinJiaweiclass FuOutput extends XSBundle {
45e18c367fSLinJiawei  val data = UInt(XLEN.W)
46e18c367fSLinJiawei  val uop = new MicroOp
47e18c367fSLinJiawei}
48e18c367fSLinJiawei
49e18c367fSLinJiawei
5014521086SLinJiaweiclass FunctionUnitIO[TI <: Data, TO <: Data]
5114521086SLinJiawei(
5214521086SLinJiawei  cfg: FuConfig,
53e18c367fSLinJiawei  len: Int
5414521086SLinJiawei) extends XSBundle
5514521086SLinJiawei{
5614521086SLinJiawei  val in = Flipped(DecoupledIO(new Bundle() {
5714521086SLinJiawei    val src = Vec(cfg.srcCnt, UInt(len.W))
5814521086SLinJiawei    val uop = new MicroOp
59ead41f51SLinJiawei
60ead41f51SLinJiawei    def connectToExuInput(exuIn: ExuInput): Unit = {
61ead41f51SLinJiawei      val exuSrcIn = Seq(exuIn.src1, exuIn.src2, exuIn.src3)
62ead41f51SLinJiawei      src.zip(exuSrcIn).foreach{case (x, y) => x := y}
63ead41f51SLinJiawei      uop := exuIn.uop
64ead41f51SLinJiawei    }
6514521086SLinJiawei  }))
66ead41f51SLinJiawei
67e18c367fSLinJiawei  val out = DecoupledIO(new FuOutput)
68ead41f51SLinJiawei
6914521086SLinJiawei  val redirectIn = Flipped(ValidIO(new Redirect))
7012bb47ddSLinJiawei
7112bb47ddSLinJiawei  override def cloneType: FunctionUnitIO.this.type =
72e18c367fSLinJiawei    new FunctionUnitIO(cfg, len).asInstanceOf[this.type]
7314521086SLinJiawei}
7414521086SLinJiawei
75e18c367fSLinJiaweiabstract class FunctionUnit
7614521086SLinJiawei(
77e18c367fSLinJiawei  val cfg: FuConfig,
78e18c367fSLinJiawei  val len: Int = 64
7914521086SLinJiawei) extends XSModule {
8014521086SLinJiawei
81e18c367fSLinJiawei  val io = IO(new FunctionUnitIO(cfg, len))
8214521086SLinJiawei
8314521086SLinJiawei}
8414521086SLinJiawei
85e18c367fSLinJiaweitrait HasPipelineReg { this: FunctionUnit =>
86e18c367fSLinJiawei
87e18c367fSLinJiawei  require(cfg.latency.latencyVal.nonEmpty && cfg.latency.latencyVal.get > 0)
88e18c367fSLinJiawei  val latency = cfg.latency.latencyVal.get
8914521086SLinJiawei
9014521086SLinJiawei  val validVec = io.in.valid +: Array.fill(latency)(RegInit(false.B))
9114521086SLinJiawei  val rdyVec = Array.fill(latency)(Wire(Bool())) :+ io.out.ready
9214521086SLinJiawei  val uopVec = io.in.bits.uop +: Array.fill(latency)(Reg(new MicroOp))
9314521086SLinJiawei
9414521086SLinJiawei
953136ee6aSLinJiawei  val flushVec = uopVec.zip(validVec).map(x => x._2 && x._1.roqIdx.needFlush(io.redirectIn))
9614521086SLinJiawei
9714521086SLinJiawei  for (i <- 0 until latency) {
9814521086SLinJiawei    rdyVec(i) := !validVec(i + 1) || rdyVec(i + 1)
9914521086SLinJiawei  }
10014521086SLinJiawei
10114521086SLinJiawei  for (i <- 1 to latency) {
10214521086SLinJiawei    when(flushVec(i - 1) || rdyVec(i) && !validVec(i - 1)) {
10314521086SLinJiawei      validVec(i) := false.B
10414521086SLinJiawei    }.elsewhen(rdyVec(i - 1) && validVec(i - 1) && !flushVec(i - 1)) {
10514521086SLinJiawei      validVec(i) := validVec(i - 1)
10614521086SLinJiawei      uopVec(i) := uopVec(i - 1)
10714521086SLinJiawei    }
10814521086SLinJiawei  }
10914521086SLinJiawei
11014521086SLinJiawei  io.in.ready := rdyVec(0)
11114521086SLinJiawei  io.out.valid := validVec.last && !flushVec.last
11214521086SLinJiawei  io.out.bits.uop := uopVec.last
11314521086SLinJiawei
11414521086SLinJiawei  def PipelineReg[TT <: Data](i: Int)(next: TT) = RegEnable(
11514521086SLinJiawei    next,
11614521086SLinJiawei    enable = validVec(i - 1) && rdyVec(i - 1) && !flushVec(i - 1)
11714521086SLinJiawei  )
11814521086SLinJiawei
11914521086SLinJiawei  def S1Reg[TT <: Data](next: TT): TT = PipelineReg[TT](1)(next)
12014521086SLinJiawei
12114521086SLinJiawei  def S2Reg[TT <: Data](next: TT): TT = PipelineReg[TT](2)(next)
12214521086SLinJiawei
12314521086SLinJiawei  def S3Reg[TT <: Data](next: TT): TT = PipelineReg[TT](3)(next)
12414521086SLinJiawei
12514521086SLinJiawei  def S4Reg[TT <: Data](next: TT): TT = PipelineReg[TT](4)(next)
12614521086SLinJiawei
12714521086SLinJiawei  def S5Reg[TT <: Data](next: TT): TT = PipelineReg[TT](5)(next)
12814521086SLinJiawei}
129cafb3558SLinJiawei
130e18c367fSLinJiaweiobject FunctionUnit extends HasXSParameter {
131c84054caSLinJiawei
132*8a4dc19aSLinJiawei  def multiplier = new ArrayMultiplier(XLEN+1, Seq(0, 2))
133e18c367fSLinJiawei  def divider = new Divider(XLEN)
134e18c367fSLinJiawei  def alu = new Alu
135c84054caSLinJiawei
136e18c367fSLinJiawei  def jmp = new Jump
137e18c367fSLinJiawei  def fence = new Fence
138e18c367fSLinJiawei  def csr = new CSR
139e18c367fSLinJiawei  def i2f = new IntToFloatSingleCycle
140cafb3558SLinJiawei
141e18c367fSLinJiawei  def fmac = new FMA
142e18c367fSLinJiawei  def fcmp = new FCMP
143e18c367fSLinJiawei  def fmv = new FMV(XLEN)
144e18c367fSLinJiawei  def f2i = new FloatToInt
145e18c367fSLinJiawei  def f32toF64 = new F32toF64
146e18c367fSLinJiawei  def f64toF32 = new F64toF32
147e18c367fSLinJiawei  def fdivSqrt = new DivSqrt
148cafb3558SLinJiawei
149e18c367fSLinJiawei  def fmiscSel(fu: String)(x: FPUSubModule): Bool = {
150e18c367fSLinJiawei    x.io.in.bits.uop.ctrl.fuOpType.head(4) === s"b$fu".U
151e18c367fSLinJiawei  }
152b8f08ca0SZhangZifei
1536624015fSLinJiawei  val lduCfg =
1543e60a357SLinJiawei    FuConfig(FuType.ldu, 1, 0, writeIntRf = true, writeFpRf = true, hasRedirect = false,
1553e60a357SLinJiawei      UncertainLatency()
1563e60a357SLinJiawei    )
1576624015fSLinJiawei
1586624015fSLinJiawei  val stuCfg =
1593e60a357SLinJiawei    FuConfig(FuType.stu, 2, 1, writeIntRf = false, writeFpRf = false, hasRedirect = false,
1603e60a357SLinJiawei      UncertainLatency()
1613e60a357SLinJiawei    )
162cafb3558SLinJiawei
16368c44d2dSAllen  val mouCfg =
1643e60a357SLinJiawei    FuConfig(FuType.mou, 2, 0, writeIntRf = false, writeFpRf = false, hasRedirect = false,
1653e60a357SLinJiawei      UncertainLatency()
1663e60a357SLinJiawei  )
167cafb3558SLinJiawei}
168