xref: /XiangShan/src/main/scala/xiangshan/backend/issue/DataArray.scala (revision c15d13addb1a8d41338fd24b73198001606945c6)
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_LUI_LOAD, 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
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
39class DataArrayMultiWriteIO(numEntries: Int, numSrc: Int, dataBits: Int)(implicit p: Parameters) extends XSBundle {
40  val enable = Input(Bool())
41  val addr   = Vec(numSrc, Input(UInt(numEntries.W)))
42  val data   = Input(UInt(dataBits.W))
43}
44
45class DataArrayDelayedWriteIO(numEntries: Int, numSrc: Int, dataBits: Int)(implicit p: Parameters) extends XSBundle {
46  val mask = Vec(numSrc, Input(Bool()))
47  val addr = Input(UInt(numEntries.W))
48  val data = Vec(numSrc, Input(UInt(dataBits.W)))
49}
50
51class DataArrayIO(params: RSParams)(implicit p: Parameters) extends XSBundle {
52  val read = Vec(params.numDeq + 1, new DataArrayReadIO(params.numEntries, params.numSrc, params.dataBits))
53  val write = Vec(params.numEnq, new DataArrayWriteIO(params.numEntries, params.numSrc, params.dataBits))
54  val multiWrite = Vec(params.numWakeup, new DataArrayMultiWriteIO(params.numEntries, params.numSrc, params.dataBits))
55  val delayedWrite = if (params.delayedSrc) Vec(params.numEnq, new DataArrayDelayedWriteIO(params.numEntries, params.numSrc, params.dataBits)) else null
56}
57
58class DataArray(params: RSParams)(implicit p: Parameters) extends XSModule {
59  val io = IO(new DataArrayIO(params))
60
61  for (i <- 0 until params.numSrc) {
62    val delayedWen = if (params.delayedSrc) io.delayedWrite.map(_.mask(i)) else Seq()
63    val delayedWaddr = if (params.delayedSrc) io.delayedWrite.map(_.addr) else Seq()
64    val delayedWdata = if (params.delayedSrc) io.delayedWrite.map(_.data(i)) else Seq()
65
66    val wen = io.write.map(w => w.enable && w.mask(i)) ++ io.multiWrite.map(_.enable) ++ delayedWen
67    val waddr = io.write.map(_.addr) ++ io.multiWrite.map(_.addr(i)) ++ delayedWaddr
68    val wdata = io.write.map(_.data(i)) ++ io.multiWrite.map(_.data) ++ delayedWdata
69
70    val dataModule = Module(new AsyncRawDataModuleTemplate(UInt(params.dataBits.W), params.numEntries, io.read.length, wen.length))
71    dataModule.io.rvec := VecInit(io.read.map(_.addr))
72    io.read.map(_.data(i)).zip(dataModule.io.rdata).foreach{ case (d, r) => d := r }
73    dataModule.io.wen := wen
74    dataModule.io.wvec := waddr
75    dataModule.io.wdata := wdata
76
77    for (i <- 0 until params.numEntries) {
78      val w = VecInit(wen.indices.map(j => dataModule.io.wen(j) && dataModule.io.wvec(j)(i)))
79      XSError(RegNext(PopCount(w) > 1.U), s"why not OH $i?")
80      when(PopCount(w) > 1.U) {
81        XSDebug("ERROR: RS DataArray write overlap!\n")
82      }
83    }
84  }
85
86}
87
88class ImmExtractor(numSrc: Int, dataBits: Int)(implicit p: Parameters) extends XSModule {
89  val io = IO(new Bundle {
90    val uop = Input(new MicroOp)
91    val data_in = Vec(numSrc, Input(UInt(dataBits.W)))
92    val data_out = Vec(numSrc, Output(UInt(dataBits.W)))
93  })
94  io.data_out := io.data_in
95
96  val jump_pc = IO(Input(UInt(VAddrBits.W)))
97  val jalr_target = IO(Input(UInt(VAddrBits.W)))
98  jump_pc <> DontCare
99  jalr_target <> DontCare
100}
101
102class JumpImmExtractor(implicit p: Parameters) extends ImmExtractor(2, 64) {
103  when (SrcType.isPc(io.uop.ctrl.srcType(0))) {
104    io.data_out(0) := SignExt(jump_pc, XLEN)
105  }
106  // when src1 is reg (like sfence's asid) do not let data_out(1) be the jalr_target
107  when (SrcType.isPcOrImm(io.uop.ctrl.srcType(1))) {
108    io.data_out(1) := jalr_target
109  }
110}
111
112class AluImmExtractor(implicit p: Parameters) extends ImmExtractor(2, 64) {
113  when (SrcType.isImm(io.uop.ctrl.srcType(1))) {
114    val imm32 = Mux(io.uop.ctrl.selImm === SelImm.IMM_U,
115      ImmUnion.U.toImm32(io.uop.ctrl.imm),
116      ImmUnion.I.toImm32(io.uop.ctrl.imm)
117    )
118    io.data_out(1) := SignExt(imm32, XLEN)
119  }
120}
121
122class MduImmExtractor(implicit p: Parameters) extends ImmExtractor(2, 64) {
123  when (SrcType.isImm(io.uop.ctrl.srcType(1))) {
124    val imm32 = ImmUnion.I.toImm32(io.uop.ctrl.imm)
125    io.data_out(1) := SignExt(imm32, XLEN)
126  }
127}
128
129class LoadImmExtractor(implicit p: Parameters) extends ImmExtractor(1, 64) {
130  when (SrcType.isImm(io.uop.ctrl.srcType(0))) {
131    io.data_out(0) := SignExt(Imm_LUI_LOAD().getLuiImm(io.uop), XLEN)
132  }
133}
134
135object ImmExtractor {
136  def apply(params: RSParams, uop: MicroOp, data_in: Vec[UInt])
137           (implicit p: Parameters) = {
138    val immExt = Module(params.subMod.immExtractorGen(params.numSrc, params.dataBits, p))
139    immExt.io.uop := uop
140    immExt.io.data_in := data_in
141
142    immExt.jalr_target <> DontCare
143    immExt.jump_pc <> DontCare
144    immExt
145  }
146}
147