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 chipsalliance.rocketchip.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)(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 resp(way) := Mux( 83 RegEnable(read_way_bypass, read.valid), 84 RegEnable(bypass_data, read_way_bypass), 85 RegEnable(meta_array(read.bits.idx)(way), read.valid) 86 ) 87 }) 88 } 89 90 io.write.zipWithIndex.foreach { 91 case (write, wport) => 92 write.ready := true.B 93 write.bits.way_en.asBools.zipWithIndex.foreach { 94 case (wen, way) => 95 s0_way_wen(way)(wport) := write.valid && wen 96 s1_way_wen(way)(wport) := RegNext(s0_way_wen(way)(wport)) 97 s1_way_waddr(way)(wport) := RegEnable(write.bits.idx, s0_way_wen(way)(wport)) 98 s1_way_wdata(way)(wport) := RegEnable(write.bits.meta, s0_way_wen(way)(wport)) 99 when (s1_way_wen(way)(wport)) { 100 meta_array(s1_way_waddr(way)(wport))(way) := s1_way_wdata(way)(wport) 101 } 102 } 103 } 104} 105 106class L1FlagMetaArray(readPorts: Int, writePorts: Int)(implicit p: Parameters) extends DCacheModule { 107 val io = IO(new Bundle() { 108 val read = Vec(readPorts, Flipped(DecoupledIO(new MetaReadReq))) 109 val resp = Output(Vec(readPorts, Vec(nWays, Bool()))) 110 val write = Vec(writePorts, Flipped(DecoupledIO(new FlagMetaWriteReq))) 111 // customized cache op port 112 // val cacheOp = Flipped(new L1CacheInnerOpIO) 113 }) 114 115 val meta_array = RegInit( 116 VecInit(Seq.fill(nSets)( 117 VecInit(Seq.fill(nWays)(0.U.asTypeOf(false.B))) 118 )) 119 ) 120 121 val s0_way_wen = Wire(Vec(nWays, Vec(writePorts, Bool()))) 122 val s1_way_wen = Wire(Vec(nWays, Vec(writePorts, Bool()))) 123 val s1_way_waddr = Wire(Vec(nWays, Vec(writePorts, UInt(idxBits.W)))) 124 val s1_way_wdata = Wire(Vec(nWays, Vec(writePorts, Bool()))) 125 126 (io.read.zip(io.resp)).zipWithIndex.foreach { 127 case ((read, resp), i) => 128 read.ready := true.B 129 (0 until nWays).map(way => { 130 val read_way_bypass = WireInit(false.B) 131 val bypass_data = Wire(Bool()) 132 bypass_data := DontCare 133 (0 until writePorts).map(wport => 134 when(s1_way_wen(way)(wport) && s1_way_waddr(way)(wport) === read.bits.idx){ 135 read_way_bypass := true.B 136 bypass_data := s1_way_wdata(way)(wport) 137 } 138 ) 139 resp(way) := Mux( 140 RegEnable(read_way_bypass, read.valid), 141 RegEnable(bypass_data, read_way_bypass), 142 meta_array(RegEnable(read.bits.idx, read.valid))(way) 143 ) 144 }) 145 } 146 147 io.write.zipWithIndex.foreach { 148 case (write, wport) => 149 write.ready := true.B 150 write.bits.way_en.asBools.zipWithIndex.foreach { 151 case (wen, way) => 152 s0_way_wen(way)(wport) := write.valid && wen 153 s1_way_wen(way)(wport) := RegNext(s0_way_wen(way)(wport)) 154 s1_way_waddr(way)(wport) := RegEnable(write.bits.idx, s0_way_wen(way)(wport)) 155 s1_way_wdata(way)(wport) := RegEnable(write.bits.flag, s0_way_wen(way)(wport)) 156 when (s1_way_wen(way)(wport)) { 157 meta_array(s1_way_waddr(way)(wport))(way) := s1_way_wdata(way)(wport) 158 } 159 } 160 } 161} 162 163class SourceMetaWriteReq(implicit p: Parameters) extends MetaReadReq { 164 val source = UInt(L1PfSourceBits.W) 165} 166 167class L1PrefetchSourceArray(readPorts: Int, writePorts: Int)(implicit p: Parameters) extends DCacheModule { 168 val io = IO(new Bundle() { 169 val read = Vec(readPorts, Flipped(DecoupledIO(new MetaReadReq))) 170 val resp = Output(Vec(readPorts, Vec(nWays, UInt(L1PfSourceBits.W)))) 171 val write = Vec(writePorts, Flipped(DecoupledIO(new SourceMetaWriteReq))) 172 }) 173 174 val meta_array = RegInit( 175 VecInit(Seq.fill(nSets)( 176 VecInit(Seq.fill(nWays)(0.U(L1PfSourceBits.W))) 177 )) 178 ) 179 180 val s0_way_wen = Wire(Vec(nWays, Vec(writePorts, Bool()))) 181 val s1_way_wen = Wire(Vec(nWays, Vec(writePorts, Bool()))) 182 val s1_way_waddr = Wire(Vec(nWays, Vec(writePorts, UInt(idxBits.W)))) 183 val s1_way_wdata = Wire(Vec(nWays, Vec(writePorts, UInt(L1PfSourceBits.W)))) 184 185 (io.read.zip(io.resp)).zipWithIndex.foreach { 186 case ((read, resp), i) => 187 read.ready := true.B 188 (0 until nWays).map(way => { 189 val read_way_bypass = WireInit(false.B) 190 val bypass_data = Wire(UInt(L1PfSourceBits.W)) 191 bypass_data := DontCare 192 (0 until writePorts).map(wport => 193 when(s1_way_wen(way)(wport) && s1_way_waddr(way)(wport) === read.bits.idx){ 194 read_way_bypass := true.B 195 bypass_data := s1_way_wdata(way)(wport) 196 } 197 ) 198 resp(way) := Mux( 199 RegEnable(read_way_bypass, read.valid), 200 RegEnable(bypass_data, read_way_bypass), 201 meta_array(RegEnable(read.bits.idx, read.valid))(way) 202 ) 203 }) 204 } 205 206 io.write.zipWithIndex.foreach { 207 case (write, wport) => 208 write.ready := true.B 209 write.bits.way_en.asBools.zipWithIndex.foreach { 210 case (wen, way) => 211 s0_way_wen(way)(wport) := write.valid && wen 212 s1_way_wen(way)(wport) := RegNext(s0_way_wen(way)(wport)) 213 s1_way_waddr(way)(wport) := RegEnable(write.bits.idx, s0_way_wen(way)(wport)) 214 s1_way_wdata(way)(wport) := RegEnable(write.bits.source, s0_way_wen(way)(wport)) 215 when (s1_way_wen(way)(wport)) { 216 meta_array(s1_way_waddr(way)(wport))(way) := s1_way_wdata(way)(wport) 217 } 218 } 219 } 220} 221