xref: /XiangShan/src/main/scala/xiangshan/backend/issue/DataArray.scala (revision 5c7674fe439b80ea3bb6c6207b7d169ed6183be5)
1package xiangshan.backend.issue
2
3import chipsalliance.rocketchip.config.Parameters
4import chisel3._
5import chisel3.util._
6import xiangshan._
7import utils._
8
9class DataArrayReadIO(numEntries: Int, numSrc: Int, dataBits: Int)(implicit p: Parameters) extends XSBundle {
10  val addr = Input(UInt(numEntries.W))
11  val data = Vec(numSrc, Output(UInt(dataBits.W)))
12
13  override def cloneType: DataArrayReadIO.this.type =
14    new DataArrayReadIO(numEntries, numSrc, dataBits).asInstanceOf[this.type]
15}
16
17class DataArrayWriteIO(numEntries: Int, numSrc: Int, dataBits: Int)(implicit p: Parameters) extends XSBundle {
18  val enable = Input(Bool())
19  val mask   = Vec(numSrc, Input(Bool()))
20  val addr   = Input(UInt(numEntries.W))
21  val data   = Vec(numSrc, Input(UInt(dataBits.W)))
22
23  override def cloneType: DataArrayWriteIO.this.type =
24    new DataArrayWriteIO(numEntries, numSrc, dataBits).asInstanceOf[this.type]
25}
26
27class DataArrayMultiWriteIO(numEntries: Int, numSrc: Int, dataBits: Int)(implicit p: Parameters) extends XSBundle {
28  val enable = Input(Bool())
29  val addr   = Vec(numSrc, Input(UInt(numEntries.W)))
30  val data   = Input(UInt(dataBits.W))
31
32  override def cloneType: DataArrayMultiWriteIO.this.type =
33    new DataArrayMultiWriteIO(numEntries, numSrc, dataBits).asInstanceOf[this.type]
34}
35
36class DataArrayIO(config: RSConfig)(implicit p: Parameters) extends XSBundle {
37  val read = Vec(config.numDeq, new DataArrayReadIO(config.numEntries, config.numSrc, config.dataBits))
38  val write = Vec(config.numEnq, new DataArrayWriteIO(config.numEntries, config.numSrc, config.dataBits))
39  val multiWrite = Vec(config.numValueBroadCast, new DataArrayMultiWriteIO(config.numEntries, config.numSrc, config.dataBits))
40  val delayedWrite = if (config.delayedRf) Vec(config.numEnq, Flipped(ValidIO(UInt(config.dataBits.W)))) else null
41
42  override def cloneType: DataArrayIO.this.type =
43    new DataArrayIO(config).asInstanceOf[this.type]
44}
45
46class DataArray(config: RSConfig)(implicit p: Parameters) extends XSModule {
47  val io = IO(new DataArrayIO(config))
48
49  // single array for each source
50  def genSingleArray(raddr: Seq[UInt], wen: Seq[Bool], waddr: Seq[UInt], wdata: Seq[UInt]) = {
51    val dataArray = Reg(Vec(config.numEntries, UInt(config.dataBits.W)))
52
53    // write
54    for (((en, addr), wdata) <- wen.zip(waddr).zip(wdata)) {
55      dataArray.zipWithIndex.map { case (entry, i) =>
56        when (en && addr(i)) {
57          entry := wdata
58        }
59      }
60
61      XSDebug(en, p"write ${Hexadecimal(wdata)} to address ${OHToUInt(addr)}\n")
62    }
63
64    // read
65    val rdata = VecInit(raddr.map{ addr =>
66      XSError(PopCount(addr) > 1.U, p"addr ${Binary(addr)} should be one-hot")
67      Mux1H(addr, dataArray)
68    })
69
70    rdata
71  }
72
73  for (i <- 0 until config.numSrc) {
74    val delayedWen = if (i == 1 && config.delayedRf) io.delayedWrite.map(_.valid) else Seq()
75    val delayedWaddr = if (i == 1 && config.delayedRf) RegNext(VecInit(io.write.map(_.addr))) else Seq()
76    val delayedWdata = if (i == 1 && config.delayedRf) io.delayedWrite.map(_.bits) else Seq()
77
78    val wen = io.write.map(w => w.enable && w.mask(i)) ++ io.multiWrite.map(_.enable) ++ delayedWen
79    val waddr = io.write.map(_.addr) ++ io.multiWrite.map(_.addr(i)) ++ delayedWaddr
80    val wdata = io.write.map(_.data(i)) ++ io.multiWrite.map(_.data) ++ delayedWdata
81
82    val rdata = genSingleArray(io.read.map(_.addr), wen, waddr, wdata)
83    io.read.zip(rdata).map{ case (rport, data) => rport.data(i) := data }
84  }
85
86}
87