xref: /XiangShan/src/main/scala/xiangshan/backend/regcache/RegCacheDataModule.scala (revision 86102875bc9491279d643aa7e08fb4dd12929987)
1*86102875Ssinsanction/***************************************************************************************
2*86102875Ssinsanction* Copyright (c) 2020-2021 Institute of Computing Technology, Chinese Academy of Sciences
3*86102875Ssinsanction* Copyright (c) 2020-2021 Peng Cheng Laboratory
4*86102875Ssinsanction*
5*86102875Ssinsanction* XiangShan is licensed under Mulan PSL v2.
6*86102875Ssinsanction* You can use this software according to the terms and conditions of the Mulan PSL v2.
7*86102875Ssinsanction* You may obtain a copy of Mulan PSL v2 at:
8*86102875Ssinsanction*          http://license.coscl.org.cn/MulanPSL2
9*86102875Ssinsanction*
10*86102875Ssinsanction* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
11*86102875Ssinsanction* EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
12*86102875Ssinsanction* MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
13*86102875Ssinsanction*
14*86102875Ssinsanction* See the Mulan PSL v2 for more details.
15*86102875Ssinsanction***************************************************************************************/
16*86102875Ssinsanction
17*86102875Ssinsanctionpackage xiangshan.backend.regcache
18*86102875Ssinsanction
19*86102875Ssinsanctionimport org.chipsalliance.cde.config.Parameters
20*86102875Ssinsanctionimport chisel3._
21*86102875Ssinsanctionimport chisel3.util._
22*86102875Ssinsanctionimport xiangshan._
23*86102875Ssinsanctionimport utils._
24*86102875Ssinsanctionimport xiangshan.backend.BackendParams
25*86102875Ssinsanction
26*86102875Ssinsanctionclass RCReadPort(dataWidth: Int, addrWidth: Int) extends Bundle {
27*86102875Ssinsanction  val ren  = Input(Bool())
28*86102875Ssinsanction  val addr = Input(UInt(addrWidth.W))
29*86102875Ssinsanction  val data = Output(UInt(dataWidth.W))
30*86102875Ssinsanction}
31*86102875Ssinsanction
32*86102875Ssinsanctionclass RCWritePort(dataWidth: Int, addrWidth: Int, tagWidth: Int, debugEn: Boolean) extends Bundle {
33*86102875Ssinsanction  val wen  = Input(Bool())
34*86102875Ssinsanction  val addr = Input(UInt(addrWidth.W))
35*86102875Ssinsanction  val data = Input(UInt(dataWidth.W))
36*86102875Ssinsanction  val tag  = OptionWrapper(debugEn, Input(UInt(tagWidth.W)))
37*86102875Ssinsanction}
38*86102875Ssinsanction
39*86102875Ssinsanctionclass RegCacheDataModule
40*86102875Ssinsanction(
41*86102875Ssinsanction  name: String,
42*86102875Ssinsanction  numEntries: Int,
43*86102875Ssinsanction  numReadPorts: Int,
44*86102875Ssinsanction  numWritePorts: Int,
45*86102875Ssinsanction  dataWidth: Int,
46*86102875Ssinsanction  addrWidth: Int,
47*86102875Ssinsanction  tagWidth: Int,
48*86102875Ssinsanction)(implicit p: Parameters) extends XSModule {
49*86102875Ssinsanction  val io = IO(new Bundle() {
50*86102875Ssinsanction    val readPorts = Vec(numReadPorts, new RCReadPort(dataWidth, addrWidth))
51*86102875Ssinsanction    val writePorts = Vec(numWritePorts, new RCWritePort(dataWidth, addrWidth, tagWidth, backendParams.debugEn))
52*86102875Ssinsanction    val validInfo = Vec(numEntries, Output(Bool()))
53*86102875Ssinsanction  })
54*86102875Ssinsanction
55*86102875Ssinsanction  println(s"[RegCache] $name: size: $numEntries, read: $numReadPorts, write: $numWritePorts")
56*86102875Ssinsanction
57*86102875Ssinsanction  val v   = RegInit(VecInit(Seq.fill(numEntries)(false.B)))
58*86102875Ssinsanction  val mem = Reg(Vec(numEntries, UInt(dataWidth.W)))
59*86102875Ssinsanction  val tag = OptionWrapper(backendParams.debugEn, Reg(Vec(numEntries, UInt(tagWidth.W))))
60*86102875Ssinsanction
61*86102875Ssinsanction  for ((r, i) <- io.readPorts.zipWithIndex) {
62*86102875Ssinsanction    r.data := mem(r.addr)
63*86102875Ssinsanction    when (r.ren) {
64*86102875Ssinsanction      assert(v(r.addr), s"$name readPorts $i read a invalid entry")
65*86102875Ssinsanction    }
66*86102875Ssinsanction  }
67*86102875Ssinsanction
68*86102875Ssinsanction  val writePorts = io.writePorts
69*86102875Ssinsanction  for (i <- writePorts.indices) {
70*86102875Ssinsanction    if (i < writePorts.size-1) {
71*86102875Ssinsanction      val hasSameWrite = writePorts.drop(i + 1).map(w => w.wen && w.addr === writePorts(i).addr && writePorts(i).wen).reduce(_ || _)
72*86102875Ssinsanction      assert(!hasSameWrite, s"$name has two or more writePorts writing the same entry")
73*86102875Ssinsanction    }
74*86102875Ssinsanction  }
75*86102875Ssinsanction  for (i <- mem.indices) {
76*86102875Ssinsanction    val wenOH = VecInit(io.writePorts.map(w => w.wen && w.addr === i.U))
77*86102875Ssinsanction    val wData = Mux1H(wenOH, io.writePorts.map(_.data))
78*86102875Ssinsanction    when (wenOH.asUInt.orR) {
79*86102875Ssinsanction      v(i)   := true.B
80*86102875Ssinsanction      mem(i) := wData
81*86102875Ssinsanction    }
82*86102875Ssinsanction    if (backendParams.debugEn) {
83*86102875Ssinsanction      val wTag = Mux1H(wenOH, io.writePorts.map(_.tag.get))
84*86102875Ssinsanction      when (wenOH.asUInt.orR) {
85*86102875Ssinsanction        tag.get(i) := wTag
86*86102875Ssinsanction      }
87*86102875Ssinsanction    }
88*86102875Ssinsanction  }
89*86102875Ssinsanction
90*86102875Ssinsanction  io.validInfo := v
91*86102875Ssinsanction}
92