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