1/*************************************************************************************** 2* Copyright (c) 2020-2021 Institute of Computing Technology, Chinese Academy of Sciences 3* 4* XiangShan is licensed under Mulan PSL v2. 5* You can use this software according to the terms and conditions of the Mulan PSL v2. 6* You may obtain a copy of Mulan PSL v2 at: 7* http://license.coscl.org.cn/MulanPSL2 8* 9* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, 10* EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, 11* MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE. 12* 13* See the Mulan PSL v2 for more details. 14***************************************************************************************/ 15 16package xiangshan.frontend 17import utils._ 18import chisel3._ 19import chisel3.util._ 20import chipsalliance.rocketchip.config.Parameters 21import freechips.rocketchip.diplomacy.{LazyModule, LazyModuleImp} 22import xiangshan._ 23import xiangshan.cache._ 24import xiangshan.cache.prefetch.L1plusPrefetcher 25import xiangshan.backend.fu.HasExceptionNO 26import system.L1CacheErrorInfo 27 28 29class Frontend()(implicit p: Parameters) extends LazyModule with HasXSParameter{ 30 31 val instrUncache = LazyModule(new InstrUncache()) 32 33 lazy val module = new FrontendImp(this) 34} 35 36 37class FrontendImp (outer: Frontend) extends LazyModuleImp(outer) 38 with HasL1plusCacheParameters 39 with HasXSParameter 40 with HasExceptionNO 41{ 42 val io = IO(new Bundle() { 43 val icacheMemAcq = DecoupledIO(new L1plusCacheReq) 44 val icacheMemGrant = Flipped(DecoupledIO(new L1plusCacheResp)) 45 val l1plusFlush = Output(Bool()) 46 val fencei = Input(Bool()) 47 val ptw = new TlbPtwIO 48 val backend = new FrontendToCtrlIO 49 val sfence = Input(new SfenceBundle) 50 val tlbCsr = Input(new TlbCsrBundle) 51 val csrCtrl = Input(new CustomCSRCtrlIO) 52 val error = new L1CacheErrorInfo 53 val frontendInfo = new Bundle { 54 val ibufFull = Output(Bool()) 55 val bpuInfo = new Bundle { 56 val bpRight = Output(UInt(XLEN.W)) 57 val bpWrong = Output(UInt(XLEN.W)) 58 } 59 } 60 }) 61 62 val bpu = Module(new Predictor) 63 val ifu = Module(new NewIFU) 64 val ibuffer = Module(new Ibuffer) 65 val l1plusPrefetcher = Module(new L1plusPrefetcher) 66 val icacheMeta = Module(new ICacheMetaArray) 67 val icacheData = Module(new ICacheDataArray) 68 val icacheMissQueue = Module(new ICacheMissQueue) 69 val instrUncache = outer.instrUncache.module 70 val ftq = Module(new Ftq) 71 72 val needFlush = io.backend.redirect_cfiUpdate.valid 73 74 //IFU-Ftq 75 ifu.io.ftqInter.fromFtq <> ftq.io.toIfu 76 ftq.io.fromIfu <> ifu.io.ftqInter.toFtq 77 bpu.io.ftq_to_bpu <> ftq.io.toBpu 78 ftq.io.fromBpu <> bpu.io.bpu_to_ftq 79 //IFU-ICache 80 ifu.io.icacheInter.toIMeta <> icacheMeta.io.read 81 ifu.io.icacheInter.fromIMeta <> icacheMeta.io.readResp 82 ifu.io.icacheInter.toIData <> icacheData.io.read 83 ifu.io.icacheInter.fromIData <> icacheData.io.readResp 84 85 for(i <- 0 until 2){ 86 ifu.io.icacheInter.fromMissQueue(i) <> icacheMissQueue.io.resp(i) 87 icacheMissQueue.io.req(i) <> ifu.io.icacheInter.toMissQueue(i) 88 } 89 //IFU-Ibuffer 90 ifu.io.toIbuffer <> ibuffer.io.in 91 92 //ICache 93 icacheMeta.io.write <> icacheMissQueue.io.meta_write 94 icacheData.io.write <> icacheMissQueue.io.data_write 95 96 // to icache 97 val grantClientId = clientId(io.icacheMemGrant.bits.id) 98 val grantEntryId = entryId(io.icacheMemGrant.bits.id) 99 100 l1plusPrefetcher.io.mem_grant.valid := io.icacheMemGrant.valid && grantClientId === l1plusPrefetcherId.U 101 l1plusPrefetcher.io.mem_grant.bits := io.icacheMemGrant.bits 102 l1plusPrefetcher.io.mem_grant.bits.id := Cat(0.U(clientIdWidth.W), grantEntryId) 103 assert(RegNext(!l1plusPrefetcher.io.mem_grant.valid || (l1plusPrefetcher.io.mem_grant.ready && grantClientId === l1plusPrefetcherId.U))) 104 io.icacheMemGrant.ready := Mux(grantClientId === icacheMissQueueId.U, 105 icacheMissQueue.io.mem_grant.ready, 106 l1plusPrefetcher.io.mem_grant.ready) 107 //ifu.io.fencei := RegNext(io.fencei) 108 109 ftq.io.fromBackend <> io.backend.toFtq 110 io.backend.fromFtq <> ftq.io.toBackend 111 io.frontendInfo.bpuInfo <> ftq.io.bpuInfo 112 113 114 instrUncache.io.req <> DontCare 115 instrUncache.io.resp <> DontCare 116 instrUncache.io.flush <> DontCare 117 // to tlb 118 119 120 // from icache and l1plus prefetcher 121 io.l1plusFlush := DontCare 122 l1plusPrefetcher.io.in.valid := DontCare 123 l1plusPrefetcher.io.in.bits := DontCare 124 l1plusPrefetcher.io.enable := RegNext(io.csrCtrl.l1plus_pf_enable) 125 val memAcquireArb = Module(new Arbiter(new L1plusCacheReq, nClients)) 126 memAcquireArb.io.in(icacheMissQueueId) <> icacheMissQueue.io.mem_acquire 127 memAcquireArb.io.in(icacheMissQueueId).bits.id := Cat(icacheMissQueueId.U(clientIdWidth.W), 128 entryId(icacheMissQueue.io.mem_acquire.bits.id)) 129 memAcquireArb.io.in(l1plusPrefetcherId) <> l1plusPrefetcher.io.mem_acquire 130 memAcquireArb.io.in(l1plusPrefetcherId).bits.id := Cat(l1plusPrefetcherId.U(clientIdWidth.W), 131 entryId(l1plusPrefetcher.io.mem_acquire.bits.id)) 132 io.icacheMemAcq <> memAcquireArb.io.out 133 // itlb to ptw 134 io.ptw <> DontCare 135 // backend to ibuffer 136 ibuffer.io.flush := needFlush 137 // ibuffer to backend 138 io.backend.cfVec <> ibuffer.io.out 139 140 io.error <> DontCare 141 142 val frontendBubble = PopCount((0 until DecodeWidth).map(i => io.backend.cfVec(i).ready && !ibuffer.io.out(i).valid)) 143 XSPerfAccumulate("FrontendBubble", frontendBubble) 144 145 io.frontendInfo.ibufFull := RegNext(ibuffer.io.full) 146} 147