xref: /XiangShan/src/main/scala/xiangshan/backend/regfile/Regfile.scala (revision 8bdbde1e5685a9f33e8e9142fdebbf35e95bcd45)
1package xiangshan.backend.regfile
2
3import chisel3._
4import chisel3.util._
5import chisel3.util.experimental.BoringUtils
6import xiangshan._
7
8class RfReadPort extends XSBundle {
9  val addr = Input(UInt(PhyRegIdxWidth.W))
10  val data = Output(UInt(XLEN.W))
11}
12
13class RfWritePort extends XSBundle {
14  val wen = Input(Bool())
15  val addr = Input(UInt(PhyRegIdxWidth.W))
16  val data = Input(UInt(XLEN.W))
17}
18
19class Regfile
20(
21  numReadPorts: Int,
22  numWirtePorts: Int,
23  hasZero: Boolean,
24  isMemRf: Boolean = false
25) extends XSModule {
26  val io = IO(new Bundle() {
27    val readPorts = Vec(numReadPorts, new RfReadPort)
28    val writePorts = Vec(numWirtePorts, new RfWritePort)
29  })
30
31  val mem = Mem(NRPhyRegs, UInt(XLEN.W))
32
33  val debugRegSync = WireInit(0.U(XLEN.W))
34  val debugCnt = RegInit(0.U((PhyRegIdxWidth+1).W))
35  when(!debugCnt.head(1).asBool()){
36    debugCnt := debugCnt + 1.U
37    if(isMemRf){
38      BoringUtils.addSink(debugRegSync, "DEBUG_REG_SYNC")
39      mem(debugCnt) := debugRegSync
40    } else if (hasZero) {
41      debugRegSync := mem(debugCnt)
42      BoringUtils.addSource(debugRegSync, "DEBUG_REG_SYNC")
43    }
44  }
45
46  for(r <- io.readPorts){
47    val addr_reg = RegNext(r.addr)
48    r.data := {if(hasZero) Mux(addr_reg===0.U, 0.U, mem(addr_reg)) else mem(addr_reg)}
49  }
50
51  for(w <- io.writePorts){
52    when(w.wen){
53      mem(w.addr) := w.data
54    }
55  }
56
57  if(!isMemRf){
58    val debugArchRat = WireInit(VecInit(Seq.fill(32)(0.U(PhyRegIdxWidth.W))))
59    BoringUtils.addSink(debugArchRat, if(hasZero) "DEBUG_INI_ARCH_RAT" else "DEBUG_FP_ARCH_RAT")
60
61    val debugArchReg = WireInit(VecInit(debugArchRat.zipWithIndex.map(x => if(hasZero && x._2==0) 0.U else mem(x._1))))
62    BoringUtils.addSource(debugArchReg, if(hasZero) "DEBUG_INT_ARCH_REG" else "DEBUG_FP_ARCH_REG")
63  }
64}
65