11f0e2dc7SJiawei Lin/*************************************************************************************** 21f0e2dc7SJiawei Lin* Copyright (c) 2020-2021 Institute of Computing Technology, Chinese Academy of Sciences 31f0e2dc7SJiawei Lin* Copyright (c) 2020-2021 Peng Cheng Laboratory 41f0e2dc7SJiawei Lin* 51f0e2dc7SJiawei Lin* XiangShan is licensed under Mulan PSL v2. 61f0e2dc7SJiawei Lin* You can use this software according to the terms and conditions of the Mulan PSL v2. 71f0e2dc7SJiawei Lin* You may obtain a copy of Mulan PSL v2 at: 81f0e2dc7SJiawei Lin* http://license.coscl.org.cn/MulanPSL2 91f0e2dc7SJiawei Lin* 101f0e2dc7SJiawei Lin* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, 111f0e2dc7SJiawei Lin* EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, 121f0e2dc7SJiawei Lin* MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE. 131f0e2dc7SJiawei Lin* 141f0e2dc7SJiawei Lin* See the Mulan PSL v2 for more details. 151f0e2dc7SJiawei Lin***************************************************************************************/ 161f0e2dc7SJiawei Lin 171f0e2dc7SJiawei Linpackage xiangshan.cache 181f0e2dc7SJiawei Lin 198891a219SYinan Xuimport org.chipsalliance.cde.config.Parameters 201f0e2dc7SJiawei Linimport chisel3._ 211f0e2dc7SJiawei Linimport chisel3.util._ 221f0e2dc7SJiawei Linimport freechips.rocketchip.tilelink.ClientStates._ 231f0e2dc7SJiawei Linimport freechips.rocketchip.tilelink.MemoryOpCategories._ 241f0e2dc7SJiawei Linimport freechips.rocketchip.tilelink.TLPermissions._ 251f0e2dc7SJiawei Linimport freechips.rocketchip.tilelink.{ClientMetadata, ClientStates, TLPermissions} 26ad3ba452Szhanglinjuanimport utils._ 273c02ee8fSwakafaimport utility._ 28d2b20d1aSTang Haojinimport xiangshan.{L1CacheErrorInfo, XSCoreParamsKey} 29ffd3154dSCharlieLiuimport xiangshan.mem.prefetch._ 300d32f713Shappy-lximport xiangshan.mem.HasL1PrefetchSourceParameter 311f0e2dc7SJiawei Lin 32ad3ba452Szhanglinjuanclass MainPipeReq(implicit p: Parameters) extends DCacheBundle { 33ad3ba452Szhanglinjuan val miss = Bool() // only amo miss will refill in main pipe 341f0e2dc7SJiawei Lin val miss_id = UInt(log2Up(cfg.nMissEntries).W) 351f0e2dc7SJiawei Lin val miss_param = UInt(TLPermissions.bdWidth.W) 361f0e2dc7SJiawei Lin val miss_dirty = Bool() 371f0e2dc7SJiawei Lin 381f0e2dc7SJiawei Lin val probe = Bool() 391f0e2dc7SJiawei Lin val probe_param = UInt(TLPermissions.bdWidth.W) 401f0e2dc7SJiawei Lin val probe_need_data = Bool() 411f0e2dc7SJiawei Lin 421f0e2dc7SJiawei Lin // request info 43ad3ba452Szhanglinjuan // reqs from Store, AMO use this 441f0e2dc7SJiawei Lin // probe does not use this 451f0e2dc7SJiawei Lin val source = UInt(sourceTypeWidth.W) 461f0e2dc7SJiawei Lin val cmd = UInt(M_SZ.W) 471f0e2dc7SJiawei Lin // if dcache size > 32KB, vaddr is also needed for store 481f0e2dc7SJiawei Lin // vaddr is used to get extra index bits 491f0e2dc7SJiawei Lin val vaddr = UInt(VAddrBits.W) 501f0e2dc7SJiawei Lin // must be aligned to block 511f0e2dc7SJiawei Lin val addr = UInt(PAddrBits.W) 521f0e2dc7SJiawei Lin 531f0e2dc7SJiawei Lin // store 541f0e2dc7SJiawei Lin val store_data = UInt((cfg.blockBytes * 8).W) 551f0e2dc7SJiawei Lin val store_mask = UInt(cfg.blockBytes.W) 561f0e2dc7SJiawei Lin 571f0e2dc7SJiawei Lin // which word does amo work on? 581f0e2dc7SJiawei Lin val word_idx = UInt(log2Up(cfg.blockBytes * 8 / DataBits).W) 5938c29594Szhanglinjuan val amo_data = UInt(QuadWordBits.W) 6038c29594Szhanglinjuan val amo_mask = UInt(QuadWordBytes.W) 6138c29594Szhanglinjuan val amo_cmp = UInt(QuadWordBits.W) // data to be compared in AMOCAS 621f0e2dc7SJiawei Lin 630f59c834SWilliam Wang // error 640f59c834SWilliam Wang val error = Bool() 650f59c834SWilliam Wang 66578c21a4Szhanglinjuan // replace 67578c21a4Szhanglinjuan val replace = Bool() 68578c21a4Szhanglinjuan val replace_way_en = UInt(DCacheWays.W) 69578c21a4Szhanglinjuan 70ffd3154dSCharlieLiu // prefetch 71ffd3154dSCharlieLiu val pf_source = UInt(L1PfSourceBits.W) 72ffd3154dSCharlieLiu val access = Bool() 73ffd3154dSCharlieLiu 741f0e2dc7SJiawei Lin val id = UInt(reqIdWidth.W) 751f0e2dc7SJiawei Lin 76ad3ba452Szhanglinjuan def isLoad: Bool = source === LOAD_SOURCE.U 77ad3ba452Szhanglinjuan def isStore: Bool = source === STORE_SOURCE.U 78ad3ba452Szhanglinjuan def isAMO: Bool = source === AMO_SOURCE.U 791f0e2dc7SJiawei Lin 8038c29594Szhanglinjuan def quad_word_idx = word_idx >> 1 8138c29594Szhanglinjuan 82ad3ba452Szhanglinjuan def convertStoreReq(store: DCacheLineReq): MainPipeReq = { 83ad3ba452Szhanglinjuan val req = Wire(new MainPipeReq) 84ad3ba452Szhanglinjuan req := DontCare 85ad3ba452Szhanglinjuan req.miss := false.B 86ad3ba452Szhanglinjuan req.miss_dirty := false.B 87ad3ba452Szhanglinjuan req.probe := false.B 88ad3ba452Szhanglinjuan req.probe_need_data := false.B 89ad3ba452Szhanglinjuan req.source := STORE_SOURCE.U 90ad3ba452Szhanglinjuan req.cmd := store.cmd 91ad3ba452Szhanglinjuan req.addr := store.addr 92ad3ba452Szhanglinjuan req.vaddr := store.vaddr 93ad3ba452Szhanglinjuan req.store_data := store.data 94ad3ba452Szhanglinjuan req.store_mask := store.mask 95578c21a4Szhanglinjuan req.replace := false.B 960f59c834SWilliam Wang req.error := false.B 97ad3ba452Szhanglinjuan req.id := store.id 98ad3ba452Szhanglinjuan req 991f0e2dc7SJiawei Lin } 1001f0e2dc7SJiawei Lin} 1011f0e2dc7SJiawei Lin 102c3a5fe5fShappy-lxclass MainPipeStatus(implicit p: Parameters) extends DCacheBundle { 103c3a5fe5fShappy-lx val set = UInt(idxBits.W) 104c3a5fe5fShappy-lx val way_en = UInt(nWays.W) 105c3a5fe5fShappy-lx} 106c3a5fe5fShappy-lx 107ffd3154dSCharlieLiuclass MainPipeInfoToMQ(implicit p:Parameters) extends DCacheBundle { 10873c515a4SCharlieLiu val s2_valid = Bool() 109ffd3154dSCharlieLiu val s2_miss_id = UInt(log2Up(cfg.nMissEntries).W) // For refill data selection 110ffd3154dSCharlieLiu val s2_replay_to_mq = Bool() 11173c515a4SCharlieLiu val s3_valid = Bool() 112ffd3154dSCharlieLiu val s3_miss_id = UInt(log2Up(cfg.nMissEntries).W) // For mshr release 113ffd3154dSCharlieLiu val s3_refill_resp = Bool() 114ffd3154dSCharlieLiu} 115ffd3154dSCharlieLiu 1160d32f713Shappy-lxclass MainPipe(implicit p: Parameters) extends DCacheModule with HasPerfEvents with HasL1PrefetchSourceParameter { 117ad3ba452Szhanglinjuan val io = IO(new Bundle() { 118ad3ba452Szhanglinjuan // probe queue 119ad3ba452Szhanglinjuan val probe_req = Flipped(DecoupledIO(new MainPipeReq)) 120ad3ba452Szhanglinjuan // store miss go to miss queue 121a98b054bSWilliam Wang val miss_req = DecoupledIO(new MissReq) 122fa9ac9b6SWilliam Wang val miss_resp = Input(new MissResp) // miss resp is used to support plru update 123ffd3154dSCharlieLiu val refill_req = Flipped(DecoupledIO(new MainPipeReq)) 12408b0bc30Shappy-lx // send miss request to wbq 12508b0bc30Shappy-lx val wbq_conflict_check = Valid(UInt()) 12608b0bc30Shappy-lx val wbq_block_miss_req = Input(Bool()) 127ad3ba452Szhanglinjuan // store buffer 128ad3ba452Szhanglinjuan val store_req = Flipped(DecoupledIO(new DCacheLineReq)) 129ad3ba452Szhanglinjuan val store_replay_resp = ValidIO(new DCacheLineResp) 130ad3ba452Szhanglinjuan val store_hit_resp = ValidIO(new DCacheLineResp) 131ad3ba452Szhanglinjuan // atmoics 132ad3ba452Szhanglinjuan val atomic_req = Flipped(DecoupledIO(new MainPipeReq)) 133ffd3154dSCharlieLiu val atomic_resp = ValidIO(new MainPipeResp) 134ffd3154dSCharlieLiu // find matched refill data in missentry 135ffd3154dSCharlieLiu val mainpipe_info = Output(new MainPipeInfoToMQ) 136ffd3154dSCharlieLiu // missqueue refill data 137ffd3154dSCharlieLiu val refill_info = Flipped(ValidIO(new MissQueueRefillInfo)) 138ad3ba452Szhanglinjuan // write-back queue 139ad3ba452Szhanglinjuan val wb = DecoupledIO(new WritebackReq) 140c3a5fe5fShappy-lx val wb_ready_dup = Vec(nDupWbReady, Input(Bool())) 1411f0e2dc7SJiawei Lin 142b8f6ff86SWilliam Wang // data sram 143d2b20d1aSTang Haojin val data_read = Vec(LoadPipelineWidth, Input(Bool())) 1447a5caa97Szhanglinjuan val data_read_intend = Output(Bool()) 145d2b20d1aSTang Haojin val data_readline = DecoupledIO(new L1BankedDataReadLineReq) 146ebe07d61S梁森 Liang Sen val data_readline_can_go = Output(Bool()) 147ebe07d61S梁森 Liang Sen val data_readline_stall = Output(Bool()) 148ebe07d61S梁森 Liang Sen val data_readline_can_resp = Output(Bool()) 149ad3ba452Szhanglinjuan val data_resp = Input(Vec(DCacheBanks, new L1BankedDataReadResult())) 1506786cfb7SWilliam Wang val readline_error_delayed = Input(Bool()) 151ad3ba452Szhanglinjuan val data_write = DecoupledIO(new L1BankedDataWriteReq) 1526c7e5e86Szhanglinjuan val data_write_dup = Vec(DCacheBanks, Valid(new L1BankedDataWriteReqCtrl)) 153c3a5fe5fShappy-lx val data_write_ready_dup = Vec(nDupDataWriteReady, Input(Bool())) 1541f0e2dc7SJiawei Lin 155b8f6ff86SWilliam Wang // meta array 156ad3ba452Szhanglinjuan val meta_read = DecoupledIO(new MetaReadReq) 15741b68474SWilliam Wang val meta_resp = Input(Vec(nWays, new Meta)) 1583af6aa6eSWilliam Wang val meta_write = DecoupledIO(new CohMetaWriteReq) 1593af6aa6eSWilliam Wang val extra_meta_resp = Input(Vec(nWays, new DCacheExtraMeta)) 1603af6aa6eSWilliam Wang val error_flag_write = DecoupledIO(new FlagMetaWriteReq) 1610d32f713Shappy-lx val prefetch_flag_write = DecoupledIO(new SourceMetaWriteReq) 1623af6aa6eSWilliam Wang val access_flag_write = DecoupledIO(new FlagMetaWriteReq) 1631f0e2dc7SJiawei Lin 164b8f6ff86SWilliam Wang // tag sram 165ad3ba452Szhanglinjuan val tag_read = DecoupledIO(new TagReadReq) 16641b68474SWilliam Wang val tag_resp = Input(Vec(nWays, UInt(encTagBits.W))) 167ad3ba452Szhanglinjuan val tag_write = DecoupledIO(new TagWriteReq) 168c3a5fe5fShappy-lx val tag_write_ready_dup = Vec(nDupTagWriteReady, Input(Bool())) 16909ae47d2SWilliam Wang val tag_write_intend = Output(new Bool()) 170ad3ba452Szhanglinjuan 171ad3ba452Szhanglinjuan // update state vec in replacement algo 172ad3ba452Szhanglinjuan val replace_access = ValidIO(new ReplacementAccessBundle) 173ad3ba452Szhanglinjuan // find the way to be replaced 174ad3ba452Szhanglinjuan val replace_way = new ReplacementWayReqIO 175ad3ba452Szhanglinjuan 1761461d8f8SCharlieLiu // writeback addr to be replaced 1777ecd6591SCharlie Liu val replace_addr = ValidIO(UInt(PAddrBits.W)) 1787ecd6591SCharlie Liu val replace_block = Input(Bool()) 1791461d8f8SCharlieLiu 180ffd3154dSCharlieLiu // sms prefetch 181ffd3154dSCharlieLiu val sms_agt_evict_req = DecoupledIO(new AGTEvictReq) 182ffd3154dSCharlieLiu 183ad3ba452Szhanglinjuan val status = new Bundle() { 184ad3ba452Szhanglinjuan val s0_set = ValidIO(UInt(idxBits.W)) 185c3a5fe5fShappy-lx val s1, s2, s3 = ValidIO(new MainPipeStatus) 186ad3ba452Szhanglinjuan } 187c3a5fe5fShappy-lx val status_dup = Vec(nDupStatus, new Bundle() { 188c3a5fe5fShappy-lx val s1, s2, s3 = ValidIO(new MainPipeStatus) 189c3a5fe5fShappy-lx }) 1901f0e2dc7SJiawei Lin 1911f0e2dc7SJiawei Lin // lrsc locked block should block probe 1921f0e2dc7SJiawei Lin val lrsc_locked_block = Output(Valid(UInt(PAddrBits.W))) 193ad3ba452Szhanglinjuan val invalid_resv_set = Input(Bool()) 194300ded30SWilliam Wang val update_resv_set = Output(Bool()) 195b899def8SWilliam Wang val block_lr = Output(Bool()) 196dd95524eSzhanglinjuan 197dd95524eSzhanglinjuan // ecc error 1980184a80eSYanqin Li val error = Output(ValidIO(new L1CacheErrorInfo)) 19972dab974Scz4e val pseudo_error = Flipped(DecoupledIO(Vec(DCacheBanks, new CtrlUnitSignalingBundle))) 20072dab974Scz4e val pseudo_tag_error_inj_done = Output(Bool()) 20172dab974Scz4e val pseudo_data_error_inj_done = Output(Bool()) 2022fdb4d6aShappy-lx // force write 2032fdb4d6aShappy-lx val force_write = Input(Bool()) 204ffd3154dSCharlieLiu 205ffd3154dSCharlieLiu val bloom_filter_query = new Bundle { 206ffd3154dSCharlieLiu val set = ValidIO(new BloomQueryBundle(BLOOM_FILTER_ENTRY_NUM)) 207ffd3154dSCharlieLiu val clr = ValidIO(new BloomQueryBundle(BLOOM_FILTER_ENTRY_NUM)) 208ffd3154dSCharlieLiu } 2091f0e2dc7SJiawei Lin }) 2101f0e2dc7SJiawei Lin 211ad3ba452Szhanglinjuan // meta array is made of regs, so meta write or read should always be ready 212ad3ba452Szhanglinjuan assert(RegNext(io.meta_read.ready)) 213ad3ba452Szhanglinjuan assert(RegNext(io.meta_write.ready)) 2141f0e2dc7SJiawei Lin 215ad3ba452Szhanglinjuan val s1_s0_set_conflict, s2_s0_set_conlict, s3_s0_set_conflict = Wire(Bool()) 216ad3ba452Szhanglinjuan val set_conflict = s1_s0_set_conflict || s2_s0_set_conlict || s3_s0_set_conflict 21769790076Szhanglinjuan // check sbuffer store req set_conflict in parallel with req arbiter 21869790076Szhanglinjuan // it will speed up the generation of store_req.ready, which is in crit. path 21969790076Szhanglinjuan val s1_s0_set_conflict_store, s2_s0_set_conlict_store, s3_s0_set_conflict_store = Wire(Bool()) 22069790076Szhanglinjuan val store_set_conflict = s1_s0_set_conflict_store || s2_s0_set_conlict_store || s3_s0_set_conflict_store 2211f0e2dc7SJiawei Lin val s1_ready, s2_ready, s3_ready = Wire(Bool()) 2221f0e2dc7SJiawei Lin 223ad3ba452Szhanglinjuan // convert store req to main pipe req, and select a req from store and probe 224d2b20d1aSTang Haojin val storeWaitCycles = RegInit(0.U(4.W)) 2252fdb4d6aShappy-lx val StoreWaitThreshold = Wire(UInt(4.W)) 226c686adcdSYinan Xu StoreWaitThreshold := Constantin.createRecord(s"StoreWaitThreshold_${p(XSCoreParamsKey).HartId}", initValue = 0) 227d2b20d1aSTang Haojin val storeWaitTooLong = storeWaitCycles >= StoreWaitThreshold 228d2b20d1aSTang Haojin val loadsAreComing = io.data_read.asUInt.orR 2292fdb4d6aShappy-lx val storeCanAccept = storeWaitTooLong || !loadsAreComing || io.force_write 230d2b20d1aSTang Haojin 231ad3ba452Szhanglinjuan val store_req = Wire(DecoupledIO(new MainPipeReq)) 232ad3ba452Szhanglinjuan store_req.bits := (new MainPipeReq).convertStoreReq(io.store_req.bits) 233d2b20d1aSTang Haojin store_req.valid := io.store_req.valid && storeCanAccept 234d2b20d1aSTang Haojin io.store_req.ready := store_req.ready && storeCanAccept 235d2b20d1aSTang Haojin 236ffd3154dSCharlieLiu 237d2b20d1aSTang Haojin when (store_req.fire) { // if wait too long and write success, reset counter. 238d2b20d1aSTang Haojin storeWaitCycles := 0.U 2392fdb4d6aShappy-lx } .elsewhen (storeWaitCycles < StoreWaitThreshold && io.store_req.valid && !store_req.ready) { // if block store, increase counter. 240d2b20d1aSTang Haojin storeWaitCycles := storeWaitCycles + 1.U 241d2b20d1aSTang Haojin } 242ad3ba452Szhanglinjuan 243ad3ba452Szhanglinjuan // s0: read meta and tag 244ad3ba452Szhanglinjuan val req = Wire(DecoupledIO(new MainPipeReq)) 245578c21a4Szhanglinjuan arbiter( 246578c21a4Szhanglinjuan in = Seq( 247578c21a4Szhanglinjuan io.probe_req, 248ffd3154dSCharlieLiu io.refill_req, 249c2bbba9fSCharlieLiu store_req, // Note: store_req.ready is now manually assigned for better timing 250ffd3154dSCharlieLiu io.atomic_req, 251578c21a4Szhanglinjuan ), 252578c21a4Szhanglinjuan out = req, 253578c21a4Szhanglinjuan name = Some("main_pipe_req") 254578c21a4Szhanglinjuan ) 25569790076Szhanglinjuan 25669790076Szhanglinjuan val store_idx = get_idx(io.store_req.bits.vaddr) 25769790076Szhanglinjuan // manually assign store_req.ready for better timing 25869790076Szhanglinjuan // now store_req set conflict check is done in parallel with req arbiter 25969790076Szhanglinjuan store_req.ready := io.meta_read.ready && io.tag_read.ready && s1_ready && !store_set_conflict && 260ffd3154dSCharlieLiu !io.probe_req.valid && !io.refill_req.valid && !io.atomic_req.valid 261ad3ba452Szhanglinjuan val s0_req = req.bits 262ad3ba452Szhanglinjuan val s0_idx = get_idx(s0_req.vaddr) 263e352f418SWilliam Wang val s0_need_tag = io.tag_read.valid 264ad3ba452Szhanglinjuan val s0_can_go = io.meta_read.ready && io.tag_read.ready && s1_ready && !set_conflict 265ad3ba452Szhanglinjuan val s0_fire = req.valid && s0_can_go 2661f0e2dc7SJiawei Lin 2672f0227efScz4e req.ready := s0_can_go 2682f0227efScz4e 2691f0e2dc7SJiawei Lin val bank_write = VecInit((0 until DCacheBanks).map(i => get_mask_of_bank(i, s0_req.store_mask).orR)).asUInt 2701f0e2dc7SJiawei Lin val bank_full_write = VecInit((0 until DCacheBanks).map(i => get_mask_of_bank(i, s0_req.store_mask).andR)).asUInt 2711f0e2dc7SJiawei Lin val banks_full_overwrite = bank_full_write.andR 2721f0e2dc7SJiawei Lin 2731f0e2dc7SJiawei Lin val banked_store_rmask = bank_write & ~bank_full_write 2741f0e2dc7SJiawei Lin val banked_full_rmask = ~0.U(DCacheBanks.W) 2751f0e2dc7SJiawei Lin val banked_none_rmask = 0.U(DCacheBanks.W) 2761f0e2dc7SJiawei Lin 277ad3ba452Szhanglinjuan val store_need_data = !s0_req.probe && s0_req.isStore && banked_store_rmask.orR 2781f0e2dc7SJiawei Lin val probe_need_data = s0_req.probe 279ad3ba452Szhanglinjuan val amo_need_data = !s0_req.probe && s0_req.isAMO 280ad3ba452Szhanglinjuan val miss_need_data = s0_req.miss 281578c21a4Szhanglinjuan val replace_need_data = s0_req.replace 2821f0e2dc7SJiawei Lin 283578c21a4Szhanglinjuan val banked_need_data = store_need_data || probe_need_data || amo_need_data || miss_need_data || replace_need_data 2841f0e2dc7SJiawei Lin 285ad3ba452Szhanglinjuan val s0_banked_rmask = Mux(store_need_data, banked_store_rmask, 286578c21a4Szhanglinjuan Mux(probe_need_data || amo_need_data || miss_need_data || replace_need_data, 2871f0e2dc7SJiawei Lin banked_full_rmask, 2881f0e2dc7SJiawei Lin banked_none_rmask 2891f0e2dc7SJiawei Lin )) 2901f0e2dc7SJiawei Lin 2911f0e2dc7SJiawei Lin // generate wmask here and use it in stage 2 2921f0e2dc7SJiawei Lin val banked_store_wmask = bank_write 2931f0e2dc7SJiawei Lin val banked_full_wmask = ~0.U(DCacheBanks.W) 2941f0e2dc7SJiawei Lin val banked_none_wmask = 0.U(DCacheBanks.W) 2951f0e2dc7SJiawei Lin 296ad3ba452Szhanglinjuan // s1: read data 2971f0e2dc7SJiawei Lin val s1_valid = RegInit(false.B) 2981f0e2dc7SJiawei Lin val s1_need_data = RegEnable(banked_need_data, s0_fire) 2991f0e2dc7SJiawei Lin val s1_req = RegEnable(s0_req, s0_fire) 3001f0e2dc7SJiawei Lin val s1_banked_rmask = RegEnable(s0_banked_rmask, s0_fire) 3011f0e2dc7SJiawei Lin val s1_banked_store_wmask = RegEnable(banked_store_wmask, s0_fire) 302e352f418SWilliam Wang val s1_need_tag = RegEnable(s0_need_tag, s0_fire) 303d2b20d1aSTang Haojin val s1_can_go = s2_ready && (io.data_readline.ready || !s1_need_data) 304ad3ba452Szhanglinjuan val s1_fire = s1_valid && s1_can_go 305ad3ba452Szhanglinjuan val s1_idx = get_idx(s1_req.vaddr) 3062f0227efScz4e val s1_dmWay = RegEnable(get_direct_map_way(s0_req.vaddr), s0_fire) 307b909b713Szhanglinjuan 3081f0e2dc7SJiawei Lin when (s0_fire) { 3091f0e2dc7SJiawei Lin s1_valid := true.B 3101f0e2dc7SJiawei Lin }.elsewhen (s1_fire) { 3111f0e2dc7SJiawei Lin s1_valid := false.B 3121f0e2dc7SJiawei Lin } 3132f0227efScz4e s1_ready := !s1_valid || s1_can_go 3142f0227efScz4e s1_s0_set_conflict := s1_valid && s0_idx === s1_idx 3152f0227efScz4e s1_s0_set_conflict_store := s1_valid && store_idx === s1_idx 3161f0e2dc7SJiawei Lin 317ad3ba452Szhanglinjuan def wayMap[T <: Data](f: Int => T) = VecInit((0 until nWays).map(f)) 31872dab974Scz4e val meta_resp = Wire(Vec(nWays, (new Meta).asUInt)) 31972dab974Scz4e meta_resp := Mux(GatedValidRegNext(s0_fire), VecInit(io.meta_resp.map(_.asUInt)), RegEnable(meta_resp, s1_valid)) 32072dab974Scz4e // pseudo ecc enc tag 32172dab974Scz4e val pseudo_tag_toggle_mask = Mux( 32272dab974Scz4e io.pseudo_error.valid && io.pseudo_error.bits(0).valid, 32372dab974Scz4e io.pseudo_error.bits(0).mask(tagBits - 1, 0), 32472dab974Scz4e 0.U(tagBits.W) 32572dab974Scz4e ) 32672dab974Scz4e val pseudo_encTag_resp = io.tag_resp.map { 32772dab974Scz4e case real_enc => 32872dab974Scz4e if (cacheCtrlParamsOpt.nonEmpty && EnableTagEcc) { 32972dab974Scz4e val ecc = real_enc(encTagBits - 1, tagBits) 33072dab974Scz4e val toggleTag = real_enc(tagBits - 1, 0) ^ pseudo_tag_toggle_mask 33172dab974Scz4e Cat(ecc, toggleTag) 33272dab974Scz4e } else { 33372dab974Scz4e real_enc 33472dab974Scz4e } 33572dab974Scz4e } 33672dab974Scz4e val encTag_resp = Wire(io.tag_resp.cloneType) 33772dab974Scz4e encTag_resp := Mux(GatedValidRegNext(s0_fire), VecInit(pseudo_encTag_resp), RegEnable(encTag_resp, s1_valid)) 33872dab974Scz4e val tag_resp = encTag_resp.map(encTag => encTag(tagBits - 1, 0)) 33972dab974Scz4e val s1_meta_valids = wayMap((w: Int) => Meta(meta_resp(w)).coh.isValid()).asUInt 34072dab974Scz4e val s1_tag_errors = wayMap((w: Int) => s1_meta_valids(w) && dcacheParameters.tagCode.decode(encTag_resp(w)).error).asUInt 341302eb948Scz4e val s1_tag_eq_way = wayMap((w: Int) => tag_resp(w) === get_tag(s1_req.addr)).asUInt 342302eb948Scz4e val s1_tag_ecc_eq_way = wayMap((w: Int) => s1_tag_eq_way(w) && !s1_tag_errors(w)).asUInt 343302eb948Scz4e val s1_tag_ecc_match_way = wayMap((w: Int) => s1_tag_ecc_eq_way(w) && s1_meta_valids(w)).asUInt 344302eb948Scz4e val s1_tag_match = ParallelORR(s1_tag_ecc_match_way) 345e20d4bd0Scz4e val s1_real_tag_match_way = Wire(UInt(nWays.W)) 346e20d4bd0Scz4e s1_real_tag_match_way := Mux( 347e20d4bd0Scz4e GatedValidRegNext(s0_fire), 348e20d4bd0Scz4e wayMap((w: Int) => io.tag_resp(w)(tagBits - 1, 0) === get_tag(s1_req.addr) && s1_meta_valids(w)).asUInt, 349e20d4bd0Scz4e RegEnable(s1_real_tag_match_way, 0.U.asTypeOf(s1_real_tag_match_way.cloneType), s1_valid) 350e20d4bd0Scz4e ) 351ad3ba452Szhanglinjuan 35295ee175cSsfencevma val s1_hit_tag = get_tag(s1_req.addr) 353302eb948Scz4e val s1_hit_coh = ClientMetadata(ParallelMux(s1_tag_ecc_match_way.asBools, (0 until nWays).map(w => meta_resp(w)))) 354302eb948Scz4e val s1_flag_error = ParallelMux(s1_tag_ecc_match_way.asBools, (0 until nWays).map(w => io.extra_meta_resp(w).error)) 355302eb948Scz4e val s1_extra_meta = ParallelMux(s1_tag_ecc_match_way.asBools, (0 until nWays).map(w => io.extra_meta_resp(w))) 35672dab974Scz4e io.pseudo_tag_error_inj_done := s1_fire && s1_meta_valids.orR 357ad3ba452Szhanglinjuan 3580d32f713Shappy-lx XSPerfAccumulate("probe_unused_prefetch", s1_req.probe && isFromL1Prefetch(s1_extra_meta.prefetch) && !s1_extra_meta.access) // may not be accurate 3590d32f713Shappy-lx XSPerfAccumulate("replace_unused_prefetch", s1_req.replace && isFromL1Prefetch(s1_extra_meta.prefetch) && !s1_extra_meta.access) // may not be accurate 3603af6aa6eSWilliam Wang 361ad3ba452Szhanglinjuan // replacement policy 362282f71c4Shappy-lx val s1_invalid_vec = wayMap(w => !meta_resp(w).asTypeOf(new Meta).coh.isValid()) 363282f71c4Shappy-lx val s1_have_invalid_way = s1_invalid_vec.asUInt.orR 364282f71c4Shappy-lx val s1_invalid_way_en = ParallelPriorityMux(s1_invalid_vec.zipWithIndex.map(x => x._1 -> UIntToOH(x._2.U(nWays.W)))) 365ad3ba452Szhanglinjuan val s1_repl_way_en = WireInit(0.U(nWays.W)) 366282f71c4Shappy-lx s1_repl_way_en := Mux( 3675adc4829SYanqin Li GatedValidRegNext(s0_fire), 368f275998aSsfencevma UIntToOH(io.replace_way.way), 3695adc4829SYanqin Li RegEnable(s1_repl_way_en, s1_valid) 370282f71c4Shappy-lx ) 371cd2ff98bShappy-lx val s1_repl_tag = ParallelMux(s1_repl_way_en.asBools, (0 until nWays).map(w => tag_resp(w))) 372cd2ff98bShappy-lx val s1_repl_coh = ParallelMux(s1_repl_way_en.asBools, (0 until nWays).map(w => meta_resp(w))).asTypeOf(new ClientMetadata) 373ffd3154dSCharlieLiu val s1_repl_pf = ParallelMux(s1_repl_way_en.asBools, (0 until nWays).map(w => io.extra_meta_resp(w).prefetch)) 374ad3ba452Szhanglinjuan 3756216e2e1SWilliam Wang val s1_repl_way_raw = WireInit(0.U(log2Up(nWays).W)) 3765adc4829SYanqin Li s1_repl_way_raw := Mux(GatedValidRegNext(s0_fire), io.replace_way.way, RegEnable(s1_repl_way_raw, s1_valid)) 3776216e2e1SWilliam Wang 3787ecd6591SCharlie Liu val s1_need_replacement = s1_req.miss && !s1_tag_match 3797ecd6591SCharlie Liu val s1_need_eviction = s1_req.miss && !s1_tag_match && s1_repl_coh.state =/= ClientStates.Nothing 380ffd3154dSCharlieLiu 381d69a8286Scz4e val s1_no_error_way_en = Mux(s1_need_replacement, s1_repl_way_en, s1_real_tag_match_way) 382d69a8286Scz4e val s1_error_way_en = Mux(ParallelORR(s1_real_tag_match_way), s1_real_tag_match_way, s1_repl_way_en) 383d69a8286Scz4e val s1_way_en = Mux(io.pseudo_error.valid, s1_error_way_en, s1_no_error_way_en) 3847459e344SWilliam Wang assert(!RegNext(s1_fire && PopCount(s1_way_en) > 1.U)) 385ffd3154dSCharlieLiu 386147e663aSsfencevma val s1_tag = s1_hit_tag 387147e663aSsfencevma val s1_coh = s1_hit_coh 388ad3ba452Szhanglinjuan 389282f71c4Shappy-lx XSPerfAccumulate("store_has_invalid_way_but_select_valid_way", io.replace_way.set.valid && wayMap(w => !meta_resp(w).asTypeOf(new Meta).coh.isValid()).asUInt.orR && s1_need_replacement && s1_repl_coh.isValid()) 390282f71c4Shappy-lx XSPerfAccumulate("store_using_replacement", io.replace_way.set.valid && s1_need_replacement) 391282f71c4Shappy-lx 392a98b054bSWilliam Wang val s1_has_permission = s1_hit_coh.onAccess(s1_req.cmd)._1 393a98b054bSWilliam Wang val s1_hit = s1_tag_match && s1_has_permission 394fad7c425SAnzo val s1_pregen_can_go_to_mq = !s1_req.replace && !s1_req.probe && !s1_req.miss && (s1_req.isStore || s1_req.isAMO && s1_req.cmd =/= M_XSC) && !s1_hit 395a98b054bSWilliam Wang 396ad3ba452Szhanglinjuan // s2: select data, return resp if this is a store miss 397ad3ba452Szhanglinjuan val s2_valid = RegInit(false.B) 398ad3ba452Szhanglinjuan val s2_req = RegEnable(s1_req, s1_fire) 39972dab974Scz4e val s2_tag_errors = RegEnable(s1_tag_errors, s1_fire) 400ad3ba452Szhanglinjuan val s2_tag_match = RegEnable(s1_tag_match, s1_fire) 401e20d4bd0Scz4e val s2_tag_match_way = RegEnable(s1_real_tag_match_way, s1_fire) 402ad3ba452Szhanglinjuan val s2_hit_coh = RegEnable(s1_hit_coh, s1_fire) 403ad3ba452Szhanglinjuan val (s2_has_permission, _, s2_new_hit_coh) = s2_hit_coh.onAccess(s2_req.cmd) 404c5dfcce5Szhanglinjuan 405ad3ba452Szhanglinjuan val s2_repl_tag = RegEnable(s1_repl_tag, s1_fire) 406ad3ba452Szhanglinjuan val s2_repl_coh = RegEnable(s1_repl_coh, s1_fire) 407ffd3154dSCharlieLiu val s2_repl_pf = RegEnable(s1_repl_pf, s1_fire) 408ad3ba452Szhanglinjuan val s2_need_replacement = RegEnable(s1_need_replacement, s1_fire) 4097ecd6591SCharlie Liu val s2_need_eviction = RegEnable(s1_need_eviction, s1_fire) 4109ef181f4SWilliam Wang val s2_need_data = RegEnable(s1_need_data, s1_fire) 411516950f9SWilliam Wang val s2_need_tag = RegEnable(s1_need_tag, s1_fire) 412ad3ba452Szhanglinjuan val s2_idx = get_idx(s2_req.vaddr) 413b909b713Szhanglinjuan 414ad3ba452Szhanglinjuan val s2_way_en = RegEnable(s1_way_en, s1_fire) 415147e663aSsfencevma val s2_tag = Mux(s2_need_replacement, s2_repl_tag, RegEnable(s1_tag, s1_fire)) 416147e663aSsfencevma val s2_coh = Mux(s2_need_replacement, s2_repl_coh, RegEnable(s1_coh, s1_fire)) 417ad3ba452Szhanglinjuan val s2_banked_store_wmask = RegEnable(s1_banked_store_wmask, s1_fire) 4189ef181f4SWilliam Wang val s2_flag_error = RegEnable(s1_flag_error, s1_fire) 41931d5a9c4Ssfencevma val s2_tag_error = WireInit(false.B) 4201b353fffSCharlie Liu val s2_l2_error = Mux(io.refill_info.valid, io.refill_info.bits.error, s2_req.error) 4216786cfb7SWilliam Wang val s2_error = s2_flag_error || s2_tag_error || s2_l2_error // data_error not included 4226786cfb7SWilliam Wang 4236786cfb7SWilliam Wang val s2_may_report_data_error = s2_need_data && s2_coh.state =/= ClientStates.Nothing 424ad3ba452Szhanglinjuan 425ad3ba452Szhanglinjuan val s2_hit = s2_tag_match && s2_has_permission 426fad7c425SAnzo val s2_sc = s2_req.cmd === M_XSC 427*dccbba58Scz4e val s2_lr = s2_req.cmd === M_XLR 428ad3ba452Szhanglinjuan val s2_amo_hit = s2_hit && !s2_req.probe && !s2_req.miss && s2_req.isAMO 429ad3ba452Szhanglinjuan val s2_store_hit = s2_hit && !s2_req.probe && !s2_req.miss && s2_req.isStore 430*dccbba58Scz4e val s2_should_not_report_ecc_error = !s2_req.miss && (s2_req.isAMO && !s2_lr || s2_req.isStore) 431ad3ba452Szhanglinjuan 43231d5a9c4Ssfencevma if(EnableTagEcc) { 43372dab974Scz4e s2_tag_error := s2_tag_errors.orR && s2_need_tag 43431d5a9c4Ssfencevma } 43531d5a9c4Ssfencevma 4362f0227efScz4e s2_s0_set_conlict := s2_valid && s0_idx === s2_idx 4372f0227efScz4e s2_s0_set_conlict_store := s2_valid && store_idx === s2_idx 438ad3ba452Szhanglinjuan 439ad3ba452Szhanglinjuan // For a store req, it either hits and goes to s3, or miss and enter miss queue immediately 44073c515a4SCharlieLiu val s2_req_miss_without_data = Mux(s2_valid, s2_req.miss && !io.refill_info.valid, false.B) 4417ecd6591SCharlie Liu val s2_can_go_to_mq_replay = (s2_req_miss_without_data && RegEnable(s2_req_miss_without_data && !io.mainpipe_info.s2_replay_to_mq, false.B, s2_valid)) || io.replace_block // miss_req in s2 but refill data is invalid, can block 1 cycle 442a98b054bSWilliam Wang val s2_can_go_to_mq = RegEnable(s1_pregen_can_go_to_mq, s1_fire) 443fad7c425SAnzo val s2_can_go_to_s3 = (s2_sc || s2_req.replace || s2_req.probe || (s2_req.miss && io.refill_info.valid && !io.replace_block) || (s2_req.isStore || s2_req.isAMO) && s2_hit) && s3_ready 444ffd3154dSCharlieLiu assert(RegNext(!(s2_valid && s2_can_go_to_s3 && s2_can_go_to_mq && s2_can_go_to_mq_replay))) 445ffd3154dSCharlieLiu val s2_can_go = s2_can_go_to_s3 || s2_can_go_to_mq || s2_can_go_to_mq_replay 446ad3ba452Szhanglinjuan val s2_fire = s2_valid && s2_can_go 4472f0227efScz4e val s2_fire_to_s3 = s2_valid && s2_can_go_to_s3 448ad3ba452Szhanglinjuan when (s1_fire) { 449ad3ba452Szhanglinjuan s2_valid := true.B 450ad3ba452Szhanglinjuan }.elsewhen (s2_fire) { 451ad3ba452Szhanglinjuan s2_valid := false.B 452ad3ba452Szhanglinjuan } 4532f0227efScz4e s2_ready := !s2_valid || s2_can_go 45408b0bc30Shappy-lx val replay = !io.miss_req.ready || io.wbq_block_miss_req 455ad3ba452Szhanglinjuan 456ebe07d61S梁森 Liang Sen io.data_readline_can_go := GatedValidRegNext(s1_fire) 457ebe07d61S梁森 Liang Sen io.data_readline_stall := s2_valid 458ebe07d61S梁森 Liang Sen io.data_readline_can_resp := s2_fire_to_s3 4591f0e2dc7SJiawei Lin 4601f0e2dc7SJiawei Lin def mergePutData(old_data: UInt, new_data: UInt, wmask: UInt): UInt = { 4611f0e2dc7SJiawei Lin val full_wmask = FillInterleaved(8, wmask) 4621f0e2dc7SJiawei Lin ((~full_wmask & old_data) | (full_wmask & new_data)) 4631f0e2dc7SJiawei Lin } 464ebe07d61S梁森 Liang Sen val s2_merge_mask = Wire(Vec(DCacheBanks, UInt(DCacheSRAMRowBytes.W))) 465ebe07d61S梁森 Liang Sen val s2_store_data_merged_without_cache = Wire(Vec(DCacheBanks, UInt(DCacheSRAMRowBits.W))) 4661f0e2dc7SJiawei Lin for (i <- 0 until DCacheBanks) { 467ffd3154dSCharlieLiu val new_data = get_data_of_bank(i, Mux(s2_req.miss, io.refill_info.bits.store_data, s2_req.store_data)) 4681f0e2dc7SJiawei Lin // for amo hit, we should use read out SRAM data 4691f0e2dc7SJiawei Lin // do not merge with store data 470ebe07d61S梁森 Liang Sen s2_merge_mask(i) := Mux(s2_amo_hit, 0.U(wordBytes.W), get_mask_of_bank(i, Mux(s2_req.miss, io.refill_info.bits.store_mask, s2_req.store_mask))) 471ebe07d61S梁森 Liang Sen s2_store_data_merged_without_cache(i) := mergePutData(0.U(DCacheSRAMRowBits.W), new_data, s2_merge_mask(i)) 4721f0e2dc7SJiawei Lin } 4731f0e2dc7SJiawei Lin 47472dab974Scz4e io.pseudo_data_error_inj_done := s2_fire_to_s3 && (s2_tag_error || s2_hit) && s2_may_report_data_error 47572dab974Scz4e io.pseudo_error.ready := false.B 476ffd3154dSCharlieLiu XSError(s2_valid && s2_can_go_to_s3 && s2_req.miss && !io.refill_info.valid, "MainPipe req can go to s3 but no refill data") 477b8f6ff86SWilliam Wang 478ad3ba452Szhanglinjuan // s3: write data, meta and tag 479ad3ba452Szhanglinjuan val s3_valid = RegInit(false.B) 480ad3ba452Szhanglinjuan val s3_req = RegEnable(s2_req, s2_fire_to_s3) 481ffd3154dSCharlieLiu val s3_miss_param = RegEnable(io.refill_info.bits.miss_param, s2_fire_to_s3) 482ffd3154dSCharlieLiu val s3_miss_dirty = RegEnable(io.refill_info.bits.miss_dirty, s2_fire_to_s3) 483ad3ba452Szhanglinjuan val s3_tag = RegEnable(s2_tag, s2_fire_to_s3) 484ad3ba452Szhanglinjuan val s3_tag_match = RegEnable(s2_tag_match, s2_fire_to_s3) 485ad3ba452Szhanglinjuan val s3_coh = RegEnable(s2_coh, s2_fire_to_s3) 486ad3ba452Szhanglinjuan val s3_hit = RegEnable(s2_hit, s2_fire_to_s3) 487ad3ba452Szhanglinjuan val s3_amo_hit = RegEnable(s2_amo_hit, s2_fire_to_s3) 488ad3ba452Szhanglinjuan val s3_store_hit = RegEnable(s2_store_hit, s2_fire_to_s3) 489ad3ba452Szhanglinjuan val s3_hit_coh = RegEnable(s2_hit_coh, s2_fire_to_s3) 490ad3ba452Szhanglinjuan val s3_new_hit_coh = RegEnable(s2_new_hit_coh, s2_fire_to_s3) 491ad3ba452Szhanglinjuan val s3_way_en = RegEnable(s2_way_en, s2_fire_to_s3) 492ad3ba452Szhanglinjuan val s3_banked_store_wmask = RegEnable(s2_banked_store_wmask, s2_fire_to_s3) 4932f0227efScz4e val s3_idx = RegEnable(s2_idx, s2_fire_to_s3) 494ebe07d61S梁森 Liang Sen val s3_store_data_merged_without_cache = RegEnable(s2_store_data_merged_without_cache, s2_fire_to_s3) 495ebe07d61S梁森 Liang Sen val s3_merge_mask = RegEnable(VecInit(s2_merge_mask.map(~_)), s2_fire_to_s3) 496ebe07d61S梁森 Liang Sen 497ebe07d61S梁森 Liang Sen val s3_data_resp = io.data_resp 498ebe07d61S梁森 Liang Sen val s3_data = WireInit(VecInit((0 until DCacheBanks).map(i => { 499ebe07d61S梁森 Liang Sen s3_data_resp(i).raw_data 500ebe07d61S梁森 Liang Sen }))) 501ebe07d61S梁森 Liang Sen val s3_store_data_merged = Wire(Vec(DCacheBanks, UInt(DCacheSRAMRowBits.W))) 502ebe07d61S梁森 Liang Sen for (i <- 0 until DCacheBanks) { 503ebe07d61S梁森 Liang Sen // for amo hit, we should use read out SRAM data 504ebe07d61S梁森 Liang Sen // do not merge with store data 505ebe07d61S梁森 Liang Sen s3_store_data_merged(i) := mergePutData(s3_store_data_merged_without_cache(i), s3_data(i), s3_merge_mask(i)) 506ebe07d61S梁森 Liang Sen } 507ebe07d61S梁森 Liang Sen 508ebe07d61S梁森 Liang Sen val s3_data_word = s3_store_data_merged(s3_req.word_idx) 509ebe07d61S梁森 Liang Sen val s3_data_quad_word = VecInit((0 until DCacheBanks).map(i => { 510ebe07d61S梁森 Liang Sen if (i == (DCacheBanks - 1)) s3_store_data_merged(i) 511ebe07d61S梁森 Liang Sen else Cat(s3_store_data_merged(i + 1), s3_store_data_merged(i)) 512ebe07d61S梁森 Liang Sen }))(s3_req.word_idx) 513ebe07d61S梁森 Liang Sen 514fad7c425SAnzo val s3_sc_fail = Wire(Bool()) // miss or lr mismatch 515648f5569Scz4e val s3_need_replacement = RegEnable(s2_need_replacement, s2_fire_to_s3) 516648f5569Scz4e 5172f0227efScz4e val (_, probe_shrink_param, probe_new_coh) = s3_coh.onProbe(s3_req.probe_param) 5182f0227efScz4e val (_, miss_shrink_param, _) = s3_coh.onCacheControl(M_FLUSH) 519b909b713Szhanglinjuan 520ad3ba452Szhanglinjuan val miss_update_meta = s3_req.miss 5212f0227efScz4e val probe_update_meta = s3_req.probe && s3_tag_match && s3_coh =/= probe_new_coh 5222f0227efScz4e val store_update_meta = s3_req.isStore && !s3_req.probe && s3_hit_coh =/= s3_new_hit_coh 523fad7c425SAnzo val amo_update_meta = s3_req.isAMO && !s3_req.probe && s3_hit_coh =/= s3_new_hit_coh && !s3_sc_fail 5242f0227efScz4e val amo_wait_amoalu = s3_req.isAMO && s3_req.cmd =/= M_XLR && s3_req.cmd =/= M_XSC && !isAMOCAS(s3_req.cmd) 5252f0227efScz4e val update_meta = (miss_update_meta || probe_update_meta || store_update_meta || amo_update_meta) && !s3_req.replace 5261f0e2dc7SJiawei Lin 5271f0e2dc7SJiawei Lin def missCohGen(cmd: UInt, param: UInt, dirty: Bool) = { 5281f0e2dc7SJiawei Lin val c = categorize(cmd) 52945f43e6eSTang Haojin MuxLookup(Cat(c, param, dirty), Nothing)(Seq( 5301f0e2dc7SJiawei Lin //(effect param) -> (next) 5311f0e2dc7SJiawei Lin Cat(rd, toB, false.B) -> Branch, 5321f0e2dc7SJiawei Lin Cat(rd, toB, true.B) -> Branch, 5331f0e2dc7SJiawei Lin Cat(rd, toT, false.B) -> Trunk, 5341f0e2dc7SJiawei Lin Cat(rd, toT, true.B) -> Dirty, 5351f0e2dc7SJiawei Lin Cat(wi, toT, false.B) -> Trunk, 5361f0e2dc7SJiawei Lin Cat(wi, toT, true.B) -> Dirty, 5371f0e2dc7SJiawei Lin Cat(wr, toT, false.B) -> Dirty, 5381f0e2dc7SJiawei Lin Cat(wr, toT, true.B) -> Dirty)) 5391f0e2dc7SJiawei Lin } 540ffd3154dSCharlieLiu 5412f0227efScz4e val miss_new_coh = ClientMetadata(missCohGen(s3_req.cmd, s3_miss_param, s3_miss_dirty)) 5421f0e2dc7SJiawei Lin 543648f5569Scz4e // report ecc error 544648f5569Scz4e val s3_tag_error = RegEnable(s2_tag_error, false.B, s2_fire) 545648f5569Scz4e // data_error will be reported by data array 1 cycle after data read resp 546648f5569Scz4e val s3_data_error = Wire(Bool()) 547648f5569Scz4e s3_data_error := Mux(GatedValidRegNextN(s1_fire, 2), // ecc check result is generated 2 cycle after read req 548648f5569Scz4e io.readline_error_delayed && RegNext(s2_may_report_data_error), 549648f5569Scz4e RegNext(s3_data_error) // do not update s3_data_error if !s1_fire 550648f5569Scz4e ) 551648f5569Scz4e val s3_l2_error = RegEnable(s2_l2_error, false.B, s2_fire) 552648f5569Scz4e val s3_flag_error = RegEnable(s2_flag_error, false.B, s2_fire) 553648f5569Scz4e // error signal for amo inst 554648f5569Scz4e // s3_error = s3_flag_error || s3_tag_error || s3_l2_error || s3_data_error 555648f5569Scz4e val s3_error = RegEnable(s2_error, 0.U.asTypeOf(s2_error), s2_fire) || s3_data_error 556648f5569Scz4e val s3_error_paddr = get_block_addr(RegEnable(Cat(s2_tag, get_untag(s2_req.vaddr)), s2_fire)) 557648f5569Scz4e 5581f0e2dc7SJiawei Lin // LR, SC and AMO 5591f0e2dc7SJiawei Lin val debug_sc_fail_addr = RegInit(0.U) 5601f0e2dc7SJiawei Lin val debug_sc_fail_cnt = RegInit(0.U(8.W)) 561dc6f6b7bSWilliam Wang val debug_sc_addr_match_fail_cnt = RegInit(0.U(8.W)) 5621f0e2dc7SJiawei Lin 563b899def8SWilliam Wang val lrsc_count = RegInit(0.U(log2Ceil(LRSCCycles).W)) 5642f0227efScz4e val lrsc_valid = lrsc_count > LRSCBackOff.U 5651f0e2dc7SJiawei Lin val lrsc_addr = Reg(UInt()) 5662f0227efScz4e 5672f0227efScz4e val s3_s_amoalu = RegInit(false.B) 5682f0227efScz4e val s3_lr = !s3_req.probe && s3_req.isAMO && s3_req.cmd === M_XLR 5692f0227efScz4e val s3_sc = !s3_req.probe && s3_req.isAMO && s3_req.cmd === M_XSC 5702f0227efScz4e val s3_cas = !s3_req.probe && s3_req.isAMO && isAMOCAS(s3_req.cmd) 5712f0227efScz4e val s3_lrsc_addr_match = lrsc_valid && lrsc_addr === get_block_addr(s3_req.addr) 5722f0227efScz4e val debug_s3_sc_fail_addr_match = s3_sc && lrsc_addr === get_block_addr(s3_req.addr) && !lrsc_valid 57338c29594Szhanglinjuan 574fad7c425SAnzo s3_sc_fail := s3_sc && (!s3_lrsc_addr_match || !s3_hit) 57538c29594Szhanglinjuan val s3_cas_fail = s3_cas && (FillInterleaved(8, s3_req.amo_mask) & (s3_req.amo_cmp ^ s3_data_quad_word)) =/= 0.U 5761f0e2dc7SJiawei Lin 5772f0227efScz4e val s3_can_do_amo = (s3_req.miss && !s3_req.probe && s3_req.isAMO) || s3_amo_hit 5782f0227efScz4e val s3_can_do_amo_write = s3_can_do_amo && isWrite(s3_req.cmd) && !s3_sc_fail && !s3_cas_fail 579ad3ba452Szhanglinjuan 5802f0227efScz4e when (s3_valid && (s3_lr || s3_sc)) { 5811f0e2dc7SJiawei Lin when (s3_can_do_amo && s3_lr) { 582b899def8SWilliam Wang lrsc_count := (LRSCCycles - 1).U 5832f0227efScz4e lrsc_addr := get_block_addr(s3_req.addr) 5841f0e2dc7SJiawei Lin } .otherwise { 5851f0e2dc7SJiawei Lin lrsc_count := 0.U 5861f0e2dc7SJiawei Lin } 587811121deSzhanglinjuan }.elsewhen (io.invalid_resv_set) { 588811121deSzhanglinjuan // when we release this block, 589811121deSzhanglinjuan // we invalidate this reservation set 590811121deSzhanglinjuan lrsc_count := 0.U 591f5d5a4f3SCharlieLiu }.elsewhen (lrsc_count > 0.U) { 5921f0e2dc7SJiawei Lin lrsc_count := lrsc_count - 1.U 5931f0e2dc7SJiawei Lin } 5941f0e2dc7SJiawei Lin 5955adc4829SYanqin Li 5962f0227efScz4e io.lrsc_locked_block.valid := lrsc_valid 5972f0227efScz4e io.lrsc_locked_block.bits := lrsc_addr 598f5d5a4f3SCharlieLiu io.block_lr := GatedValidRegNext(lrsc_count > 0.U) 5991f0e2dc7SJiawei Lin 600300ded30SWilliam Wang // When we update update_resv_set, block all probe req in the next cycle 601300ded30SWilliam Wang // It should give Probe reservation set addr compare an independent cycle, 602300ded30SWilliam Wang // which will lead to better timing 6032f0227efScz4e io.update_resv_set := s3_valid && s3_lr && s3_can_do_amo 604300ded30SWilliam Wang 6052f0227efScz4e when (s3_valid) { 6062f0227efScz4e when (s3_req.addr === debug_sc_fail_addr) { 6071f0e2dc7SJiawei Lin when (s3_sc_fail) { 6081f0e2dc7SJiawei Lin debug_sc_fail_cnt := debug_sc_fail_cnt + 1.U 6091f0e2dc7SJiawei Lin } .elsewhen (s3_sc) { 6101f0e2dc7SJiawei Lin debug_sc_fail_cnt := 0.U 6111f0e2dc7SJiawei Lin } 6121f0e2dc7SJiawei Lin } .otherwise { 6131f0e2dc7SJiawei Lin when (s3_sc_fail) { 6142f0227efScz4e debug_sc_fail_addr := s3_req.addr 6151f0e2dc7SJiawei Lin debug_sc_fail_cnt := 1.U 6161f0e2dc7SJiawei Lin } 6171f0e2dc7SJiawei Lin } 6181f0e2dc7SJiawei Lin } 619dc6f6b7bSWilliam Wang XSWarn(debug_sc_fail_cnt > 100.U, "L1DCache failed too many SCs in a row") 620dc6f6b7bSWilliam Wang 6212f0227efScz4e when (s3_valid) { 6222f0227efScz4e when (s3_req.addr === debug_sc_fail_addr) { 623dc6f6b7bSWilliam Wang when (debug_s3_sc_fail_addr_match) { 624dc6f6b7bSWilliam Wang debug_sc_addr_match_fail_cnt := debug_sc_addr_match_fail_cnt + 1.U 625dc6f6b7bSWilliam Wang } .elsewhen (s3_sc) { 626dc6f6b7bSWilliam Wang debug_sc_addr_match_fail_cnt := 0.U 627dc6f6b7bSWilliam Wang } 628dc6f6b7bSWilliam Wang } .otherwise { 629dc6f6b7bSWilliam Wang when (s3_sc_fail) { 630dc6f6b7bSWilliam Wang debug_sc_addr_match_fail_cnt := 1.U 631dc6f6b7bSWilliam Wang } 632dc6f6b7bSWilliam Wang } 633dc6f6b7bSWilliam Wang } 634dc6f6b7bSWilliam Wang XSError(debug_sc_addr_match_fail_cnt > 100.U, "L1DCache failed too many SCs in a row, resv set addr always match") 635dc6f6b7bSWilliam Wang 6361f0e2dc7SJiawei Lin 6371f0e2dc7SJiawei Lin val banked_amo_wmask = UIntToOH(s3_req.word_idx) 6382f0227efScz4e val update_data = s3_req.miss || s3_store_hit || s3_can_do_amo_write 6391f0e2dc7SJiawei Lin 6401f0e2dc7SJiawei Lin // generate write data 6411f0e2dc7SJiawei Lin // AMO hits 6422f0227efScz4e val do_amoalu = amo_wait_amoalu && s3_valid && !s3_s_amoalu 6431f0e2dc7SJiawei Lin val amoalu = Module(new AMOALU(wordBits)) 6441f0e2dc7SJiawei Lin amoalu.io.mask := s3_req.amo_mask 6451f0e2dc7SJiawei Lin amoalu.io.cmd := s3_req.cmd 6461f0e2dc7SJiawei Lin amoalu.io.lhs := s3_data_word 6471f0e2dc7SJiawei Lin amoalu.io.rhs := s3_req.amo_data 6481f0e2dc7SJiawei Lin 6491f0e2dc7SJiawei Lin // merge amo write data 65038c29594Szhanglinjuan val s3_amo_data_merged = Wire(Vec(DCacheBanks, UInt(DCacheSRAMRowBits.W))) // exclude AMOCAS 65196b1e495SWilliam Wang val s3_sc_data_merged = Wire(Vec(DCacheBanks, UInt(DCacheSRAMRowBits.W))) 65238c29594Szhanglinjuan val s3_cas_data_merged = Wire(Vec(DCacheBanks, UInt(DCacheSRAMRowBits.W))) 6531f0e2dc7SJiawei Lin for (i <- 0 until DCacheBanks) { 6541f0e2dc7SJiawei Lin val old_data = s3_store_data_merged(i) 6551f0e2dc7SJiawei Lin val new_data = amoalu.io.out 65696b1e495SWilliam Wang val wmask = Mux( 6572f0227efScz4e s3_req.word_idx === i.U, 65896b1e495SWilliam Wang ~0.U(wordBytes.W), 65996b1e495SWilliam Wang 0.U(wordBytes.W) 66096b1e495SWilliam Wang ) 6611f0e2dc7SJiawei Lin s3_amo_data_merged(i) := mergePutData(old_data, new_data, wmask) 662166de7b7Szhanglinjuan s3_sc_data_merged(i) := mergePutData(old_data, s3_req.amo_data, 6632f0227efScz4e Mux(s3_req.word_idx === i.U && !s3_sc_fail, s3_req.amo_mask, 0.U(wordBytes.W)) 664166de7b7Szhanglinjuan ) 6653d4fb120Szhanglinjuan val l_select = !s3_cas_fail && s3_req.word_idx === i.U 6662f0227efScz4e val h_select = !s3_cas_fail && s3_req.cmd === M_XA_CASQ && 6672f0227efScz4e (if (i % 2 == 1) s3_req.word_idx === (i - 1).U else false.B) 66838c29594Szhanglinjuan s3_cas_data_merged(i) := mergePutData( 66938c29594Szhanglinjuan old_data = old_data, 67038c29594Szhanglinjuan new_data = Mux(h_select, s3_req.amo_data >> DataBits, s3_req.amo_data.take(DataBits)), 67138c29594Szhanglinjuan wmask = Mux( 67238c29594Szhanglinjuan h_select, 67338c29594Szhanglinjuan s3_req.amo_mask >> wordBytes, 67438c29594Szhanglinjuan Mux( 67538c29594Szhanglinjuan l_select, 67638c29594Szhanglinjuan s3_req.amo_mask.take(wordBytes), 67738c29594Szhanglinjuan 0.U(wordBytes.W) 67838c29594Szhanglinjuan ) 67938c29594Szhanglinjuan ) 68038c29594Szhanglinjuan ) 68196b1e495SWilliam Wang } 68296b1e495SWilliam Wang val s3_amo_data_merged_reg = RegEnable(s3_amo_data_merged, do_amoalu) 6832f0227efScz4e val miss_wb = s3_req.miss && s3_need_replacement && s3_coh.state =/= ClientStates.Nothing 684ad3ba452Szhanglinjuan val probe_wb = s3_req.probe 685578c21a4Szhanglinjuan val replace_wb = s3_req.replace 6862f0227efScz4e val need_wb = miss_wb || probe_wb || replace_wb 6871f0e2dc7SJiawei Lin 688578c21a4Szhanglinjuan val writeback_param = Mux(probe_wb, probe_shrink_param, miss_shrink_param) 689fddcfe1fSwakafa val writeback_data = if (dcacheParameters.alwaysReleaseData) { 6902f0227efScz4e s3_tag_match && s3_req.probe && s3_req.probe_need_data || 6912f0227efScz4e s3_coh === ClientStates.Dirty || (miss_wb || replace_wb) && s3_coh.state =/= ClientStates.Nothing 692fddcfe1fSwakafa } else { 6932f0227efScz4e s3_tag_match && s3_req.probe && s3_req.probe_need_data || s3_coh === ClientStates.Dirty 694fddcfe1fSwakafa } 6951f0e2dc7SJiawei Lin 6962f0227efScz4e val s3_probe_can_go = s3_req.probe && io.wb.ready && (io.meta_write.ready || !probe_update_meta) 6972f0227efScz4e val s3_store_can_go = s3_req.source === STORE_SOURCE.U && !s3_req.probe && (io.meta_write.ready || !store_update_meta) && (io.data_write.ready || !update_data) && !s3_req.miss 698fad7c425SAnzo val s3_amo_can_go = s3_amo_hit && (io.meta_write.ready || !amo_update_meta) && (io.data_write.ready || !update_data) && (s3_s_amoalu || !amo_wait_amoalu) || s3_sc_fail 6992f0227efScz4e val s3_miss_can_go = s3_req.miss && 700ad3ba452Szhanglinjuan (io.meta_write.ready || !amo_update_meta) && 701ad3ba452Szhanglinjuan (io.data_write.ready || !update_data) && 7022f0227efScz4e (s3_s_amoalu || !amo_wait_amoalu) && 703ad3ba452Szhanglinjuan io.tag_write.ready && 704ad3ba452Szhanglinjuan io.wb.ready 7052f0227efScz4e val s3_replace_nothing = s3_req.replace && s3_coh.state === ClientStates.Nothing 7062f0227efScz4e val s3_replace_can_go = s3_req.replace && (s3_replace_nothing || io.wb.ready) 707578c21a4Szhanglinjuan val s3_can_go = s3_probe_can_go || s3_store_can_go || s3_amo_can_go || s3_miss_can_go || s3_replace_can_go 708184d2cf0SWilliam Wang val s3_update_data_cango = s3_store_can_go || s3_amo_can_go || s3_miss_can_go // used to speed up data_write gen 7092f0227efScz4e val s3_fire = s3_valid && s3_can_go 7102f0227efScz4e when (s2_fire_to_s3) { 7112f0227efScz4e s3_valid := true.B 7122f0227efScz4e }.elsewhen (s3_fire) { 7132f0227efScz4e s3_valid := false.B 714c3a5fe5fShappy-lx } 7152f0227efScz4e when (do_amoalu) { s3_s_amoalu := true.B } 7162f0227efScz4e when (s3_fire) { s3_s_amoalu := false.B } 717c3a5fe5fShappy-lx 7182f0227efScz4e val s3_probe_new_coh = probe_new_coh 719ca18e2c6Szhanglinjuan val new_coh = Mux( 7202f0227efScz4e miss_update_meta, 721ca18e2c6Szhanglinjuan miss_new_coh, 722ca18e2c6Szhanglinjuan Mux( 723ca18e2c6Szhanglinjuan probe_update_meta, 724b8f6ff86SWilliam Wang s3_probe_new_coh, 725ca18e2c6Szhanglinjuan Mux( 7262f0227efScz4e store_update_meta || amo_update_meta, 7272f0227efScz4e s3_new_hit_coh, 728ca18e2c6Szhanglinjuan ClientMetadata.onReset 729ca18e2c6Szhanglinjuan ) 730ca18e2c6Szhanglinjuan ) 731ca18e2c6Szhanglinjuan ) 732ca18e2c6Szhanglinjuan val banked_wmask = Mux( 7332f0227efScz4e s3_req.miss, 734ca18e2c6Szhanglinjuan banked_full_wmask, 735ca18e2c6Szhanglinjuan Mux( 7362f0227efScz4e s3_store_hit, 7372f0227efScz4e s3_banked_store_wmask, 738ca18e2c6Szhanglinjuan Mux( 7392f0227efScz4e s3_can_do_amo_write, 74038c29594Szhanglinjuan Mux( 7412f0227efScz4e isAMOCASQ(s3_req.cmd), 74238c29594Szhanglinjuan FillInterleaved(2, UIntToOH(s3_req.quad_word_idx)), 7432f0227efScz4e UIntToOH(s3_req.word_idx) 74438c29594Szhanglinjuan ), 745ca18e2c6Szhanglinjuan banked_none_wmask 746ca18e2c6Szhanglinjuan ) 747ca18e2c6Szhanglinjuan ) 748ca18e2c6Szhanglinjuan ) 749ca18e2c6Szhanglinjuan assert(!(s3_valid && banked_wmask.orR && !update_data)) 750ca18e2c6Szhanglinjuan 751ca18e2c6Szhanglinjuan for (i <- 0 until DCacheBanks) { 752ca18e2c6Szhanglinjuan val old_data = s3_store_data_merged(i) 7532f0227efScz4e s3_sc_data_merged(i) := mergePutData(old_data, s3_req.amo_data, 754ca18e2c6Szhanglinjuan Mux( 7552f0227efScz4e s3_req.word_idx === i.U && !s3_sc_fail, 7562f0227efScz4e s3_req.amo_mask, 757ca18e2c6Szhanglinjuan 0.U(wordBytes.W) 758ca18e2c6Szhanglinjuan ) 759ca18e2c6Szhanglinjuan ) 760ca18e2c6Szhanglinjuan } 7616c7e5e86Szhanglinjuan for (i <- 0 until DCacheBanks) { 7622f0227efScz4e io.data_write_dup(i).valid := s3_valid && s3_update_data_cango && update_data 7632f0227efScz4e io.data_write_dup(i).bits.way_en := s3_way_en 7642f0227efScz4e io.data_write_dup(i).bits.addr := s3_req.vaddr 7656c7e5e86Szhanglinjuan } 7666c7e5e86Szhanglinjuan 7672f0227efScz4e s3_ready := !s3_valid || s3_can_go 7682f0227efScz4e s3_s0_set_conflict := s3_valid && s3_idx === s0_idx 7692f0227efScz4e s3_s0_set_conflict_store := s3_valid && s3_idx === store_idx 7702f0227efScz4e //assert(RegNext(!s3_valid || !(s3_req.source === STORE_SOURCE.U && !s3_req.probe) || s3_hit)) // miss store should never come to s3 ,fixed(reserve) 7711f0e2dc7SJiawei Lin 772b6c14329Scz4e io.meta_read.valid := req.valid 773ad3ba452Szhanglinjuan io.meta_read.bits.idx := get_idx(s0_req.vaddr) 774578c21a4Szhanglinjuan io.meta_read.bits.way_en := Mux(s0_req.replace, s0_req.replace_way_en, ~0.U(nWays.W)) 7751f0e2dc7SJiawei Lin 776b6c14329Scz4e io.tag_read.valid := req.valid && !s0_req.replace 777ad3ba452Szhanglinjuan io.tag_read.bits.idx := get_idx(s0_req.vaddr) 778ad3ba452Szhanglinjuan io.tag_read.bits.way_en := ~0.U(nWays.W) 7791f0e2dc7SJiawei Lin 7802f0227efScz4e io.data_read_intend := s1_valid && s1_need_data 7812f0227efScz4e io.data_readline.valid := s1_valid && s1_need_data 782d2b20d1aSTang Haojin io.data_readline.bits.rmask := s1_banked_rmask 783d2b20d1aSTang Haojin io.data_readline.bits.way_en := s1_way_en 7842f0227efScz4e io.data_readline.bits.addr := s1_req.vaddr 7851f0e2dc7SJiawei Lin 7862f0227efScz4e io.miss_req.valid := s2_valid && s2_can_go_to_mq 787a98b054bSWilliam Wang val miss_req = io.miss_req.bits 788a98b054bSWilliam Wang miss_req := DontCare 789a98b054bSWilliam Wang miss_req.source := s2_req.source 7900d32f713Shappy-lx miss_req.pf_source := L1_HW_PREFETCH_NULL 791a98b054bSWilliam Wang miss_req.cmd := s2_req.cmd 792a98b054bSWilliam Wang miss_req.addr := s2_req.addr 7932f0227efScz4e miss_req.vaddr := s2_req.vaddr 794a98b054bSWilliam Wang miss_req.store_data := s2_req.store_data 795a98b054bSWilliam Wang miss_req.store_mask := s2_req.store_mask 796a98b054bSWilliam Wang miss_req.word_idx := s2_req.word_idx 797a98b054bSWilliam Wang miss_req.amo_data := s2_req.amo_data 798a98b054bSWilliam Wang miss_req.amo_mask := s2_req.amo_mask 7996d8be4c6SCharlieLiu miss_req.amo_cmp := s2_req.amo_cmp 800a98b054bSWilliam Wang miss_req.req_coh := s2_hit_coh 801a98b054bSWilliam Wang miss_req.id := s2_req.id 802a98b054bSWilliam Wang miss_req.cancel := false.B 8032db9ec44SLinJiawei miss_req.pc := DontCare 804d67c873fSzhanglinjuan miss_req.full_overwrite := s2_req.isStore && s2_req.store_mask.andR 8051f0e2dc7SJiawei Lin 8062f0227efScz4e io.wbq_conflict_check.valid := s2_valid && s2_can_go_to_mq 80708b0bc30Shappy-lx io.wbq_conflict_check.bits := s2_req.addr 80808b0bc30Shappy-lx 8092f0227efScz4e io.store_replay_resp.valid := s2_valid && s2_can_go_to_mq && replay && s2_req.isStore 810ad3ba452Szhanglinjuan io.store_replay_resp.bits.data := DontCare 811ad3ba452Szhanglinjuan io.store_replay_resp.bits.miss := true.B 812ad3ba452Szhanglinjuan io.store_replay_resp.bits.replay := true.B 813ad3ba452Szhanglinjuan io.store_replay_resp.bits.id := s2_req.id 8141f0e2dc7SJiawei Lin 8152f0227efScz4e io.store_hit_resp.valid := s3_valid && (s3_store_can_go || (s3_miss_can_go && s3_req.isStore)) 816ad3ba452Szhanglinjuan io.store_hit_resp.bits.data := DontCare 817ad3ba452Szhanglinjuan io.store_hit_resp.bits.miss := false.B 818ad3ba452Szhanglinjuan io.store_hit_resp.bits.replay := false.B 819ad3ba452Szhanglinjuan io.store_hit_resp.bits.id := s3_req.id 8201f0e2dc7SJiawei Lin 821ffd3154dSCharlieLiu val atomic_hit_resp = Wire(new MainPipeResp) 822ffd3154dSCharlieLiu atomic_hit_resp.source := s3_req.source 82338c29594Szhanglinjuan atomic_hit_resp.data := Mux(s3_sc, s3_sc_fail.asUInt, s3_data_quad_word) 824ad3ba452Szhanglinjuan atomic_hit_resp.miss := false.B 825ad3ba452Szhanglinjuan atomic_hit_resp.miss_id := s3_req.miss_id 826026615fcSWilliam Wang atomic_hit_resp.error := s3_error 827ad3ba452Szhanglinjuan atomic_hit_resp.replay := false.B 8282f0227efScz4e atomic_hit_resp.ack_miss_queue := s3_req.miss 8292f0227efScz4e atomic_hit_resp.id := lrsc_valid 830ffd3154dSCharlieLiu val atomic_replay_resp = Wire(new MainPipeResp) 831ffd3154dSCharlieLiu atomic_replay_resp.source := s2_req.source 832ad3ba452Szhanglinjuan atomic_replay_resp.data := DontCare 833ad3ba452Szhanglinjuan atomic_replay_resp.miss := true.B 834ad3ba452Szhanglinjuan atomic_replay_resp.miss_id := DontCare 835026615fcSWilliam Wang atomic_replay_resp.error := false.B 836ad3ba452Szhanglinjuan atomic_replay_resp.replay := true.B 837ad3ba452Szhanglinjuan atomic_replay_resp.ack_miss_queue := false.B 838ad3ba452Szhanglinjuan atomic_replay_resp.id := DontCare 839ffd3154dSCharlieLiu 840deb92d67SCharlieLiu val atomic_replay_resp_valid = s2_valid && s2_can_go_to_mq && replay && s2_req.isAMO 841deb92d67SCharlieLiu val atomic_hit_resp_valid = s3_valid && (s3_amo_can_go || s3_miss_can_go && s3_req.isAMO) 842ffd3154dSCharlieLiu 843ad3ba452Szhanglinjuan io.atomic_resp.valid := atomic_replay_resp_valid || atomic_hit_resp_valid 844ad3ba452Szhanglinjuan io.atomic_resp.bits := Mux(atomic_replay_resp_valid, atomic_replay_resp, atomic_hit_resp) 8451f0e2dc7SJiawei Lin 8462f0227efScz4e // io.replace_resp.valid := s3_fire && s3_req.replace 847ffd3154dSCharlieLiu // io.replace_resp.bits := s3_req.miss_id 848578c21a4Szhanglinjuan 8492f0227efScz4e io.meta_write.valid := s3_fire && update_meta 8502f0227efScz4e io.meta_write.bits.idx := s3_idx 8512f0227efScz4e io.meta_write.bits.way_en := s3_way_en 852ad3ba452Szhanglinjuan io.meta_write.bits.meta.coh := new_coh 8531f0e2dc7SJiawei Lin 8542f0227efScz4e io.error_flag_write.valid := s3_fire && update_meta && (s3_l2_error || s3_req.miss) 8552f0227efScz4e io.error_flag_write.bits.idx := s3_idx 8562f0227efScz4e io.error_flag_write.bits.way_en := s3_way_en 8573af6aa6eSWilliam Wang io.error_flag_write.bits.flag := s3_l2_error 8583af6aa6eSWilliam Wang 8593af6aa6eSWilliam Wang // if we use (prefetch_flag && meta =/= ClientStates.Nothing) for prefetch check 8603af6aa6eSWilliam Wang // prefetch_flag_write can be omited 8612f0227efScz4e io.prefetch_flag_write.valid := s3_fire && s3_req.miss 8622f0227efScz4e io.prefetch_flag_write.bits.idx := s3_idx 8632f0227efScz4e io.prefetch_flag_write.bits.way_en := s3_way_en 864ffd3154dSCharlieLiu io.prefetch_flag_write.bits.source := s3_req.pf_source 8653af6aa6eSWilliam Wang 866ffd3154dSCharlieLiu // regenerate repl_way & repl_coh 867ffd3154dSCharlieLiu io.bloom_filter_query.set.valid := s2_fire_to_s3 && s2_req.miss && !isFromL1Prefetch(s2_repl_pf) && s2_repl_coh.isValid() && isFromL1Prefetch(s2_req.pf_source) 868ffd3154dSCharlieLiu io.bloom_filter_query.set.bits.addr := io.bloom_filter_query.set.bits.get_addr(Cat(s2_repl_tag, get_untag(s2_req.vaddr))) // the evict block address 869ffd3154dSCharlieLiu 870ffd3154dSCharlieLiu io.bloom_filter_query.clr.valid := s3_fire && isFromL1Prefetch(s3_req.pf_source) 871ffd3154dSCharlieLiu io.bloom_filter_query.clr.bits.addr := io.bloom_filter_query.clr.bits.get_addr(s3_req.addr) 872ffd3154dSCharlieLiu 873ffd3154dSCharlieLiu XSPerfAccumulate("mainpipe_update_prefetchArray", io.prefetch_flag_write.valid) 874ffd3154dSCharlieLiu XSPerfAccumulate("mainpipe_s2_miss_req", s2_valid && s2_req.miss) 875ffd3154dSCharlieLiu XSPerfAccumulate("mainpipe_s2_block_penalty", s2_valid && s2_req.miss && !io.refill_info.valid) 876ffd3154dSCharlieLiu XSPerfAccumulate("mainpipe_s2_missqueue_replay", s2_valid && s2_can_go_to_mq_replay) 877ffd3154dSCharlieLiu XSPerfAccumulate("mainpipe_slot_conflict_1_2", (s1_idx === s2_idx && s1_way_en === s2_way_en && s1_req.miss && s2_req.miss && s1_valid && s2_valid )) 8782f0227efScz4e XSPerfAccumulate("mainpipe_slot_conflict_1_3", (s1_idx === s3_idx && s1_way_en === s3_way_en && s1_req.miss && s3_req.miss && s1_valid && s3_valid)) 8792f0227efScz4e XSPerfAccumulate("mainpipe_slot_conflict_2_3", (s2_idx === s3_idx && s2_way_en === s3_way_en && s2_req.miss && s3_req.miss && s2_valid && s3_valid)) 8803af6aa6eSWilliam Wang // probe / replace will not update access bit 8812f0227efScz4e io.access_flag_write.valid := s3_fire && !s3_req.probe && !s3_req.replace 8822f0227efScz4e io.access_flag_write.bits.idx := s3_idx 8832f0227efScz4e io.access_flag_write.bits.way_en := s3_way_en 884ffd3154dSCharlieLiu // io.access_flag_write.bits.flag := true.B 885ffd3154dSCharlieLiu io.access_flag_write.bits.flag :=Mux(s3_req.miss, s3_req.access, true.B) 886026615fcSWilliam Wang 8872f0227efScz4e io.tag_write.valid := s3_fire && s3_req.miss 8882f0227efScz4e io.tag_write.bits.idx := s3_idx 8892f0227efScz4e io.tag_write.bits.way_en := s3_way_en 8902f0227efScz4e io.tag_write.bits.tag := get_tag(s3_req.addr) 891b34797bcScz4e io.tag_write.bits.ecc := DontCare // generate ecc code in tagArray 8922f0227efScz4e io.tag_write.bits.vaddr := s3_req.vaddr 8931f0e2dc7SJiawei Lin 8942f0227efScz4e io.tag_write_intend := s3_req.miss && s3_valid 89509ae47d2SWilliam Wang XSPerfAccumulate("fake_tag_write_intend", io.tag_write_intend && !io.tag_write.valid) 89609ae47d2SWilliam Wang XSPerfAccumulate("mainpipe_tag_write", io.tag_write.valid) 89709ae47d2SWilliam Wang 8987ecd6591SCharlie Liu io.replace_addr.valid := s2_valid && s2_need_eviction 8997ecd6591SCharlie Liu io.replace_addr.bits := get_block_addr(Cat(s2_tag, get_untag(s2_req.vaddr))) 9001461d8f8SCharlieLiu 90109ae47d2SWilliam Wang assert(!RegNext(io.tag_write.valid && !io.tag_write_intend)) 90209ae47d2SWilliam Wang 9032f0227efScz4e io.data_write.valid := s3_valid && s3_update_data_cango && update_data 9042f0227efScz4e io.data_write.bits.way_en := s3_way_en 9052f0227efScz4e io.data_write.bits.addr := s3_req.vaddr 906ad3ba452Szhanglinjuan io.data_write.bits.wmask := banked_wmask 90796b1e495SWilliam Wang io.data_write.bits.data := Mux( 9082f0227efScz4e amo_wait_amoalu, 90996b1e495SWilliam Wang s3_amo_data_merged_reg, 91096b1e495SWilliam Wang Mux( 9112f0227efScz4e s3_sc, 9122f0227efScz4e s3_sc_data_merged, 91338c29594Szhanglinjuan Mux( 91438c29594Szhanglinjuan s3_cas, 91538c29594Szhanglinjuan s3_cas_data_merged, 91696b1e495SWilliam Wang s3_store_data_merged 91796b1e495SWilliam Wang ) 91896b1e495SWilliam Wang ) 91938c29594Szhanglinjuan ) 920ffd3154dSCharlieLiu //assert(RegNext(!io.meta_write.valid || !s3_req.replace)) 921578c21a4Szhanglinjuan assert(RegNext(!io.tag_write.valid || !s3_req.replace)) 922578c21a4Szhanglinjuan assert(RegNext(!io.data_write.valid || !s3_req.replace)) 9231f0e2dc7SJiawei Lin 9242f0227efScz4e io.wb.valid := s3_valid && ( 925578c21a4Szhanglinjuan // replace 9262f0227efScz4e s3_req.replace && !s3_replace_nothing || 927ad3ba452Szhanglinjuan // probe can go to wbq 9282f0227efScz4e s3_req.probe && (io.meta_write.ready || !probe_update_meta) || 929ad3ba452Szhanglinjuan // amo miss can go to wbq 9302f0227efScz4e s3_req.miss && 9312f0227efScz4e (io.meta_write.ready || !amo_update_meta) && 9322f0227efScz4e (io.data_write.ready || !update_data) && 9332f0227efScz4e (s3_s_amoalu || !amo_wait_amoalu) && 9342f0227efScz4e io.tag_write.ready 9352f0227efScz4e ) && need_wb 936b909b713Szhanglinjuan 937648f5569Scz4e io.wb.bits.addr := get_block_addr(Cat(s3_tag, get_untag(s3_req.vaddr))) 9382f0227efScz4e io.wb.bits.param := writeback_param 9392f0227efScz4e io.wb.bits.voluntary := s3_req.miss || s3_req.replace 9402f0227efScz4e io.wb.bits.hasData := writeback_data && !s3_tag_error 9412f0227efScz4e io.wb.bits.dirty := s3_coh === ClientStates.Dirty 942935edac4STang Haojin io.wb.bits.data := s3_data.asUInt 94372dab974Scz4e io.wb.bits.corrupt := s3_tag_error || s3_data_error 9442f0227efScz4e io.wb.bits.delay_release := s3_req.replace 945578c21a4Szhanglinjuan io.wb.bits.miss_id := s3_req.miss_id 9461f0e2dc7SJiawei Lin 947fa9ac9b6SWilliam Wang // update plru in main pipe s3 9485adc4829SYanqin Li io.replace_access.valid := GatedValidRegNext(s2_fire_to_s3) && !s3_req.probe && (s3_req.miss || ((s3_req.isAMO || s3_req.isStore) && s3_hit)) 9492f0227efScz4e io.replace_access.bits.set := s3_idx 950ffd3154dSCharlieLiu io.replace_access.bits.way := OHToUInt(s3_way_en) 9511f0e2dc7SJiawei Lin 9525adc4829SYanqin Li io.replace_way.set.valid := GatedValidRegNext(s0_fire) 9532f0227efScz4e io.replace_way.set.bits := s1_idx 9542f0227efScz4e io.replace_way.dmWay := s1_dmWay 9551f0e2dc7SJiawei Lin 956ffd3154dSCharlieLiu // send evict hint to sms 95708b0bc30Shappy-lx val sms_agt_evict_valid = s2_valid && s2_req.miss && s2_fire_to_s3 95808b0bc30Shappy-lx io.sms_agt_evict_req.valid := GatedValidRegNext(sms_agt_evict_valid) 95908b0bc30Shappy-lx io.sms_agt_evict_req.bits.vaddr := RegEnable(Cat(s2_repl_tag(tagBits - 1, 2), s2_req.vaddr(13,12), 0.U((VAddrBits - tagBits).W)), sms_agt_evict_valid) 960ffd3154dSCharlieLiu 961ad3ba452Szhanglinjuan // TODO: consider block policy of a finer granularity 962ad3ba452Szhanglinjuan io.status.s0_set.valid := req.valid 963ad3ba452Szhanglinjuan io.status.s0_set.bits := get_idx(s0_req.vaddr) 9642f0227efScz4e io.status.s1.valid := s1_valid 965c3a5fe5fShappy-lx io.status.s1.bits.set := s1_idx 966ad3ba452Szhanglinjuan io.status.s1.bits.way_en := s1_way_en 9672f0227efScz4e io.status.s2.valid := s2_valid && !s2_req.replace 9682f0227efScz4e io.status.s2.bits.set := s2_idx 969ad3ba452Szhanglinjuan io.status.s2.bits.way_en := s2_way_en 9702f0227efScz4e io.status.s3.valid := s3_valid && !s3_req.replace 9712f0227efScz4e io.status.s3.bits.set := s3_idx 972ad3ba452Szhanglinjuan io.status.s3.bits.way_en := s3_way_en 973cd365d4cSrvcoresjw 974c3a5fe5fShappy-lx for ((s, i) <- io.status_dup.zipWithIndex) { 9752f0227efScz4e s.s1.valid := s1_valid 976c3a5fe5fShappy-lx s.s1.bits.set := RegEnable(get_idx(s0_req.vaddr), s0_fire) 977c3a5fe5fShappy-lx s.s1.bits.way_en := s1_way_en 9782f0227efScz4e s.s2.valid := s2_valid && !RegEnable(s1_req.replace, s1_fire) 979c3a5fe5fShappy-lx s.s2.bits.set := RegEnable(get_idx(s1_req.vaddr), s1_fire) 980d69a8286Scz4e s.s2.bits.way_en := s2_way_en 9812f0227efScz4e s.s3.valid := s3_valid && !RegEnable(s2_req.replace, s2_fire_to_s3) 982c3a5fe5fShappy-lx s.s3.bits.set := RegEnable(get_idx(s2_req.vaddr), s2_fire_to_s3) 983c3a5fe5fShappy-lx s.s3.bits.way_en := RegEnable(s2_way_en, s2_fire_to_s3) 984c3a5fe5fShappy-lx } 985c3a5fe5fShappy-lx dontTouch(io.status_dup) 986c3a5fe5fShappy-lx 9871b353fffSCharlie Liu io.mainpipe_info.s2_valid := s2_valid && s2_req.miss 988ffd3154dSCharlieLiu io.mainpipe_info.s2_miss_id := s2_req.miss_id 989ffd3154dSCharlieLiu io.mainpipe_info.s2_replay_to_mq := s2_valid && s2_can_go_to_mq_replay 99073c515a4SCharlieLiu io.mainpipe_info.s3_valid := s3_valid 99173c515a4SCharlieLiu io.mainpipe_info.s3_miss_id := s3_req.miss_id 992ffd3154dSCharlieLiu io.mainpipe_info.s3_refill_resp := RegNext(s2_valid && s2_req.miss && s2_fire_to_s3) 993ffd3154dSCharlieLiu 9946786cfb7SWilliam Wang // report error to beu and csr, 1 cycle after read data resp 9950184a80eSYanqin Li io.error := 0.U.asTypeOf(ValidIO(new L1CacheErrorInfo)) 9966786cfb7SWilliam Wang // report error, update error csr 997*dccbba58Scz4e io.error.valid := s3_error && GatedValidRegNext(s2_fire && !s2_should_not_report_ecc_error) 9986786cfb7SWilliam Wang // only tag_error and data_error will be reported to beu 9996786cfb7SWilliam Wang // l2_error should not be reported (l2 will report that) 1000ca39d1dbScz4e io.error.bits.report_to_beu := (s3_tag_error || s3_data_error) && RegNext(s2_fire) 1001648f5569Scz4e io.error.bits.paddr := s3_error_paddr 10022f0227efScz4e io.error.bits.source.tag := s3_tag_error 10030184a80eSYanqin Li io.error.bits.source.data := s3_data_error 10042f0227efScz4e io.error.bits.source.l2 := s3_flag_error || s3_l2_error 10052f0227efScz4e io.error.bits.opType.store := s3_req.isStore && !s3_req.probe 10062f0227efScz4e io.error.bits.opType.probe := s3_req.probe 10072f0227efScz4e io.error.bits.opType.release := s3_req.replace 10082f0227efScz4e io.error.bits.opType.atom := s3_req.isAMO && !s3_req.probe 1009dd95524eSzhanglinjuan 1010cd365d4cSrvcoresjw val perfEvents = Seq( 1011cd365d4cSrvcoresjw ("dcache_mp_req ", s0_fire ), 10121ca0e4f3SYinan Xu ("dcache_mp_total_penalty", PopCount(VecInit(Seq(s0_fire, s1_valid, s2_valid, s3_valid)))) 1013cd365d4cSrvcoresjw ) 10141ca0e4f3SYinan Xu generatePerfEvent() 10151f0e2dc7SJiawei Lin} 1016