xref: /XiangShan/src/main/scala/xiangshan/backend/fu/FunctionUnit.scala (revision f64ff6e81d5e9cff127aa7f58ec36e2a70eafba1)
1cafb3558SLinJiaweipackage xiangshan.backend.fu
2cafb3558SLinJiawei
3cafb3558SLinJiaweiimport chisel3._
4cafb3558SLinJiaweiimport chisel3.util._
5cafb3558SLinJiaweiimport xiangshan._
652c3f215SLinJiaweiimport xiangshan.backend.MDUOpType
752c3f215SLinJiaweiimport xiangshan.backend.fu.fpu.FPUOpType.{FU_D2S, FU_DIVSQRT, FU_F2I, FU_FCMP, FU_FMV, FU_S2D}
8e18c367fSLinJiaweiimport xiangshan.backend.fu.fpu.divsqrt.DivSqrt
9e18c367fSLinJiaweiimport xiangshan.backend.fu.fpu._
10e18c367fSLinJiaweiimport xiangshan.backend.fu.fpu.fma.FMA
11cafb3558SLinJiawei
12cafb3558SLinJiawei/*
13cafb3558SLinJiawei    XiangShan Function Unit
14cafb3558SLinJiawei    A Exu can have one or more function units
15cafb3558SLinJiawei */
16cafb3558SLinJiawei
173e60a357SLinJiaweitrait HasFuLatency {
183e60a357SLinJiawei  val latencyVal: Option[Int]
193e60a357SLinJiawei}
203e60a357SLinJiawei
213e60a357SLinJiaweicase class CertainLatency(value: Int) extends HasFuLatency {
223e60a357SLinJiawei  override val latencyVal: Option[Int] = Some(value)
233e60a357SLinJiawei}
243e60a357SLinJiawei
253e60a357SLinJiaweicase class UncertainLatency() extends HasFuLatency {
263e60a357SLinJiawei  override val latencyVal: Option[Int] = None
273e60a357SLinJiawei}
283e60a357SLinJiawei
2916df83adSZhangZifei
30cafb3558SLinJiaweicase class FuConfig
31cafb3558SLinJiawei(
3252c3f215SLinJiawei  fuGen: () => FunctionUnit,
3352c3f215SLinJiawei  fuSel: FunctionUnit => Bool,
34cafb3558SLinJiawei  fuType: UInt,
35cafb3558SLinJiawei  numIntSrc: Int,
36cafb3558SLinJiawei  numFpSrc: Int,
37cafb3558SLinJiawei  writeIntRf: Boolean,
38cafb3558SLinJiawei  writeFpRf: Boolean,
393e60a357SLinJiawei  hasRedirect: Boolean,
403e60a357SLinJiawei  latency: HasFuLatency = CertainLatency(0)
4114521086SLinJiawei) {
4214521086SLinJiawei  def srcCnt: Int = math.max(numIntSrc, numFpSrc)
43c84054caSLinJiawei}
44c84054caSLinJiawei
45e18c367fSLinJiawei
46e18c367fSLinJiaweiclass FuOutput extends XSBundle {
47e18c367fSLinJiawei  val data = UInt(XLEN.W)
48e18c367fSLinJiawei  val uop = new MicroOp
49e18c367fSLinJiawei}
50e18c367fSLinJiawei
51e18c367fSLinJiawei
5252c3f215SLinJiaweiclass FunctionUnitIO(len: Int) extends XSBundle {
5314521086SLinJiawei  val in = Flipped(DecoupledIO(new Bundle() {
5452c3f215SLinJiawei    val src = Vec(3, UInt(len.W))
5514521086SLinJiawei    val uop = new MicroOp
5614521086SLinJiawei  }))
57ead41f51SLinJiawei
58e18c367fSLinJiawei  val out = DecoupledIO(new FuOutput)
59ead41f51SLinJiawei
6014521086SLinJiawei  val redirectIn = Flipped(ValidIO(new Redirect))
6112bb47ddSLinJiawei
6212bb47ddSLinJiawei  override def cloneType: FunctionUnitIO.this.type =
6352c3f215SLinJiawei    new FunctionUnitIO(len).asInstanceOf[this.type]
6414521086SLinJiawei}
6514521086SLinJiawei
6652c3f215SLinJiaweiabstract class FunctionUnit(len: Int = 64) extends XSModule {
6714521086SLinJiawei
6852c3f215SLinJiawei  val io = IO(new FunctionUnitIO(len))
6914521086SLinJiawei
7014521086SLinJiawei}
7114521086SLinJiawei
7252c3f215SLinJiaweitrait HasPipelineReg {
7352c3f215SLinJiawei  this: FunctionUnit =>
74e18c367fSLinJiawei
75*f64ff6e8SLinJiawei  def latency: Int
7652c3f215SLinJiawei
7752c3f215SLinJiawei  require(latency > 0)
7814521086SLinJiawei
7914521086SLinJiawei  val validVec = io.in.valid +: Array.fill(latency)(RegInit(false.B))
8014521086SLinJiawei  val rdyVec = Array.fill(latency)(Wire(Bool())) :+ io.out.ready
8114521086SLinJiawei  val uopVec = io.in.bits.uop +: Array.fill(latency)(Reg(new MicroOp))
8214521086SLinJiawei
8314521086SLinJiawei
843136ee6aSLinJiawei  val flushVec = uopVec.zip(validVec).map(x => x._2 && x._1.roqIdx.needFlush(io.redirectIn))
8514521086SLinJiawei
8614521086SLinJiawei  for (i <- 0 until latency) {
8714521086SLinJiawei    rdyVec(i) := !validVec(i + 1) || rdyVec(i + 1)
8814521086SLinJiawei  }
8914521086SLinJiawei
9014521086SLinJiawei  for (i <- 1 to latency) {
9114521086SLinJiawei    when(flushVec(i - 1) || rdyVec(i) && !validVec(i - 1)) {
9214521086SLinJiawei      validVec(i) := false.B
9314521086SLinJiawei    }.elsewhen(rdyVec(i - 1) && validVec(i - 1) && !flushVec(i - 1)) {
9414521086SLinJiawei      validVec(i) := validVec(i - 1)
9514521086SLinJiawei      uopVec(i) := uopVec(i - 1)
9614521086SLinJiawei    }
9714521086SLinJiawei  }
9814521086SLinJiawei
9914521086SLinJiawei  io.in.ready := rdyVec(0)
10014521086SLinJiawei  io.out.valid := validVec.last && !flushVec.last
10114521086SLinJiawei  io.out.bits.uop := uopVec.last
10214521086SLinJiawei
10314521086SLinJiawei  def PipelineReg[TT <: Data](i: Int)(next: TT) = RegEnable(
10414521086SLinJiawei    next,
10514521086SLinJiawei    enable = validVec(i - 1) && rdyVec(i - 1) && !flushVec(i - 1)
10614521086SLinJiawei  )
10714521086SLinJiawei
10814521086SLinJiawei  def S1Reg[TT <: Data](next: TT): TT = PipelineReg[TT](1)(next)
10914521086SLinJiawei
11014521086SLinJiawei  def S2Reg[TT <: Data](next: TT): TT = PipelineReg[TT](2)(next)
11114521086SLinJiawei
11214521086SLinJiawei  def S3Reg[TT <: Data](next: TT): TT = PipelineReg[TT](3)(next)
11314521086SLinJiawei
11414521086SLinJiawei  def S4Reg[TT <: Data](next: TT): TT = PipelineReg[TT](4)(next)
11514521086SLinJiawei
11614521086SLinJiawei  def S5Reg[TT <: Data](next: TT): TT = PipelineReg[TT](5)(next)
11714521086SLinJiawei}
118cafb3558SLinJiawei
119e18c367fSLinJiaweiobject FunctionUnit extends HasXSParameter {
120c84054caSLinJiawei
1215018a303SLinJiawei  def divider = new SRT4Divider(XLEN)
12252c3f215SLinJiawei
1238a4dc19aSLinJiawei  def multiplier = new ArrayMultiplier(XLEN + 1, Seq(0, 2))
1243ff0763bSljw
125e18c367fSLinJiawei  def alu = new Alu
126c84054caSLinJiawei
127e18c367fSLinJiawei  def jmp = new Jump
12852c3f215SLinJiawei
129e18c367fSLinJiawei  def fence = new Fence
13052c3f215SLinJiawei
131e18c367fSLinJiawei  def csr = new CSR
13252c3f215SLinJiawei
133e18c367fSLinJiawei  def i2f = new IntToFloatSingleCycle
134cafb3558SLinJiawei
135e18c367fSLinJiawei  def fmac = new FMA
13652c3f215SLinJiawei
137e18c367fSLinJiawei  def fcmp = new FCMP
13852c3f215SLinJiawei
139e18c367fSLinJiawei  def fmv = new FMV(XLEN)
14052c3f215SLinJiawei
141e18c367fSLinJiawei  def f2i = new FloatToInt
14252c3f215SLinJiawei
143e18c367fSLinJiawei  def f32toF64 = new F32toF64
14452c3f215SLinJiawei
145e18c367fSLinJiawei  def f64toF32 = new F64toF32
14652c3f215SLinJiawei
147e18c367fSLinJiawei  def fdivSqrt = new DivSqrt
148cafb3558SLinJiawei
14952c3f215SLinJiawei  def fmiscSel(fu: String)(x: FunctionUnit): Bool = {
150e18c367fSLinJiawei    x.io.in.bits.uop.ctrl.fuOpType.head(4) === s"b$fu".U
151e18c367fSLinJiawei  }
152b8f08ca0SZhangZifei
15352c3f215SLinJiawei  val aluCfg = FuConfig(
15452c3f215SLinJiawei    fuGen = alu _,
15552c3f215SLinJiawei    fuSel = _ => true.B,
15652c3f215SLinJiawei    fuType = FuType.alu,
15752c3f215SLinJiawei    numIntSrc = 2,
15852c3f215SLinJiawei    numFpSrc = 0,
15952c3f215SLinJiawei    writeIntRf = true,
16052c3f215SLinJiawei    writeFpRf = false,
16152c3f215SLinJiawei    hasRedirect = true
16252c3f215SLinJiawei  )
16352c3f215SLinJiawei
16452c3f215SLinJiawei  val jmpCfg = FuConfig(
16552c3f215SLinJiawei    fuGen = jmp _,
16652c3f215SLinJiawei    fuSel = (x: FunctionUnit) => x.io.in.bits.uop.ctrl.fuType === FuType.jmp,
16752c3f215SLinJiawei    fuType = FuType.jmp,
16852c3f215SLinJiawei    numIntSrc = 1,
16952c3f215SLinJiawei    numFpSrc = 0,
17052c3f215SLinJiawei    writeIntRf = true,
17152c3f215SLinJiawei    writeFpRf = false,
17252c3f215SLinJiawei    hasRedirect = true
17352c3f215SLinJiawei  )
17452c3f215SLinJiawei
17552c3f215SLinJiawei  val fenceCfg = FuConfig(
17652c3f215SLinJiawei    fuGen = fence _,
17752c3f215SLinJiawei    fuSel = (x: FunctionUnit) => x.io.in.bits.uop.ctrl.fuType === FuType.fence,
17852c3f215SLinJiawei    FuType.fence, 1, 0, writeIntRf = false, writeFpRf = false, hasRedirect = false
17952c3f215SLinJiawei  )
18052c3f215SLinJiawei
18152c3f215SLinJiawei  val csrCfg = FuConfig(
18252c3f215SLinJiawei    fuGen = csr _,
18352c3f215SLinJiawei    fuSel = (x: FunctionUnit) => x.io.in.bits.uop.ctrl.fuType === FuType.csr,
18452c3f215SLinJiawei    fuType = FuType.csr,
18552c3f215SLinJiawei    numIntSrc = 1,
18652c3f215SLinJiawei    numFpSrc = 0,
18752c3f215SLinJiawei    writeIntRf = true,
18852c3f215SLinJiawei    writeFpRf = false,
18952c3f215SLinJiawei    hasRedirect = false
19052c3f215SLinJiawei  )
19152c3f215SLinJiawei
19252c3f215SLinJiawei  val i2fCfg = FuConfig(
19352c3f215SLinJiawei    fuGen = i2f _,
19452c3f215SLinJiawei    fuSel = (x: FunctionUnit) => x.io.in.bits.uop.ctrl.fuType === FuType.i2f,
19552c3f215SLinJiawei    FuType.i2f,
19652c3f215SLinJiawei    numIntSrc = 1,
19752c3f215SLinJiawei    numFpSrc = 0,
19852c3f215SLinJiawei    writeIntRf = false,
19952c3f215SLinJiawei    writeFpRf = true,
20052c3f215SLinJiawei    hasRedirect = false,
20152c3f215SLinJiawei    CertainLatency(0)
20252c3f215SLinJiawei  )
20352c3f215SLinJiawei
20452c3f215SLinJiawei  val divCfg = FuConfig(
20552c3f215SLinJiawei    fuGen = divider _,
20652c3f215SLinJiawei    fuSel = (x: FunctionUnit) => MDUOpType.isDiv(x.io.in.bits.uop.ctrl.fuOpType),
20752c3f215SLinJiawei    FuType.div,
20852c3f215SLinJiawei    2,
20952c3f215SLinJiawei    0,
21052c3f215SLinJiawei    writeIntRf = true,
21152c3f215SLinJiawei    writeFpRf = false,
21252c3f215SLinJiawei    hasRedirect = false,
2133e60a357SLinJiawei    UncertainLatency()
2143e60a357SLinJiawei  )
2156624015fSLinJiawei
21652c3f215SLinJiawei  val mulCfg = FuConfig(
21752c3f215SLinJiawei    fuGen = multiplier _,
21852c3f215SLinJiawei    fuSel = (x: FunctionUnit) => MDUOpType.isMul(x.io.in.bits.uop.ctrl.fuOpType),
21952c3f215SLinJiawei    FuType.mul,
22052c3f215SLinJiawei    2,
22152c3f215SLinJiawei    0,
22252c3f215SLinJiawei    writeIntRf = true,
22352c3f215SLinJiawei    writeFpRf = false,
22452c3f215SLinJiawei    hasRedirect = false,
22552c3f215SLinJiawei    CertainLatency(3)
22652c3f215SLinJiawei  )
22752c3f215SLinJiawei
22852c3f215SLinJiawei  val fmacCfg = FuConfig(
22952c3f215SLinJiawei    fuGen = fmac _,
23052c3f215SLinJiawei    fuSel = _ => true.B,
23152c3f215SLinJiawei    FuType.fmac, 0, 3, writeIntRf = false, writeFpRf = true, hasRedirect = false, CertainLatency(5)
23252c3f215SLinJiawei  )
23352c3f215SLinJiawei
23452c3f215SLinJiawei  val fcmpCfg = FuConfig(
23552c3f215SLinJiawei    fuGen = fcmp _,
23652c3f215SLinJiawei    fuSel = fmiscSel(FU_FCMP),
23752c3f215SLinJiawei    FuType.fmisc, 0, 2, writeIntRf = true, writeFpRf = false, hasRedirect = false, CertainLatency(2)
23852c3f215SLinJiawei  )
23952c3f215SLinJiawei
24052c3f215SLinJiawei  val fmvCfg = FuConfig(
24152c3f215SLinJiawei    fuGen = fmv _,
24252c3f215SLinJiawei    fuSel = fmiscSel(FU_FMV),
24352c3f215SLinJiawei    FuType.fmisc, 0, 2, writeIntRf = true, writeFpRf = true, hasRedirect = false, CertainLatency(1)
24452c3f215SLinJiawei  )
24552c3f215SLinJiawei
24652c3f215SLinJiawei  val f2iCfg = FuConfig(
24752c3f215SLinJiawei    fuGen = f2i _,
24852c3f215SLinJiawei    fuSel = fmiscSel(FU_F2I),
24952c3f215SLinJiawei    FuType.fmisc, 0, 1, writeIntRf = true, writeFpRf = false, hasRedirect = false, CertainLatency(2)
25052c3f215SLinJiawei  )
25152c3f215SLinJiawei
25252c3f215SLinJiawei  val s2dCfg = FuConfig(
25352c3f215SLinJiawei    fuGen = f32toF64 _,
25452c3f215SLinJiawei    fuSel = fmiscSel(FU_S2D),
25552c3f215SLinJiawei    FuType.fmisc, 0, 1, writeIntRf = false, writeFpRf = true, hasRedirect = false, CertainLatency(2)
25652c3f215SLinJiawei  )
25752c3f215SLinJiawei
25852c3f215SLinJiawei  val d2sCfg = FuConfig(
25952c3f215SLinJiawei    fuGen = f64toF32 _,
26052c3f215SLinJiawei    fuSel = fmiscSel(FU_D2S),
26152c3f215SLinJiawei    FuType.fmisc, 0, 1, writeIntRf = false, writeFpRf = true, hasRedirect = false, CertainLatency(2)
26252c3f215SLinJiawei  )
26352c3f215SLinJiawei
26452c3f215SLinJiawei  val fdivSqrtCfg = FuConfig(
26552c3f215SLinJiawei    fuGen = fdivSqrt _,
26652c3f215SLinJiawei    fuSel = fmiscSel(FU_DIVSQRT),
26752c3f215SLinJiawei    FuType.fDivSqrt, 0, 2, writeIntRf = false, writeFpRf = true, hasRedirect = false, UncertainLatency()
26852c3f215SLinJiawei  )
26952c3f215SLinJiawei
27052c3f215SLinJiawei  val lduCfg = FuConfig(
27152c3f215SLinJiawei    null, // DontCare
27252c3f215SLinJiawei    null,
27352c3f215SLinJiawei    FuType.ldu, 1, 0, writeIntRf = true, writeFpRf = true, hasRedirect = false,
2743e60a357SLinJiawei    UncertainLatency()
2753e60a357SLinJiawei  )
276cafb3558SLinJiawei
27752c3f215SLinJiawei  val stuCfg = FuConfig(
27852c3f215SLinJiawei    null,
27952c3f215SLinJiawei    null,
28052c3f215SLinJiawei    FuType.stu, 2, 1, writeIntRf = false, writeFpRf = false, hasRedirect = false,
28152c3f215SLinJiawei    UncertainLatency()
28252c3f215SLinJiawei  )
28352c3f215SLinJiawei
28452c3f215SLinJiawei  val mouCfg = FuConfig(
28552c3f215SLinJiawei    null,
28652c3f215SLinJiawei    null,
28752c3f215SLinJiawei    FuType.mou, 2, 0, writeIntRf = false, writeFpRf = false, hasRedirect = false,
2883e60a357SLinJiawei    UncertainLatency()
2893e60a357SLinJiawei  )
290cafb3558SLinJiawei}
291