xref: /XiangShan/src/main/scala/xiangshan/backend/issue/DataArray.scala (revision c6d439803a044ea209139672b25e35fe8d7f4aa0)
1/***************************************************************************************
2* Copyright (c) 2020-2021 Institute of Computing Technology, Chinese Academy of Sciences
3*
4* XiangShan is licensed under Mulan PSL v2.
5* You can use this software according to the terms and conditions of the Mulan PSL v2.
6* You may obtain a copy of Mulan PSL v2 at:
7*          http://license.coscl.org.cn/MulanPSL2
8*
9* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
10* EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
11* MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
12*
13* See the Mulan PSL v2 for more details.
14***************************************************************************************/
15
16package xiangshan.backend.issue
17
18import chipsalliance.rocketchip.config.Parameters
19import chisel3._
20import chisel3.util._
21import xiangshan._
22import utils._
23
24class DataArrayReadIO(numEntries: Int, numSrc: Int, dataBits: Int)(implicit p: Parameters) extends XSBundle {
25  val addr = Input(UInt(numEntries.W))
26  val data = Vec(numSrc, Output(UInt(dataBits.W)))
27
28  override def cloneType: DataArrayReadIO.this.type =
29    new DataArrayReadIO(numEntries, numSrc, dataBits).asInstanceOf[this.type]
30}
31
32class DataArrayWriteIO(numEntries: Int, numSrc: Int, dataBits: Int)(implicit p: Parameters) extends XSBundle {
33  val enable = Input(Bool())
34  val mask   = Vec(numSrc, Input(Bool()))
35  val addr   = Input(UInt(numEntries.W))
36  val data   = Vec(numSrc, Input(UInt(dataBits.W)))
37
38  override def cloneType: DataArrayWriteIO.this.type =
39    new DataArrayWriteIO(numEntries, numSrc, dataBits).asInstanceOf[this.type]
40}
41
42class DataArrayMultiWriteIO(numEntries: Int, numSrc: Int, dataBits: Int)(implicit p: Parameters) extends XSBundle {
43  val enable = Input(Bool())
44  val addr   = Vec(numSrc, Input(UInt(numEntries.W)))
45  val data   = Input(UInt(dataBits.W))
46
47  override def cloneType: DataArrayMultiWriteIO.this.type =
48    new DataArrayMultiWriteIO(numEntries, numSrc, dataBits).asInstanceOf[this.type]
49}
50
51class DataArrayIO(config: RSConfig)(implicit p: Parameters) extends XSBundle {
52  val read = Vec(config.numDeq, new DataArrayReadIO(config.numEntries, config.numSrc, config.dataBits))
53  val write = Vec(config.numEnq, new DataArrayWriteIO(config.numEntries, config.numSrc, config.dataBits))
54  val multiWrite = Vec(config.numValueBroadCast, new DataArrayMultiWriteIO(config.numEntries, config.numSrc, config.dataBits))
55  val delayedWrite = if (config.delayedRf) Vec(config.numEnq, Flipped(ValidIO(UInt(config.dataBits.W)))) else null
56
57  override def cloneType: DataArrayIO.this.type =
58    new DataArrayIO(config).asInstanceOf[this.type]
59}
60
61class DataArray(config: RSConfig)(implicit p: Parameters) extends XSModule {
62  val io = IO(new DataArrayIO(config))
63
64  // single array for each source
65  def genSingleArray(raddr: Seq[UInt], wen: Seq[Bool], waddr: Seq[UInt], wdata: Seq[UInt]) = {
66    val dataArray = Reg(Vec(config.numEntries, UInt(config.dataBits.W)))
67
68    // write
69    for (((en, addr), wdata) <- wen.zip(waddr).zip(wdata)) {
70      dataArray.zipWithIndex.map { case (entry, i) =>
71        when (en && addr(i)) {
72          entry := wdata
73        }
74      }
75
76      XSDebug(en, p"write ${Hexadecimal(wdata)} to address ${OHToUInt(addr)}\n")
77    }
78
79    // read
80    val rdata = VecInit(raddr.map{ addr =>
81      XSError(PopCount(addr) > 1.U, p"addr ${Binary(addr)} should be one-hot")
82      Mux1H(addr, dataArray)
83    })
84
85    rdata
86  }
87
88  for (i <- 0 until config.numSrc) {
89    val delayedWen = if (i == 1 && config.delayedRf) io.delayedWrite.map(_.valid) else Seq()
90    val delayedWaddr = if (i == 1 && config.delayedRf) RegNext(VecInit(io.write.map(_.addr))) else Seq()
91    val delayedWdata = if (i == 1 && config.delayedRf) io.delayedWrite.map(_.bits) else Seq()
92
93    val wen = io.write.map(w => w.enable && w.mask(i)) ++ io.multiWrite.map(_.enable) ++ delayedWen
94    val waddr = io.write.map(_.addr) ++ io.multiWrite.map(_.addr(i)) ++ delayedWaddr
95    val wdata = io.write.map(_.data(i)) ++ io.multiWrite.map(_.data) ++ delayedWdata
96
97    val rdata = genSingleArray(io.read.map(_.addr), wen, waddr, wdata)
98    io.read.zip(rdata).map{ case (rport, data) => rport.data(i) := data }
99  }
100
101}
102