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