xref: /XiangShan/src/main/scala/xiangshan/backend/fu/FunctionUnit.scala (revision 7f1506e34f4f1556f09fd3d96108d0b558ad4881)
1cafb3558SLinJiaweipackage xiangshan.backend.fu
2cafb3558SLinJiawei
3cafb3558SLinJiaweiimport chisel3._
4cafb3558SLinJiaweiimport chisel3.util._
5cafb3558SLinJiaweiimport xiangshan._
652c3f215SLinJiaweiimport xiangshan.backend.MDUOpType
7e18c367fSLinJiaweiimport xiangshan.backend.fu.fpu._
8cafb3558SLinJiawei
93e60a357SLinJiaweitrait HasFuLatency {
103e60a357SLinJiawei  val latencyVal: Option[Int]
113e60a357SLinJiawei}
123e60a357SLinJiawei
133e60a357SLinJiaweicase class CertainLatency(value: Int) extends HasFuLatency {
143e60a357SLinJiawei  override val latencyVal: Option[Int] = Some(value)
153e60a357SLinJiawei}
163e60a357SLinJiawei
173e60a357SLinJiaweicase class UncertainLatency() extends HasFuLatency {
183e60a357SLinJiawei  override val latencyVal: Option[Int] = None
193e60a357SLinJiawei}
203e60a357SLinJiawei
2116df83adSZhangZifei
22cafb3558SLinJiaweicase class FuConfig
23cafb3558SLinJiawei(
2452c3f215SLinJiawei  fuGen: () => FunctionUnit,
2552c3f215SLinJiawei  fuSel: FunctionUnit => Bool,
26cafb3558SLinJiawei  fuType: UInt,
27cafb3558SLinJiawei  numIntSrc: Int,
28cafb3558SLinJiawei  numFpSrc: Int,
29cafb3558SLinJiawei  writeIntRf: Boolean,
30cafb3558SLinJiawei  writeFpRf: Boolean,
313e60a357SLinJiawei  hasRedirect: Boolean,
323e60a357SLinJiawei  latency: HasFuLatency = CertainLatency(0)
3314521086SLinJiawei) {
3414521086SLinJiawei  def srcCnt: Int = math.max(numIntSrc, numFpSrc)
35c84054caSLinJiawei}
36c84054caSLinJiawei
37e18c367fSLinJiawei
38e18c367fSLinJiaweiclass FuOutput extends XSBundle {
39e18c367fSLinJiawei  val data = UInt(XLEN.W)
40e18c367fSLinJiawei  val uop = new MicroOp
41e18c367fSLinJiawei}
42e18c367fSLinJiawei
43e18c367fSLinJiawei
4452c3f215SLinJiaweiclass FunctionUnitIO(len: Int) extends XSBundle {
4514521086SLinJiawei  val in = Flipped(DecoupledIO(new Bundle() {
4652c3f215SLinJiawei    val src = Vec(3, UInt(len.W))
4714521086SLinJiawei    val uop = new MicroOp
4814521086SLinJiawei  }))
49ead41f51SLinJiawei
50e18c367fSLinJiawei  val out = DecoupledIO(new FuOutput)
51ead41f51SLinJiawei
5214521086SLinJiawei  val redirectIn = Flipped(ValidIO(new Redirect))
5312bb47ddSLinJiawei
5412bb47ddSLinJiawei  override def cloneType: FunctionUnitIO.this.type =
5552c3f215SLinJiawei    new FunctionUnitIO(len).asInstanceOf[this.type]
5614521086SLinJiawei}
5714521086SLinJiawei
5852c3f215SLinJiaweiabstract class FunctionUnit(len: Int = 64) extends XSModule {
5914521086SLinJiawei
6052c3f215SLinJiawei  val io = IO(new FunctionUnitIO(len))
6114521086SLinJiawei
6214521086SLinJiawei}
6314521086SLinJiawei
6452c3f215SLinJiaweitrait HasPipelineReg {
6552c3f215SLinJiawei  this: FunctionUnit =>
66e18c367fSLinJiawei
67f64ff6e8SLinJiawei  def latency: Int
6852c3f215SLinJiawei
6952c3f215SLinJiawei  require(latency > 0)
7014521086SLinJiawei
7114521086SLinJiawei  val validVec = io.in.valid +: Array.fill(latency)(RegInit(false.B))
7214521086SLinJiawei  val rdyVec = Array.fill(latency)(Wire(Bool())) :+ io.out.ready
7314521086SLinJiawei  val uopVec = io.in.bits.uop +: Array.fill(latency)(Reg(new MicroOp))
7414521086SLinJiawei
7514521086SLinJiawei
763136ee6aSLinJiawei  val flushVec = uopVec.zip(validVec).map(x => x._2 && x._1.roqIdx.needFlush(io.redirectIn))
7714521086SLinJiawei
7814521086SLinJiawei  for (i <- 0 until latency) {
7914521086SLinJiawei    rdyVec(i) := !validVec(i + 1) || rdyVec(i + 1)
8014521086SLinJiawei  }
8114521086SLinJiawei
8214521086SLinJiawei  for (i <- 1 to latency) {
8314521086SLinJiawei    when(flushVec(i - 1) || rdyVec(i) && !validVec(i - 1)) {
8414521086SLinJiawei      validVec(i) := false.B
8514521086SLinJiawei    }.elsewhen(rdyVec(i - 1) && validVec(i - 1) && !flushVec(i - 1)) {
8614521086SLinJiawei      validVec(i) := validVec(i - 1)
8714521086SLinJiawei      uopVec(i) := uopVec(i - 1)
8814521086SLinJiawei    }
8914521086SLinJiawei  }
9014521086SLinJiawei
9114521086SLinJiawei  io.in.ready := rdyVec(0)
9214521086SLinJiawei  io.out.valid := validVec.last && !flushVec.last
9314521086SLinJiawei  io.out.bits.uop := uopVec.last
9414521086SLinJiawei
9514521086SLinJiawei  def PipelineReg[TT <: Data](i: Int)(next: TT) = RegEnable(
9614521086SLinJiawei    next,
9714521086SLinJiawei    enable = validVec(i - 1) && rdyVec(i - 1) && !flushVec(i - 1)
9814521086SLinJiawei  )
9914521086SLinJiawei
10014521086SLinJiawei  def S1Reg[TT <: Data](next: TT): TT = PipelineReg[TT](1)(next)
10114521086SLinJiawei
10214521086SLinJiawei  def S2Reg[TT <: Data](next: TT): TT = PipelineReg[TT](2)(next)
10314521086SLinJiawei
10414521086SLinJiawei  def S3Reg[TT <: Data](next: TT): TT = PipelineReg[TT](3)(next)
10514521086SLinJiawei
10614521086SLinJiawei  def S4Reg[TT <: Data](next: TT): TT = PipelineReg[TT](4)(next)
10714521086SLinJiawei
10814521086SLinJiawei  def S5Reg[TT <: Data](next: TT): TT = PipelineReg[TT](5)(next)
10914521086SLinJiawei}
110cafb3558SLinJiawei
111e18c367fSLinJiaweiobject FunctionUnit extends HasXSParameter {
112c84054caSLinJiawei
1135018a303SLinJiawei  def divider = new SRT4Divider(XLEN)
11452c3f215SLinJiawei
1158a4dc19aSLinJiawei  def multiplier = new ArrayMultiplier(XLEN + 1, Seq(0, 2))
1163ff0763bSljw
117e18c367fSLinJiawei  def alu = new Alu
118c84054caSLinJiawei
119e18c367fSLinJiawei  def jmp = new Jump
12052c3f215SLinJiawei
121e18c367fSLinJiawei  def fence = new Fence
12252c3f215SLinJiawei
123e18c367fSLinJiawei  def csr = new CSR
12452c3f215SLinJiawei
125*7f1506e3SLinJiawei  def i2f = new IntToFP
126cafb3558SLinJiawei
127e18c367fSLinJiawei  def fmac = new FMA
12852c3f215SLinJiawei
129*7f1506e3SLinJiawei  def f2i = new FPToInt
13052c3f215SLinJiawei
131*7f1506e3SLinJiawei  def f2f = new FPToFP
13252c3f215SLinJiawei
133*7f1506e3SLinJiawei  def fdivSqrt = new FDIvSqrt
134cafb3558SLinJiawei
13552c3f215SLinJiawei  def fmiscSel(fu: String)(x: FunctionUnit): Bool = {
136e18c367fSLinJiawei    x.io.in.bits.uop.ctrl.fuOpType.head(4) === s"b$fu".U
137e18c367fSLinJiawei  }
138b8f08ca0SZhangZifei
139*7f1506e3SLinJiawei  def f2iSel(x: FunctionUnit): Bool = {
140*7f1506e3SLinJiawei    x.io.in.bits.uop.ctrl.fuType === FuType.i2f
141*7f1506e3SLinJiawei  }
142*7f1506e3SLinJiawei
143*7f1506e3SLinJiawei  def i2fSel(x: FunctionUnit): Bool = {
144*7f1506e3SLinJiawei    x.io.in.bits.uop.ctrl.fpu.fromInt
145*7f1506e3SLinJiawei  }
146*7f1506e3SLinJiawei
147*7f1506e3SLinJiawei  def f2fSel(x: FunctionUnit): Bool = {
148*7f1506e3SLinJiawei    val ctrl = x.io.in.bits.uop.ctrl.fpu
149*7f1506e3SLinJiawei    ctrl.fpWen && !ctrl.div && !ctrl.sqrt
150*7f1506e3SLinJiawei  }
151*7f1506e3SLinJiawei
152*7f1506e3SLinJiawei  def fdivSqrtSel(x: FunctionUnit): Bool = {
153*7f1506e3SLinJiawei    val ctrl = x.io.in.bits.uop.ctrl.fpu
154*7f1506e3SLinJiawei    ctrl.div || ctrl.sqrt
155*7f1506e3SLinJiawei  }
156*7f1506e3SLinJiawei
15752c3f215SLinJiawei  val aluCfg = FuConfig(
15852c3f215SLinJiawei    fuGen = alu _,
15952c3f215SLinJiawei    fuSel = _ => true.B,
16052c3f215SLinJiawei    fuType = FuType.alu,
16152c3f215SLinJiawei    numIntSrc = 2,
16252c3f215SLinJiawei    numFpSrc = 0,
16352c3f215SLinJiawei    writeIntRf = true,
16452c3f215SLinJiawei    writeFpRf = false,
16552c3f215SLinJiawei    hasRedirect = true
16652c3f215SLinJiawei  )
16752c3f215SLinJiawei
16852c3f215SLinJiawei  val jmpCfg = FuConfig(
16952c3f215SLinJiawei    fuGen = jmp _,
17052c3f215SLinJiawei    fuSel = (x: FunctionUnit) => x.io.in.bits.uop.ctrl.fuType === FuType.jmp,
17152c3f215SLinJiawei    fuType = FuType.jmp,
17252c3f215SLinJiawei    numIntSrc = 1,
17352c3f215SLinJiawei    numFpSrc = 0,
17452c3f215SLinJiawei    writeIntRf = true,
17552c3f215SLinJiawei    writeFpRf = false,
17652c3f215SLinJiawei    hasRedirect = true
17752c3f215SLinJiawei  )
17852c3f215SLinJiawei
17952c3f215SLinJiawei  val fenceCfg = FuConfig(
18052c3f215SLinJiawei    fuGen = fence _,
18152c3f215SLinJiawei    fuSel = (x: FunctionUnit) => x.io.in.bits.uop.ctrl.fuType === FuType.fence,
1820bdd9eadSZhangZifei    FuType.fence, 1, 0, writeIntRf = false, writeFpRf = false, hasRedirect = false,
1830bdd9eadSZhangZifei    UncertainLatency() // TODO: need rewrite latency structure, not just this value
18452c3f215SLinJiawei  )
18552c3f215SLinJiawei
18652c3f215SLinJiawei  val csrCfg = FuConfig(
18752c3f215SLinJiawei    fuGen = csr _,
18852c3f215SLinJiawei    fuSel = (x: FunctionUnit) => x.io.in.bits.uop.ctrl.fuType === FuType.csr,
18952c3f215SLinJiawei    fuType = FuType.csr,
19052c3f215SLinJiawei    numIntSrc = 1,
19152c3f215SLinJiawei    numFpSrc = 0,
19252c3f215SLinJiawei    writeIntRf = true,
19352c3f215SLinJiawei    writeFpRf = false,
19452c3f215SLinJiawei    hasRedirect = false
19552c3f215SLinJiawei  )
19652c3f215SLinJiawei
19752c3f215SLinJiawei  val i2fCfg = FuConfig(
19852c3f215SLinJiawei    fuGen = i2f _,
199*7f1506e3SLinJiawei    fuSel = i2fSel,
20052c3f215SLinJiawei    FuType.i2f,
20152c3f215SLinJiawei    numIntSrc = 1,
20252c3f215SLinJiawei    numFpSrc = 0,
20352c3f215SLinJiawei    writeIntRf = false,
20452c3f215SLinJiawei    writeFpRf = true,
20552c3f215SLinJiawei    hasRedirect = false,
20652c3f215SLinJiawei    CertainLatency(0)
20752c3f215SLinJiawei  )
20852c3f215SLinJiawei
20952c3f215SLinJiawei  val divCfg = FuConfig(
21052c3f215SLinJiawei    fuGen = divider _,
21152c3f215SLinJiawei    fuSel = (x: FunctionUnit) => MDUOpType.isDiv(x.io.in.bits.uop.ctrl.fuOpType),
21252c3f215SLinJiawei    FuType.div,
21352c3f215SLinJiawei    2,
21452c3f215SLinJiawei    0,
21552c3f215SLinJiawei    writeIntRf = true,
21652c3f215SLinJiawei    writeFpRf = false,
21752c3f215SLinJiawei    hasRedirect = false,
2183e60a357SLinJiawei    UncertainLatency()
2193e60a357SLinJiawei  )
2206624015fSLinJiawei
22152c3f215SLinJiawei  val mulCfg = FuConfig(
22252c3f215SLinJiawei    fuGen = multiplier _,
22352c3f215SLinJiawei    fuSel = (x: FunctionUnit) => MDUOpType.isMul(x.io.in.bits.uop.ctrl.fuOpType),
22452c3f215SLinJiawei    FuType.mul,
22552c3f215SLinJiawei    2,
22652c3f215SLinJiawei    0,
22752c3f215SLinJiawei    writeIntRf = true,
22852c3f215SLinJiawei    writeFpRf = false,
22952c3f215SLinJiawei    hasRedirect = false,
23052c3f215SLinJiawei    CertainLatency(3)
23152c3f215SLinJiawei  )
23252c3f215SLinJiawei
23352c3f215SLinJiawei  val fmacCfg = FuConfig(
23452c3f215SLinJiawei    fuGen = fmac _,
23552c3f215SLinJiawei    fuSel = _ => true.B,
23652c3f215SLinJiawei    FuType.fmac, 0, 3, writeIntRf = false, writeFpRf = true, hasRedirect = false, CertainLatency(5)
23752c3f215SLinJiawei  )
23852c3f215SLinJiawei
23952c3f215SLinJiawei  val f2iCfg = FuConfig(
24052c3f215SLinJiawei    fuGen = f2i _,
241*7f1506e3SLinJiawei    fuSel = f2iSel,
24252c3f215SLinJiawei    FuType.fmisc, 0, 1, writeIntRf = true, writeFpRf = false, hasRedirect = false, CertainLatency(2)
24352c3f215SLinJiawei  )
24452c3f215SLinJiawei
245*7f1506e3SLinJiawei  val f2fCfg = FuConfig(
246*7f1506e3SLinJiawei    fuGen = f2f _,
247*7f1506e3SLinJiawei    fuSel = f2iSel,
24852c3f215SLinJiawei    FuType.fmisc, 0, 1, writeIntRf = false, writeFpRf = true, hasRedirect = false, CertainLatency(2)
24952c3f215SLinJiawei  )
25052c3f215SLinJiawei
25152c3f215SLinJiawei  val fdivSqrtCfg = FuConfig(
25252c3f215SLinJiawei    fuGen = fdivSqrt _,
253*7f1506e3SLinJiawei    fuSel = fdivSqrtSel,
25452c3f215SLinJiawei    FuType.fDivSqrt, 0, 2, writeIntRf = false, writeFpRf = true, hasRedirect = false, UncertainLatency()
25552c3f215SLinJiawei  )
25652c3f215SLinJiawei
25752c3f215SLinJiawei  val lduCfg = FuConfig(
25852c3f215SLinJiawei    null, // DontCare
25952c3f215SLinJiawei    null,
26052c3f215SLinJiawei    FuType.ldu, 1, 0, writeIntRf = true, writeFpRf = true, hasRedirect = false,
2613e60a357SLinJiawei    UncertainLatency()
2623e60a357SLinJiawei  )
263cafb3558SLinJiawei
26452c3f215SLinJiawei  val stuCfg = FuConfig(
26552c3f215SLinJiawei    null,
26652c3f215SLinJiawei    null,
26752c3f215SLinJiawei    FuType.stu, 2, 1, writeIntRf = false, writeFpRf = false, hasRedirect = false,
26852c3f215SLinJiawei    UncertainLatency()
26952c3f215SLinJiawei  )
27052c3f215SLinJiawei
27152c3f215SLinJiawei  val mouCfg = FuConfig(
27252c3f215SLinJiawei    null,
27352c3f215SLinJiawei    null,
27452c3f215SLinJiawei    FuType.mou, 2, 0, writeIntRf = false, writeFpRf = false, hasRedirect = false,
2753e60a357SLinJiawei    UncertainLatency()
2763e60a357SLinJiawei  )
277cafb3558SLinJiawei}
278