xref: /XiangShan/src/main/scala/xiangshan/backend/fu/FunctionUnit.scala (revision 75f32f6b867f2cc89a778937f8468057ecaf74bb)
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
38e50fb2d7SLinJiaweiclass FuOutput(val len: Int) extends XSBundle {
39e50fb2d7SLinJiawei  val data = UInt(len.W)
40e18c367fSLinJiawei  val uop = new MicroOp
41e18c367fSLinJiawei}
42e18c367fSLinJiawei
43e18c367fSLinJiawei
44e50fb2d7SLinJiaweiclass FunctionUnitIO(val 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
50e50fb2d7SLinJiawei  val out = DecoupledIO(new FuOutput(len))
51ead41f51SLinJiawei
5214521086SLinJiawei  val redirectIn = Flipped(ValidIO(new Redirect))
5314521086SLinJiawei}
5414521086SLinJiawei
5552c3f215SLinJiaweiabstract class FunctionUnit(len: Int = 64) extends XSModule {
5614521086SLinJiawei
5752c3f215SLinJiawei  val io = IO(new FunctionUnitIO(len))
5814521086SLinJiawei
5914521086SLinJiawei}
6014521086SLinJiawei
6152c3f215SLinJiaweitrait HasPipelineReg {
6252c3f215SLinJiawei  this: FunctionUnit =>
63e18c367fSLinJiawei
64f64ff6e8SLinJiawei  def latency: Int
6552c3f215SLinJiawei
6652c3f215SLinJiawei  require(latency > 0)
6714521086SLinJiawei
6814521086SLinJiawei  val validVec = io.in.valid +: Array.fill(latency)(RegInit(false.B))
6914521086SLinJiawei  val rdyVec = Array.fill(latency)(Wire(Bool())) :+ io.out.ready
7014521086SLinJiawei  val uopVec = io.in.bits.uop +: Array.fill(latency)(Reg(new MicroOp))
7114521086SLinJiawei
7214521086SLinJiawei
733136ee6aSLinJiawei  val flushVec = uopVec.zip(validVec).map(x => x._2 && x._1.roqIdx.needFlush(io.redirectIn))
7414521086SLinJiawei
7514521086SLinJiawei  for (i <- 0 until latency) {
7614521086SLinJiawei    rdyVec(i) := !validVec(i + 1) || rdyVec(i + 1)
7714521086SLinJiawei  }
7814521086SLinJiawei
7914521086SLinJiawei  for (i <- 1 to latency) {
8014521086SLinJiawei    when(flushVec(i - 1) || rdyVec(i) && !validVec(i - 1)) {
8114521086SLinJiawei      validVec(i) := false.B
8214521086SLinJiawei    }.elsewhen(rdyVec(i - 1) && validVec(i - 1) && !flushVec(i - 1)) {
8314521086SLinJiawei      validVec(i) := validVec(i - 1)
8414521086SLinJiawei      uopVec(i) := uopVec(i - 1)
8514521086SLinJiawei    }
8614521086SLinJiawei  }
8714521086SLinJiawei
8814521086SLinJiawei  io.in.ready := rdyVec(0)
8914521086SLinJiawei  io.out.valid := validVec.last && !flushVec.last
9014521086SLinJiawei  io.out.bits.uop := uopVec.last
9114521086SLinJiawei
92*75f32f6bSLinJiawei  def regEnable(i: Int): Bool = validVec(i - 1) && rdyVec(i - 1) && !flushVec(i - 1)
93*75f32f6bSLinJiawei
9414521086SLinJiawei  def PipelineReg[TT <: Data](i: Int)(next: TT) = RegEnable(
9514521086SLinJiawei    next,
96*75f32f6bSLinJiawei    enable = regEnable(i)
9714521086SLinJiawei  )
9814521086SLinJiawei
9914521086SLinJiawei  def S1Reg[TT <: Data](next: TT): TT = PipelineReg[TT](1)(next)
10014521086SLinJiawei
10114521086SLinJiawei  def S2Reg[TT <: Data](next: TT): TT = PipelineReg[TT](2)(next)
10214521086SLinJiawei
10314521086SLinJiawei  def S3Reg[TT <: Data](next: TT): TT = PipelineReg[TT](3)(next)
10414521086SLinJiawei
10514521086SLinJiawei  def S4Reg[TT <: Data](next: TT): TT = PipelineReg[TT](4)(next)
10614521086SLinJiawei
10714521086SLinJiawei  def S5Reg[TT <: Data](next: TT): TT = PipelineReg[TT](5)(next)
10814521086SLinJiawei}
109cafb3558SLinJiawei
110e18c367fSLinJiaweiobject FunctionUnit extends HasXSParameter {
111c84054caSLinJiawei
1125018a303SLinJiawei  def divider = new SRT4Divider(XLEN)
11352c3f215SLinJiawei
1148a4dc19aSLinJiawei  def multiplier = new ArrayMultiplier(XLEN + 1, Seq(0, 2))
1153ff0763bSljw
116e18c367fSLinJiawei  def alu = new Alu
117c84054caSLinJiawei
118e18c367fSLinJiawei  def jmp = new Jump
11952c3f215SLinJiawei
120e18c367fSLinJiawei  def fence = new Fence
12152c3f215SLinJiawei
122e18c367fSLinJiawei  def csr = new CSR
12352c3f215SLinJiawei
1247f1506e3SLinJiawei  def i2f = new IntToFP
125cafb3558SLinJiawei
126e18c367fSLinJiawei  def fmac = new FMA
12752c3f215SLinJiawei
1287f1506e3SLinJiawei  def f2i = new FPToInt
12952c3f215SLinJiawei
1307f1506e3SLinJiawei  def f2f = new FPToFP
13152c3f215SLinJiawei
132e50fb2d7SLinJiawei  def fdivSqrt = new FDivSqrt
133b8f08ca0SZhangZifei
1347f1506e3SLinJiawei  def f2iSel(x: FunctionUnit): Bool = {
135e50fb2d7SLinJiawei    x.io.in.bits.uop.ctrl.rfWen
1367f1506e3SLinJiawei  }
1377f1506e3SLinJiawei
1387f1506e3SLinJiawei  def i2fSel(x: FunctionUnit): Bool = {
1397f1506e3SLinJiawei    x.io.in.bits.uop.ctrl.fpu.fromInt
1407f1506e3SLinJiawei  }
1417f1506e3SLinJiawei
1427f1506e3SLinJiawei  def f2fSel(x: FunctionUnit): Bool = {
1437f1506e3SLinJiawei    val ctrl = x.io.in.bits.uop.ctrl.fpu
1447f1506e3SLinJiawei    ctrl.fpWen && !ctrl.div && !ctrl.sqrt
1457f1506e3SLinJiawei  }
1467f1506e3SLinJiawei
1477f1506e3SLinJiawei  def fdivSqrtSel(x: FunctionUnit): Bool = {
1487f1506e3SLinJiawei    val ctrl = x.io.in.bits.uop.ctrl.fpu
1497f1506e3SLinJiawei    ctrl.div || ctrl.sqrt
1507f1506e3SLinJiawei  }
1517f1506e3SLinJiawei
15252c3f215SLinJiawei  val aluCfg = FuConfig(
15352c3f215SLinJiawei    fuGen = alu _,
15452c3f215SLinJiawei    fuSel = _ => true.B,
15552c3f215SLinJiawei    fuType = FuType.alu,
15652c3f215SLinJiawei    numIntSrc = 2,
15752c3f215SLinJiawei    numFpSrc = 0,
15852c3f215SLinJiawei    writeIntRf = true,
15952c3f215SLinJiawei    writeFpRf = false,
16052c3f215SLinJiawei    hasRedirect = true
16152c3f215SLinJiawei  )
16252c3f215SLinJiawei
16352c3f215SLinJiawei  val jmpCfg = FuConfig(
16452c3f215SLinJiawei    fuGen = jmp _,
16552c3f215SLinJiawei    fuSel = (x: FunctionUnit) => x.io.in.bits.uop.ctrl.fuType === FuType.jmp,
16652c3f215SLinJiawei    fuType = FuType.jmp,
16752c3f215SLinJiawei    numIntSrc = 1,
16852c3f215SLinJiawei    numFpSrc = 0,
16952c3f215SLinJiawei    writeIntRf = true,
17052c3f215SLinJiawei    writeFpRf = false,
17152c3f215SLinJiawei    hasRedirect = true
17252c3f215SLinJiawei  )
17352c3f215SLinJiawei
17452c3f215SLinJiawei  val fenceCfg = FuConfig(
17552c3f215SLinJiawei    fuGen = fence _,
17652c3f215SLinJiawei    fuSel = (x: FunctionUnit) => x.io.in.bits.uop.ctrl.fuType === FuType.fence,
1770bdd9eadSZhangZifei    FuType.fence, 1, 0, writeIntRf = false, writeFpRf = false, hasRedirect = false,
1780bdd9eadSZhangZifei    UncertainLatency() // TODO: need rewrite latency structure, not just this value
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 _,
1947f1506e3SLinJiawei    fuSel = i2fSel,
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,
231e50fb2d7SLinJiawei    FuType.fmac, 0, 3, writeIntRf = false, writeFpRf = true, hasRedirect = false, CertainLatency(4)
23252c3f215SLinJiawei  )
23352c3f215SLinJiawei
23452c3f215SLinJiawei  val f2iCfg = FuConfig(
23552c3f215SLinJiawei    fuGen = f2i _,
2367f1506e3SLinJiawei    fuSel = f2iSel,
23752c3f215SLinJiawei    FuType.fmisc, 0, 1, writeIntRf = true, writeFpRf = false, hasRedirect = false, CertainLatency(2)
23852c3f215SLinJiawei  )
23952c3f215SLinJiawei
2407f1506e3SLinJiawei  val f2fCfg = FuConfig(
2417f1506e3SLinJiawei    fuGen = f2f _,
242e50fb2d7SLinJiawei    fuSel = f2fSel,
24352c3f215SLinJiawei    FuType.fmisc, 0, 1, writeIntRf = false, writeFpRf = true, hasRedirect = false, CertainLatency(2)
24452c3f215SLinJiawei  )
24552c3f215SLinJiawei
24652c3f215SLinJiawei  val fdivSqrtCfg = FuConfig(
24752c3f215SLinJiawei    fuGen = fdivSqrt _,
2487f1506e3SLinJiawei    fuSel = fdivSqrtSel,
24952c3f215SLinJiawei    FuType.fDivSqrt, 0, 2, writeIntRf = false, writeFpRf = true, hasRedirect = false, UncertainLatency()
25052c3f215SLinJiawei  )
25152c3f215SLinJiawei
25252c3f215SLinJiawei  val lduCfg = FuConfig(
25352c3f215SLinJiawei    null, // DontCare
25452c3f215SLinJiawei    null,
25552c3f215SLinJiawei    FuType.ldu, 1, 0, writeIntRf = true, writeFpRf = true, hasRedirect = false,
2563e60a357SLinJiawei    UncertainLatency()
2573e60a357SLinJiawei  )
258cafb3558SLinJiawei
25952c3f215SLinJiawei  val stuCfg = FuConfig(
26052c3f215SLinJiawei    null,
26152c3f215SLinJiawei    null,
26252c3f215SLinJiawei    FuType.stu, 2, 1, writeIntRf = false, writeFpRf = false, hasRedirect = false,
26352c3f215SLinJiawei    UncertainLatency()
26452c3f215SLinJiawei  )
26552c3f215SLinJiawei
26652c3f215SLinJiawei  val mouCfg = FuConfig(
26752c3f215SLinJiawei    null,
26852c3f215SLinJiawei    null,
26952c3f215SLinJiawei    FuType.mou, 2, 0, writeIntRf = false, writeFpRf = false, hasRedirect = false,
2703e60a357SLinJiawei    UncertainLatency()
2713e60a357SLinJiawei  )
272cafb3558SLinJiawei}
273