1/*************************************************************************************** 2* Copyright (c) 2020-2021 Institute of Computing Technology, Chinese Academy of Sciences 3* Copyright (c) 2020-2021 Peng Cheng Laboratory 4* 5* XiangShan is licensed under Mulan PSL v2. 6* You can use this software according to the terms and conditions of the Mulan PSL v2. 7* You may obtain a copy of Mulan PSL v2 at: 8* http://license.coscl.org.cn/MulanPSL2 9* 10* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, 11* EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, 12* MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE. 13* 14* See the Mulan PSL v2 for more details. 15***************************************************************************************/ 16 17package xiangshan.cache 18 19import freechips.rocketchip.tilelink.ClientMetadata 20import org.chipsalliance.cde.config.Parameters 21import chisel3._ 22import chisel3.util._ 23import xiangshan.L1CacheErrorInfo 24import xiangshan.cache.CacheInstrucion._ 25 26class Meta(implicit p: Parameters) extends DCacheBundle { 27 val coh = new ClientMetadata 28} 29 30object Meta { 31 def apply(meta: UInt)(implicit p: Parameters) = { 32 val m = Wire(new Meta) 33 m.coh := meta.asTypeOf(new ClientMetadata) 34 m 35 } 36} 37 38class MetaReadReq(implicit p: Parameters) extends DCacheBundle { 39 val idx = UInt(idxBits.W) 40 val way_en = UInt(nWays.W) 41} 42 43class CohMetaWriteReq(implicit p: Parameters) extends MetaReadReq { 44 val meta = new Meta 45} 46 47class FlagMetaWriteReq(implicit p: Parameters) extends MetaReadReq { 48 val flag = Bool() 49} 50 51class L1CohMetaArray(readPorts: Int, writePorts: Int, bypassRead: Boolean = false)(implicit p: Parameters) extends DCacheModule { 52 val io = IO(new Bundle() { 53 val read = Vec(readPorts, Flipped(DecoupledIO(new MetaReadReq))) 54 val resp = Output(Vec(readPorts, Vec(nWays, new Meta))) 55 val write = Vec(writePorts, Flipped(DecoupledIO(new CohMetaWriteReq))) 56 }) 57 58 val meta_array = RegInit( 59 VecInit(Seq.fill(nSets)( 60 VecInit(Seq.fill(nWays)(0.U.asTypeOf(new Meta))) 61 )) 62 ) 63 64 val s0_way_wen = Wire(Vec(nWays, Vec(writePorts, Bool()))) 65 val s1_way_wen = Wire(Vec(nWays, Vec(writePorts, Bool()))) 66 val s1_way_waddr = Wire(Vec(nWays, Vec(writePorts, UInt(idxBits.W)))) 67 val s1_way_wdata = Wire(Vec(nWays, Vec(writePorts, new Meta))) 68 69 (io.read.zip(io.resp)).zipWithIndex.foreach { 70 case ((read, resp), i) => 71 read.ready := true.B 72 (0 until nWays).map(way => { 73 val read_way_bypass = WireInit(false.B) 74 val bypass_data = Wire(new Meta) 75 bypass_data := DontCare 76 (0 until writePorts).map(wport => 77 when(s1_way_wen(way)(wport) && s1_way_waddr(way)(wport) === read.bits.idx){ 78 read_way_bypass := true.B 79 bypass_data := s1_way_wdata(way)(wport) 80 } 81 ) 82 if (bypassRead) { 83 resp(way) := Mux( 84 RegEnable(read_way_bypass, read.valid), 85 RegEnable(bypass_data, read_way_bypass), 86 RegEnable(meta_array(read.bits.idx)(way), read.valid) 87 ) 88 } else { 89 resp(way) := meta_array(RegEnable(read.bits.idx, read.valid))(way) 90 } 91 }) 92 } 93 94 io.write.zipWithIndex.foreach { 95 case (write, wport) => 96 write.ready := true.B 97 write.bits.way_en.asBools.zipWithIndex.foreach { 98 case (wen, way) => 99 s0_way_wen(way)(wport) := write.valid && wen 100 s1_way_wen(way)(wport) := RegNext(s0_way_wen(way)(wport)) 101 s1_way_waddr(way)(wport) := RegEnable(write.bits.idx, s0_way_wen(way)(wport)) 102 s1_way_wdata(way)(wport) := RegEnable(write.bits.meta, s0_way_wen(way)(wport)) 103 when (s1_way_wen(way)(wport)) { 104 meta_array(s1_way_waddr(way)(wport))(way) := s1_way_wdata(way)(wport) 105 } 106 } 107 } 108} 109 110class L1FlagMetaArray(readPorts: Int, writePorts: Int)(implicit p: Parameters) extends DCacheModule { 111 val io = IO(new Bundle() { 112 val read = Vec(readPorts, Flipped(DecoupledIO(new MetaReadReq))) 113 val resp = Output(Vec(readPorts, Vec(nWays, Bool()))) 114 val write = Vec(writePorts, Flipped(DecoupledIO(new FlagMetaWriteReq))) 115 // customized cache op port 116 // val cacheOp = Flipped(new L1CacheInnerOpIO) 117 }) 118 119 val meta_array = RegInit( 120 VecInit(Seq.fill(nSets)( 121 VecInit(Seq.fill(nWays)(0.U.asTypeOf(false.B))) 122 )) 123 ) 124 125 val s0_way_wen = Wire(Vec(nWays, Vec(writePorts, Bool()))) 126 val s1_way_wen = Wire(Vec(nWays, Vec(writePorts, Bool()))) 127 val s1_way_waddr = Wire(Vec(nWays, Vec(writePorts, UInt(idxBits.W)))) 128 val s1_way_wdata = Wire(Vec(nWays, Vec(writePorts, Bool()))) 129 130 (io.read.zip(io.resp)).zipWithIndex.foreach { 131 case ((read, resp), i) => 132 read.ready := true.B 133 (0 until nWays).map(way => { 134 val read_way_bypass = WireInit(false.B) 135 val bypass_data = Wire(Bool()) 136 bypass_data := DontCare 137 (0 until writePorts).map(wport => 138 when(s1_way_wen(way)(wport) && s1_way_waddr(way)(wport) === read.bits.idx){ 139 read_way_bypass := true.B 140 bypass_data := s1_way_wdata(way)(wport) 141 } 142 ) 143 resp(way) := Mux( 144 RegEnable(read_way_bypass, read.valid), 145 RegEnable(bypass_data, read_way_bypass), 146 meta_array(RegEnable(read.bits.idx, read.valid))(way) 147 ) 148 }) 149 } 150 151 io.write.zipWithIndex.foreach { 152 case (write, wport) => 153 write.ready := true.B 154 write.bits.way_en.asBools.zipWithIndex.foreach { 155 case (wen, way) => 156 s0_way_wen(way)(wport) := write.valid && wen 157 s1_way_wen(way)(wport) := RegNext(s0_way_wen(way)(wport)) 158 s1_way_waddr(way)(wport) := RegEnable(write.bits.idx, s0_way_wen(way)(wport)) 159 s1_way_wdata(way)(wport) := RegEnable(write.bits.flag, s0_way_wen(way)(wport)) 160 when (s1_way_wen(way)(wport)) { 161 meta_array(s1_way_waddr(way)(wport))(way) := s1_way_wdata(way)(wport) 162 } 163 } 164 } 165} 166 167class SourceMetaWriteReq(implicit p: Parameters) extends MetaReadReq { 168 val source = UInt(L1PfSourceBits.W) 169} 170 171class L1PrefetchSourceArray(readPorts: Int, writePorts: Int)(implicit p: Parameters) extends DCacheModule { 172 val io = IO(new Bundle() { 173 val read = Vec(readPorts, Flipped(DecoupledIO(new MetaReadReq))) 174 val resp = Output(Vec(readPorts, Vec(nWays, UInt(L1PfSourceBits.W)))) 175 val write = Vec(writePorts, Flipped(DecoupledIO(new SourceMetaWriteReq))) 176 }) 177 178 val meta_array = RegInit( 179 VecInit(Seq.fill(nSets)( 180 VecInit(Seq.fill(nWays)(0.U(L1PfSourceBits.W))) 181 )) 182 ) 183 184 val s0_way_wen = Wire(Vec(nWays, Vec(writePorts, Bool()))) 185 val s1_way_wen = Wire(Vec(nWays, Vec(writePorts, Bool()))) 186 val s1_way_waddr = Wire(Vec(nWays, Vec(writePorts, UInt(idxBits.W)))) 187 val s1_way_wdata = Wire(Vec(nWays, Vec(writePorts, UInt(L1PfSourceBits.W)))) 188 189 (io.read.zip(io.resp)).zipWithIndex.foreach { 190 case ((read, resp), i) => 191 read.ready := true.B 192 (0 until nWays).map(way => { 193 val read_way_bypass = WireInit(false.B) 194 val bypass_data = Wire(UInt(L1PfSourceBits.W)) 195 bypass_data := DontCare 196 (0 until writePorts).map(wport => 197 when(s1_way_wen(way)(wport) && s1_way_waddr(way)(wport) === read.bits.idx){ 198 read_way_bypass := true.B 199 bypass_data := s1_way_wdata(way)(wport) 200 } 201 ) 202 resp(way) := Mux( 203 RegEnable(read_way_bypass, read.valid), 204 RegEnable(bypass_data, read_way_bypass), 205 meta_array(RegEnable(read.bits.idx, read.valid))(way) 206 ) 207 }) 208 } 209 210 io.write.zipWithIndex.foreach { 211 case (write, wport) => 212 write.ready := true.B 213 write.bits.way_en.asBools.zipWithIndex.foreach { 214 case (wen, way) => 215 s0_way_wen(way)(wport) := write.valid && wen 216 s1_way_wen(way)(wport) := RegNext(s0_way_wen(way)(wport)) 217 s1_way_waddr(way)(wport) := RegEnable(write.bits.idx, s0_way_wen(way)(wport)) 218 s1_way_wdata(way)(wport) := RegEnable(write.bits.source, s0_way_wen(way)(wport)) 219 when (s1_way_wen(way)(wport)) { 220 meta_array(s1_way_waddr(way)(wport))(way) := s1_way_wdata(way)(wport) 221 } 222 } 223 } 224} 225