xref: /XiangShan/src/main/scala/xiangshan/cache/dcache/meta/AsynchronousMetaArray.scala (revision 51e45dbbf87325e45ff2af6ca86ed6c7eed04464)
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 org.chipsalliance.cde.config.Parameters
21import chisel3._
22import chisel3.util._
23import xiangshan.L1CacheErrorInfo
24import xiangshan.cache.CacheInstrucion._
25
26class Meta(implicit p: Parameters) extends DCacheBundle {
27  val coh = new ClientMetadata
28}
29
30object Meta {
31  def apply(meta: UInt)(implicit p: Parameters) = {
32    val m = Wire(new Meta)
33    m.coh := meta.asTypeOf(new ClientMetadata)
34    m
35  }
36}
37
38class MetaReadReq(implicit p: Parameters) extends DCacheBundle {
39  val idx = UInt(idxBits.W)
40  val way_en = UInt(nWays.W)
41}
42
43class CohMetaWriteReq(implicit p: Parameters) extends MetaReadReq {
44  val meta = new Meta
45}
46
47class FlagMetaWriteReq(implicit p: Parameters) extends MetaReadReq {
48  val flag = Bool()
49}
50
51class L1CohMetaArray(readPorts: Int, writePorts: Int)(implicit p: Parameters) extends DCacheModule {
52  val io = IO(new Bundle() {
53    val read = Vec(readPorts, Flipped(DecoupledIO(new MetaReadReq)))
54    val resp = Output(Vec(readPorts, Vec(nWays, new Meta)))
55    val write = Vec(writePorts, Flipped(DecoupledIO(new CohMetaWriteReq)))
56  })
57
58  val meta_array = RegInit(
59    VecInit(Seq.fill(nSets)(
60      VecInit(Seq.fill(nWays)(0.U.asTypeOf(new Meta)))
61    ))
62  )
63
64  val s0_way_wen = Wire(Vec(nWays, Vec(writePorts, Bool())))
65  val s1_way_wen = Wire(Vec(nWays, Vec(writePorts, Bool())))
66  val s1_way_waddr = Wire(Vec(nWays, Vec(writePorts, UInt(idxBits.W))))
67  val s1_way_wdata = Wire(Vec(nWays, Vec(writePorts, new Meta)))
68
69  (io.read.zip(io.resp)).zipWithIndex.foreach {
70    case ((read, resp), i) =>
71      read.ready := true.B
72      (0 until nWays).map(way => {
73        val read_way_bypass = WireInit(false.B)
74        val bypass_data = Wire(new Meta)
75        bypass_data := DontCare
76        (0 until writePorts).map(wport =>
77          when(s1_way_wen(way)(wport) && s1_way_waddr(way)(wport) === read.bits.idx){
78            read_way_bypass := true.B
79            bypass_data := s1_way_wdata(way)(wport)
80          }
81        )
82        resp(way) := Mux(
83          RegEnable(read_way_bypass, read.valid),
84          RegEnable(bypass_data, read_way_bypass),
85          RegEnable(meta_array(read.bits.idx)(way), read.valid)
86        )
87      })
88  }
89
90  io.write.zipWithIndex.foreach {
91    case (write, wport) =>
92      write.ready := true.B
93      write.bits.way_en.asBools.zipWithIndex.foreach {
94        case (wen, way) =>
95          s0_way_wen(way)(wport) := write.valid && wen
96          s1_way_wen(way)(wport) := RegNext(s0_way_wen(way)(wport))
97          s1_way_waddr(way)(wport) := RegEnable(write.bits.idx, s0_way_wen(way)(wport))
98          s1_way_wdata(way)(wport) := RegEnable(write.bits.meta, s0_way_wen(way)(wport))
99          when (s1_way_wen(way)(wport)) {
100            meta_array(s1_way_waddr(way)(wport))(way) := s1_way_wdata(way)(wport)
101          }
102      }
103  }
104}
105
106class L1FlagMetaArray(readPorts: Int, writePorts: Int)(implicit p: Parameters) extends DCacheModule {
107  val io = IO(new Bundle() {
108    val read = Vec(readPorts, Flipped(DecoupledIO(new MetaReadReq)))
109    val resp = Output(Vec(readPorts, Vec(nWays, Bool())))
110    val write = Vec(writePorts, Flipped(DecoupledIO(new FlagMetaWriteReq)))
111    // customized cache op port
112    // val cacheOp = Flipped(new L1CacheInnerOpIO)
113  })
114
115  val meta_array = RegInit(
116    VecInit(Seq.fill(nSets)(
117      VecInit(Seq.fill(nWays)(0.U.asTypeOf(false.B)))
118    ))
119  )
120
121  val s0_way_wen = Wire(Vec(nWays, Vec(writePorts, Bool())))
122  val s1_way_wen = Wire(Vec(nWays, Vec(writePorts, Bool())))
123  val s1_way_waddr = Wire(Vec(nWays, Vec(writePorts, UInt(idxBits.W))))
124  val s1_way_wdata = Wire(Vec(nWays, Vec(writePorts, Bool())))
125
126  (io.read.zip(io.resp)).zipWithIndex.foreach {
127    case ((read, resp), i) =>
128      read.ready := true.B
129      (0 until nWays).map(way => {
130        val read_way_bypass = WireInit(false.B)
131        val bypass_data = Wire(Bool())
132        bypass_data := DontCare
133        (0 until writePorts).map(wport =>
134          when(s1_way_wen(way)(wport) && s1_way_waddr(way)(wport) === read.bits.idx){
135            read_way_bypass := true.B
136            bypass_data := s1_way_wdata(way)(wport)
137          }
138        )
139        resp(way) := Mux(
140          RegEnable(read_way_bypass, read.valid),
141          RegEnable(bypass_data, read_way_bypass),
142          meta_array(RegEnable(read.bits.idx, read.valid))(way)
143        )
144      })
145  }
146
147  io.write.zipWithIndex.foreach {
148    case (write, wport) =>
149      write.ready := true.B
150      write.bits.way_en.asBools.zipWithIndex.foreach {
151        case (wen, way) =>
152          s0_way_wen(way)(wport) := write.valid && wen
153          s1_way_wen(way)(wport) := RegNext(s0_way_wen(way)(wport))
154          s1_way_waddr(way)(wport) := RegEnable(write.bits.idx, s0_way_wen(way)(wport))
155          s1_way_wdata(way)(wport) := RegEnable(write.bits.flag, s0_way_wen(way)(wport))
156          when (s1_way_wen(way)(wport)) {
157            meta_array(s1_way_waddr(way)(wport))(way) := s1_way_wdata(way)(wport)
158          }
159      }
160  }
161}
162
163class SourceMetaWriteReq(implicit p: Parameters) extends MetaReadReq {
164  val source = UInt(L1PfSourceBits.W)
165}
166
167class L1PrefetchSourceArray(readPorts: Int, writePorts: Int)(implicit p: Parameters) extends DCacheModule {
168  val io = IO(new Bundle() {
169    val read = Vec(readPorts, Flipped(DecoupledIO(new MetaReadReq)))
170    val resp = Output(Vec(readPorts, Vec(nWays, UInt(L1PfSourceBits.W))))
171    val write = Vec(writePorts, Flipped(DecoupledIO(new SourceMetaWriteReq)))
172  })
173
174  val meta_array = RegInit(
175    VecInit(Seq.fill(nSets)(
176      VecInit(Seq.fill(nWays)(0.U(L1PfSourceBits.W)))
177    ))
178  )
179
180  val s0_way_wen = Wire(Vec(nWays, Vec(writePorts, Bool())))
181  val s1_way_wen = Wire(Vec(nWays, Vec(writePorts, Bool())))
182  val s1_way_waddr = Wire(Vec(nWays, Vec(writePorts, UInt(idxBits.W))))
183  val s1_way_wdata = Wire(Vec(nWays, Vec(writePorts, UInt(L1PfSourceBits.W))))
184
185  (io.read.zip(io.resp)).zipWithIndex.foreach {
186    case ((read, resp), i) =>
187      read.ready := true.B
188      (0 until nWays).map(way => {
189        val read_way_bypass = WireInit(false.B)
190        val bypass_data = Wire(UInt(L1PfSourceBits.W))
191        bypass_data := DontCare
192        (0 until writePorts).map(wport =>
193          when(s1_way_wen(way)(wport) && s1_way_waddr(way)(wport) === read.bits.idx){
194            read_way_bypass := true.B
195            bypass_data := s1_way_wdata(way)(wport)
196          }
197        )
198        resp(way) := Mux(
199          RegEnable(read_way_bypass, read.valid),
200          RegEnable(bypass_data, read_way_bypass),
201          meta_array(RegEnable(read.bits.idx, read.valid))(way)
202        )
203      })
204  }
205
206  io.write.zipWithIndex.foreach {
207    case (write, wport) =>
208      write.ready := true.B
209      write.bits.way_en.asBools.zipWithIndex.foreach {
210        case (wen, way) =>
211          s0_way_wen(way)(wport) := write.valid && wen
212          s1_way_wen(way)(wport) := RegNext(s0_way_wen(way)(wport))
213          s1_way_waddr(way)(wport) := RegEnable(write.bits.idx, s0_way_wen(way)(wport))
214          s1_way_wdata(way)(wport) := RegEnable(write.bits.source, s0_way_wen(way)(wport))
215          when (s1_way_wen(way)(wport)) {
216            meta_array(s1_way_waddr(way)(wport))(way) := s1_way_wdata(way)(wport)
217          }
218      }
219  }
220}
221