xref: /XiangShan/src/main/scala/xiangshan/backend/Backend.scala (revision 0200b0af44c30925e7097ad392922e471895dcfe)
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
93//  dispatch1.io.redirect <> redirect
94//  dispatch1.io.in <> rename.io.out
95  dispatch.io.redirect <> redirect
96  dispatch.io.fromRename <> rename.io.out
97  roq.io.brqRedirect <> brq.io.redirect
98//<<<<<<< HEAD
99//  roq.io.dp1Req <> dispatch1.io.toRoq
100//  dispatch1.io.roqIdxs <> roq.io.roqIdxs
101  roq.io.dp1Req <> dispatch.io.toRoq
102  dispatch.io.roqIdxs <> roq.io.roqIdxs
103
104//  dispatch2.io.in <> dispatch1.io.out
105//  intRf.io.readPorts <> dispatch2.io.readIntRf
106//  fpRf.io.readPorts <> dispatch2.io.readFpRf
107  intRf.io.readPorts <> dispatch.io.readIntRf
108  fpRf.io.readPorts <> dispatch.io.readFpRf
109//=======
110//  roq.io.dp1Req <> dispatch1.io.toRoq
111//  dispatch1.io.roqIdxs <> roq.io.roqIdxs
112//
113//  dispatch2.io.in <> dispatch1.io.out
114//  dispatch2.io.intPregRdy <> rename.io.intPregRdy
115//  dispatch2.io.fpPregRdy <> rename.io.fpPregRdy
116//  intRf.io.readPorts <> dispatch2.io.readIntRf
117//  rename.io.intRfReadAddr <> dispatch2.io.readIntRf.map(_.addr)
118//  fpRf.io.readPorts <> dispatch2.io.readFpRf
119//  rename.io.fpRfReadAddr <> dispatch2.io.readFpRf.map(_.addr)
120//
121//>>>>>>> d43dd6a5febdaa239b3a31d11582e3adbaa3014d
122
123  val exeWbReqs = exeUnits.map(_.io.out)
124  val wbIntReqs = (bruExeUnit +: (aluExeUnits ++ mulExeUnits ++ mduExeUnits)).map(_.io.out)
125  val wbFpReqs = (fmacExeUnits ++ fmiscExeUnits ++ fmiscDivSqrtExeUnits).map(_.io.out)
126  val intWbArb = Module(new WriteBackArbMtoN(wbIntReqs.length, NRWritePorts))
127  val fpWbArb = Module(new WriteBackArbMtoN(wbFpReqs.length, NRWritePorts))
128  val wbIntResults = intWbArb.io.out
129  val wbFpResults = fpWbArb.io.out
130
131  def exuOutToRfWrite(x: Valid[ExuOutput]) = {
132    val rfWrite = Wire(new RfWritePort)
133    rfWrite.wen := x.valid
134    rfWrite.addr := x.bits.uop.pdest
135    rfWrite.data := x.bits.data
136    rfWrite
137  }
138
139  intWbArb.io.in <> wbIntReqs
140  intRf.io.writePorts <> wbIntResults.map(exuOutToRfWrite)
141
142  fpWbArb.io.in <> wbFpReqs
143  fpRf.io.writePorts <> wbFpResults.map(exuOutToRfWrite)
144
145  rename.io.wbIntResults <> wbIntResults
146  rename.io.wbFpResults <> wbFpResults
147
148  roq.io.exeWbResults <> exeWbReqs
149
150
151  // TODO: Remove sink and source
152  val tmp = WireInit(0.U)
153  val sinks = Array[String](
154    "DTLBFINISH",
155    "DTLBPF",
156    "DTLBENABLE",
157    "perfCntCondMdcacheLoss",
158    "perfCntCondMl2cacheLoss",
159    "perfCntCondMdcacheHit",
160    "lsuMMIO",
161    "perfCntCondMl2cacheHit",
162    "perfCntCondMl2cacheReq",
163    "mtip",
164    "perfCntCondMdcacheReq",
165    "meip"
166  )
167  for (s <- sinks){ BoringUtils.addSink(tmp, s) }
168
169  // A fake commit
170  // TODO: difftest 6 insts per cycle
171  val commit = RegNext(RegNext(RegNext(true.B)))
172  val pc = WireInit("h80000000".U)
173  val inst = WireInit("h66666666".U)
174
175  if(!p.FPGAPlatform){
176    BoringUtils.addSource(commit, "difftestCommit")
177    BoringUtils.addSource(pc, "difftestThisPC")
178    BoringUtils.addSource(inst, "difftestThisINST")
179    BoringUtils.addSource(tmp, "difftestIsMMIO")
180    BoringUtils.addSource(tmp, "difftestIsRVC")
181    BoringUtils.addSource(tmp, "difftestIntrNO")
182    BoringUtils.addSource(VecInit(Seq.fill(64)(tmp)), "difftestRegs")
183    BoringUtils.addSource(tmp, "difftestMode")
184    BoringUtils.addSource(tmp, "difftestMstatus")
185    BoringUtils.addSource(tmp, "difftestSstatus")
186    BoringUtils.addSource(tmp, "difftestMepc")
187    BoringUtils.addSource(tmp, "difftestSepc")
188    BoringUtils.addSource(tmp, "difftestMcause")
189    BoringUtils.addSource(tmp, "difftestScause")
190  }
191
192}
193