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.{Dispatch1, Dispatch2} 13import xiangshan.backend.exu._ 14import xiangshan.backend.issue.IssueQueue 15import xiangshan.backend.regfile.Regfile 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 dispatch1 = Module(new Dispatch1) 38 val roq = Module(new Roq) 39 val dispatch2 = Module(new Dispatch2) 40 val intRf = Module(new Regfile( 41 numReadPorts = NRReadPorts, 42 numWirtePorts = NRWritePorts, 43 hasZero = true 44 )) 45 val fpRf = Module(new Regfile( 46 numReadPorts = NRReadPorts, 47 numWirtePorts = NRWritePorts, 48 hasZero = false 49 )) 50 val redirect = Mux(roq.io.redirect.valid, roq.io.redirect, brq.io.redirect) 51 val issueQueues = exeUnits.zipWithIndex.map({ case(eu, i) => 52 def needWakeup(x: Exu): Boolean = (eu.readIntRf && x.writeIntRf) || (eu.readFpRf && x.writeFpRf) 53 val wakeupCnt = exeUnits.count(needWakeup) 54 val bypassCnt = if(eu.fuTypeInt == FuType.alu.litValue()) exuConfig.AluCnt else 0 55 val iq = Module(new IssueQueue(eu.fuTypeInt, wakeupCnt, bypassCnt)) 56 iq.io.redirect <> redirect 57 iq.io.enqCtrl <> dispatch2.io.enqIQCtrl(i) 58 iq.io.enqData <> dispatch2.io.enqIQData(i) 59 iq.io.wakeUpPorts <> exeUnits.filter(needWakeup).map(_.io.out) 60 if(eu.fuTypeInt == FuType.alu.litValue()){ 61 iq.io.bypassPorts <> aluExeUnits.map(_.io.out) 62 } 63 println(s"[$i] $eu wakeupCnt:$wakeupCnt bypassCnt:$bypassCnt") 64 eu.io.in <> iq.io.deq 65 iq 66 }) 67 68 io.frontend.redirect <> redirect 69 io.frontend.commits <> roq.io.commits 70 71 decode.io.in <> io.frontend.cfVec 72 brq.io.roqRedirect <> roq.io.redirect 73 brq.io.enqReqs <> decode.io.toBrq 74 decode.io.brMasks <> brq.io.brMasks 75 decode.io.brTags <> brq.io.brTags 76 decBuf.io.in <> decode.io.out 77 78 rename.io.redirect <> redirect 79 rename.io.roqCommits <> roq.io.commits 80 rename.io.in <> decBuf.io.out 81 82 dispatch1.io.redirect <> redirect 83 dispatch1.io.in <> rename.io.out 84 roq.io.brqRedirect <> brq.io.redirect 85 roq.io.dp1Req <> dispatch1.io.toRoq 86 dispatch1.io.roqIdxs <> roq.io.roqIdxs 87 88 dispatch2.io.in <> dispatch1.io.out 89 intRf.io.readPorts <> dispatch2.io.readIntRf 90 fpRf.io.readPorts <> dispatch2.io.readFpRf 91 92 93 val exeWbReqs = exeUnits.map(_.io.out) 94 val wbIntReqs = (bruExeUnit +: (aluExeUnits ++ mulExeUnits ++ mduExeUnits)).map(_.io.out) 95 val wbFpReqs = (fmacExeUnits ++ fmiscExeUnits ++ fmiscDivSqrtExeUnits).map(_.io.out) 96 val intWbArb = Module(new WriteBackArbMtoN(wbIntReqs.length, NRWritePorts)) 97 val fpWbArb = Module(new WriteBackArbMtoN(wbFpReqs.length, NRWritePorts)) 98 99 intWbArb.io.in <> wbIntReqs 100 intRf.io.writePorts <> intWbArb.io.out 101 102 fpWbArb.io.in <> wbFpReqs 103 fpRf.io.writePorts <> fpWbArb.io.out 104 105 roq.io.exeWbResults <> exeWbReqs 106 107 108 // TODO: Remove sink and source 109 val tmp = WireInit(0.U) 110 val sinks = Array[String]( 111 "DTLBFINISH", 112 "DTLBPF", 113 "DTLBENABLE", 114 "perfCntCondMdcacheLoss", 115 "perfCntCondMl2cacheLoss", 116 "perfCntCondMdcacheHit", 117 "lsuMMIO", 118 "perfCntCondMl2cacheHit", 119 "perfCntCondMl2cacheReq", 120 "mtip", 121 "perfCntCondMdcacheReq", 122 "meip" 123 ) 124 for (s <- sinks){ BoringUtils.addSink(tmp, s) } 125 126 // A fake commit 127 // TODO: difftest 6 insts per cycle 128 val commit = RegNext(RegNext(RegNext(true.B))) 129 val pc = WireInit("h80000000".U) 130 val inst = WireInit("h66666666".U) 131 132 if(!p.FPGAPlatform){ 133 BoringUtils.addSource(commit, "difftestCommit") 134 BoringUtils.addSource(pc, "difftestThisPC") 135 BoringUtils.addSource(inst, "difftestThisINST") 136 BoringUtils.addSource(tmp, "difftestIsMMIO") 137 BoringUtils.addSource(tmp, "difftestIsRVC") 138 BoringUtils.addSource(tmp, "difftestIntrNO") 139 BoringUtils.addSource(VecInit(Seq.fill(64)(tmp)), "difftestRegs") 140 BoringUtils.addSource(tmp, "difftestMode") 141 BoringUtils.addSource(tmp, "difftestMstatus") 142 BoringUtils.addSource(tmp, "difftestSstatus") 143 BoringUtils.addSource(tmp, "difftestMepc") 144 BoringUtils.addSource(tmp, "difftestSepc") 145 BoringUtils.addSource(tmp, "difftestMcause") 146 BoringUtils.addSource(tmp, "difftestScause") 147 } 148 149} 150