xref: /XiangShan/src/main/scala/xiangshan/backend/regcache/RegCacheTagModule.scala (revision 67af58f7331d0a9e533d10c82109c7762301e661)
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.backend.regcache
18
19import org.chipsalliance.cde.config.Parameters
20import chisel3._
21import chisel3.util._
22import xiangshan._
23import utils._
24import xiangshan.backend.BackendParams
25import freechips.rocketchip.util.SeqBoolBitwiseOps
26
27class RCTagTableReadPort(addrWidth: Int, tagWidth: Int)(implicit p: Parameters) extends XSBundle {
28  val ren   = Input(Bool())
29  val tag   = Input(UInt(tagWidth.W))
30  val valid = Output(Bool())
31  val addr  = Output(UInt(addrWidth.W))
32}
33
34class RCTagTableWritePort(addrWidth: Int, tagWidth: Int)(implicit p: Parameters) extends XSBundle {
35  val wen   = Input(Bool())
36  val addr  = Input(UInt(addrWidth.W))
37  val tag   = Input(UInt(tagWidth.W))
38  val loadDependency = Vec(LoadPipelineWidth, Input(UInt(LoadDependencyWidth.W)))
39}
40
41class RegCacheTagModule
42(
43  name: String,
44  numEntries: Int,
45  numReadPorts: Int,
46  numWritePorts: Int,
47  addrWidth: Int,
48  tagWidth: Int,
49)(implicit p: Parameters) extends XSModule {
50  val io = IO(new Bundle() {
51    val readPorts = Vec(numReadPorts, new RCTagTableReadPort(addrWidth, tagWidth))
52    val writePorts = Vec(numWritePorts, new RCTagTableWritePort(addrWidth, tagWidth))
53
54    val cancelVec = Vec(numEntries, Input(Bool()))
55
56    val validVec = Vec(numEntries, Output(Bool()))
57    val tagVec = Vec(numEntries, Output(UInt(tagWidth.W)))
58    val loadDependencyVec = Vec(numEntries, Vec(LoadPipelineWidth, Output(UInt(LoadDependencyWidth.W))))
59  })
60
61  println(s"[RegCacheTagModule] $name: size: $numEntries, read: $numReadPorts, write: $numWritePorts")
62
63  val v   = RegInit(VecInit(Seq.fill(numEntries)(false.B)))
64  val tag = Reg(Vec(numEntries, UInt(tagWidth.W)))
65  val loadDependency = Reg(Vec(numEntries, Vec(LoadPipelineWidth, UInt(LoadDependencyWidth.W))))
66
67  for ((r, i) <- io.readPorts.zipWithIndex) {
68    val matchOH = v.zip(tag).map(x => x._1 && x._2 === r.tag)
69    r.valid := Mux(r.ren, matchOH.orR, false.B)
70    r.addr  := OHToUInt(matchOH)
71    when (r.ren) {
72      assert(PopCount(matchOH) <= 1.U, s"$name readPorts $i has more than 1 matched entry")
73    }
74  }
75
76  val writePorts = io.writePorts
77  for (i <- writePorts.indices) {
78    if (i < writePorts.size-1) {
79      val hasSameWrite = writePorts.drop(i + 1).map(w => w.wen && w.addr === writePorts(i).addr && writePorts(i).wen).reduce(_ || _)
80      assert(!hasSameWrite, s"$name has two or more writePorts writing the same entry")
81    }
82  }
83
84  for (i <- tag.indices) {
85    val wenOH = VecInit(io.writePorts.map(w => w.wen && w.addr === i.U))
86    val wTag = Mux1H(wenOH, io.writePorts.map(_.tag))
87    val wLoadDependency = Mux1H(wenOH, io.writePorts.map(_.loadDependency))
88
89    when (wenOH.asUInt.orR) {
90      v(i)   := true.B
91      tag(i) := wTag
92      loadDependency(i) := wLoadDependency
93    }
94    .elsewhen (io.cancelVec(i)) {
95      v(i)   := false.B
96    }
97    .elsewhen (loadDependency(i).map(x => x.orR).reduce(_ || _)) {
98      loadDependency(i) := loadDependency(i).map(l => l << 1)
99    }
100  }
101
102  io.validVec := v
103  io.tagVec := tag
104  io.loadDependencyVec := loadDependency
105}
106