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