xref: /XiangShan/src/main/scala/xiangshan/backend/regfile/Regfile.scala (revision a1ca6e1522f68ebf93e050417ea980cdc754e624)
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(
38*a1ca6e15SZhangZifei  name: String,
395844fcf0SLinJiawei  numReadPorts: Int,
4093b61a80SYinan Xu  numWritePorts: Int,
419684eb4fSLinJiawei  hasZero: Boolean,
4273faecdcSXuan Hu  len: Int,
4373faecdcSXuan Hu  width: Int,
442225d46eSJiawei Lin)(implicit p: Parameters) extends XSModule {
455844fcf0SLinJiawei  val io = IO(new Bundle() {
4673faecdcSXuan Hu    val readPorts = Vec(numReadPorts, new RfReadPort(len, width))
4773faecdcSXuan Hu    val writePorts = Vec(numWritePorts, new RfWritePort(len, width))
4873faecdcSXuan Hu    val debug_rports = Vec(32, new RfReadPort(len, width))
495844fcf0SLinJiawei  })
500c701001SLinJiawei
51*a1ca6e15SZhangZifei  println(name + ": size:" + NRPhyRegs + " read: " + numReadPorts + " write: " + numWritePorts)
5205f23f57SWilliam Wang
53fc8a3b3fSljw  val mem = Reg(Vec(NRPhyRegs, UInt(len.W)))
540c701001SLinJiawei  for (r <- io.readPorts) {
55b441ea13SYikeZhou    val rdata = if (hasZero) Mux(r.addr === 0.U, 0.U, mem(r.addr)) else mem(r.addr)
56b441ea13SYikeZhou    r.data := RegNext(rdata)
570c701001SLinJiawei  }
580c701001SLinJiawei  for (w <- io.writePorts) {
590c701001SLinJiawei    when(w.wen) {
600c701001SLinJiawei      mem(w.addr) := w.data
610c701001SLinJiawei    }
620c701001SLinJiawei  }
636624015fSLinJiawei
642225d46eSJiawei Lin  for (rport <- io.debug_rports) {
652225d46eSJiawei Lin    val zero_rdata = Mux(rport.addr === 0.U, 0.U, mem(rport.addr))
662225d46eSJiawei Lin    rport.data := (if (hasZero) zero_rdata else mem(rport.addr))
67adb5df20SYinan Xu  }
685844fcf0SLinJiawei}
6944dead2fSZhangZifei
7093b61a80SYinan Xuobject Regfile {
7193b61a80SYinan Xu  def apply(
72*a1ca6e15SZhangZifei    name         : String,
7393b61a80SYinan Xu    numEntries   : Int,
7493b61a80SYinan Xu    raddr        : Seq[UInt],
7593b61a80SYinan Xu    wen          : Seq[Bool],
7693b61a80SYinan Xu    waddr        : Seq[UInt],
7793b61a80SYinan Xu    wdata        : Seq[UInt],
7893b61a80SYinan Xu    hasZero      : Boolean,
797154d65eSYinan Xu    withReset    : Boolean = false,
8073faecdcSXuan Hu    debugReadAddr: Option[Seq[UInt]] = None,
8193b61a80SYinan Xu  )(implicit p: Parameters): Seq[UInt] = {
8293b61a80SYinan Xu    val numReadPorts = raddr.length
8393b61a80SYinan Xu    val numWritePorts = wen.length
8493b61a80SYinan Xu    require(wen.length == waddr.length)
8593b61a80SYinan Xu    require(wen.length == wdata.length)
8693b61a80SYinan Xu    val dataBits = wdata.map(_.getWidth).min
8793b61a80SYinan Xu    require(wdata.map(_.getWidth).min == wdata.map(_.getWidth).max, s"dataBits != $dataBits")
8873faecdcSXuan Hu    val addrBits = waddr.map(_.getWidth).min
8973faecdcSXuan Hu    require(waddr.map(_.getWidth).min == waddr.map(_.getWidth).max, s"addrBits != $addrBits")
9073faecdcSXuan Hu
91*a1ca6e15SZhangZifei    val regfile = Module(new Regfile(name, numReadPorts, numWritePorts, hasZero, dataBits, addrBits))
9293b61a80SYinan Xu    val rdata = regfile.io.readPorts.zip(raddr).map { case (rport, addr) =>
9393b61a80SYinan Xu      rport.addr := addr
9493b61a80SYinan Xu      rport.data
9544dead2fSZhangZifei    }
9673faecdcSXuan Hu
9793b61a80SYinan Xu    regfile.io.writePorts.zip(wen).zip(waddr).zip(wdata).foreach{ case (((wport, en), addr), data) =>
9893b61a80SYinan Xu      wport.wen := en
9993b61a80SYinan Xu      wport.addr := addr
10093b61a80SYinan Xu      wport.data := data
101067dba72SLinJiawei    }
10293b61a80SYinan Xu    if (withReset) {
10393b61a80SYinan Xu      val numResetCycles = math.ceil(numEntries / numWritePorts).toInt
10493b61a80SYinan Xu      val resetCounter = RegInit(numResetCycles.U)
10593b61a80SYinan Xu      val resetWaddr = RegInit(VecInit((0 until numWritePorts).map(_.U(log2Up(numEntries + 1).W))))
10693b61a80SYinan Xu      val inReset = resetCounter =/= 0.U
10793b61a80SYinan Xu      when (inReset) {
10893b61a80SYinan Xu        resetCounter := resetCounter - 1.U
10993b61a80SYinan Xu        resetWaddr := VecInit(resetWaddr.map(_ + numWritePorts.U))
11093b61a80SYinan Xu      }
11193b61a80SYinan Xu      when (!inReset) {
11293b61a80SYinan Xu        resetWaddr.map(_ := 0.U)
11393b61a80SYinan Xu      }
11493b61a80SYinan Xu      for ((wport, i) <- regfile.io.writePorts.zipWithIndex) {
11593b61a80SYinan Xu        wport.wen := inReset || wen(i)
11693b61a80SYinan Xu        wport.addr := Mux(inReset, resetWaddr(i), waddr(i))
11793b61a80SYinan Xu        wport.data := wdata(i)
11893b61a80SYinan Xu      }
11993b61a80SYinan Xu    }
12093b61a80SYinan Xu    regfile.io.debug_rports := DontCare
12173faecdcSXuan Hu    val debug_rdata = regfile.io.debug_rports.zip(debugReadAddr.getOrElse(Seq())).map { case (rport, addr) =>
12293b61a80SYinan Xu      rport.addr := addr
12393b61a80SYinan Xu      rport.data
12493b61a80SYinan Xu    }
12593b61a80SYinan Xu    rdata ++ debug_rdata
12693b61a80SYinan Xu  }
12793b61a80SYinan Xu}
12873faecdcSXuan Hu
12973faecdcSXuan Huobject IntRegFile {
13073faecdcSXuan Hu  def apply(
131*a1ca6e15SZhangZifei    name         : String,
13273faecdcSXuan Hu    numEntries   : Int,
13373faecdcSXuan Hu    raddr        : Seq[UInt],
13473faecdcSXuan Hu    wen          : Seq[Bool],
13573faecdcSXuan Hu    waddr        : Seq[UInt],
13673faecdcSXuan Hu    wdata        : Seq[UInt],
13773faecdcSXuan Hu    withReset    : Boolean = false,
13873faecdcSXuan Hu    debugReadAddr: Option[Seq[UInt]] = None,
13973faecdcSXuan Hu  )(implicit p: Parameters): Seq[UInt] = {
14073faecdcSXuan Hu    Regfile(
141*a1ca6e15SZhangZifei      name, numEntries, raddr, wen, waddr, wdata,
14273faecdcSXuan Hu      hasZero = true, withReset, debugReadAddr)
14373faecdcSXuan Hu  }
14473faecdcSXuan Hu}
14573faecdcSXuan Hu
14673faecdcSXuan Huobject VfRegFile {
14773faecdcSXuan Hu  def apply(
148*a1ca6e15SZhangZifei    name         : String,
14973faecdcSXuan Hu    numEntries   : Int,
15073faecdcSXuan Hu    splitNum     : Int,
15173faecdcSXuan Hu    raddr        : Seq[UInt],
15273faecdcSXuan Hu    wen          : Seq[Seq[Bool]],
15373faecdcSXuan Hu    waddr        : Seq[UInt],
15473faecdcSXuan Hu    wdata        : Seq[UInt],
15573faecdcSXuan Hu    withReset    : Boolean = false,
15673faecdcSXuan Hu    debugReadAddr: Option[Seq[UInt]] = None,
15773faecdcSXuan Hu  )(implicit p: Parameters) : Seq[UInt] = {
15873faecdcSXuan Hu    require(splitNum >= 1, "splitNum should be no less than 1")
15973faecdcSXuan Hu    require(splitNum == wen.length, "splitNum should be equal to length of wen vec")
16073faecdcSXuan Hu    if (splitNum == 1) {
161*a1ca6e15SZhangZifei      Regfile(name, numEntries, raddr, wen.head, waddr, wdata,
16273faecdcSXuan Hu        hasZero = false, withReset, debugReadAddr)
16373faecdcSXuan Hu    }
16473faecdcSXuan Hu
16573faecdcSXuan Hu    val dataWidth = 64
16673faecdcSXuan Hu    val numReadPorts = raddr.length + debugReadAddr.getOrElse(Seq()).length
16773faecdcSXuan Hu    require(splitNum > 1 && wdata.head.getWidth == dataWidth * splitNum)
16873faecdcSXuan Hu    val wdataVec = Wire(Vec(splitNum, Vec(wdata.length, UInt(dataWidth.W))))
16973faecdcSXuan Hu    var rdataVec = Wire(Vec(splitNum, Vec(numReadPorts, UInt(dataWidth.W))))
17073faecdcSXuan Hu    for (i <- 0 until splitNum) {
17173faecdcSXuan Hu      wdataVec(i) := wdata.map(_((i + 1) * dataWidth - 1, i * dataWidth))
172*a1ca6e15SZhangZifei      rdataVec(i) := Regfile(name+s"Part${i}", numEntries, raddr, wen(i), waddr, wdataVec(i),
17373faecdcSXuan Hu        hasZero = false, withReset, debugReadAddr)
17473faecdcSXuan Hu    }
17573faecdcSXuan Hu    val rdata = Wire(Vec(numReadPorts, UInt(wdata.head.getWidth.W)))
17673faecdcSXuan Hu    for (i <- 0 until rdata.length) {
17773faecdcSXuan Hu      rdata(i) := Cat(rdataVec.map(_(i)))
17873faecdcSXuan Hu    }
17973faecdcSXuan Hu    rdata
18073faecdcSXuan Hu  }
18173faecdcSXuan Hu
18273faecdcSXuan Hu//  // for dummy usage
18373faecdcSXuan Hu//  def apply(
18473faecdcSXuan Hu//    numEntries   : Int,
18573faecdcSXuan Hu//    raddr        : Vec[UInt],
18673faecdcSXuan Hu//    wen          : Vec[Bool],
18773faecdcSXuan Hu//    waddr        : Vec[UInt],
18873faecdcSXuan Hu//    wdata        : Vec[UInt],
18973faecdcSXuan Hu//    withReset    : Boolean = false,
19073faecdcSXuan Hu//    debugReadAddr: Option[Vec[UInt]] = None,
19173faecdcSXuan Hu//  )(implicit p: Parameters) : Unit = {
19273faecdcSXuan Hu//    Regfile(numEntries, raddr, wen, waddr, wdata,
19373faecdcSXuan Hu//      hasZero = false, withReset, debugReadAddr)
19473faecdcSXuan Hu//  }
19573faecdcSXuan Hu}
196