xref: /XiangShan/src/main/scala/xiangshan/backend/rename/BusyTable.scala (revision 8891a219bbc84f568e1d134854d8d5ed86d6d560)
1/***************************************************************************************
2* Copyright (c) 2020-2021 Institute of Computing Technology, Chinese Academy of Sciences
3* Copyright (c) 2020-2021 Peng Cheng Laboratory
4*
5* XiangShan is licensed under Mulan PSL v2.
6* You can use this software according to the terms and conditions of the Mulan PSL v2.
7* You may obtain a copy of Mulan PSL v2 at:
8*          http://license.coscl.org.cn/MulanPSL2
9*
10* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
11* EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
12* MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
13*
14* See the Mulan PSL v2 for more details.
15***************************************************************************************/
16
17package xiangshan.backend.rename
18
19import org.chipsalliance.cde.config.Parameters
20import chisel3._
21import chisel3.util._
22import xiangshan._
23import utils._
24import utility._
25
26class BusyTableReadIO(implicit p: Parameters) extends XSBundle {
27  val req = Input(UInt(PhyRegIdxWidth.W))
28  val resp = Output(Bool())
29}
30
31class BusyTable(numReadPorts: Int, numWritePorts: Int)(implicit p: Parameters) extends XSModule with HasPerfEvents {
32  val io = IO(new Bundle() {
33    // set preg state to busy
34    val allocPregs = Vec(RenameWidth, Flipped(ValidIO(UInt(PhyRegIdxWidth.W))))
35    // set preg state to ready (write back regfile + rob walk)
36    val wbPregs = Vec(numWritePorts, Flipped(ValidIO(UInt(PhyRegIdxWidth.W))))
37    // read preg state
38    val read = Vec(numReadPorts, new BusyTableReadIO)
39  })
40
41  val table = RegInit(0.U(NRPhyRegs.W))
42
43  def reqVecToMask(rVec: Vec[Valid[UInt]]): UInt = {
44    ParallelOR(rVec.map(v => Mux(v.valid, UIntToOH(v.bits), 0.U)))
45  }
46
47  val wbMask = reqVecToMask(io.wbPregs)
48  val allocMask = reqVecToMask(io.allocPregs)
49
50  val tableAfterWb = table & (~wbMask).asUInt
51  val tableAfterAlloc = tableAfterWb | allocMask
52
53  io.read.foreach(r => r.resp := !table(r.req))
54
55  table := tableAfterAlloc
56
57  val oddTable = table.asBools.zipWithIndex.filter(_._2 % 2 == 1).map(_._1)
58  val evenTable = table.asBools.zipWithIndex.filter(_._2 % 2 == 0).map(_._1)
59  val busyCount = RegNext(RegNext(PopCount(oddTable)) + RegNext(PopCount(evenTable)))
60
61  XSDebug(p"table    : ${Binary(table)}\n")
62  XSDebug(p"tableNext: ${Binary(tableAfterAlloc)}\n")
63  XSDebug(p"allocMask: ${Binary(allocMask)}\n")
64  XSDebug(p"wbMask   : ${Binary(wbMask)}\n")
65  for (i <- 0 until NRPhyRegs) {
66    XSDebug(table(i), "%d is busy\n", i.U)
67  }
68
69  XSPerfAccumulate("busy_count", PopCount(table))
70
71  val perfEvents = Seq(
72    ("std_freelist_1_4_valid", busyCount < (NRPhyRegs / 4).U                                      ),
73    ("std_freelist_2_4_valid", busyCount > (NRPhyRegs / 4).U && busyCount <= (NRPhyRegs / 2).U    ),
74    ("std_freelist_3_4_valid", busyCount > (NRPhyRegs / 2).U && busyCount <= (NRPhyRegs * 3 / 4).U),
75    ("std_freelist_4_4_valid", busyCount > (NRPhyRegs * 3 / 4).U                                  )
76  )
77  generatePerfEvent()
78}
79