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