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 // customized cache op port 76 val cacheOp = Flipped(new DCacheInnerOpIO) 77 }) 78// val meta_array = VecInit(Seq.fill(nSets)( 79// VecInit(Seq.fill(nWays)( 80// RegInit(0.U(encMetaBits.W)))) 81// )) 82 83 val meta_array = Reg(Vec(nSets, Vec(nWays, UInt(encMetaBits.W)))) 84 when (reset.asBool()) { 85 meta_array := 0.U.asTypeOf(meta_array.cloneType) 86 } 87 88 io.read.zip(io.resp).foreach { 89 case (read, resp) => 90 read.ready := true.B 91 resp := RegEnable(meta_array(read.bits.idx), read.valid) 92 } 93 io.write.foreach { 94 case write => 95 write.ready := true.B 96 val ecc = cacheParams.tagCode.encode(MetaAndTag(write.bits.meta.coh, write.bits.tag).asUInt)(encMetaAndTagBits - 1, metaAndTagBits) 97 val encMeta = Cat(ecc, write.bits.meta.asUInt) 98 require(encMeta.getWidth == encMetaBits) 99 write.bits.way_en.asBools.zipWithIndex.foreach { 100 case (wen, i) => 101 when (write.valid && wen) { 102 meta_array(write.bits.idx)(i) := encMeta 103 } 104 } 105 } 106 107 // deal with customized cache op 108 io.cacheOp.resp := DontCare // TODO 109 110 // TODO 111 io.errors.foreach { 112 case error => 113 error := DontCare 114 error.ecc_error.valid := false.B 115 } 116} 117