xref: /XiangShan/src/main/scala/xiangshan/mem/MaskedDataModule.scala (revision f320e0f01bd645f0a3045a8a740e60dd770734a9)
1c6d43980SLemover/***************************************************************************************
2c6d43980SLemover* Copyright (c) 2020-2021 Institute of Computing Technology, Chinese Academy of Sciences
3*f320e0f0SYinan Xu* Copyright (c) 2020-2021 Peng Cheng Laboratory
4c6d43980SLemover*
5c6d43980SLemover* XiangShan is licensed under Mulan PSL v2.
6c6d43980SLemover* You can use this software according to the terms and conditions of the Mulan PSL v2.
7c6d43980SLemover* You may obtain a copy of Mulan PSL v2 at:
8c6d43980SLemover*          http://license.coscl.org.cn/MulanPSL2
9c6d43980SLemover*
10c6d43980SLemover* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
11c6d43980SLemover* EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
12c6d43980SLemover* MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
13c6d43980SLemover*
14c6d43980SLemover* See the Mulan PSL v2 for more details.
15c6d43980SLemover***************************************************************************************/
16c6d43980SLemover
170f22ee7cSWilliam Wangpackage xiangshan.mem
180f22ee7cSWilliam Wang
190f22ee7cSWilliam Wangimport chisel3._
200f22ee7cSWilliam Wangimport chisel3.util._
210f22ee7cSWilliam Wangimport xiangshan._
220f22ee7cSWilliam Wangimport utils._
230f22ee7cSWilliam Wangimport xiangshan.cache._
240f22ee7cSWilliam Wang
252225d46eSJiawei Linclass MaskedSyncDataModuleTemplate[T <: Data](
262225d46eSJiawei Lin  gen: T, numEntries: Int, numRead: Int, numWrite: Int, numMRead: Int = 0, numMWrite: Int = 0
272225d46eSJiawei Lin) extends Module {
280f22ee7cSWilliam Wang  val io = IO(new Bundle {
290f22ee7cSWilliam Wang    // address indexed sync read
300f22ee7cSWilliam Wang    val raddr = Input(Vec(numRead, UInt(log2Up(numEntries).W)))
310f22ee7cSWilliam Wang    val rdata = Output(Vec(numRead, gen))
320f22ee7cSWilliam Wang    // masked sync read (1H)
330f22ee7cSWilliam Wang    val mrmask = Input(Vec(numMRead, Vec(numEntries, Bool())))
340f22ee7cSWilliam Wang    val mrdata = Output(Vec(numMRead, gen))
350f22ee7cSWilliam Wang    // address indexed write
360f22ee7cSWilliam Wang    val wen   = Input(Vec(numWrite, Bool()))
370f22ee7cSWilliam Wang    val waddr = Input(Vec(numWrite, UInt(log2Up(numEntries).W)))
380f22ee7cSWilliam Wang    val wdata = Input(Vec(numWrite, gen))
390f22ee7cSWilliam Wang    // masked write
400f22ee7cSWilliam Wang    val mwmask = Input(Vec(numMWrite, Vec(numEntries, Bool())))
410f22ee7cSWilliam Wang    val mwdata = Input(Vec(numMWrite, gen))
420f22ee7cSWilliam Wang  })
430f22ee7cSWilliam Wang
440f22ee7cSWilliam Wang  val data = Reg(Vec(numEntries, gen))
450f22ee7cSWilliam Wang
460f22ee7cSWilliam Wang  // read ports
470f22ee7cSWilliam Wang  for (i <- 0 until numRead) {
480f22ee7cSWilliam Wang    io.rdata(i) := data(RegNext(io.raddr(i)))
490f22ee7cSWilliam Wang  }
500f22ee7cSWilliam Wang
510f22ee7cSWilliam Wang  // masked read ports
520f22ee7cSWilliam Wang  for (i <- 0 until numMRead) {
530f22ee7cSWilliam Wang    io.mrdata(i) := Mux1H(RegNext(io.mrmask(i)), data)
540f22ee7cSWilliam Wang  }
550f22ee7cSWilliam Wang
560f22ee7cSWilliam Wang  // write ports (with priorities)
570f22ee7cSWilliam Wang  for (i <- 0 until numWrite) {
580f22ee7cSWilliam Wang    when (io.wen(i)) {
590f22ee7cSWilliam Wang      data(io.waddr(i)) := io.wdata(i)
600f22ee7cSWilliam Wang    }
610f22ee7cSWilliam Wang  }
620f22ee7cSWilliam Wang
630f22ee7cSWilliam Wang  // masked write
640f22ee7cSWilliam Wang  for (j <- 0 until numEntries) {
650f22ee7cSWilliam Wang    val wen = VecInit((0 until numMWrite).map(i => io.mwmask(i)(j))).asUInt.orR
660f22ee7cSWilliam Wang    when (wen) {
670f22ee7cSWilliam Wang      data(j) := VecInit((0 until numMWrite).map(i => {
680f22ee7cSWilliam Wang        Mux(io.mwmask(i)(j), io.mwdata(i), 0.U).asUInt
690f22ee7cSWilliam Wang      })).reduce(_ | _)
700f22ee7cSWilliam Wang    }
710f22ee7cSWilliam Wang  }
720f22ee7cSWilliam Wang
730f22ee7cSWilliam Wang  // DataModuleTemplate should not be used when there're any write conflicts
740f22ee7cSWilliam Wang  for (i <- 0 until numWrite) {
750f22ee7cSWilliam Wang    for (j <- i+1 until numWrite) {
760f22ee7cSWilliam Wang      assert(!(io.wen(i) && io.wen(j) && io.waddr(i) === io.waddr(j)))
770f22ee7cSWilliam Wang    }
780f22ee7cSWilliam Wang  }
790f22ee7cSWilliam Wang}
80