xref: /XiangShan/src/main/scala/xiangshan/backend/issue/DataArray.scala (revision c84ff7ef874df038bead035106276de5d460dc18)
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._
23import xiangshan.backend.decode.{ImmUnion, Imm_U}
24import xiangshan.backend.exu.ExuConfig
25
26class DataArrayReadIO(numEntries: Int, numSrc: Int, dataBits: Int)(implicit p: Parameters) extends XSBundle {
27  val addr = Input(UInt(numEntries.W))
28  val data = Vec(numSrc, Output(UInt(dataBits.W)))
29
30  override def cloneType: DataArrayReadIO.this.type =
31    new DataArrayReadIO(numEntries, numSrc, dataBits).asInstanceOf[this.type]
32}
33
34class DataArrayWriteIO(numEntries: Int, numSrc: Int, dataBits: Int)(implicit p: Parameters) extends XSBundle {
35  val enable = Input(Bool())
36  val mask   = Vec(numSrc, Input(Bool()))
37  val addr   = Input(UInt(numEntries.W))
38  val data   = Vec(numSrc, Input(UInt(dataBits.W)))
39
40  override def cloneType: DataArrayWriteIO.this.type =
41    new DataArrayWriteIO(numEntries, numSrc, dataBits).asInstanceOf[this.type]
42}
43
44class DataArrayMultiWriteIO(numEntries: Int, numSrc: Int, dataBits: Int)(implicit p: Parameters) extends XSBundle {
45  val enable = Input(Bool())
46  val addr   = Vec(numSrc, Input(UInt(numEntries.W)))
47  val data   = Input(UInt(dataBits.W))
48
49  override def cloneType: DataArrayMultiWriteIO.this.type =
50    new DataArrayMultiWriteIO(numEntries, numSrc, dataBits).asInstanceOf[this.type]
51}
52
53class DataArrayIO(config: RSConfig)(implicit p: Parameters) extends XSBundle {
54  val read = Vec(config.numDeq, new DataArrayReadIO(config.numEntries, config.numSrc, config.dataBits))
55  val write = Vec(config.numEnq, new DataArrayWriteIO(config.numEntries, config.numSrc, config.dataBits))
56  val multiWrite = Vec(config.numValueBroadCast, new DataArrayMultiWriteIO(config.numEntries, config.numSrc, config.dataBits))
57  val delayedWrite = if (config.delayedRf) Vec(config.numEnq, Flipped(ValidIO(UInt(config.dataBits.W)))) else null
58
59  override def cloneType: DataArrayIO.this.type =
60    new DataArrayIO(config).asInstanceOf[this.type]
61}
62
63class DataArray(config: RSConfig)(implicit p: Parameters) extends XSModule {
64  val io = IO(new DataArrayIO(config))
65
66  for (i <- 0 until config.numSrc) {
67    val delayedWen = if (i == 1 && config.delayedRf) io.delayedWrite.map(_.valid) else Seq()
68    val delayedWaddr = if (i == 1 && config.delayedRf) RegNext(VecInit(io.write.map(_.addr))) else Seq()
69    val delayedWdata = if (i == 1 && config.delayedRf) io.delayedWrite.map(_.bits) else Seq()
70
71    val wen = io.write.map(w => w.enable && w.mask(i)) ++ io.multiWrite.map(_.enable) ++ delayedWen
72    val waddr = io.write.map(_.addr) ++ io.multiWrite.map(_.addr(i)) ++ delayedWaddr
73    val wdata = io.write.map(_.data(i)) ++ io.multiWrite.map(_.data) ++ delayedWdata
74
75    val dataModule = Module(new AsyncRawDataModuleTemplate(UInt(config.dataBits.W), config.numEntries, io.read.length, wen.length))
76    dataModule.io.rvec := VecInit(io.read.map(_.addr))
77    io.read.map(_.data(i)).zip(dataModule.io.rdata).map{ case (d, r) => d := r }
78    dataModule.io.wen := wen
79    dataModule.io.wvec := waddr
80    dataModule.io.wdata := wdata
81  }
82
83}
84
85class ImmExtractor(numSrc: Int, dataBits: Int)(implicit p: Parameters) extends XSModule {
86  val io = IO(new Bundle {
87    val uop = Input(new MicroOp)
88    val data_in = Vec(numSrc, Input(UInt(dataBits.W)))
89    val data_out = Vec(numSrc, Output(UInt(dataBits.W)))
90  })
91  io.data_out := io.data_in
92}
93
94class JumpImmExtractor(implicit p: Parameters) extends ImmExtractor(2, 64) {
95  val jump_pc = IO(Input(UInt(VAddrBits.W)))
96  val jalr_target = IO(Input(UInt(VAddrBits.W)))
97
98  when (SrcType.isPc(io.uop.ctrl.srcType(0))) {
99    io.data_out(0) := SignExt(jump_pc, XLEN)
100  }
101  io.data_out(1) := jalr_target
102}
103
104class AluImmExtractor(implicit p: Parameters) extends ImmExtractor(2, 64) {
105  when (SrcType.isImm(io.uop.ctrl.srcType(1))) {
106    val imm32 = Mux(io.uop.ctrl.selImm === SelImm.IMM_U,
107      ImmUnion.U.toImm32(io.uop.ctrl.imm),
108      ImmUnion.I.toImm32(io.uop.ctrl.imm)
109    )
110    io.data_out(1) := SignExt(imm32, XLEN)
111  }
112}
113
114object ImmExtractor {
115  def apply(config: RSConfig, exuCfg: ExuConfig, uop: MicroOp, data_in: Vec[UInt], pc: UInt, target: UInt)(implicit p: Parameters): Vec[UInt] = {
116    val immExt = exuCfg match {
117      case JumpExeUnitCfg => {
118        val ext = Module(new JumpImmExtractor)
119        ext.jump_pc := pc
120        ext.jalr_target := target
121        ext
122      }
123      case AluExeUnitCfg => Module(new AluImmExtractor)
124      case _ => Module(new ImmExtractor(config.numSrc, config.dataBits))
125    }
126    immExt.io.uop := uop
127    immExt.io.data_in := data_in
128    immExt.io.data_out
129  }
130}
131