xref: /XiangShan/src/main/scala/xiangshan/backend/regcache/RegCacheAgeTimer.scala (revision f8124f70b7e3f89cee66b47ad7e05393de7a8d1b)
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 hasReadReq = (0 until numEntries).map{ i =>
55    io.readPorts.map(r => r.ren && r.addr === i.U).reduce(_ || _)
56  }
57  val hasWriteReq = (0 until numEntries).map{ i =>
58    io.writePorts.map(w => w.wen && w.addr === i.U).reduce(_ || _)
59  }
60
61  for ((atNext, i) <- ageTimerNext.zipWithIndex) {
62    when(hasWriteReq(i)) {
63      atNext := 0.U
64    }.elsewhen(hasReadReq(i)) {
65      atNext := ageTimer(i)
66    }.elsewhen(ageTimer(i) === 3.U && io.validInfo(i)) {
67      atNext := 3.U
68    }.otherwise {
69      atNext := ageTimer(i) + 1.U
70    }
71    ageTimer(i) := atNext
72  }
73
74  def age_cmp_func(row: Int, col: Int): Bool = {
75    if (row == col)
76      true.B
77    else if (row < col) {
78      val res = Wire(Bool())
79      when (io.validInfo(row) && !io.validInfo(col)) {
80        res := false.B
81      }.elsewhen (!io.validInfo(row) && io.validInfo(col)) {
82        res := true.B
83      }.otherwise {
84        res := ageTimerNext(row) >= ageTimerNext(col)
85      }
86      res
87    }
88    else
89      !age_cmp_func(col, row)
90  }
91
92  for (i <- 0 until numEntries) {
93    for (j <- 0 until numEntries) {
94      io.ageInfo(i)(j) := age_cmp_func(i, j)
95    }
96  }
97}
98