xref: /XiangShan/src/main/scala/xiangshan/cache/dcache/meta/AsynchronousMetaArray.scala (revision 08b0bc306dc55249d4b6f985ded955c9f4ca8d54)
1ad3ba452Szhanglinjuan/***************************************************************************************
2ad3ba452Szhanglinjuan* Copyright (c) 2020-2021 Institute of Computing Technology, Chinese Academy of Sciences
3ad3ba452Szhanglinjuan* Copyright (c) 2020-2021 Peng Cheng Laboratory
4ad3ba452Szhanglinjuan*
5ad3ba452Szhanglinjuan* XiangShan is licensed under Mulan PSL v2.
6ad3ba452Szhanglinjuan* You can use this software according to the terms and conditions of the Mulan PSL v2.
7ad3ba452Szhanglinjuan* You may obtain a copy of Mulan PSL v2 at:
8ad3ba452Szhanglinjuan*          http://license.coscl.org.cn/MulanPSL2
9ad3ba452Szhanglinjuan*
10ad3ba452Szhanglinjuan* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
11ad3ba452Szhanglinjuan* EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
12ad3ba452Szhanglinjuan* MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
13ad3ba452Szhanglinjuan*
14ad3ba452Szhanglinjuan* See the Mulan PSL v2 for more details.
15ad3ba452Szhanglinjuan***************************************************************************************/
16ad3ba452Szhanglinjuan
17ad3ba452Szhanglinjuanpackage xiangshan.cache
18ad3ba452Szhanglinjuan
19ad3ba452Szhanglinjuanimport freechips.rocketchip.tilelink.ClientMetadata
208891a219SYinan Xuimport org.chipsalliance.cde.config.Parameters
21ad3ba452Szhanglinjuanimport chisel3._
22ad3ba452Szhanglinjuanimport chisel3.util._
23ad3ba452Szhanglinjuanimport xiangshan.L1CacheErrorInfo
2477decb47Szhanglinjuanimport xiangshan.cache.CacheInstrucion._
25ad3ba452Szhanglinjuan
26ad3ba452Szhanglinjuanclass Meta(implicit p: Parameters) extends DCacheBundle {
27ad3ba452Szhanglinjuan  val coh = new ClientMetadata
28ad3ba452Szhanglinjuan}
29ad3ba452Szhanglinjuan
30ad3ba452Szhanglinjuanobject Meta {
31ad3ba452Szhanglinjuan  def apply(meta: UInt)(implicit p: Parameters) = {
32ad3ba452Szhanglinjuan    val m = Wire(new Meta)
33ad3ba452Szhanglinjuan    m.coh := meta.asTypeOf(new ClientMetadata)
34ad3ba452Szhanglinjuan    m
35ad3ba452Szhanglinjuan  }
36ad3ba452Szhanglinjuan}
37ad3ba452Szhanglinjuan
38ad3ba452Szhanglinjuanclass MetaReadReq(implicit p: Parameters) extends DCacheBundle {
39ad3ba452Szhanglinjuan  val idx = UInt(idxBits.W)
40ad3ba452Szhanglinjuan  val way_en = UInt(nWays.W)
41ad3ba452Szhanglinjuan}
42ad3ba452Szhanglinjuan
433af6aa6eSWilliam Wangclass CohMetaWriteReq(implicit p: Parameters) extends MetaReadReq {
44ad3ba452Szhanglinjuan  val meta = new Meta
4577decb47Szhanglinjuan}
4677decb47Szhanglinjuan
473af6aa6eSWilliam Wangclass FlagMetaWriteReq(implicit p: Parameters) extends MetaReadReq {
483af6aa6eSWilliam Wang  val flag = Bool()
49026615fcSWilliam Wang}
50026615fcSWilliam Wang
51*08b0bc30Shappy-lxclass L1CohMetaArray(readPorts: Int, writePorts: Int, bypassRead: Boolean = false)(implicit p: Parameters) extends DCacheModule {
52ad3ba452Szhanglinjuan  val io = IO(new Bundle() {
53ad3ba452Szhanglinjuan    val read = Vec(readPorts, Flipped(DecoupledIO(new MetaReadReq)))
5441b68474SWilliam Wang    val resp = Output(Vec(readPorts, Vec(nWays, new Meta)))
553af6aa6eSWilliam Wang    val write = Vec(writePorts, Flipped(DecoupledIO(new CohMetaWriteReq)))
56ad3ba452Szhanglinjuan  })
57ad3ba452Szhanglinjuan
5893f90faaSWilliam Wang  val meta_array = RegInit(
5993f90faaSWilliam Wang    VecInit(Seq.fill(nSets)(
6093f90faaSWilliam Wang      VecInit(Seq.fill(nWays)(0.U.asTypeOf(new Meta)))
6193f90faaSWilliam Wang    ))
6293f90faaSWilliam Wang  )
6393f90faaSWilliam Wang
6493f90faaSWilliam Wang  val s0_way_wen = Wire(Vec(nWays, Vec(writePorts, Bool())))
6593f90faaSWilliam Wang  val s1_way_wen = Wire(Vec(nWays, Vec(writePorts, Bool())))
6693f90faaSWilliam Wang  val s1_way_waddr = Wire(Vec(nWays, Vec(writePorts, UInt(idxBits.W))))
6793f90faaSWilliam Wang  val s1_way_wdata = Wire(Vec(nWays, Vec(writePorts, new Meta)))
68ad3ba452Szhanglinjuan
6977decb47Szhanglinjuan  (io.read.zip(io.resp)).zipWithIndex.foreach {
7077decb47Szhanglinjuan    case ((read, resp), i) =>
71ad3ba452Szhanglinjuan      read.ready := true.B
7293f90faaSWilliam Wang      (0 until nWays).map(way => {
7393f90faaSWilliam Wang        val read_way_bypass = WireInit(false.B)
7493f90faaSWilliam Wang        val bypass_data = Wire(new Meta)
7593f90faaSWilliam Wang        bypass_data := DontCare
7693f90faaSWilliam Wang        (0 until writePorts).map(wport =>
7793f90faaSWilliam Wang          when(s1_way_wen(way)(wport) && s1_way_waddr(way)(wport) === read.bits.idx){
7893f90faaSWilliam Wang            read_way_bypass := true.B
7993f90faaSWilliam Wang            bypass_data := s1_way_wdata(way)(wport)
8093f90faaSWilliam Wang          }
8193f90faaSWilliam Wang        )
82*08b0bc30Shappy-lx        if (bypassRead) {
8393f90faaSWilliam Wang          resp(way) := Mux(
8493f90faaSWilliam Wang            RegEnable(read_way_bypass, read.valid),
8593f90faaSWilliam Wang            RegEnable(bypass_data, read_way_bypass),
8693f90faaSWilliam Wang            RegEnable(meta_array(read.bits.idx)(way), read.valid)
8793f90faaSWilliam Wang          )
88*08b0bc30Shappy-lx        } else {
89*08b0bc30Shappy-lx          resp(way) := meta_array(RegEnable(read.bits.idx, read.valid))(way)
90*08b0bc30Shappy-lx        }
9193f90faaSWilliam Wang      })
92ad3ba452Szhanglinjuan  }
9377decb47Szhanglinjuan
9493f90faaSWilliam Wang  io.write.zipWithIndex.foreach {
9593f90faaSWilliam Wang    case (write, wport) =>
96ad3ba452Szhanglinjuan      write.ready := true.B
97ad3ba452Szhanglinjuan      write.bits.way_en.asBools.zipWithIndex.foreach {
9893f90faaSWilliam Wang        case (wen, way) =>
9993f90faaSWilliam Wang          s0_way_wen(way)(wport) := write.valid && wen
10093f90faaSWilliam Wang          s1_way_wen(way)(wport) := RegNext(s0_way_wen(way)(wport))
10193f90faaSWilliam Wang          s1_way_waddr(way)(wport) := RegEnable(write.bits.idx, s0_way_wen(way)(wport))
10293f90faaSWilliam Wang          s1_way_wdata(way)(wport) := RegEnable(write.bits.meta, s0_way_wen(way)(wport))
10393f90faaSWilliam Wang          when (s1_way_wen(way)(wport)) {
10493f90faaSWilliam Wang            meta_array(s1_way_waddr(way)(wport))(way) := s1_way_wdata(way)(wport)
105ad3ba452Szhanglinjuan          }
106ad3ba452Szhanglinjuan      }
107ad3ba452Szhanglinjuan  }
108ad3ba452Szhanglinjuan}
109026615fcSWilliam Wang
1103af6aa6eSWilliam Wangclass L1FlagMetaArray(readPorts: Int, writePorts: Int)(implicit p: Parameters) extends DCacheModule {
111026615fcSWilliam Wang  val io = IO(new Bundle() {
112026615fcSWilliam Wang    val read = Vec(readPorts, Flipped(DecoupledIO(new MetaReadReq)))
113026615fcSWilliam Wang    val resp = Output(Vec(readPorts, Vec(nWays, Bool())))
1143af6aa6eSWilliam Wang    val write = Vec(writePorts, Flipped(DecoupledIO(new FlagMetaWriteReq)))
115026615fcSWilliam Wang    // customized cache op port
116026615fcSWilliam Wang    // val cacheOp = Flipped(new L1CacheInnerOpIO)
117026615fcSWilliam Wang  })
118026615fcSWilliam Wang
11993f90faaSWilliam Wang  val meta_array = RegInit(
12093f90faaSWilliam Wang    VecInit(Seq.fill(nSets)(
12193f90faaSWilliam Wang      VecInit(Seq.fill(nWays)(0.U.asTypeOf(false.B)))
12293f90faaSWilliam Wang    ))
12393f90faaSWilliam Wang  )
124026615fcSWilliam Wang
12593f90faaSWilliam Wang  val s0_way_wen = Wire(Vec(nWays, Vec(writePorts, Bool())))
12693f90faaSWilliam Wang  val s1_way_wen = Wire(Vec(nWays, Vec(writePorts, Bool())))
12793f90faaSWilliam Wang  val s1_way_waddr = Wire(Vec(nWays, Vec(writePorts, UInt(idxBits.W))))
12893f90faaSWilliam Wang  val s1_way_wdata = Wire(Vec(nWays, Vec(writePorts, Bool())))
12993f90faaSWilliam Wang
13093f90faaSWilliam Wang  (io.read.zip(io.resp)).zipWithIndex.foreach {
13193f90faaSWilliam Wang    case ((read, resp), i) =>
132026615fcSWilliam Wang      read.ready := true.B
13393f90faaSWilliam Wang      (0 until nWays).map(way => {
13493f90faaSWilliam Wang        val read_way_bypass = WireInit(false.B)
13593f90faaSWilliam Wang        val bypass_data = Wire(Bool())
13693f90faaSWilliam Wang        bypass_data := DontCare
13793f90faaSWilliam Wang        (0 until writePorts).map(wport =>
13893f90faaSWilliam Wang          when(s1_way_wen(way)(wport) && s1_way_waddr(way)(wport) === read.bits.idx){
13993f90faaSWilliam Wang            read_way_bypass := true.B
14093f90faaSWilliam Wang            bypass_data := s1_way_wdata(way)(wport)
14193f90faaSWilliam Wang          }
14293f90faaSWilliam Wang        )
14393f90faaSWilliam Wang        resp(way) := Mux(
14493f90faaSWilliam Wang          RegEnable(read_way_bypass, read.valid),
14593f90faaSWilliam Wang          RegEnable(bypass_data, read_way_bypass),
14693f90faaSWilliam Wang          meta_array(RegEnable(read.bits.idx, read.valid))(way)
14793f90faaSWilliam Wang        )
14893f90faaSWilliam Wang      })
149026615fcSWilliam Wang  }
150026615fcSWilliam Wang
15193f90faaSWilliam Wang  io.write.zipWithIndex.foreach {
15293f90faaSWilliam Wang    case (write, wport) =>
153026615fcSWilliam Wang      write.ready := true.B
154026615fcSWilliam Wang      write.bits.way_en.asBools.zipWithIndex.foreach {
15593f90faaSWilliam Wang        case (wen, way) =>
15693f90faaSWilliam Wang          s0_way_wen(way)(wport) := write.valid && wen
15793f90faaSWilliam Wang          s1_way_wen(way)(wport) := RegNext(s0_way_wen(way)(wport))
15893f90faaSWilliam Wang          s1_way_waddr(way)(wport) := RegEnable(write.bits.idx, s0_way_wen(way)(wport))
1593af6aa6eSWilliam Wang          s1_way_wdata(way)(wport) := RegEnable(write.bits.flag, s0_way_wen(way)(wport))
16093f90faaSWilliam Wang          when (s1_way_wen(way)(wport)) {
16193f90faaSWilliam Wang            meta_array(s1_way_waddr(way)(wport))(way) := s1_way_wdata(way)(wport)
162026615fcSWilliam Wang          }
163026615fcSWilliam Wang      }
164026615fcSWilliam Wang  }
165026615fcSWilliam Wang}
1660d32f713Shappy-lx
1670d32f713Shappy-lxclass SourceMetaWriteReq(implicit p: Parameters) extends MetaReadReq {
1680d32f713Shappy-lx  val source = UInt(L1PfSourceBits.W)
1690d32f713Shappy-lx}
1700d32f713Shappy-lx
1710d32f713Shappy-lxclass L1PrefetchSourceArray(readPorts: Int, writePorts: Int)(implicit p: Parameters) extends DCacheModule {
1720d32f713Shappy-lx  val io = IO(new Bundle() {
1730d32f713Shappy-lx    val read = Vec(readPorts, Flipped(DecoupledIO(new MetaReadReq)))
1740d32f713Shappy-lx    val resp = Output(Vec(readPorts, Vec(nWays, UInt(L1PfSourceBits.W))))
1750d32f713Shappy-lx    val write = Vec(writePorts, Flipped(DecoupledIO(new SourceMetaWriteReq)))
1760d32f713Shappy-lx  })
1770d32f713Shappy-lx
1780d32f713Shappy-lx  val meta_array = RegInit(
1790d32f713Shappy-lx    VecInit(Seq.fill(nSets)(
1800d32f713Shappy-lx      VecInit(Seq.fill(nWays)(0.U(L1PfSourceBits.W)))
1810d32f713Shappy-lx    ))
1820d32f713Shappy-lx  )
1830d32f713Shappy-lx
1840d32f713Shappy-lx  val s0_way_wen = Wire(Vec(nWays, Vec(writePorts, Bool())))
1850d32f713Shappy-lx  val s1_way_wen = Wire(Vec(nWays, Vec(writePorts, Bool())))
1860d32f713Shappy-lx  val s1_way_waddr = Wire(Vec(nWays, Vec(writePorts, UInt(idxBits.W))))
1870d32f713Shappy-lx  val s1_way_wdata = Wire(Vec(nWays, Vec(writePorts, UInt(L1PfSourceBits.W))))
1880d32f713Shappy-lx
1890d32f713Shappy-lx  (io.read.zip(io.resp)).zipWithIndex.foreach {
1900d32f713Shappy-lx    case ((read, resp), i) =>
1910d32f713Shappy-lx      read.ready := true.B
1920d32f713Shappy-lx      (0 until nWays).map(way => {
1930d32f713Shappy-lx        val read_way_bypass = WireInit(false.B)
1940d32f713Shappy-lx        val bypass_data = Wire(UInt(L1PfSourceBits.W))
1950d32f713Shappy-lx        bypass_data := DontCare
1960d32f713Shappy-lx        (0 until writePorts).map(wport =>
1970d32f713Shappy-lx          when(s1_way_wen(way)(wport) && s1_way_waddr(way)(wport) === read.bits.idx){
1980d32f713Shappy-lx            read_way_bypass := true.B
1990d32f713Shappy-lx            bypass_data := s1_way_wdata(way)(wport)
2000d32f713Shappy-lx          }
2010d32f713Shappy-lx        )
2020d32f713Shappy-lx        resp(way) := Mux(
2030d32f713Shappy-lx          RegEnable(read_way_bypass, read.valid),
2040d32f713Shappy-lx          RegEnable(bypass_data, read_way_bypass),
2050d32f713Shappy-lx          meta_array(RegEnable(read.bits.idx, read.valid))(way)
2060d32f713Shappy-lx        )
2070d32f713Shappy-lx      })
2080d32f713Shappy-lx  }
2090d32f713Shappy-lx
2100d32f713Shappy-lx  io.write.zipWithIndex.foreach {
2110d32f713Shappy-lx    case (write, wport) =>
2120d32f713Shappy-lx      write.ready := true.B
2130d32f713Shappy-lx      write.bits.way_en.asBools.zipWithIndex.foreach {
2140d32f713Shappy-lx        case (wen, way) =>
2150d32f713Shappy-lx          s0_way_wen(way)(wport) := write.valid && wen
2160d32f713Shappy-lx          s1_way_wen(way)(wport) := RegNext(s0_way_wen(way)(wport))
2170d32f713Shappy-lx          s1_way_waddr(way)(wport) := RegEnable(write.bits.idx, s0_way_wen(way)(wport))
2180d32f713Shappy-lx          s1_way_wdata(way)(wport) := RegEnable(write.bits.source, s0_way_wen(way)(wport))
2190d32f713Shappy-lx          when (s1_way_wen(way)(wport)) {
2200d32f713Shappy-lx            meta_array(s1_way_waddr(way)(wport))(way) := s1_way_wdata(way)(wport)
2210d32f713Shappy-lx          }
2220d32f713Shappy-lx      }
2230d32f713Shappy-lx  }
2240d32f713Shappy-lx}
225