xref: /XiangShan/src/main/scala/xiangshan/backend/regcache/RegCacheAgeTimer.scala (revision f25e75d97d152e589c9b42e0b106951d881ee6b2)
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