xref: /XiangShan/src/main/scala/xiangshan/mem/MaskedDataModule.scala (revision 39f2ec76d83f983643468ae98702c27ff06db684)
1c6d43980SLemover/***************************************************************************************
2c6d43980SLemover* Copyright (c) 2020-2021 Institute of Computing Technology, Chinese Academy of Sciences
3f320e0f0SYinan 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](
26*39f2ec76SWilliam Wang  gen: T,
27*39f2ec76SWilliam Wang  numEntries: Int,
28*39f2ec76SWilliam Wang  numRead: Int,
29*39f2ec76SWilliam Wang  numWrite: Int,
30*39f2ec76SWilliam Wang  numMRead: Int = 0,
31*39f2ec76SWilliam Wang  numMWrite: Int = 0
322225d46eSJiawei Lin) extends Module {
330f22ee7cSWilliam Wang  val io = IO(new Bundle {
340f22ee7cSWilliam Wang    // address indexed sync read
350f22ee7cSWilliam Wang    val raddr = Input(Vec(numRead, UInt(log2Up(numEntries).W)))
360f22ee7cSWilliam Wang    val rdata = Output(Vec(numRead, gen))
370f22ee7cSWilliam Wang    // masked sync read (1H)
380f22ee7cSWilliam Wang    val mrmask = Input(Vec(numMRead, Vec(numEntries, Bool())))
390f22ee7cSWilliam Wang    val mrdata = Output(Vec(numMRead, gen))
400f22ee7cSWilliam Wang    // address indexed write
410f22ee7cSWilliam Wang    val wen   = Input(Vec(numWrite, Bool()))
420f22ee7cSWilliam Wang    val waddr = Input(Vec(numWrite, UInt(log2Up(numEntries).W)))
430f22ee7cSWilliam Wang    val wdata = Input(Vec(numWrite, gen))
440f22ee7cSWilliam Wang    // masked write
450f22ee7cSWilliam Wang    val mwmask = Input(Vec(numMWrite, Vec(numEntries, Bool())))
460f22ee7cSWilliam Wang    val mwdata = Input(Vec(numMWrite, gen))
470f22ee7cSWilliam Wang  })
480f22ee7cSWilliam Wang
490f22ee7cSWilliam Wang  val data = Reg(Vec(numEntries, gen))
500f22ee7cSWilliam Wang
510f22ee7cSWilliam Wang  // read ports
520f22ee7cSWilliam Wang  for (i <- 0 until numRead) {
530f22ee7cSWilliam Wang    io.rdata(i) := data(RegNext(io.raddr(i)))
540f22ee7cSWilliam Wang  }
550f22ee7cSWilliam Wang
560f22ee7cSWilliam Wang  // masked read ports
570f22ee7cSWilliam Wang  for (i <- 0 until numMRead) {
580f22ee7cSWilliam Wang    io.mrdata(i) := Mux1H(RegNext(io.mrmask(i)), data)
590f22ee7cSWilliam Wang  }
600f22ee7cSWilliam Wang
610f22ee7cSWilliam Wang  // write ports (with priorities)
620f22ee7cSWilliam Wang  for (i <- 0 until numWrite) {
630f22ee7cSWilliam Wang    when (io.wen(i)) {
640f22ee7cSWilliam Wang      data(io.waddr(i)) := io.wdata(i)
650f22ee7cSWilliam Wang    }
660f22ee7cSWilliam Wang  }
670f22ee7cSWilliam Wang
680f22ee7cSWilliam Wang  // masked write
690f22ee7cSWilliam Wang  for (j <- 0 until numEntries) {
700f22ee7cSWilliam Wang    val wen = VecInit((0 until numMWrite).map(i => io.mwmask(i)(j))).asUInt.orR
710f22ee7cSWilliam Wang    when (wen) {
720f22ee7cSWilliam Wang      data(j) := VecInit((0 until numMWrite).map(i => {
730f22ee7cSWilliam Wang        Mux(io.mwmask(i)(j), io.mwdata(i), 0.U).asUInt
740f22ee7cSWilliam Wang      })).reduce(_ | _)
750f22ee7cSWilliam Wang    }
760f22ee7cSWilliam Wang  }
770f22ee7cSWilliam Wang
780f22ee7cSWilliam Wang  // DataModuleTemplate should not be used when there're any write conflicts
790f22ee7cSWilliam Wang  for (i <- 0 until numWrite) {
800f22ee7cSWilliam Wang    for (j <- i+1 until numWrite) {
810f22ee7cSWilliam Wang      assert(!(io.wen(i) && io.wen(j) && io.waddr(i) === io.waddr(j)))
820f22ee7cSWilliam Wang    }
830f22ee7cSWilliam Wang  }
840f22ee7cSWilliam Wang}
85*39f2ec76SWilliam Wang
86*39f2ec76SWilliam Wangclass MaskedBankedSyncDataModuleTemplate[T <: Data](
87*39f2ec76SWilliam Wang  gen: T,
88*39f2ec76SWilliam Wang  numEntries: Int,
89*39f2ec76SWilliam Wang  numRead: Int,
90*39f2ec76SWilliam Wang  numWrite: Int,
91*39f2ec76SWilliam Wang  numMRead: Int = 0,
92*39f2ec76SWilliam Wang  numMWrite: Int = 0,
93*39f2ec76SWilliam Wang  numWBanks: Int = 2
94*39f2ec76SWilliam Wang) extends Module {
95*39f2ec76SWilliam Wang  val io = IO(new Bundle {
96*39f2ec76SWilliam Wang    // address indexed sync read
97*39f2ec76SWilliam Wang    val raddr = Input(Vec(numRead, UInt(log2Up(numEntries).W)))
98*39f2ec76SWilliam Wang    val rdata = Output(Vec(numRead, gen))
99*39f2ec76SWilliam Wang    // masked sync read (1H)
100*39f2ec76SWilliam Wang    val mrmask = Input(Vec(numMRead, Vec(numEntries, Bool())))
101*39f2ec76SWilliam Wang    val mrdata = Output(Vec(numMRead, gen))
102*39f2ec76SWilliam Wang    // address indexed write
103*39f2ec76SWilliam Wang    val wen   = Input(Vec(numWrite, Bool()))
104*39f2ec76SWilliam Wang    val waddr = Input(Vec(numWrite, UInt(log2Up(numEntries).W)))
105*39f2ec76SWilliam Wang    val wdata = Input(Vec(numWrite, gen))
106*39f2ec76SWilliam Wang    // masked write
107*39f2ec76SWilliam Wang    val mwmask = Input(Vec(numMWrite, Vec(numEntries, Bool())))
108*39f2ec76SWilliam Wang    val mwdata = Input(Vec(numMWrite, gen))
109*39f2ec76SWilliam Wang  })
110*39f2ec76SWilliam Wang
111*39f2ec76SWilliam Wang  require(isPow2(numWBanks))
112*39f2ec76SWilliam Wang  require(numWBanks >= 2)
113*39f2ec76SWilliam Wang
114*39f2ec76SWilliam Wang  val numEntryPerBank = numEntries / numWBanks
115*39f2ec76SWilliam Wang
116*39f2ec76SWilliam Wang  val data = Reg(Vec(numEntries, gen))
117*39f2ec76SWilliam Wang
118*39f2ec76SWilliam Wang  // read ports
119*39f2ec76SWilliam Wang  for (i <- 0 until numRead) {
120*39f2ec76SWilliam Wang    val raddr_dec = RegNext(UIntToOH(io.raddr(i)))
121*39f2ec76SWilliam Wang    io.rdata(i) := Mux1H(raddr_dec, data)
122*39f2ec76SWilliam Wang  }
123*39f2ec76SWilliam Wang
124*39f2ec76SWilliam Wang  // masked read ports
125*39f2ec76SWilliam Wang  for (i <- 0 until numMRead) {
126*39f2ec76SWilliam Wang    io.mrdata(i) := Mux1H(RegNext(io.mrmask(i)), data)
127*39f2ec76SWilliam Wang  }
128*39f2ec76SWilliam Wang
129*39f2ec76SWilliam Wang  val waddr_dec = io.waddr.map(a => UIntToOH(a))
130*39f2ec76SWilliam Wang
131*39f2ec76SWilliam Wang  def selectBankMask(in: UInt, bank: Int): UInt = {
132*39f2ec76SWilliam Wang    in((bank + 1) * numEntryPerBank - 1, bank * numEntryPerBank)
133*39f2ec76SWilliam Wang  }
134*39f2ec76SWilliam Wang
135*39f2ec76SWilliam Wang  for (bank <- 0 until numWBanks) {
136*39f2ec76SWilliam Wang    // write ports
137*39f2ec76SWilliam Wang    // s0: write to bank level buffer
138*39f2ec76SWilliam Wang    val s0_bank_waddr_dec = waddr_dec.map(a => selectBankMask(a, bank))
139*39f2ec76SWilliam Wang    val s0_bank_write_en = io.wen.zip(s0_bank_waddr_dec).map(w => w._1 && w._2.orR)
140*39f2ec76SWilliam Wang    s0_bank_waddr_dec.zipWithIndex.map(a =>
141*39f2ec76SWilliam Wang      a._1.suggestName("s0_bank_waddr_dec" + bank + "_" + a._2)
142*39f2ec76SWilliam Wang    )
143*39f2ec76SWilliam Wang    s0_bank_write_en.zipWithIndex.map(a =>
144*39f2ec76SWilliam Wang      a._1.suggestName("s0_bank_write_en" + bank + "_" + a._2)
145*39f2ec76SWilliam Wang    )
146*39f2ec76SWilliam Wang    // s1: write data to entries
147*39f2ec76SWilliam Wang    val s1_bank_waddr_dec = s0_bank_waddr_dec.zip(s0_bank_write_en).map(w => RegEnable(w._1, w._2))
148*39f2ec76SWilliam Wang    val s1_bank_wen = RegNext(VecInit(s0_bank_write_en))
149*39f2ec76SWilliam Wang    val s1_wdata = io.wdata.zip(s0_bank_write_en).map(w => RegEnable(w._1, w._2))
150*39f2ec76SWilliam Wang    s1_bank_waddr_dec.zipWithIndex.map(a =>
151*39f2ec76SWilliam Wang      a._1.suggestName("s1_bank_waddr_dec" + bank + "_" + a._2)
152*39f2ec76SWilliam Wang    )
153*39f2ec76SWilliam Wang    s1_bank_wen.zipWithIndex.map(a =>
154*39f2ec76SWilliam Wang      a._1.suggestName("s1_bank_wen" + bank + "_" + a._2)
155*39f2ec76SWilliam Wang    )
156*39f2ec76SWilliam Wang    s1_wdata.zipWithIndex.map(a =>
157*39f2ec76SWilliam Wang      a._1.suggestName("s1_wdata" + bank + "_" + a._2)
158*39f2ec76SWilliam Wang    )
159*39f2ec76SWilliam Wang    // masked write ports
160*39f2ec76SWilliam Wang    // s0: write to bank level buffer
161*39f2ec76SWilliam Wang    val s0_bank_mwmask = io.mwmask.map(a => selectBankMask(a.asUInt, bank))
162*39f2ec76SWilliam Wang    val s0_bank_mwrite_en = s0_bank_mwmask.map(w => w.orR)
163*39f2ec76SWilliam Wang    s0_bank_mwmask.zipWithIndex.map(a =>
164*39f2ec76SWilliam Wang      a._1.suggestName("s0_bank_mwmask" + bank + "_" + a._2)
165*39f2ec76SWilliam Wang    )
166*39f2ec76SWilliam Wang    s0_bank_mwrite_en.zipWithIndex.map(a =>
167*39f2ec76SWilliam Wang      a._1.suggestName("s0_bank_mwrite_en" + bank + "_" + a._2)
168*39f2ec76SWilliam Wang    )
169*39f2ec76SWilliam Wang    // s1: write data to entries
170*39f2ec76SWilliam Wang    val s1_bank_mwmask = s0_bank_mwmask.map(a => RegNext(a))
171*39f2ec76SWilliam Wang    val s1_mwdata = io.mwdata.zip(s0_bank_mwrite_en).map(w => RegEnable(w._1, w._2))
172*39f2ec76SWilliam Wang    s1_bank_mwmask.zipWithIndex.map(a =>
173*39f2ec76SWilliam Wang      a._1.suggestName("s1_bank_mwmask" + bank + "_" + a._2)
174*39f2ec76SWilliam Wang    )
175*39f2ec76SWilliam Wang    s1_mwdata.zipWithIndex.map(a =>
176*39f2ec76SWilliam Wang      a._1.suggestName("s1_mwdata" + bank + "_" + a._2)
177*39f2ec76SWilliam Wang    )
178*39f2ec76SWilliam Wang
179*39f2ec76SWilliam Wang    // entry write
180*39f2ec76SWilliam Wang    for (entry <- 0 until numEntryPerBank) {
181*39f2ec76SWilliam Wang      // write ports
182*39f2ec76SWilliam Wang      val s1_entry_write_en_vec = s1_bank_wen.zip(s1_bank_waddr_dec).map(w => w._1 && w._2(entry))
183*39f2ec76SWilliam Wang      val s1_entry_write_en = VecInit(s1_entry_write_en_vec).asUInt.orR
184*39f2ec76SWilliam Wang      val s1_entry_write_data = Mux1H(s1_entry_write_en_vec, s1_wdata)
185*39f2ec76SWilliam Wang      // masked write ports
186*39f2ec76SWilliam Wang      val s1_bank_mwrite_en_vec = s1_bank_mwmask.map(_(entry))
187*39f2ec76SWilliam Wang      val s1_bank_mwrite_en = VecInit(s1_bank_mwrite_en_vec).asUInt.orR
188*39f2ec76SWilliam Wang      val s1_bank_mwrite_data = Mux1H(s1_bank_mwrite_en_vec, s1_mwdata)
189*39f2ec76SWilliam Wang      when (s1_entry_write_en || s1_bank_mwrite_en) {
190*39f2ec76SWilliam Wang        data(bank * numEntryPerBank + entry) := Mux1H(
191*39f2ec76SWilliam Wang          Seq(s1_entry_write_en, s1_bank_mwrite_en),
192*39f2ec76SWilliam Wang          Seq(s1_entry_write_data, s1_bank_mwrite_data)
193*39f2ec76SWilliam Wang        )
194*39f2ec76SWilliam Wang      }
195*39f2ec76SWilliam Wang      s1_entry_write_en_vec.zipWithIndex.map(a =>
196*39f2ec76SWilliam Wang        a._1.suggestName("s1_entry_write_en_vec" + bank + "_" + entry + "_" + a._2)
197*39f2ec76SWilliam Wang      )
198*39f2ec76SWilliam Wang      s1_bank_mwrite_en_vec.zipWithIndex.map(a =>
199*39f2ec76SWilliam Wang        a._1.suggestName("s1_bank_mwrite_en_vec" + bank + "_" + entry + "_" + a._2)
200*39f2ec76SWilliam Wang      )
201*39f2ec76SWilliam Wang      s1_entry_write_en.suggestName("s1_entry_write_en" + bank + "_" + entry)
202*39f2ec76SWilliam Wang      s1_entry_write_data.suggestName("s1_entry_write_data" + bank + "_" + entry)
203*39f2ec76SWilliam Wang      s1_bank_mwrite_en.suggestName("s1_bank_mwrite_en" + bank + "_" + entry)
204*39f2ec76SWilliam Wang      s1_bank_mwrite_data.suggestName("s1_bank_mwrite_data" + bank + "_" + entry)
205*39f2ec76SWilliam Wang    }
206*39f2ec76SWilliam Wang  }
207*39f2ec76SWilliam Wang}
208