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