xref: /XiangShan/src/main/scala/xiangshan/mem/MaskedDataModule.scala (revision 57bb43b5f11c3f1e89ac52f232fe73056b35d9bd)
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.mem
18
19import chisel3._
20import chisel3.util._
21import xiangshan._
22import utils._
23import xiangshan.cache._
24
25class MaskedSyncDataModuleTemplate[T <: Data](
26  gen: T, numEntries: Int, numRead: Int, numWrite: Int, numMRead: Int = 0, numMWrite: Int = 0
27) extends Module {
28  val io = IO(new Bundle {
29    // address indexed sync read
30    val raddr = Input(Vec(numRead, UInt(log2Up(numEntries).W)))
31    val rdata = Output(Vec(numRead, gen))
32    // masked sync read (1H)
33    val mrmask = Input(Vec(numMRead, Vec(numEntries, Bool())))
34    val mrdata = Output(Vec(numMRead, gen))
35    // address indexed write
36    val wen   = Input(Vec(numWrite, Bool()))
37    val waddr = Input(Vec(numWrite, UInt(log2Up(numEntries).W)))
38    val wdata = Input(Vec(numWrite, gen))
39    // masked write
40    val mwmask = Input(Vec(numMWrite, Vec(numEntries, Bool())))
41    val mwdata = Input(Vec(numMWrite, gen))
42  })
43
44  val data = Reg(Vec(numEntries, gen))
45
46  // read ports
47  for (i <- 0 until numRead) {
48    io.rdata(i) := data(RegNext(io.raddr(i)))
49  }
50
51  // masked read ports
52  for (i <- 0 until numMRead) {
53    io.mrdata(i) := Mux1H(RegNext(io.mrmask(i)), data)
54  }
55
56  // write ports (with priorities)
57  for (i <- 0 until numWrite) {
58    when (io.wen(i)) {
59      data(io.waddr(i)) := io.wdata(i)
60    }
61  }
62
63  // masked write
64  for (j <- 0 until numEntries) {
65    val wen = VecInit((0 until numMWrite).map(i => io.mwmask(i)(j))).asUInt.orR
66    when (wen) {
67      data(j) := VecInit((0 until numMWrite).map(i => {
68        Mux(io.mwmask(i)(j), io.mwdata(i), 0.U).asUInt
69      })).reduce(_ | _)
70    }
71  }
72
73  // DataModuleTemplate should not be used when there're any write conflicts
74  for (i <- 0 until numWrite) {
75    for (j <- i+1 until numWrite) {
76      assert(!(io.wen(i) && io.wen(j) && io.waddr(i) === io.waddr(j)))
77    }
78  }
79}
80