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 chipsalliance.rocketchip.config.Parameters 20import chisel3._ 21import chisel3.util._ 22import freechips.rocketchip.tilelink.{ClientMetadata, TLClientParameters, TLEdgeOut} 23import system.L1CacheErrorInfo 24import utils.{Code, ParallelOR, ReplacementPolicy, SRAMTemplate, XSDebug} 25 26import scala.math.max 27 28 29class L1DataReadReq(implicit p: Parameters) extends DCacheBundle { 30 // you can choose which bank to read to save power 31 val rmask = Bits(blockRows.W) 32 val way_en = Bits(nWays.W) 33 val addr = Bits(untagBits.W) 34} 35 36// Now, we can write a cache-block in a single cycle 37class L1DataWriteReq(implicit p: Parameters) extends L1DataReadReq { 38 val wmask = Bits(blockRows.W) 39 val data = Vec(blockRows, Bits(rowBits.W)) 40} 41 42abstract class AbstractDataArray(implicit p: Parameters) extends DCacheModule { 43 val io = IO(new DCacheBundle { 44 val read = Vec(3, Flipped(DecoupledIO(new L1DataReadReq))) 45 val write = Flipped(DecoupledIO(new L1DataWriteReq)) 46 val resp = Output(Vec(3, Vec(blockRows, Bits(encRowBits.W)))) 47 val nacks = Output(Vec(3, Bool())) 48 val errors = Output(Vec(3, new L1CacheErrorInfo)) 49 }) 50 51 def pipeMap[T <: Data](f: Int => T) = VecInit((0 until 3).map(f)) 52 53 def dumpRead() = { 54 (0 until 3) map { w => 55 when(io.read(w).valid) { 56 XSDebug(s"DataArray Read channel: $w valid way_en: %x addr: %x\n", 57 io.read(w).bits.way_en, io.read(w).bits.addr) 58 } 59 } 60 } 61 62 def dumpWrite() = { 63 when(io.write.valid) { 64 XSDebug(s"DataArray Write valid way_en: %x addr: %x\n", 65 io.write.bits.way_en, io.write.bits.addr) 66 67 (0 until blockRows) map { r => 68 XSDebug(s"cycle: $r data: %x wmask: %x\n", 69 io.write.bits.data(r), io.write.bits.wmask(r)) 70 } 71 } 72 } 73 74 def dumpResp() = { 75 (0 until 3) map { w => 76 XSDebug(s"DataArray ReadResp channel: $w\n") 77 (0 until blockRows) map { r => 78 XSDebug(s"cycle: $r data: %x\n", io.resp(w)(r)) 79 } 80 } 81 } 82 83 def dumpNack() = { 84 (0 until 3) map { w => 85 when(io.nacks(w)) { 86 XSDebug(s"DataArray NACK channel: $w\n") 87 } 88 } 89 } 90 91 def dump() = { 92 dumpRead 93 dumpWrite 94 dumpNack 95 dumpResp 96 } 97} 98