xref: /XiangShan/src/main/scala/xiangshan/backend/regcache/AgeDetector.scala (revision 86102875bc9491279d643aa7e08fb4dd12929987)
1*86102875Ssinsanction/***************************************************************************************
2*86102875Ssinsanction * Copyright (c) 2020-2021 Institute of Computing Technology, Chinese Academy of Sciences
3*86102875Ssinsanction * Copyright (c) 2020-2021 Peng Cheng Laboratory
4*86102875Ssinsanction *
5*86102875Ssinsanction * XiangShan is licensed under Mulan PSL v2.
6*86102875Ssinsanction * You can use this software according to the terms and conditions of the Mulan PSL v2.
7*86102875Ssinsanction * You may obtain a copy of Mulan PSL v2 at:
8*86102875Ssinsanction *          http://license.coscl.org.cn/MulanPSL2
9*86102875Ssinsanction *
10*86102875Ssinsanction * THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
11*86102875Ssinsanction * EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
12*86102875Ssinsanction * MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
13*86102875Ssinsanction *
14*86102875Ssinsanction * See the Mulan PSL v2 for more details.
15*86102875Ssinsanction ***************************************************************************************/
16*86102875Ssinsanction
17*86102875Ssinsanctionpackage xiangshan.backend.regcache
18*86102875Ssinsanction
19*86102875Ssinsanctionimport org.chipsalliance.cde.config.Parameters
20*86102875Ssinsanctionimport chisel3._
21*86102875Ssinsanctionimport chisel3.util._
22*86102875Ssinsanctionimport xiangshan._
23*86102875Ssinsanctionimport utils._
24*86102875Ssinsanctionimport utility._
25*86102875Ssinsanction
26*86102875Ssinsanctionclass RegCacheAgeDetector(numEntries: Int, numReplace: Int)(implicit p: Parameters) extends XSModule {
27*86102875Ssinsanction  val io = IO(new Bundle {
28*86102875Ssinsanction    val ageInfo = Vec(numEntries, Vec(numEntries, Input(Bool())))
29*86102875Ssinsanction    val out = Vec(numReplace, Output(UInt(log2Up(numEntries).W)))
30*86102875Ssinsanction  })
31*86102875Ssinsanction
32*86102875Ssinsanction  // age(i)(j): entry i is older than entry j
33*86102875Ssinsanction  val age = Seq.fill(numEntries)(Seq.fill(numEntries)(RegInit(true.B)))
34*86102875Ssinsanction  val nextAge = Seq.fill(numEntries)(Seq.fill(numEntries)(Wire(Bool())))
35*86102875Ssinsanction
36*86102875Ssinsanction  // to reduce reg usage, only use upper matrix
37*86102875Ssinsanction  def get_age(row: Int, col: Int): Bool = {
38*86102875Ssinsanction    if (row < col)
39*86102875Ssinsanction      age(row)(col)
40*86102875Ssinsanction    else if (row == col)
41*86102875Ssinsanction      true.B
42*86102875Ssinsanction    else
43*86102875Ssinsanction      !age(col)(row)
44*86102875Ssinsanction  }
45*86102875Ssinsanction
46*86102875Ssinsanction  //only for row <= col
47*86102875Ssinsanction  for((row, i) <- nextAge.zipWithIndex) {
48*86102875Ssinsanction    for((elem, j) <- row.zipWithIndex) {
49*86102875Ssinsanction      if (i == j) {
50*86102875Ssinsanction        // an entry is always older than itself
51*86102875Ssinsanction        elem := true.B
52*86102875Ssinsanction      }
53*86102875Ssinsanction      else if (i < j) {
54*86102875Ssinsanction        elem := io.ageInfo(i)(j)
55*86102875Ssinsanction      }
56*86102875Ssinsanction      else {
57*86102875Ssinsanction        elem := !nextAge(j)(i)
58*86102875Ssinsanction      }
59*86102875Ssinsanction      age(i)(j) := elem
60*86102875Ssinsanction    }
61*86102875Ssinsanction  }
62*86102875Ssinsanction
63*86102875Ssinsanction  val rowOnesSum = (0 until numEntries).map(i =>
64*86102875Ssinsanction    PopCount((0 until numEntries).map(j => get_age(i, j)))
65*86102875Ssinsanction  )
66*86102875Ssinsanction
67*86102875Ssinsanction  io.out.zipWithIndex.foreach { case (out, idx) =>
68*86102875Ssinsanction    out := PriorityMux(rowOnesSum.map(_ === (numEntries - idx).U).zip((0 until numEntries).map(_.U)))
69*86102875Ssinsanction    assert(PopCount(rowOnesSum.map(_ === (numEntries - idx).U)) === 1.U, s"row sum of replace entry ($idx) is not one-hot")
70*86102875Ssinsanction  }
71*86102875Ssinsanction}
72*86102875Ssinsanction
73*86102875Ssinsanctionobject RegCacheAgeDetector {
74*86102875Ssinsanction  def apply(numEntries: Int, numReplace: Int, ageInfo: Vec[Vec[Bool]])(implicit p: Parameters): Vec[UInt] = {
75*86102875Ssinsanction    val age = Module(new RegCacheAgeDetector(numEntries, numReplace))
76*86102875Ssinsanction    age.io.ageInfo := ageInfo
77*86102875Ssinsanction    age.io.out
78*86102875Ssinsanction  }
79*86102875Ssinsanction}