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}