xref: /XiangShan/src/main/scala/xiangshan/backend/regfile/Regfile.scala (revision 730cfbc0bf03569aa07dd82ba3fb41eb7413e13c)
1c6d43980SLemover/***************************************************************************************
2c6d43980SLemover* Copyright (c) 2020-2021 Institute of Computing Technology, Chinese Academy of Sciences
3f320e0f0SYinan Xu* Copyright (c) 2020-2021 Peng Cheng Laboratory
4c6d43980SLemover*
5c6d43980SLemover* XiangShan is licensed under Mulan PSL v2.
6c6d43980SLemover* You can use this software according to the terms and conditions of the Mulan PSL v2.
7c6d43980SLemover* You may obtain a copy of Mulan PSL v2 at:
8c6d43980SLemover*          http://license.coscl.org.cn/MulanPSL2
9c6d43980SLemover*
10c6d43980SLemover* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
11c6d43980SLemover* EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
12c6d43980SLemover* MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
13c6d43980SLemover*
14c6d43980SLemover* See the Mulan PSL v2 for more details.
15c6d43980SLemover***************************************************************************************/
16c6d43980SLemover
175844fcf0SLinJiaweipackage xiangshan.backend.regfile
185844fcf0SLinJiawei
192225d46eSJiawei Linimport chipsalliance.rocketchip.config.Parameters
205844fcf0SLinJiaweiimport chisel3._
215844fcf0SLinJiaweiimport chisel3.util._
225844fcf0SLinJiaweiimport xiangshan._
23*730cfbc0SXuan Huimport xiangshan.backend.datapath.DataConfig.{DataConfig, FpData, IntData, VecData}
24*730cfbc0SXuan Huimport xiangshan.backend.Bundles.IssueQueueWakeUpBundle
255844fcf0SLinJiawei
26027c9765SXuan Huclass RfReadPort(dataWidth: Int, addrWidth: Int) extends Bundle {
279ab1568eSczw  val addr = Input(UInt(addrWidth.W))
289ab1568eSczw  val data = Output(UInt(dataWidth.W))
295844fcf0SLinJiawei}
305844fcf0SLinJiawei
31027c9765SXuan Huclass RfWritePort(dataWidth: Int, addrWidth: Int) extends Bundle {
325844fcf0SLinJiawei  val wen = Input(Bool())
339ab1568eSczw  val addr = Input(UInt(addrWidth.W))
349ab1568eSczw  val data = Input(UInt(dataWidth.W))
355844fcf0SLinJiawei}
365844fcf0SLinJiawei
37*730cfbc0SXuan Huclass RfReadPortWithConfig(val rfReadDataCfg: DataConfig, addrWidth: Int) extends Bundle {
38*730cfbc0SXuan Hu  val addr: UInt = Input(UInt(addrWidth.W))
39*730cfbc0SXuan Hu  val data: UInt = Output(UInt(rfReadDataCfg.dataWidth.W))
40*730cfbc0SXuan Hu  val srcType: UInt = Input(UInt(3.W))
41*730cfbc0SXuan Hu
42*730cfbc0SXuan Hu  def readInt: Boolean = rfReadDataCfg.isInstanceOf[IntData]
43*730cfbc0SXuan Hu  def readFp : Boolean = rfReadDataCfg.isInstanceOf[FpData]
44*730cfbc0SXuan Hu  def readVec: Boolean = rfReadDataCfg.isInstanceOf[VecData]
45*730cfbc0SXuan Hu}
46*730cfbc0SXuan Hu
47*730cfbc0SXuan Huclass RfWritePortWithConfig(val rfWriteDataCfg: DataConfig, addrWidth: Int) extends Bundle {
48*730cfbc0SXuan Hu  val wen = Input(Bool())
49*730cfbc0SXuan Hu  val addr = Input(UInt(addrWidth.W))
50*730cfbc0SXuan Hu  val data = Input(UInt(rfWriteDataCfg.dataWidth.W))
51*730cfbc0SXuan Hu  val intWen = Input(Bool())
52*730cfbc0SXuan Hu  val fpWen = Input(Bool())
53*730cfbc0SXuan Hu  val vecWen = Input(Bool())
54*730cfbc0SXuan Hu  def writeInt: Boolean = rfWriteDataCfg.isInstanceOf[IntData]
55*730cfbc0SXuan Hu  def writeFp : Boolean = rfWriteDataCfg.isInstanceOf[FpData]
56*730cfbc0SXuan Hu  def writeVec: Boolean = rfWriteDataCfg.isInstanceOf[VecData]
57*730cfbc0SXuan Hu
58*730cfbc0SXuan Hu  def toWakeUpBundle: ValidIO[IssueQueueWakeUpBundle] = {
59*730cfbc0SXuan Hu    val wakeup = Wire(ValidIO(new IssueQueueWakeUpBundle(addrWidth)))
60*730cfbc0SXuan Hu    wakeup.bits.pdest := this.addr
61*730cfbc0SXuan Hu    wakeup.bits.rfWen := this.intWen && this.wen
62*730cfbc0SXuan Hu    wakeup.bits.fpWen := this.fpWen && this.wen
63*730cfbc0SXuan Hu    wakeup.bits.vecWen := this.vecWen && this.wen
64*730cfbc0SXuan Hu    wakeup.valid := this.wen
65*730cfbc0SXuan Hu    wakeup
66*730cfbc0SXuan Hu  }
67*730cfbc0SXuan Hu}
68*730cfbc0SXuan Hu
695844fcf0SLinJiaweiclass Regfile
705844fcf0SLinJiawei(
71a1ca6e15SZhangZifei  name: String,
72027c9765SXuan Hu  numPregs: Int,
735844fcf0SLinJiawei  numReadPorts: Int,
7493b61a80SYinan Xu  numWritePorts: Int,
759684eb4fSLinJiawei  hasZero: Boolean,
7673faecdcSXuan Hu  len: Int,
7773faecdcSXuan Hu  width: Int,
78027c9765SXuan Hu) extends Module {
795844fcf0SLinJiawei  val io = IO(new Bundle() {
8073faecdcSXuan Hu    val readPorts = Vec(numReadPorts, new RfReadPort(len, width))
8173faecdcSXuan Hu    val writePorts = Vec(numWritePorts, new RfWritePort(len, width))
8235d1557aSZiyue Zhang    val debug_rports = Vec(64, new RfReadPort(len, width))
835844fcf0SLinJiawei  })
840c701001SLinJiawei
85027c9765SXuan Hu  println(name + ": size:" + numPregs + " read: " + numReadPorts + " write: " + numWritePorts)
8605f23f57SWilliam Wang
87027c9765SXuan Hu  val mem = Reg(Vec(numPregs, UInt(len.W)))
880c701001SLinJiawei  for (r <- io.readPorts) {
89b441ea13SYikeZhou    val rdata = if (hasZero) Mux(r.addr === 0.U, 0.U, mem(r.addr)) else mem(r.addr)
903dca89ecSXuan Hu    r.data := RegNext(rdata)
910c701001SLinJiawei  }
920c701001SLinJiawei  for (w <- io.writePorts) {
930c701001SLinJiawei    when(w.wen) {
940c701001SLinJiawei      mem(w.addr) := w.data
950c701001SLinJiawei    }
960c701001SLinJiawei  }
976624015fSLinJiawei
982225d46eSJiawei Lin  for (rport <- io.debug_rports) {
992225d46eSJiawei Lin    val zero_rdata = Mux(rport.addr === 0.U, 0.U, mem(rport.addr))
1002225d46eSJiawei Lin    rport.data := (if (hasZero) zero_rdata else mem(rport.addr))
101adb5df20SYinan Xu  }
1025844fcf0SLinJiawei}
10344dead2fSZhangZifei
10493b61a80SYinan Xuobject Regfile {
105*730cfbc0SXuan Hu  // non-return version
10693b61a80SYinan Xu  def apply(
107a1ca6e15SZhangZifei    name         : String,
10893b61a80SYinan Xu    numEntries   : Int,
10993b61a80SYinan Xu    raddr        : Seq[UInt],
110*730cfbc0SXuan Hu    rdata        : Vec[UInt],
11193b61a80SYinan Xu    wen          : Seq[Bool],
11293b61a80SYinan Xu    waddr        : Seq[UInt],
11393b61a80SYinan Xu    wdata        : Seq[UInt],
11493b61a80SYinan Xu    hasZero      : Boolean,
1157154d65eSYinan Xu    withReset    : Boolean = false,
116*730cfbc0SXuan Hu    debugReadAddr: Option[Seq[UInt]],
117*730cfbc0SXuan Hu    debugReadData: Option[Vec[UInt]],
118*730cfbc0SXuan Hu  )(implicit p: Parameters): Unit = {
11993b61a80SYinan Xu    val numReadPorts = raddr.length
12093b61a80SYinan Xu    val numWritePorts = wen.length
12193b61a80SYinan Xu    require(wen.length == waddr.length)
12293b61a80SYinan Xu    require(wen.length == wdata.length)
12393b61a80SYinan Xu    val dataBits = wdata.map(_.getWidth).min
12493b61a80SYinan Xu    require(wdata.map(_.getWidth).min == wdata.map(_.getWidth).max, s"dataBits != $dataBits")
12573faecdcSXuan Hu    val addrBits = waddr.map(_.getWidth).min
12673faecdcSXuan Hu    require(waddr.map(_.getWidth).min == waddr.map(_.getWidth).max, s"addrBits != $addrBits")
12773faecdcSXuan Hu
128027c9765SXuan Hu    val regfile = Module(new Regfile(name, numEntries, numReadPorts, numWritePorts, hasZero, dataBits, addrBits))
129*730cfbc0SXuan Hu    rdata := regfile.io.readPorts.zip(raddr).map { case (rport, addr) =>
13093b61a80SYinan Xu      rport.addr := addr
13193b61a80SYinan Xu      rport.data
13244dead2fSZhangZifei    }
13373faecdcSXuan Hu
13493b61a80SYinan Xu    regfile.io.writePorts.zip(wen).zip(waddr).zip(wdata).foreach{ case (((wport, en), addr), data) =>
13593b61a80SYinan Xu      wport.wen := en
13693b61a80SYinan Xu      wport.addr := addr
13793b61a80SYinan Xu      wport.data := data
138067dba72SLinJiawei    }
13993b61a80SYinan Xu    if (withReset) {
14093b61a80SYinan Xu      val numResetCycles = math.ceil(numEntries / numWritePorts).toInt
14193b61a80SYinan Xu      val resetCounter = RegInit(numResetCycles.U)
14293b61a80SYinan Xu      val resetWaddr = RegInit(VecInit((0 until numWritePorts).map(_.U(log2Up(numEntries + 1).W))))
14393b61a80SYinan Xu      val inReset = resetCounter =/= 0.U
14493b61a80SYinan Xu      when (inReset) {
14593b61a80SYinan Xu        resetCounter := resetCounter - 1.U
14693b61a80SYinan Xu        resetWaddr := VecInit(resetWaddr.map(_ + numWritePorts.U))
14793b61a80SYinan Xu      }
14893b61a80SYinan Xu      when (!inReset) {
14993b61a80SYinan Xu        resetWaddr.map(_ := 0.U)
15093b61a80SYinan Xu      }
15193b61a80SYinan Xu      for ((wport, i) <- regfile.io.writePorts.zipWithIndex) {
15293b61a80SYinan Xu        wport.wen := inReset || wen(i)
15393b61a80SYinan Xu        wport.addr := Mux(inReset, resetWaddr(i), waddr(i))
15493b61a80SYinan Xu        wport.data := wdata(i)
15593b61a80SYinan Xu      }
15693b61a80SYinan Xu    }
157*730cfbc0SXuan Hu
158*730cfbc0SXuan Hu    require(debugReadAddr.nonEmpty == debugReadData.nonEmpty, "Both debug addr and data bundles should be empty or not")
15993b61a80SYinan Xu    regfile.io.debug_rports := DontCare
160*730cfbc0SXuan Hu    if (debugReadAddr.nonEmpty && debugReadData.nonEmpty) {
161*730cfbc0SXuan Hu      debugReadData.get := VecInit(regfile.io.debug_rports.zip(debugReadAddr.get).map { case (rport, addr) =>
16293b61a80SYinan Xu        rport.addr := addr
16393b61a80SYinan Xu        rport.data
164*730cfbc0SXuan Hu      })
16593b61a80SYinan Xu    }
16693b61a80SYinan Xu  }
16793b61a80SYinan Xu}
16873faecdcSXuan Hu
16973faecdcSXuan Huobject IntRegFile {
170*730cfbc0SXuan Hu  // non-return version
17173faecdcSXuan Hu  def apply(
172a1ca6e15SZhangZifei    name         : String,
17373faecdcSXuan Hu    numEntries   : Int,
17473faecdcSXuan Hu    raddr        : Seq[UInt],
175*730cfbc0SXuan Hu    rdata        : Vec[UInt],
17673faecdcSXuan Hu    wen          : Seq[Bool],
17773faecdcSXuan Hu    waddr        : Seq[UInt],
17873faecdcSXuan Hu    wdata        : Seq[UInt],
179*730cfbc0SXuan Hu    debugReadAddr: Option[Seq[UInt]],
180*730cfbc0SXuan Hu    debugReadData: Option[Vec[UInt]],
18173faecdcSXuan Hu    withReset    : Boolean = false,
182*730cfbc0SXuan Hu  )(implicit p: Parameters): Unit = {
18373faecdcSXuan Hu    Regfile(
184*730cfbc0SXuan Hu      name, numEntries, raddr, rdata, wen, waddr, wdata,
185*730cfbc0SXuan Hu      hasZero = true, withReset, debugReadAddr, debugReadData)
18673faecdcSXuan Hu  }
18773faecdcSXuan Hu}
18873faecdcSXuan Hu
18973faecdcSXuan Huobject VfRegFile {
190*730cfbc0SXuan Hu  // non-return version
19173faecdcSXuan Hu  def apply(
192a1ca6e15SZhangZifei    name         : String,
19373faecdcSXuan Hu    numEntries   : Int,
19473faecdcSXuan Hu    splitNum     : Int,
19573faecdcSXuan Hu    raddr        : Seq[UInt],
196*730cfbc0SXuan Hu    rdata        : Vec[UInt],
19773faecdcSXuan Hu    wen          : Seq[Seq[Bool]],
19873faecdcSXuan Hu    waddr        : Seq[UInt],
19973faecdcSXuan Hu    wdata        : Seq[UInt],
200*730cfbc0SXuan Hu    debugReadAddr: Option[Seq[UInt]],
201*730cfbc0SXuan Hu    debugReadData: Option[Vec[UInt]],
20273faecdcSXuan Hu    withReset    : Boolean = false,
203*730cfbc0SXuan Hu  )(implicit p: Parameters): Unit = {
20473faecdcSXuan Hu    require(splitNum >= 1, "splitNum should be no less than 1")
20573faecdcSXuan Hu    require(splitNum == wen.length, "splitNum should be equal to length of wen vec")
20673faecdcSXuan Hu    if (splitNum == 1) {
207*730cfbc0SXuan Hu      Regfile(
208*730cfbc0SXuan Hu        name, numEntries, raddr, rdata, wen.head, waddr, wdata,
209*730cfbc0SXuan Hu        hasZero = false, withReset, debugReadAddr, debugReadData)
210761d728dSZhangZifei    } else {
21173faecdcSXuan Hu      val dataWidth = 64
212*730cfbc0SXuan Hu      val numReadPorts = raddr.length
21373faecdcSXuan Hu      require(splitNum > 1 && wdata.head.getWidth == dataWidth * splitNum)
21473faecdcSXuan Hu      val wdataVec = Wire(Vec(splitNum, Vec(wdata.length, UInt(dataWidth.W))))
215*730cfbc0SXuan Hu      val rdataVec = Wire(Vec(splitNum, Vec(raddr.length, UInt(dataWidth.W))))
216*730cfbc0SXuan Hu      val debugRDataVec: Option[Vec[Vec[UInt]]] = debugReadData.map(x => Wire(Vec(splitNum, Vec(x.length, UInt(dataWidth.W)))))
21773faecdcSXuan Hu      for (i <- 0 until splitNum) {
21873faecdcSXuan Hu        wdataVec(i) := wdata.map(_ ((i + 1) * dataWidth - 1, i * dataWidth))
219*730cfbc0SXuan Hu        Regfile(
220*730cfbc0SXuan Hu          name + s"Part${i}", numEntries, raddr, rdataVec(i), wen(i), waddr, wdataVec(i),
221*730cfbc0SXuan Hu          hasZero = false, withReset, debugReadAddr, debugRDataVec.map(_(i))
222*730cfbc0SXuan Hu        )
22373faecdcSXuan Hu      }
22473faecdcSXuan Hu      for (i <- 0 until rdata.length) {
225761d728dSZhangZifei        rdata(i) := Cat(rdataVec.map(_ (i)).reverse)
22673faecdcSXuan Hu      }
227*730cfbc0SXuan Hu      if (debugReadData.nonEmpty) {
228*730cfbc0SXuan Hu        for (i <- 0 until debugReadData.get.length) {
229*730cfbc0SXuan Hu          debugReadData.get(i) := Cat(debugRDataVec.get.map(_ (i)).reverse)
230*730cfbc0SXuan Hu        }
231*730cfbc0SXuan Hu      }
23273faecdcSXuan Hu    }
233761d728dSZhangZifei  }
23473faecdcSXuan Hu}