xref: /XiangShan/src/main/scala/xiangshan/backend/Backend.scala (revision 9a2e6b8ae06ed24bb317fa76e397982fa714877b)
1package xiangshan.backend
2
3import bus.simplebus.SimpleBusUC
4import chisel3._
5import chisel3.util._
6import chisel3.util.experimental.BoringUtils
7import noop.MemMMUIO
8import xiangshan._
9import xiangshan.backend.decode.{DecodeBuffer, DecodeStage}
10import xiangshan.backend.rename.Rename
11import xiangshan.backend.brq.Brq
12import xiangshan.backend.dispatch.{Dispatch1, Dispatch2}
13import xiangshan.backend.exu._
14import xiangshan.backend.issue.IssueQueue
15import xiangshan.backend.regfile.Regfile
16import xiangshan.backend.roq.Roq
17
18
19/** Backend Pipeline:
20  * Decode -> Rename -> Dispatch-1 -> Dispatch-2 -> Issue -> Exe
21  */
22class Backend(implicit val p: XSConfig) extends XSModule
23  with HasExeUnits
24  with NeedImpl
25{
26  val io = IO(new Bundle {
27    val dmem = new SimpleBusUC(addrBits = VAddrBits)
28    val memMMU = Flipped(new MemMMUIO)
29    val frontend = Flipped(new FrontendToBackendIO)
30  })
31
32
33  val decode = Module(new DecodeStage)
34  val brq = Module(new Brq)
35  val decBuf = Module(new DecodeBuffer)
36  val rename = Module(new Rename)
37  val dispatch1 = Module(new Dispatch1)
38  val roq = Module(new Roq)
39  val dispatch2 = Module(new Dispatch2)
40  val intRf = Module(new Regfile(
41    numReadPorts = NRReadPorts,
42    numWirtePorts = NRWritePorts,
43    hasZero = true
44  ))
45  val fpRf = Module(new Regfile(
46    numReadPorts = NRReadPorts,
47    numWirtePorts = NRWritePorts,
48    hasZero = false
49  ))
50  val redirect = Mux(roq.io.redirect.valid, roq.io.redirect, brq.io.redirect)
51  val issueQueues = exeUnits.zipWithIndex.map({ case(eu, i) =>
52    def needWakeup(x: Exu): Boolean = (eu.readIntRf && x.writeIntRf) || (eu.readFpRf && x.writeFpRf)
53    val wakeupCnt = exeUnits.count(needWakeup)
54    val bypassCnt = if(eu.fuTypeInt == FuType.alu.litValue()) exuConfig.AluCnt else 0
55    val iq = Module(new IssueQueue(eu.fuTypeInt, wakeupCnt, bypassCnt))
56    iq.io.redirect <> redirect
57    iq.io.enqCtrl <> dispatch2.io.enqIQCtrl(i)
58    iq.io.enqData <> dispatch2.io.enqIQData(i)
59    iq.io.wakeUpPorts <> exeUnits.filter(needWakeup).map(_.io.out)
60    if(eu.fuTypeInt == FuType.alu.litValue()){
61      iq.io.bypassPorts <> aluExeUnits.map(_.io.out)
62    }
63    println(s"[$i] $eu wakeupCnt:$wakeupCnt bypassCnt:$bypassCnt")
64    eu.io.in <> iq.io.deq
65    iq
66  })
67
68  io.frontend.redirect <> redirect
69  io.frontend.commits <> roq.io.commits
70
71  decode.io.in <> io.frontend.cfVec
72  brq.io.roqRedirect <> roq.io.redirect
73  brq.io.enqReqs <> decode.io.toBrq
74  decode.io.brMasks <> brq.io.brMasks
75  decode.io.brTags <> brq.io.brTags
76  decBuf.io.in <> decode.io.out
77
78  rename.io.redirect <> redirect
79  rename.io.roqCommits <> roq.io.commits
80  rename.io.in <> decBuf.io.out
81
82  dispatch1.io.redirect <> redirect
83  dispatch1.io.in <> rename.io.out
84  roq.io.brqRedirect <> brq.io.redirect
85  roq.io.dp1Req <> dispatch1.io.toRoq
86  dispatch1.io.roqIdxs <> roq.io.roqIdxs
87
88  dispatch2.io.in <> dispatch1.io.out
89  intRf.io.readPorts <> dispatch2.io.readIntRf
90  fpRf.io.readPorts <> dispatch2.io.readFpRf
91
92
93  val exeWbReqs = exeUnits.map(_.io.out)
94  val wbIntReqs = (bruExeUnit +: (aluExeUnits ++ mulExeUnits ++ mduExeUnits)).map(_.io.out)
95  val wbFpReqs = (fmacExeUnits ++ fmiscExeUnits ++ fmiscDivSqrtExeUnits).map(_.io.out)
96  val intWbArb = Module(new WriteBackArbMtoN(wbIntReqs.length, NRWritePorts))
97  val fpWbArb = Module(new WriteBackArbMtoN(wbFpReqs.length, NRWritePorts))
98
99  intWbArb.io.in <> wbIntReqs
100  intRf.io.writePorts <> intWbArb.io.out
101
102  fpWbArb.io.in <> wbFpReqs
103  fpRf.io.writePorts <> fpWbArb.io.out
104
105  roq.io.exeWbResults <> exeWbReqs
106
107
108  // TODO: Remove sink and source
109  val tmp = WireInit(0.U)
110  val sinks = Array[String](
111    "DTLBFINISH",
112    "DTLBPF",
113    "DTLBENABLE",
114    "perfCntCondMdcacheLoss",
115    "perfCntCondMl2cacheLoss",
116    "perfCntCondMdcacheHit",
117    "lsuMMIO",
118    "perfCntCondMl2cacheHit",
119    "perfCntCondMl2cacheReq",
120    "mtip",
121    "perfCntCondMdcacheReq",
122    "meip"
123  )
124  for (s <- sinks){ BoringUtils.addSink(tmp, s) }
125
126  // A fake commit
127  // TODO: difftest 6 insts per cycle
128  val commit = RegNext(RegNext(RegNext(true.B)))
129  val pc = WireInit("h80000000".U)
130  val inst = WireInit("h66666666".U)
131
132  if(!p.FPGAPlatform){
133    BoringUtils.addSource(commit, "difftestCommit")
134    BoringUtils.addSource(pc, "difftestThisPC")
135    BoringUtils.addSource(inst, "difftestThisINST")
136    BoringUtils.addSource(tmp, "difftestIsMMIO")
137    BoringUtils.addSource(tmp, "difftestIsRVC")
138    BoringUtils.addSource(tmp, "difftestIntrNO")
139    BoringUtils.addSource(VecInit(Seq.fill(64)(tmp)), "difftestRegs")
140    BoringUtils.addSource(tmp, "difftestMode")
141    BoringUtils.addSource(tmp, "difftestMstatus")
142    BoringUtils.addSource(tmp, "difftestSstatus")
143    BoringUtils.addSource(tmp, "difftestMepc")
144    BoringUtils.addSource(tmp, "difftestSepc")
145    BoringUtils.addSource(tmp, "difftestMcause")
146    BoringUtils.addSource(tmp, "difftestScause")
147  }
148
149}
150