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