xref: /XiangShan/src/main/scala/xiangshan/mem/MaskedDataModule.scala (revision 0f22ee7c5ba2b51b0fdb4bb1b5f770815edcad50)
1*0f22ee7cSWilliam Wangpackage xiangshan.mem
2*0f22ee7cSWilliam Wang
3*0f22ee7cSWilliam Wangimport chisel3._
4*0f22ee7cSWilliam Wangimport chisel3.util._
5*0f22ee7cSWilliam Wangimport xiangshan._
6*0f22ee7cSWilliam Wangimport utils._
7*0f22ee7cSWilliam Wangimport xiangshan.cache._
8*0f22ee7cSWilliam Wang
9*0f22ee7cSWilliam Wangclass MaskedSyncDataModuleTemplate[T <: Data](gen: T, numEntries: Int, numRead: Int, numWrite: Int, numMRead: Int = 0, numMWrite: Int = 0) extends XSModule with HasDCacheParameters {
10*0f22ee7cSWilliam Wang  val io = IO(new Bundle {
11*0f22ee7cSWilliam Wang    // address indexed sync read
12*0f22ee7cSWilliam Wang    val raddr = Input(Vec(numRead, UInt(log2Up(numEntries).W)))
13*0f22ee7cSWilliam Wang    val rdata = Output(Vec(numRead, gen))
14*0f22ee7cSWilliam Wang    // masked sync read (1H)
15*0f22ee7cSWilliam Wang    val mrmask = Input(Vec(numMRead, Vec(numEntries, Bool())))
16*0f22ee7cSWilliam Wang    val mrdata = Output(Vec(numMRead, gen))
17*0f22ee7cSWilliam Wang    // address indexed write
18*0f22ee7cSWilliam Wang    val wen   = Input(Vec(numWrite, Bool()))
19*0f22ee7cSWilliam Wang    val waddr = Input(Vec(numWrite, UInt(log2Up(numEntries).W)))
20*0f22ee7cSWilliam Wang    val wdata = Input(Vec(numWrite, gen))
21*0f22ee7cSWilliam Wang    // masked write
22*0f22ee7cSWilliam Wang    val mwmask = Input(Vec(numMWrite, Vec(numEntries, Bool())))
23*0f22ee7cSWilliam Wang    val mwdata = Input(Vec(numMWrite, gen))
24*0f22ee7cSWilliam Wang  })
25*0f22ee7cSWilliam Wang
26*0f22ee7cSWilliam Wang  val data = Reg(Vec(numEntries, gen))
27*0f22ee7cSWilliam Wang
28*0f22ee7cSWilliam Wang  // read ports
29*0f22ee7cSWilliam Wang  for (i <- 0 until numRead) {
30*0f22ee7cSWilliam Wang    io.rdata(i) := data(RegNext(io.raddr(i)))
31*0f22ee7cSWilliam Wang  }
32*0f22ee7cSWilliam Wang
33*0f22ee7cSWilliam Wang  // masked read ports
34*0f22ee7cSWilliam Wang  for (i <- 0 until numMRead) {
35*0f22ee7cSWilliam Wang    io.mrdata(i) := Mux1H(RegNext(io.mrmask(i)), data)
36*0f22ee7cSWilliam Wang  }
37*0f22ee7cSWilliam Wang
38*0f22ee7cSWilliam Wang  // write ports (with priorities)
39*0f22ee7cSWilliam Wang  for (i <- 0 until numWrite) {
40*0f22ee7cSWilliam Wang    when (io.wen(i)) {
41*0f22ee7cSWilliam Wang      data(io.waddr(i)) := io.wdata(i)
42*0f22ee7cSWilliam Wang    }
43*0f22ee7cSWilliam Wang  }
44*0f22ee7cSWilliam Wang
45*0f22ee7cSWilliam Wang  // masked write
46*0f22ee7cSWilliam Wang  for (j <- 0 until numEntries) {
47*0f22ee7cSWilliam Wang    val wen = VecInit((0 until numMWrite).map(i => io.mwmask(i)(j))).asUInt.orR
48*0f22ee7cSWilliam Wang    when (wen) {
49*0f22ee7cSWilliam Wang      data(j) := VecInit((0 until numMWrite).map(i => {
50*0f22ee7cSWilliam Wang        Mux(io.mwmask(i)(j), io.mwdata(i), 0.U).asUInt
51*0f22ee7cSWilliam Wang      })).reduce(_ | _)
52*0f22ee7cSWilliam Wang    }
53*0f22ee7cSWilliam Wang  }
54*0f22ee7cSWilliam Wang
55*0f22ee7cSWilliam Wang  // DataModuleTemplate should not be used when there're any write conflicts
56*0f22ee7cSWilliam Wang  for (i <- 0 until numWrite) {
57*0f22ee7cSWilliam Wang    for (j <- i+1 until numWrite) {
58*0f22ee7cSWilliam Wang      assert(!(io.wen(i) && io.wen(j) && io.waddr(i) === io.waddr(j)))
59*0f22ee7cSWilliam Wang    }
60*0f22ee7cSWilliam Wang  }
61*0f22ee7cSWilliam Wang}
62