xref: /XiangShan/src/main/scala/xiangshan/backend/regfile/Regfile.scala (revision 73faecdc3b68e7fdacd4c95f2fdeda671edeb235)
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
25*73faecdcSXuan Huclass RfReadPort(len: Int, width: Int)(implicit p: Parameters) extends XSBundle {
26*73faecdcSXuan Hu  val addr = Input(UInt(width.W))
27ebd10a1fSYinan Xu  val data = Output(UInt(len.W))
285844fcf0SLinJiawei}
295844fcf0SLinJiawei
30*73faecdcSXuan Huclass RfWritePort(len: Int, width: Int)(implicit p: Parameters) extends XSBundle {
315844fcf0SLinJiawei  val wen = Input(Bool())
32*73faecdcSXuan 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,
41*73faecdcSXuan Hu  len: Int,
42*73faecdcSXuan Hu  width: Int,
432225d46eSJiawei Lin)(implicit p: Parameters) extends XSModule {
445844fcf0SLinJiawei  val io = IO(new Bundle() {
45*73faecdcSXuan Hu    val readPorts = Vec(numReadPorts, new RfReadPort(len, width))
46*73faecdcSXuan Hu    val writePorts = Vec(numWritePorts, new RfWritePort(len, width))
47*73faecdcSXuan Hu    val debug_rports = Vec(32, 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,
78*73faecdcSXuan 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")
86*73faecdcSXuan Hu    val addrBits = waddr.map(_.getWidth).min
87*73faecdcSXuan Hu    require(waddr.map(_.getWidth).min == waddr.map(_.getWidth).max, s"addrBits != $addrBits")
88*73faecdcSXuan Hu
89*73faecdcSXuan 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    }
94*73faecdcSXuan 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
119*73faecdcSXuan 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}
126*73faecdcSXuan Hu
127*73faecdcSXuan Huobject IntRegFile {
128*73faecdcSXuan Hu  def apply(
129*73faecdcSXuan Hu    numEntries   : Int,
130*73faecdcSXuan Hu    raddr        : Seq[UInt],
131*73faecdcSXuan Hu    wen          : Seq[Bool],
132*73faecdcSXuan Hu    waddr        : Seq[UInt],
133*73faecdcSXuan Hu    wdata        : Seq[UInt],
134*73faecdcSXuan Hu    withReset    : Boolean = false,
135*73faecdcSXuan Hu    debugReadAddr: Option[Seq[UInt]] = None,
136*73faecdcSXuan Hu  )(implicit p: Parameters): Seq[UInt] = {
137*73faecdcSXuan Hu    Regfile(
138*73faecdcSXuan Hu      numEntries, raddr, wen, waddr, wdata,
139*73faecdcSXuan Hu      hasZero = true, withReset, debugReadAddr)
140*73faecdcSXuan Hu  }
141*73faecdcSXuan Hu}
142*73faecdcSXuan Hu
143*73faecdcSXuan Huobject VfRegFile {
144*73faecdcSXuan Hu  def apply(
145*73faecdcSXuan Hu    numEntries   : Int,
146*73faecdcSXuan Hu    splitNum     : Int,
147*73faecdcSXuan Hu    raddr        : Seq[UInt],
148*73faecdcSXuan Hu    wen          : Seq[Seq[Bool]],
149*73faecdcSXuan Hu    waddr        : Seq[UInt],
150*73faecdcSXuan Hu    wdata        : Seq[UInt],
151*73faecdcSXuan Hu    withReset    : Boolean = false,
152*73faecdcSXuan Hu    debugReadAddr: Option[Seq[UInt]] = None,
153*73faecdcSXuan Hu  )(implicit p: Parameters) : Seq[UInt] = {
154*73faecdcSXuan Hu    require(splitNum >= 1, "splitNum should be no less than 1")
155*73faecdcSXuan Hu    require(splitNum == wen.length, "splitNum should be equal to length of wen vec")
156*73faecdcSXuan Hu    if (splitNum == 1) {
157*73faecdcSXuan Hu      Regfile(numEntries, raddr, wen.head, waddr, wdata,
158*73faecdcSXuan Hu        hasZero = false, withReset, debugReadAddr)
159*73faecdcSXuan Hu    }
160*73faecdcSXuan Hu
161*73faecdcSXuan Hu    val dataWidth = 64
162*73faecdcSXuan Hu    val numReadPorts = raddr.length + debugReadAddr.getOrElse(Seq()).length
163*73faecdcSXuan Hu    require(splitNum > 1 && wdata.head.getWidth == dataWidth * splitNum)
164*73faecdcSXuan Hu    val wdataVec = Wire(Vec(splitNum, Vec(wdata.length, UInt(dataWidth.W))))
165*73faecdcSXuan Hu    var rdataVec = Wire(Vec(splitNum, Vec(numReadPorts, UInt(dataWidth.W))))
166*73faecdcSXuan Hu    for (i <- 0 until splitNum) {
167*73faecdcSXuan Hu      wdataVec(i) := wdata.map(_((i + 1) * dataWidth - 1, i * dataWidth))
168*73faecdcSXuan Hu      rdataVec(i) := Regfile(numEntries, raddr, wen(i), waddr, wdataVec(i),
169*73faecdcSXuan Hu        hasZero = false, withReset, debugReadAddr)
170*73faecdcSXuan Hu    }
171*73faecdcSXuan Hu    val rdata = Wire(Vec(numReadPorts, UInt(wdata.head.getWidth.W)))
172*73faecdcSXuan Hu    for (i <- 0 until rdata.length) {
173*73faecdcSXuan Hu      rdata(i) := Cat(rdataVec.map(_(i)))
174*73faecdcSXuan Hu    }
175*73faecdcSXuan Hu    rdata
176*73faecdcSXuan Hu  }
177*73faecdcSXuan Hu
178*73faecdcSXuan Hu//  // for dummy usage
179*73faecdcSXuan Hu//  def apply(
180*73faecdcSXuan Hu//    numEntries   : Int,
181*73faecdcSXuan Hu//    raddr        : Vec[UInt],
182*73faecdcSXuan Hu//    wen          : Vec[Bool],
183*73faecdcSXuan Hu//    waddr        : Vec[UInt],
184*73faecdcSXuan Hu//    wdata        : Vec[UInt],
185*73faecdcSXuan Hu//    withReset    : Boolean = false,
186*73faecdcSXuan Hu//    debugReadAddr: Option[Vec[UInt]] = None,
187*73faecdcSXuan Hu//  )(implicit p: Parameters) : Unit = {
188*73faecdcSXuan Hu//    Regfile(numEntries, raddr, wen, waddr, wdata,
189*73faecdcSXuan Hu//      hasZero = false, withReset, debugReadAddr)
190*73faecdcSXuan Hu//  }
191*73faecdcSXuan Hu}
192