xref: /XiangShan/src/main/scala/xiangshan/cache/dcache/meta/AsynchronousMetaArray.scala (revision a273862e37f1d43bee748f2a6353320a2f52f6f4)
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