xref: /XiangShan/src/main/scala/xiangshan/backend/regfile/Regfile.scala (revision 35d1557a6f42dc59508eebb9c6c55c45162883de)
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._
21510ae4eeSJiuyang Liuimport chisel3.experimental.ExtModule
225844fcf0SLinJiaweiimport chisel3.util._
235844fcf0SLinJiaweiimport xiangshan._
245844fcf0SLinJiawei
2573faecdcSXuan Huclass RfReadPort(len: Int, width: Int)(implicit p: Parameters) extends XSBundle {
2673faecdcSXuan Hu  val addr = Input(UInt(width.W))
27ebd10a1fSYinan Xu  val data = Output(UInt(len.W))
285844fcf0SLinJiawei}
295844fcf0SLinJiawei
3073faecdcSXuan Huclass RfWritePort(len: Int, width: Int)(implicit p: Parameters) extends XSBundle {
315844fcf0SLinJiawei  val wen = Input(Bool())
3273faecdcSXuan Hu  val addr = Input(UInt(width.W))
33ebd10a1fSYinan Xu  val data = Input(UInt(len.W))
345844fcf0SLinJiawei}
355844fcf0SLinJiawei
365844fcf0SLinJiaweiclass Regfile
375844fcf0SLinJiawei(
385844fcf0SLinJiawei  numReadPorts: Int,
3993b61a80SYinan Xu  numWritePorts: Int,
409684eb4fSLinJiawei  hasZero: Boolean,
4173faecdcSXuan Hu  len: Int,
4273faecdcSXuan Hu  width: Int,
432225d46eSJiawei Lin)(implicit p: Parameters) extends XSModule {
445844fcf0SLinJiawei  val io = IO(new Bundle() {
4573faecdcSXuan Hu    val readPorts = Vec(numReadPorts, new RfReadPort(len, width))
4673faecdcSXuan Hu    val writePorts = Vec(numWritePorts, new RfWritePort(len, width))
47*35d1557aSZiyue Zhang    val debug_rports = Vec(64, new RfReadPort(len, width))
485844fcf0SLinJiawei  })
490c701001SLinJiawei
5093b61a80SYinan Xu  println("Regfile: size:" + NRPhyRegs + " read: " + numReadPorts + " write: " + numWritePorts)
5105f23f57SWilliam Wang
52fc8a3b3fSljw  val mem = Reg(Vec(NRPhyRegs, UInt(len.W)))
530c701001SLinJiawei  for (r <- io.readPorts) {
54b441ea13SYikeZhou    val rdata = if (hasZero) Mux(r.addr === 0.U, 0.U, mem(r.addr)) else mem(r.addr)
55b441ea13SYikeZhou    r.data := RegNext(rdata)
560c701001SLinJiawei  }
570c701001SLinJiawei  for (w <- io.writePorts) {
580c701001SLinJiawei    when(w.wen) {
590c701001SLinJiawei      mem(w.addr) := w.data
600c701001SLinJiawei    }
610c701001SLinJiawei  }
626624015fSLinJiawei
632225d46eSJiawei Lin  for (rport <- io.debug_rports) {
642225d46eSJiawei Lin    val zero_rdata = Mux(rport.addr === 0.U, 0.U, mem(rport.addr))
652225d46eSJiawei Lin    rport.data := (if (hasZero) zero_rdata else mem(rport.addr))
66adb5df20SYinan Xu  }
675844fcf0SLinJiawei}
6844dead2fSZhangZifei
6993b61a80SYinan Xuobject Regfile {
7093b61a80SYinan Xu  def apply(
7193b61a80SYinan Xu    numEntries   : Int,
7293b61a80SYinan Xu    raddr        : Seq[UInt],
7393b61a80SYinan Xu    wen          : Seq[Bool],
7493b61a80SYinan Xu    waddr        : Seq[UInt],
7593b61a80SYinan Xu    wdata        : Seq[UInt],
7693b61a80SYinan Xu    hasZero      : Boolean,
777154d65eSYinan Xu    withReset    : Boolean = false,
7873faecdcSXuan Hu    debugReadAddr: Option[Seq[UInt]] = None,
7993b61a80SYinan Xu  )(implicit p: Parameters): Seq[UInt] = {
8093b61a80SYinan Xu    val numReadPorts = raddr.length
8193b61a80SYinan Xu    val numWritePorts = wen.length
8293b61a80SYinan Xu    require(wen.length == waddr.length)
8393b61a80SYinan Xu    require(wen.length == wdata.length)
8493b61a80SYinan Xu    val dataBits = wdata.map(_.getWidth).min
8593b61a80SYinan Xu    require(wdata.map(_.getWidth).min == wdata.map(_.getWidth).max, s"dataBits != $dataBits")
8673faecdcSXuan Hu    val addrBits = waddr.map(_.getWidth).min
8773faecdcSXuan Hu    require(waddr.map(_.getWidth).min == waddr.map(_.getWidth).max, s"addrBits != $addrBits")
8873faecdcSXuan Hu
8973faecdcSXuan Hu    val regfile = Module(new Regfile(numReadPorts, numWritePorts, hasZero, dataBits, addrBits))
9093b61a80SYinan Xu    val rdata = regfile.io.readPorts.zip(raddr).map { case (rport, addr) =>
9193b61a80SYinan Xu      rport.addr := addr
9293b61a80SYinan Xu      rport.data
9344dead2fSZhangZifei    }
9473faecdcSXuan Hu
9593b61a80SYinan Xu    regfile.io.writePorts.zip(wen).zip(waddr).zip(wdata).foreach{ case (((wport, en), addr), data) =>
9693b61a80SYinan Xu      wport.wen := en
9793b61a80SYinan Xu      wport.addr := addr
9893b61a80SYinan Xu      wport.data := data
99067dba72SLinJiawei    }
10093b61a80SYinan Xu    if (withReset) {
10193b61a80SYinan Xu      val numResetCycles = math.ceil(numEntries / numWritePorts).toInt
10293b61a80SYinan Xu      val resetCounter = RegInit(numResetCycles.U)
10393b61a80SYinan Xu      val resetWaddr = RegInit(VecInit((0 until numWritePorts).map(_.U(log2Up(numEntries + 1).W))))
10493b61a80SYinan Xu      val inReset = resetCounter =/= 0.U
10593b61a80SYinan Xu      when (inReset) {
10693b61a80SYinan Xu        resetCounter := resetCounter - 1.U
10793b61a80SYinan Xu        resetWaddr := VecInit(resetWaddr.map(_ + numWritePorts.U))
10893b61a80SYinan Xu      }
10993b61a80SYinan Xu      when (!inReset) {
11093b61a80SYinan Xu        resetWaddr.map(_ := 0.U)
11193b61a80SYinan Xu      }
11293b61a80SYinan Xu      for ((wport, i) <- regfile.io.writePorts.zipWithIndex) {
11393b61a80SYinan Xu        wport.wen := inReset || wen(i)
11493b61a80SYinan Xu        wport.addr := Mux(inReset, resetWaddr(i), waddr(i))
11593b61a80SYinan Xu        wport.data := wdata(i)
11693b61a80SYinan Xu      }
11793b61a80SYinan Xu    }
11893b61a80SYinan Xu    regfile.io.debug_rports := DontCare
11973faecdcSXuan Hu    val debug_rdata = regfile.io.debug_rports.zip(debugReadAddr.getOrElse(Seq())).map { case (rport, addr) =>
12093b61a80SYinan Xu      rport.addr := addr
12193b61a80SYinan Xu      rport.data
12293b61a80SYinan Xu    }
12393b61a80SYinan Xu    rdata ++ debug_rdata
12493b61a80SYinan Xu  }
12593b61a80SYinan Xu}
12673faecdcSXuan Hu
12773faecdcSXuan Huobject IntRegFile {
12873faecdcSXuan Hu  def apply(
12973faecdcSXuan Hu    numEntries   : Int,
13073faecdcSXuan Hu    raddr        : Seq[UInt],
13173faecdcSXuan Hu    wen          : Seq[Bool],
13273faecdcSXuan Hu    waddr        : Seq[UInt],
13373faecdcSXuan Hu    wdata        : Seq[UInt],
13473faecdcSXuan Hu    withReset    : Boolean = false,
13573faecdcSXuan Hu    debugReadAddr: Option[Seq[UInt]] = None,
13673faecdcSXuan Hu  )(implicit p: Parameters): Seq[UInt] = {
13773faecdcSXuan Hu    Regfile(
13873faecdcSXuan Hu      numEntries, raddr, wen, waddr, wdata,
13973faecdcSXuan Hu      hasZero = true, withReset, debugReadAddr)
14073faecdcSXuan Hu  }
14173faecdcSXuan Hu}
14273faecdcSXuan Hu
14373faecdcSXuan Huobject VfRegFile {
14473faecdcSXuan Hu  def apply(
14573faecdcSXuan Hu    numEntries   : Int,
14673faecdcSXuan Hu    splitNum     : Int,
14773faecdcSXuan Hu    raddr        : Seq[UInt],
14873faecdcSXuan Hu    wen          : Seq[Seq[Bool]],
14973faecdcSXuan Hu    waddr        : Seq[UInt],
15073faecdcSXuan Hu    wdata        : Seq[UInt],
15173faecdcSXuan Hu    withReset    : Boolean = false,
15273faecdcSXuan Hu    debugReadAddr: Option[Seq[UInt]] = None,
15373faecdcSXuan Hu  )(implicit p: Parameters) : Seq[UInt] = {
15473faecdcSXuan Hu    require(splitNum >= 1, "splitNum should be no less than 1")
15573faecdcSXuan Hu    require(splitNum == wen.length, "splitNum should be equal to length of wen vec")
15673faecdcSXuan Hu    if (splitNum == 1) {
15773faecdcSXuan Hu      Regfile(numEntries, raddr, wen.head, waddr, wdata,
15873faecdcSXuan Hu        hasZero = false, withReset, debugReadAddr)
15973faecdcSXuan Hu    }
16073faecdcSXuan Hu
16173faecdcSXuan Hu    val dataWidth = 64
16273faecdcSXuan Hu    val numReadPorts = raddr.length + debugReadAddr.getOrElse(Seq()).length
16373faecdcSXuan Hu    require(splitNum > 1 && wdata.head.getWidth == dataWidth * splitNum)
16473faecdcSXuan Hu    val wdataVec = Wire(Vec(splitNum, Vec(wdata.length, UInt(dataWidth.W))))
16573faecdcSXuan Hu    var rdataVec = Wire(Vec(splitNum, Vec(numReadPorts, UInt(dataWidth.W))))
16673faecdcSXuan Hu    for (i <- 0 until splitNum) {
16773faecdcSXuan Hu      wdataVec(i) := wdata.map(_((i + 1) * dataWidth - 1, i * dataWidth))
16873faecdcSXuan Hu      rdataVec(i) := Regfile(numEntries, raddr, wen(i), waddr, wdataVec(i),
16973faecdcSXuan Hu        hasZero = false, withReset, debugReadAddr)
17073faecdcSXuan Hu    }
17173faecdcSXuan Hu    val rdata = Wire(Vec(numReadPorts, UInt(wdata.head.getWidth.W)))
17273faecdcSXuan Hu    for (i <- 0 until rdata.length) {
17373faecdcSXuan Hu      rdata(i) := Cat(rdataVec.map(_(i)))
17473faecdcSXuan Hu    }
17573faecdcSXuan Hu    rdata
17673faecdcSXuan Hu  }
17773faecdcSXuan Hu
17873faecdcSXuan Hu//  // for dummy usage
17973faecdcSXuan Hu//  def apply(
18073faecdcSXuan Hu//    numEntries   : Int,
18173faecdcSXuan Hu//    raddr        : Vec[UInt],
18273faecdcSXuan Hu//    wen          : Vec[Bool],
18373faecdcSXuan Hu//    waddr        : Vec[UInt],
18473faecdcSXuan Hu//    wdata        : Vec[UInt],
18573faecdcSXuan Hu//    withReset    : Boolean = false,
18673faecdcSXuan Hu//    debugReadAddr: Option[Vec[UInt]] = None,
18773faecdcSXuan Hu//  )(implicit p: Parameters) : Unit = {
18873faecdcSXuan Hu//    Regfile(numEntries, raddr, wen, waddr, wdata,
18973faecdcSXuan Hu//      hasZero = false, withReset, debugReadAddr)
19073faecdcSXuan Hu//  }
19173faecdcSXuan Hu}
192