xref: /XiangShan/src/main/scala/xiangshan/backend/Backend.scala (revision 8999dcd9f01b2151f0646d3d061b5d579b35fecc)
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, RfWritePort}
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    println(s"[$i] $eu Queue wakeupCnt:$wakeupCnt bypassCnt:$bypassCnt")
61    eu.io.in <> iq.io.deq
62    eu.io.redirect <> redirect
63    iq
64  })
65
66  val aluQueues = issueQueues.filter(_.fuTypeInt == FuType.alu.litValue())
67  aluQueues.foreach(aluQ => {
68    aluQ.io.bypassUops <> aluQueues.map(_.io.selectedUop)
69    aluQ.io.bypassData <> aluExeUnits.map(_.io.out)
70  })
71
72  io.frontend.redirect <> redirect
73  io.frontend.commits <> roq.io.commits
74
75  decode.io.in <> io.frontend.cfVec
76  brq.io.roqRedirect <> roq.io.redirect
77  brq.io.enqReqs <> decode.io.toBrq
78  val red2BrqArb = Module(new WriteBackArbMtoN(exuConfig.BruCnt + exuConfig.AluCnt, BrqReceiveSize))
79  red2BrqArb.io.in <>  (bruExeUnit +: aluExeUnits).map(exu => exu.io.out)
80  brq.io.exuRedirect <> red2BrqArb.io.out
81  decode.io.brMasks <> brq.io.brMasks
82  decode.io.brTags <> brq.io.brTags
83  decBuf.io.in <> decode.io.out
84
85  rename.io.redirect <> redirect
86  rename.io.roqCommits <> roq.io.commits
87  rename.io.in <> decBuf.io.out
88
89  dispatch1.io.redirect <> redirect
90  dispatch1.io.in <> rename.io.out
91  roq.io.brqRedirect <> brq.io.redirect
92  roq.io.dp1Req <> dispatch1.io.toRoq
93  dispatch1.io.roqIdxs <> roq.io.roqIdxs
94
95  dispatch2.io.in <> dispatch1.io.out
96  dispatch2.io.intPregRdy <> rename.io.intPregRdy
97  dispatch2.io.fpPregRdy <> rename.io.fpPregRdy
98  intRf.io.readPorts <> dispatch2.io.readIntRf
99  rename.io.intRfReadAddr <> dispatch2.io.readIntRf.map(_.addr)
100  fpRf.io.readPorts <> dispatch2.io.readFpRf
101  rename.io.fpRfReadAddr <> dispatch2.io.readFpRf.map(_.addr)
102
103
104  val exeWbReqs = exeUnits.map(_.io.out)
105  val wbIntReqs = (bruExeUnit +: (aluExeUnits ++ mulExeUnits ++ mduExeUnits)).map(_.io.out)
106  val wbFpReqs = (fmacExeUnits ++ fmiscExeUnits ++ fmiscDivSqrtExeUnits).map(_.io.out)
107  val intWbArb = Module(new WriteBackArbMtoN(wbIntReqs.length, NRWritePorts))
108  val fpWbArb = Module(new WriteBackArbMtoN(wbFpReqs.length, NRWritePorts))
109  val wbIntResults = intWbArb.io.out
110  val wbFpResults = fpWbArb.io.out
111
112  def exuOutToRfWrite(x: Valid[ExuOutput]) = {
113    val rfWrite = Wire(new RfWritePort)
114    rfWrite.wen := x.valid
115    rfWrite.addr := x.bits.uop.pdest
116    rfWrite.data := x.bits.data
117    rfWrite
118  }
119
120  intWbArb.io.in <> wbIntReqs
121  intRf.io.writePorts <> wbIntResults.map(exuOutToRfWrite)
122
123  fpWbArb.io.in <> wbFpReqs
124  fpRf.io.writePorts <> wbFpResults.map(exuOutToRfWrite)
125
126  rename.io.wbIntResults <> wbIntResults
127  rename.io.wbFpResults <> wbFpResults
128
129  roq.io.exeWbResults <> exeWbReqs
130
131
132  // TODO: Remove sink and source
133  val tmp = WireInit(0.U)
134  val sinks = Array[String](
135    "DTLBFINISH",
136    "DTLBPF",
137    "DTLBENABLE",
138    "perfCntCondMdcacheLoss",
139    "perfCntCondMl2cacheLoss",
140    "perfCntCondMdcacheHit",
141    "lsuMMIO",
142    "perfCntCondMl2cacheHit",
143    "perfCntCondMl2cacheReq",
144    "mtip",
145    "perfCntCondMdcacheReq",
146    "meip"
147  )
148  for (s <- sinks){ BoringUtils.addSink(tmp, s) }
149
150  // A fake commit
151  // TODO: difftest 6 insts per cycle
152  val commit = RegNext(RegNext(RegNext(true.B)))
153  val pc = WireInit("h80000000".U)
154  val inst = WireInit("h66666666".U)
155
156  if(!p.FPGAPlatform){
157    BoringUtils.addSource(commit, "difftestCommit")
158    BoringUtils.addSource(pc, "difftestThisPC")
159    BoringUtils.addSource(inst, "difftestThisINST")
160    BoringUtils.addSource(tmp, "difftestIsMMIO")
161    BoringUtils.addSource(tmp, "difftestIsRVC")
162    BoringUtils.addSource(tmp, "difftestIntrNO")
163    BoringUtils.addSource(VecInit(Seq.fill(64)(tmp)), "difftestRegs")
164    BoringUtils.addSource(tmp, "difftestMode")
165    BoringUtils.addSource(tmp, "difftestMstatus")
166    BoringUtils.addSource(tmp, "difftestSstatus")
167    BoringUtils.addSource(tmp, "difftestMepc")
168    BoringUtils.addSource(tmp, "difftestSepc")
169    BoringUtils.addSource(tmp, "difftestMcause")
170    BoringUtils.addSource(tmp, "difftestScause")
171  }
172
173}
174