xref: /XiangShan/src/main/scala/xiangshan/cache/dcache/meta/LegacyMetaArray.scala (revision 11269ca741bcbed259cf718605d4720728016f90)
13af6aa6eSWilliam Wang/***************************************************************************************
2e3da8badSTang Haojin* Copyright (c) 2024 Beijing Institute of Open Source Chip (BOSC)
3e3da8badSTang Haojin* Copyright (c) 2020-2024 Institute of Computing Technology, Chinese Academy of Sciences
43af6aa6eSWilliam Wang* Copyright (c) 2020-2021 Peng Cheng Laboratory
53af6aa6eSWilliam Wang*
63af6aa6eSWilliam Wang* XiangShan is licensed under Mulan PSL v2.
73af6aa6eSWilliam Wang* You can use this software according to the terms and conditions of the Mulan PSL v2.
83af6aa6eSWilliam Wang* You may obtain a copy of Mulan PSL v2 at:
93af6aa6eSWilliam Wang*          http://license.coscl.org.cn/MulanPSL2
103af6aa6eSWilliam Wang*
113af6aa6eSWilliam Wang* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
123af6aa6eSWilliam Wang* EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
133af6aa6eSWilliam Wang* MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
143af6aa6eSWilliam Wang*
153af6aa6eSWilliam Wang* See the Mulan PSL v2 for more details.
163af6aa6eSWilliam Wang***************************************************************************************/
173af6aa6eSWilliam Wang
183af6aa6eSWilliam Wangpackage xiangshan.cache
193af6aa6eSWilliam Wang
208891a219SYinan Xuimport org.chipsalliance.cde.config.Parameters
213af6aa6eSWilliam Wangimport chisel3._
223af6aa6eSWilliam Wangimport chisel3.util._
233af6aa6eSWilliam Wangimport freechips.rocketchip.tilelink.{ClientMetadata, TLClientParameters, TLEdgeOut}
24*11269ca7STang Haojinimport utility.{Code, ParallelOR, ReplacementPolicy, XSDebug}
25*11269ca7STang Haojinimport utility.sram.SRAMTemplate
263af6aa6eSWilliam Wangimport xiangshan.L1CacheErrorInfo
273af6aa6eSWilliam Wang
283af6aa6eSWilliam Wang// basic building blocks for L1 DCache
293af6aa6eSWilliam Wangclass L1Metadata(implicit p: Parameters) extends DCacheBundle {
303af6aa6eSWilliam Wang  val coh = new ClientMetadata
313af6aa6eSWilliam Wang  val tag = UInt(tagBits.W)
323af6aa6eSWilliam Wang}
333af6aa6eSWilliam Wang
343af6aa6eSWilliam Wangobject L1Metadata {
353af6aa6eSWilliam Wang  def apply(tag: Bits, coh: ClientMetadata, paddr: UInt)(implicit p: Parameters) = {
363af6aa6eSWilliam Wang    val meta = Wire(new L1Metadata)
373af6aa6eSWilliam Wang    meta.tag := tag
383af6aa6eSWilliam Wang    meta.coh := coh
393af6aa6eSWilliam Wang    meta
403af6aa6eSWilliam Wang  }
413af6aa6eSWilliam Wang}
423af6aa6eSWilliam Wang
433af6aa6eSWilliam Wangclass L1MetaReadReq(implicit p: Parameters) extends DCacheBundle {
443af6aa6eSWilliam Wang  val idx = UInt(idxBits.W)
453af6aa6eSWilliam Wang  val way_en = UInt(nWays.W)
463af6aa6eSWilliam Wang  val tag = UInt(tagBits.W)
473af6aa6eSWilliam Wang}
483af6aa6eSWilliam Wang
493af6aa6eSWilliam Wangclass L1MetaWriteReq(implicit p: Parameters) extends L1MetaReadReq {
503af6aa6eSWilliam Wang  val data = new L1Metadata
513af6aa6eSWilliam Wang}
523af6aa6eSWilliam Wang
533af6aa6eSWilliam Wang
543af6aa6eSWilliam Wangclass L1MetadataArray(onReset: () => L1Metadata)(implicit p: Parameters) extends DCacheModule {
553af6aa6eSWilliam Wang  val rstVal = onReset()
563af6aa6eSWilliam Wang  val metaBits = rstVal.getWidth
573af6aa6eSWilliam Wang  val encMetaBits = cacheParams.tagCode.width(metaBits)
583af6aa6eSWilliam Wang
593af6aa6eSWilliam Wang  val io = IO(new Bundle {
603af6aa6eSWilliam Wang    val read = Flipped(Decoupled(new L1MetaReadReq))
613af6aa6eSWilliam Wang    val write = Flipped(Decoupled(new L1MetaWriteReq))
623af6aa6eSWilliam Wang    val resp = Output(Vec(nWays, UInt(encMetaBits.W)))
630184a80eSYanqin Li    val error = Output(ValidIO(new L1CacheErrorInfo))
643af6aa6eSWilliam Wang  })
653af6aa6eSWilliam Wang  val rst_cnt = RegInit(0.U(log2Up(nSets + 1).W))
663af6aa6eSWilliam Wang  val rst = rst_cnt < nSets.U
673af6aa6eSWilliam Wang  val waddr = Mux(rst, rst_cnt, io.write.bits.idx)
683af6aa6eSWilliam Wang  val wdata = Mux(rst, rstVal, io.write.bits.data).asUInt
693af6aa6eSWilliam Wang  val wmask = Mux(rst || (nWays == 1).B, (-1).asSInt, io.write.bits.way_en.asSInt).asBools
703af6aa6eSWilliam Wang  val rmask = Mux(rst || (nWays == 1).B, (-1).asSInt, io.read.bits.way_en.asSInt).asBools
713af6aa6eSWilliam Wang  when(rst) {
723af6aa6eSWilliam Wang    rst_cnt := rst_cnt + 1.U
733af6aa6eSWilliam Wang  }
743af6aa6eSWilliam Wang
753af6aa6eSWilliam Wang  val tag_array = Module(new SRAMTemplate(UInt(encMetaBits.W), set = nSets, way = nWays,
763af6aa6eSWilliam Wang    shouldReset = false, holdRead = false, singlePort = true))
773af6aa6eSWilliam Wang
783af6aa6eSWilliam Wang  // tag write
793af6aa6eSWilliam Wang  val wen = rst || io.write.valid
803af6aa6eSWilliam Wang  tag_array.io.w.req.valid := wen
813af6aa6eSWilliam Wang  tag_array.io.w.req.bits.apply(
823af6aa6eSWilliam Wang    setIdx = waddr,
833af6aa6eSWilliam Wang    data = cacheParams.tagCode.encode(wdata),
843af6aa6eSWilliam Wang    waymask = VecInit(wmask).asUInt)
853af6aa6eSWilliam Wang
863af6aa6eSWilliam Wang  // tag read
87935edac4STang Haojin  val ren = io.read.fire
883af6aa6eSWilliam Wang  tag_array.io.r.req.valid := ren
893af6aa6eSWilliam Wang  tag_array.io.r.req.bits.apply(setIdx = io.read.bits.idx)
903af6aa6eSWilliam Wang  io.resp := tag_array.io.r.resp.data
913af6aa6eSWilliam Wang  val ecc_errors = tag_array.io.r.resp.data.zipWithIndex.map({ case (d, w) =>
923af6aa6eSWilliam Wang    cacheParams.tagCode.decode(d).error && RegNext(io.read.bits.way_en(w))
933af6aa6eSWilliam Wang  })
940184a80eSYanqin Li  io.error.bits.report_to_beu := RegNext(io.read.fire) && Cat(ecc_errors).orR
950184a80eSYanqin Li  io.error.bits.paddr := Cat(io.read.bits.idx, 0.U(pgUntagBits.W))
963af6aa6eSWilliam Wang
973af6aa6eSWilliam Wang  io.write.ready := !rst
983af6aa6eSWilliam Wang  io.read.ready := !wen
993af6aa6eSWilliam Wang
100e3da8badSTang Haojin  def dumpRead = {
1018b33cd30Sklin02    XSDebug(io.read.fire,
1028b33cd30Sklin02      "MetaArray Read: idx: %d way_en: %x tag: %x\n",
1033af6aa6eSWilliam Wang      io.read.bits.idx, io.read.bits.way_en, io.read.bits.tag)
1043af6aa6eSWilliam Wang  }
1053af6aa6eSWilliam Wang
106e3da8badSTang Haojin  def dumpWrite = {
1078b33cd30Sklin02    XSDebug(io.write.fire,
1088b33cd30Sklin02      "MetaArray Write: idx: %d way_en: %x tag: %x new_tag: %x new_coh: %x\n",
1093af6aa6eSWilliam Wang      io.write.bits.idx, io.write.bits.way_en, io.write.bits.tag, io.write.bits.data.tag, io.write.bits.data.coh.state)
1103af6aa6eSWilliam Wang  }
1113af6aa6eSWilliam Wang
1123af6aa6eSWilliam Wang  // def dumpResp() = {
1133af6aa6eSWilliam Wang  //   (0 until nWays) map { i =>
1143af6aa6eSWilliam Wang  //     XSDebug(s"MetaArray Resp: way: $i tag: %x coh: %x\n",
1153af6aa6eSWilliam Wang  //       io.resp(i).tag, io.resp(i).coh.state)
1163af6aa6eSWilliam Wang  //   }
1173af6aa6eSWilliam Wang  // }
1183af6aa6eSWilliam Wang
1193af6aa6eSWilliam Wang  def dump() = {
1203af6aa6eSWilliam Wang    dumpRead
1213af6aa6eSWilliam Wang    dumpWrite
1223af6aa6eSWilliam Wang    // dumpResp
1233af6aa6eSWilliam Wang  }
1243af6aa6eSWilliam Wang}
1253af6aa6eSWilliam Wang
1263af6aa6eSWilliam Wangclass DuplicatedMetaArray(numReadPorts: Int)(implicit p: Parameters) extends DCacheModule {
1273af6aa6eSWilliam Wang  def onReset = L1Metadata(0.U, ClientMetadata.onReset, 0.U)
1283af6aa6eSWilliam Wang
1293af6aa6eSWilliam Wang  val metaBits = onReset.getWidth
1303af6aa6eSWilliam Wang  val encMetaBits = cacheParams.tagCode.width(metaBits)
1313af6aa6eSWilliam Wang
1323af6aa6eSWilliam Wang  val io = IO(new DCacheBundle {
1333af6aa6eSWilliam Wang    val read = Vec(numReadPorts, Flipped(DecoupledIO(new L1MetaReadReq)))
1343af6aa6eSWilliam Wang    val write = Flipped(DecoupledIO(new L1MetaWriteReq))
1353af6aa6eSWilliam Wang    val resp = Output(Vec(numReadPorts, Vec(nWays, UInt(encMetaBits.W))))
1360184a80eSYanqin Li    val errors = Output(Vec(numReadPorts, ValidIO(new L1CacheErrorInfo)))
1373af6aa6eSWilliam Wang  })
1383af6aa6eSWilliam Wang  val meta = Seq.fill(numReadPorts) {
139e3da8badSTang Haojin    Module(new L1MetadataArray(() => onReset))
1403af6aa6eSWilliam Wang  }
1413af6aa6eSWilliam Wang
1423af6aa6eSWilliam Wang  for (w <- 0 until numReadPorts) {
1433af6aa6eSWilliam Wang    // meta(w).io.write <> io.write
1443af6aa6eSWilliam Wang    meta(w).io.write.valid := io.write.valid
1453af6aa6eSWilliam Wang    meta(w).io.write.bits := io.write.bits
1463af6aa6eSWilliam Wang    meta(w).io.read <> io.read(w)
1473af6aa6eSWilliam Wang    io.resp(w) <> meta(w).io.resp
1483af6aa6eSWilliam Wang    io.errors(w) <> meta(w).io.error
1493af6aa6eSWilliam Wang  }
1503af6aa6eSWilliam Wang  // io.write.ready := VecInit(meta.map(_.io.write.ready)).asUInt.andR
1513af6aa6eSWilliam Wang  io.write.ready := true.B
1523af6aa6eSWilliam Wang
153e3da8badSTang Haojin  def dumpRead = {
1543af6aa6eSWilliam Wang    (0 until numReadPorts) map { w =>
1558b33cd30Sklin02      XSDebug(io.read(w).fire,
1568b33cd30Sklin02        s"MetaArray Read channel: $w idx: %d way_en: %x tag: %x\n",
1573af6aa6eSWilliam Wang        io.read(w).bits.idx, io.read(w).bits.way_en, io.read(w).bits.tag)
1583af6aa6eSWilliam Wang    }
1593af6aa6eSWilliam Wang  }
1603af6aa6eSWilliam Wang
161e3da8badSTang Haojin  def dumpWrite = {
1628b33cd30Sklin02    XSDebug(io.write.fire,
1638b33cd30Sklin02      "MetaArray Write: idx: %d way_en: %x tag: %x new_tag: %x new_coh: %x\n",
1643af6aa6eSWilliam Wang      io.write.bits.idx, io.write.bits.way_en, io.write.bits.tag, io.write.bits.data.tag, io.write.bits.data.coh.state)
1653af6aa6eSWilliam Wang  }
1663af6aa6eSWilliam Wang
1673af6aa6eSWilliam Wang  // def dumpResp() = {
1683af6aa6eSWilliam Wang  //   (0 until LoadPipelineWidth) map { w =>
1693af6aa6eSWilliam Wang  //     (0 until nWays) map { i =>
1703af6aa6eSWilliam Wang  //       XSDebug(s"MetaArray Resp: channel: $w way: $i tag: %x coh: %x\n",
1713af6aa6eSWilliam Wang  //         io.resp(w)(i).tag, io.resp(w)(i).coh.state)
1723af6aa6eSWilliam Wang  //     }
1733af6aa6eSWilliam Wang  //   }
1743af6aa6eSWilliam Wang  // }
1753af6aa6eSWilliam Wang
1763af6aa6eSWilliam Wang  def dump() = {
1773af6aa6eSWilliam Wang    dumpRead
1783af6aa6eSWilliam Wang    dumpWrite
1793af6aa6eSWilliam Wang    // dumpResp
1803af6aa6eSWilliam Wang  }
1813af6aa6eSWilliam Wang}
182