xref: /XiangShan/src/main/scala/xiangshan/backend/issue/DataArray.scala (revision dc597826530cb6803c2396d6ab0e5eb176b732e0)
1/***************************************************************************************
2* Copyright (c) 2020-2021 Institute of Computing Technology, Chinese Academy of Sciences
3* Copyright (c) 2020-2021 Peng Cheng Laboratory
4*
5* XiangShan is licensed under Mulan PSL v2.
6* You can use this software according to the terms and conditions of the Mulan PSL v2.
7* You may obtain a copy of Mulan PSL v2 at:
8*          http://license.coscl.org.cn/MulanPSL2
9*
10* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
11* EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
12* MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
13*
14* See the Mulan PSL v2 for more details.
15***************************************************************************************/
16
17package xiangshan.backend.issue
18
19import chipsalliance.rocketchip.config.Parameters
20import chisel3._
21import chisel3.util._
22import xiangshan._
23import utils._
24import xiangshan.backend.decode.{ImmUnion, Imm_U}
25import xiangshan.backend.exu.ExuConfig
26
27class DataArrayReadIO(numEntries: Int, numSrc: Int, dataBits: Int)(implicit p: Parameters) extends XSBundle {
28  val addr = Input(UInt(numEntries.W))
29  val data = Vec(numSrc, Output(UInt(dataBits.W)))
30
31  override def cloneType: DataArrayReadIO.this.type =
32    new DataArrayReadIO(numEntries, numSrc, dataBits).asInstanceOf[this.type]
33}
34
35class DataArrayWriteIO(numEntries: Int, numSrc: Int, dataBits: Int)(implicit p: Parameters) extends XSBundle {
36  val enable = Input(Bool())
37  val mask   = Vec(numSrc, Input(Bool()))
38  val addr   = Input(UInt(numEntries.W))
39  val data   = Vec(numSrc, Input(UInt(dataBits.W)))
40
41  override def cloneType: DataArrayWriteIO.this.type =
42    new DataArrayWriteIO(numEntries, numSrc, dataBits).asInstanceOf[this.type]
43}
44
45class DataArrayMultiWriteIO(numEntries: Int, numSrc: Int, dataBits: Int)(implicit p: Parameters) extends XSBundle {
46  val enable = Input(Bool())
47  val addr   = Vec(numSrc, Input(UInt(numEntries.W)))
48  val data   = Input(UInt(dataBits.W))
49
50  override def cloneType: DataArrayMultiWriteIO.this.type =
51    new DataArrayMultiWriteIO(numEntries, numSrc, dataBits).asInstanceOf[this.type]
52}
53
54class DataArrayIO(params: RSParams)(implicit p: Parameters) extends XSBundle {
55  val read = Vec(params.numDeq, new DataArrayReadIO(params.numEntries, params.numSrc, params.dataBits))
56  val write = Vec(params.numEnq, new DataArrayWriteIO(params.numEntries, params.numSrc, params.dataBits))
57  val multiWrite = Vec(params.numWakeup, new DataArrayMultiWriteIO(params.numEntries, params.numSrc, params.dataBits))
58  val delayedWrite = if (params.delayedRf) Vec(params.numEnq, Flipped(ValidIO(UInt(params.dataBits.W)))) else null
59
60  override def cloneType: DataArrayIO.this.type =
61    new DataArrayIO(params).asInstanceOf[this.type]
62}
63
64class DataArray(params: RSParams)(implicit p: Parameters) extends XSModule {
65  val io = IO(new DataArrayIO(params))
66
67  for (i <- 0 until params.numSrc) {
68    val delayedWen = if (i == 1 && params.delayedRf) io.delayedWrite.map(_.valid) else Seq()
69    val delayedWaddr = if (i == 1 && params.delayedRf) RegNext(VecInit(io.write.map(_.addr))) else Seq()
70    val delayedWdata = if (i == 1 && params.delayedRf) io.delayedWrite.map(_.bits) else Seq()
71
72    val wen = io.write.map(w => w.enable && w.mask(i)) ++ io.multiWrite.map(_.enable) ++ delayedWen
73    val waddr = io.write.map(_.addr) ++ io.multiWrite.map(_.addr(i)) ++ delayedWaddr
74    val wdata = io.write.map(_.data(i)) ++ io.multiWrite.map(_.data) ++ delayedWdata
75
76    val dataModule = Module(new AsyncRawDataModuleTemplate(UInt(params.dataBits.W), params.numEntries, io.read.length, wen.length))
77    dataModule.io.rvec := VecInit(io.read.map(_.addr))
78    io.read.map(_.data(i)).zip(dataModule.io.rdata).map{ case (d, r) => d := r }
79    dataModule.io.wen := wen
80    dataModule.io.wvec := waddr
81    dataModule.io.wdata := wdata
82  }
83
84}
85
86class ImmExtractor(numSrc: Int, dataBits: Int)(implicit p: Parameters) extends XSModule {
87  val io = IO(new Bundle {
88    val uop = Input(new MicroOp)
89    val data_in = Vec(numSrc, Input(UInt(dataBits.W)))
90    val data_out = Vec(numSrc, Output(UInt(dataBits.W)))
91  })
92  io.data_out := io.data_in
93}
94
95class JumpImmExtractor(implicit p: Parameters) extends ImmExtractor(2, 64) {
96  val jump_pc = IO(Input(UInt(VAddrBits.W)))
97  val jalr_target = IO(Input(UInt(VAddrBits.W)))
98
99  when (SrcType.isPc(io.uop.ctrl.srcType(0))) {
100    io.data_out(0) := SignExt(jump_pc, XLEN)
101  }
102  io.data_out(1) := jalr_target
103}
104
105class AluImmExtractor(implicit p: Parameters) extends ImmExtractor(2, 64) {
106  when (SrcType.isImm(io.uop.ctrl.srcType(1))) {
107    val imm32 = Mux(io.uop.ctrl.selImm === SelImm.IMM_U,
108      ImmUnion.U.toImm32(io.uop.ctrl.imm),
109      ImmUnion.I.toImm32(io.uop.ctrl.imm)
110    )
111    io.data_out(1) := SignExt(imm32, XLEN)
112  }
113}
114
115object ImmExtractor {
116  def apply(params: RSParams, uop: MicroOp, data_in: Vec[UInt], pc: Option[UInt], target: Option[UInt])
117           (implicit p: Parameters): Vec[UInt] = {
118    val immExt = (params.isJump, params.isAlu) match {
119      case (true, false) => {
120        val ext = Module(new JumpImmExtractor)
121        ext.jump_pc := pc.get
122        ext.jalr_target := target.get
123        ext
124      }
125      case (false, true) => Module(new AluImmExtractor)
126      case _ => Module(new ImmExtractor(params.numSrc, params.dataBits))
127    }
128    immExt.io.uop := uop
129    immExt.io.data_in := data_in
130    immExt.io.data_out
131  }
132}
133