xref: /XiangShan/src/main/scala/xiangshan/backend/rename/RenameTable.scala (revision 3802dba502b91d813c1e563035b876c4e6288166)
1package xiangshan.backend.rename
2
3import chisel3._
4import chisel3.util._
5import xiangshan._
6
7class RatReadPort extends XSBundle {
8  val addr = Input(UInt(5.W))
9  val rdata = Output(UInt(PhyRegIdxWidth.W))
10}
11
12class RatWritePort extends XSBundle {
13  val wen = Input(Bool())
14  val addr = Input(UInt(5.W))
15  val wdata = Input(UInt(PhyRegIdxWidth.W))
16}
17
18object hartIdRTInt extends (() => Int) {
19  var x = 0
20  def apply(): Int = {
21    x = x + 1
22    x-1
23  }
24}
25
26object hartIdRTFp extends (() => Int) {
27  var x = 0
28  def apply(): Int = {
29    x = x + 1
30    x-1
31  }
32}
33
34class RenameTable(float: Boolean) extends XSModule {
35  val io = IO(new Bundle() {
36    val redirect = Flipped(ValidIO(new Redirect))
37    val walkWen = Input(Bool())
38    val readPorts = Vec({if(float) 4 else 3} * RenameWidth, new RatReadPort)
39    val specWritePorts = Vec(CommitWidth, new RatWritePort)
40    val archWritePorts = Vec(CommitWidth, new RatWritePort)
41  })
42
43  // speculative rename table
44  val spec_table = RegInit(VecInit(Seq.tabulate(32)(i => i.U(PhyRegIdxWidth.W))))
45
46  // arch state rename table
47  val arch_table = RegInit(VecInit(Seq.tabulate(32)(i => i.U(PhyRegIdxWidth.W))))
48
49  // When redirect happens (mis-prediction), don't update the rename table
50  // However, when mis-prediction and walk happens at the same time, rename table needs to be updated
51  for(w <- io.specWritePorts){
52    when(w.wen && (!io.redirect.valid || io.walkWen)) {
53      spec_table(w.addr) := w.wdata
54    }
55  }
56
57  for((r, i) <- io.readPorts.zipWithIndex){
58    r.rdata := spec_table(r.addr)
59    // for(w <- io.specWritePorts.take(i/{if(float) 4 else 3})){ // bypass
60    //   when(w.wen && (w.addr === r.addr)){ r.rdata := w.wdata }
61    // }
62  }
63
64  for(w <- io.archWritePorts){
65    when(w.wen){ arch_table(w.addr) := w.wdata }
66  }
67
68  val flush = io.redirect.valid && io.redirect.bits.isUnconditional()
69  when (flush) {
70    spec_table := arch_table
71    // spec table needs to be updated when flushPipe
72    for (w <- io.archWritePorts) {
73      when(w.wen){ spec_table(w.addr) := w.wdata }
74    }
75  }
76
77  if (!env.FPGAPlatform) {
78    ExcitingUtils.addSource(
79      arch_table,
80      if(float) "DEBUG_FP_ARCH_RAT" else "DEBUG_INI_ARCH_RAT",
81      ExcitingUtils.Debug
82    )
83  }
84
85  if (env.DualCoreDifftest) {
86    val id = if (float) hartIdRTFp() else hartIdRTInt()
87    ExcitingUtils.addSource(
88      arch_table,
89      if(float) s"DEBUG_FP_ARCH_RAT$id" else s"DEBUG_INI_ARCH_RAT$id",
90      ExcitingUtils.Debug
91    )
92  }
93}
94