xref: /XiangShan/src/main/scala/xiangshan/backend/issue/DataArray.scala (revision 8b33cd30e0034914b58520e0dc3c0c4b1aad6a03)
1package xiangshan.backend.issue
2
3import org.chipsalliance.cde.config.Parameters
4import chisel3._
5import chisel3.util._
6import utility.{AsyncRawDataModuleTemplate, XSDebug, XSError}
7import xiangshan.XSModule
8
9class OHReadBundle[T <: Data](addrLen: Int, gen: T) extends Bundle {
10  val addr = Input(UInt(addrLen.W))
11  val data = Output(gen)
12}
13
14class OHWriteBundle[T <: Data](addrLen: Int, gen: T) extends Bundle {
15  val en = Input(Bool())
16  val addr = Input(UInt(addrLen.W))
17  val data = Input(gen)
18}
19
20class DataArrayIO[T <: Data](gen: T, numRead: Int, numWrite: Int, numEntries: Int) extends Bundle {
21  val read = Vec(numRead, new OHReadBundle(numEntries, gen))
22  val write = Vec(numWrite, new OHWriteBundle(numEntries, gen))
23}
24
25class DataArray[T <: Data](gen: T, numRead: Int, numWrite: Int, numEntries: Int)
26  (implicit p: Parameters)
27  extends XSModule {
28
29  val io = IO(new DataArrayIO(gen, numRead, numWrite, numEntries))
30
31  private val dataModule = Module(new AsyncRawDataModuleTemplate(gen, numEntries, io.read.length, io.write.length))
32
33  dataModule.io.rvec  := VecInit(io.read.map(_.addr))
34  io.read.zip(dataModule.io.rdata).foreach { case (l, r) => l.data := r}
35
36  dataModule.io.wvec  := VecInit(io.write.map(_.addr))
37  dataModule.io.wen   := VecInit(io.write.map(_.en))
38  dataModule.io.wdata := VecInit(io.write.map(_.data))
39
40  // check if one entry wroten by multi bundles
41  for (i <- 0 until numEntries) {
42    val wCnt = VecInit(io.write.indices.map(j => dataModule.io.wen(j) && dataModule.io.wvec(j)(i)))
43    XSError(RegNext(PopCount(wCnt) > 1.U), s"why not OH $i?")
44    XSDebug(PopCount(wCnt) > 1.U, "ERROR: IssueQueue DataArray write overlap!\n")
45  }
46}
47