xref: /XiangShan/src/main/scala/xiangshan/backend/rename/BusyTable.scala (revision 2225d46ebbe2fd16b9b29963c27a7d0385a42709)
1package xiangshan.backend.rename
2
3import chipsalliance.rocketchip.config.Parameters
4import chisel3._
5import chisel3.util._
6import xiangshan._
7import utils._
8
9class BusyTableReadIO(implicit p: Parameters) extends XSBundle {
10  val req = Input(UInt(PhyRegIdxWidth.W))
11  val resp = Output(Bool())
12}
13
14class BusyTable(numReadPorts: Int, numWritePorts: Int)(implicit p: Parameters) extends XSModule {
15  val io = IO(new Bundle() {
16    val flush = Input(Bool())
17    // set preg state to busy
18    val allocPregs = Vec(RenameWidth, Flipped(ValidIO(UInt(PhyRegIdxWidth.W))))
19    // set preg state to ready (write back regfile + roq walk)
20    val wbPregs = Vec(numWritePorts, Flipped(ValidIO(UInt(PhyRegIdxWidth.W))))
21    // read preg state
22    val read = Vec(numReadPorts, new BusyTableReadIO)
23  })
24
25  val table = RegInit(0.U(NRPhyRegs.W))
26
27  def reqVecToMask(rVec: Vec[Valid[UInt]]): UInt = {
28    ParallelOR(rVec.map(v => Mux(v.valid, UIntToOH(v.bits), 0.U)))
29  }
30
31  val wbMask = reqVecToMask(io.wbPregs)
32  val allocMask = reqVecToMask(io.allocPregs)
33
34  val tableAfterWb = table & (~wbMask).asUInt
35  val tableAfterAlloc = tableAfterWb | allocMask
36
37  io.read.map(r => r.resp := !table(r.req))
38
39  table := tableAfterAlloc
40
41  when(io.flush){
42    table := 0.U(NRPhyRegs.W)
43  }
44
45  XSDebug(p"table    : ${Binary(table)}\n")
46  XSDebug(p"tableNext: ${Binary(tableAfterAlloc)}\n")
47  XSDebug(p"allocMask: ${Binary(allocMask)}\n")
48  XSDebug(p"wbMask   : ${Binary(wbMask)}\n")
49  for (i <- 0 until NRPhyRegs) {
50    XSDebug(table(i), "%d is busy\n", i.U)
51  }
52
53  XSPerfAccumulate("busy_count", PopCount(table))
54}
55