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