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._ 24 25class RCAgeTimerReadPort(addrWidth: Int) extends Bundle { 26 val ren = Input(Bool()) 27 val addr = Input(UInt(addrWidth.W)) 28} 29 30class RCAgeTimerWritePort(addrWidth: Int) extends Bundle { 31 val wen = Input(Bool()) 32 val addr = Input(UInt(addrWidth.W)) 33} 34 35class RegCacheAgeTimer 36( 37 numEntries: Int, 38 numReadPorts: Int, 39 numWritePorts: Int, 40 addrWidth: Int, 41)(implicit p: Parameters) extends XSModule { 42 val io = IO(new Bundle() { 43 val readPorts = Vec(numReadPorts, new RCAgeTimerReadPort(addrWidth)) 44 val writePorts = Vec(numWritePorts, new RCAgeTimerWritePort(addrWidth)) 45 val validInfo = Vec(numEntries, Input(Bool())) 46 val ageInfo = Vec(numEntries, Vec(numEntries, Output(Bool()))) 47 }) 48 49 require(numEntries % 4 == 0, "numEntries must be a multiple of 4") 50 51 val ageTimer = RegInit(VecInit((0 until numEntries).map(i => (i / (numEntries / 4)).U(2.W)))) 52 val ageTimerNext = Seq.fill(numEntries)(Wire(UInt(2.W))) 53 54 val ageTimerExtra = RegInit(VecInit((0 until 4).map(_.U(2.W)))) 55 ageTimerExtra.foreach(i => i := i + 1.U) 56 57 val hasReadReq = (0 until numEntries).map{ i => 58 io.readPorts.map(r => r.ren && r.addr === i.U).reduce(_ || _) 59 } 60 val hasWriteReq = (0 until numEntries).map{ i => 61 io.writePorts.map(w => w.wen && w.addr === i.U).reduce(_ || _) 62 } 63 64 for ((atNext, i) <- ageTimerNext.zipWithIndex) { 65 when(hasWriteReq(i)) { 66 atNext := 0.U 67 }.elsewhen(hasReadReq(i)) { 68 atNext := ageTimer(i) 69 }.elsewhen(ageTimer(i) === 3.U && io.validInfo(i)) { 70 atNext := 3.U 71 }.otherwise { 72 atNext := ageTimer(i) + 1.U 73 } 74 ageTimer(i) := atNext 75 } 76 77 def age_cmp_func(row: Int, col: Int): Bool = { 78 if (row == col) 79 true.B 80 else if (row < col) { 81 val res = Wire(Bool()) 82 when (io.validInfo(row) && !io.validInfo(col)) { 83 res := false.B 84 }.elsewhen (!io.validInfo(row) && io.validInfo(col)) { 85 res := true.B 86 }.otherwise { 87 res := Cat(ageTimerNext(row), ageTimerExtra(row / (numEntries / 4))) >= Cat(ageTimerNext(col), ageTimerExtra(col / (numEntries / 4))) 88 } 89 res 90 } 91 else 92 !age_cmp_func(col, row) 93 } 94 95 for (i <- 0 until numEntries) { 96 for (j <- 0 until numEntries) { 97 io.ageInfo(i)(j) := age_cmp_func(i, j) 98 } 99 } 100} 101