xref: /XiangShan/src/main/scala/xiangshan/backend/regcache/AgeDetector.scala (revision 86102875bc9491279d643aa7e08fb4dd12929987)
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.regcache
18
19import org.chipsalliance.cde.config.Parameters
20import chisel3._
21import chisel3.util._
22import xiangshan._
23import utils._
24import utility._
25
26class RegCacheAgeDetector(numEntries: Int, numReplace: Int)(implicit p: Parameters) extends XSModule {
27  val io = IO(new Bundle {
28    val ageInfo = Vec(numEntries, Vec(numEntries, Input(Bool())))
29    val out = Vec(numReplace, Output(UInt(log2Up(numEntries).W)))
30  })
31
32  // age(i)(j): entry i is older than entry j
33  val age = Seq.fill(numEntries)(Seq.fill(numEntries)(RegInit(true.B)))
34  val nextAge = Seq.fill(numEntries)(Seq.fill(numEntries)(Wire(Bool())))
35
36  // to reduce reg usage, only use upper matrix
37  def get_age(row: Int, col: Int): Bool = {
38    if (row < col)
39      age(row)(col)
40    else if (row == col)
41      true.B
42    else
43      !age(col)(row)
44  }
45
46  //only for row <= col
47  for((row, i) <- nextAge.zipWithIndex) {
48    for((elem, j) <- row.zipWithIndex) {
49      if (i == j) {
50        // an entry is always older than itself
51        elem := true.B
52      }
53      else if (i < j) {
54        elem := io.ageInfo(i)(j)
55      }
56      else {
57        elem := !nextAge(j)(i)
58      }
59      age(i)(j) := elem
60    }
61  }
62
63  val rowOnesSum = (0 until numEntries).map(i =>
64    PopCount((0 until numEntries).map(j => get_age(i, j)))
65  )
66
67  io.out.zipWithIndex.foreach { case (out, idx) =>
68    out := PriorityMux(rowOnesSum.map(_ === (numEntries - idx).U).zip((0 until numEntries).map(_.U)))
69    assert(PopCount(rowOnesSum.map(_ === (numEntries - idx).U)) === 1.U, s"row sum of replace entry ($idx) is not one-hot")
70  }
71}
72
73object RegCacheAgeDetector {
74  def apply(numEntries: Int, numReplace: Int, ageInfo: Vec[Vec[Bool]])(implicit p: Parameters): Vec[UInt] = {
75    val age = Module(new RegCacheAgeDetector(numEntries, numReplace))
76    age.io.ageInfo := ageInfo
77    age.io.out
78  }
79}