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 24 25class Meta(implicit p: Parameters) extends DCacheBundle { 26 val coh = new ClientMetadata 27} 28 29object Meta { 30 def apply(meta: UInt)(implicit p: Parameters) = { 31 val m = Wire(new Meta) 32 m.coh := meta.asTypeOf(new ClientMetadata) 33 m 34 } 35} 36 37class MetaAndTag(implicit p: Parameters) extends DCacheBundle { 38 val meta = new Meta 39 val tag = UInt(tagBits.W) 40} 41 42object MetaAndTag { 43 def apply(coh: ClientMetadata, tag: UInt)(implicit p: Parameters) = { 44 val x = Wire(new MetaAndTag) 45 x.meta.coh := coh 46 x.tag := tag 47 x 48 } 49} 50 51class MetaReadReq(implicit p: Parameters) extends DCacheBundle { 52 val idx = UInt(idxBits.W) 53 val way_en = UInt(nWays.W) 54} 55 56class MetaWriteReq(implicit p: Parameters) extends MetaReadReq { 57 val meta = new Meta 58 val tag = UInt(tagBits.W) // used to calculate ecc 59} 60 61class AsynchronousMetaArray(readPorts: Int, writePorts: Int)(implicit p: Parameters) extends DCacheModule { 62 def metaAndTagOnReset = MetaAndTag(ClientMetadata.onReset, 0.U) 63 64 // enc bits encode both tag and meta, but is saved in meta array 65 val metaAndTagBits = metaAndTagOnReset.getWidth 66 val encMetaAndTagBits = cacheParams.tagCode.width(metaAndTagBits) 67 val encMetaBits = encMetaAndTagBits - tagBits 68 69 val io = IO(new Bundle() { 70 // TODO: this is made of regs, so we don't need to use DecoupledIO 71 val read = Vec(readPorts, Flipped(DecoupledIO(new MetaReadReq))) 72 val resp = Output(Vec(readPorts, Vec(nWays, UInt(encMetaBits.W)))) 73 val write = Vec(writePorts, Flipped(DecoupledIO(new MetaWriteReq))) 74 val errors = Output(Vec(readPorts, new L1CacheErrorInfo)) 75 }) 76// val meta_array = VecInit(Seq.fill(nSets)( 77// VecInit(Seq.fill(nWays)( 78// RegInit(0.U(encMetaBits.W)))) 79// )) 80 81 val meta_array = Reg(Vec(nSets, Vec(nWays, UInt(encMetaBits.W)))) 82 when (reset.asBool()) { 83 meta_array := 0.U.asTypeOf(meta_array.cloneType) 84 } 85 86 io.read.zip(io.resp).foreach { 87 case (read, resp) => 88 read.ready := true.B 89 resp := RegEnable(meta_array(read.bits.idx), read.valid) 90 } 91 io.write.foreach { 92 case write => 93 write.ready := true.B 94 val ecc = cacheParams.tagCode.encode(MetaAndTag(write.bits.meta.coh, write.bits.tag).asUInt)(encMetaAndTagBits - 1, metaAndTagBits) 95 val encMeta = Cat(ecc, write.bits.meta.asUInt) 96 require(encMeta.getWidth == encMetaBits) 97 write.bits.way_en.asBools.zipWithIndex.foreach { 98 case (wen, i) => 99 when (write.valid && wen) { 100 meta_array(write.bits.idx)(i) := encMeta 101 } 102 } 103 } 104 // TODO 105 io.errors.foreach { 106 case error => 107 error := DontCare 108 error.ecc_error.valid := false.B 109 } 110} 111