xref: /XiangShan/src/main/scala/xiangshan/backend/regcache/RegCacheAgeTimer.scala (revision f25e75d97d152e589c9b42e0b106951d881ee6b2)
186102875Ssinsanction/***************************************************************************************
286102875Ssinsanction* Copyright (c) 2020-2021 Institute of Computing Technology, Chinese Academy of Sciences
386102875Ssinsanction* Copyright (c) 2020-2021 Peng Cheng Laboratory
486102875Ssinsanction*
586102875Ssinsanction* XiangShan is licensed under Mulan PSL v2.
686102875Ssinsanction* You can use this software according to the terms and conditions of the Mulan PSL v2.
786102875Ssinsanction* You may obtain a copy of Mulan PSL v2 at:
886102875Ssinsanction*          http://license.coscl.org.cn/MulanPSL2
986102875Ssinsanction*
1086102875Ssinsanction* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
1186102875Ssinsanction* EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
1286102875Ssinsanction* MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
1386102875Ssinsanction*
1486102875Ssinsanction* See the Mulan PSL v2 for more details.
1586102875Ssinsanction***************************************************************************************/
1686102875Ssinsanction
1786102875Ssinsanctionpackage xiangshan.backend.regcache
1886102875Ssinsanction
1986102875Ssinsanctionimport org.chipsalliance.cde.config.Parameters
2086102875Ssinsanctionimport chisel3._
2186102875Ssinsanctionimport chisel3.util._
2286102875Ssinsanctionimport xiangshan._
2386102875Ssinsanctionimport utils._
2486102875Ssinsanction
2586102875Ssinsanctionclass RCAgeTimerReadPort(addrWidth: Int) extends Bundle {
2686102875Ssinsanction  val ren  = Input(Bool())
2786102875Ssinsanction  val addr = Input(UInt(addrWidth.W))
2886102875Ssinsanction}
2986102875Ssinsanction
3086102875Ssinsanctionclass RCAgeTimerWritePort(addrWidth: Int) extends Bundle {
3186102875Ssinsanction  val wen  = Input(Bool())
3286102875Ssinsanction  val addr = Input(UInt(addrWidth.W))
3386102875Ssinsanction}
3486102875Ssinsanction
3586102875Ssinsanctionclass RegCacheAgeTimer
3686102875Ssinsanction(
3786102875Ssinsanction  numEntries: Int,
3886102875Ssinsanction  numReadPorts: Int,
3986102875Ssinsanction  numWritePorts: Int,
4086102875Ssinsanction  addrWidth: Int,
4186102875Ssinsanction)(implicit p: Parameters) extends XSModule {
4286102875Ssinsanction  val io = IO(new Bundle() {
4386102875Ssinsanction    val readPorts = Vec(numReadPorts, new RCAgeTimerReadPort(addrWidth))
4486102875Ssinsanction    val writePorts = Vec(numWritePorts, new RCAgeTimerWritePort(addrWidth))
4586102875Ssinsanction    val validInfo = Vec(numEntries, Input(Bool()))
4686102875Ssinsanction    val ageInfo = Vec(numEntries, Vec(numEntries, Output(Bool())))
4786102875Ssinsanction  })
4886102875Ssinsanction
49f8124f70Ssinsanction  require(numEntries % 4 == 0, "numEntries must be a multiple of 4")
50f8124f70Ssinsanction
51f8124f70Ssinsanction  val ageTimer = RegInit(VecInit((0 until numEntries).map(i => (i / (numEntries / 4)).U(2.W))))
5286102875Ssinsanction  val ageTimerNext = Seq.fill(numEntries)(Wire(UInt(2.W)))
5386102875Ssinsanction
54*f25e75d9Ssinsanction  val ageTimerExtra = RegInit(VecInit((0 until 4).map(_.U(2.W))))
55*f25e75d9Ssinsanction  ageTimerExtra.foreach(i => i := i + 1.U)
56*f25e75d9Ssinsanction
5786102875Ssinsanction  val hasReadReq = (0 until numEntries).map{ i =>
5886102875Ssinsanction    io.readPorts.map(r => r.ren && r.addr === i.U).reduce(_ || _)
5986102875Ssinsanction  }
6086102875Ssinsanction  val hasWriteReq = (0 until numEntries).map{ i =>
6186102875Ssinsanction    io.writePorts.map(w => w.wen && w.addr === i.U).reduce(_ || _)
6286102875Ssinsanction  }
6386102875Ssinsanction
6486102875Ssinsanction  for ((atNext, i) <- ageTimerNext.zipWithIndex) {
6586102875Ssinsanction    when(hasWriteReq(i)) {
6686102875Ssinsanction      atNext := 0.U
6786102875Ssinsanction    }.elsewhen(hasReadReq(i)) {
6886102875Ssinsanction      atNext := ageTimer(i)
69f8124f70Ssinsanction    }.elsewhen(ageTimer(i) === 3.U && io.validInfo(i)) {
7086102875Ssinsanction      atNext := 3.U
7186102875Ssinsanction    }.otherwise {
7286102875Ssinsanction      atNext := ageTimer(i) + 1.U
7386102875Ssinsanction    }
7486102875Ssinsanction    ageTimer(i) := atNext
7586102875Ssinsanction  }
7686102875Ssinsanction
7786102875Ssinsanction  def age_cmp_func(row: Int, col: Int): Bool = {
7886102875Ssinsanction    if (row == col)
7986102875Ssinsanction      true.B
8086102875Ssinsanction    else if (row < col) {
8186102875Ssinsanction      val res = Wire(Bool())
8286102875Ssinsanction      when (io.validInfo(row) && !io.validInfo(col)) {
8386102875Ssinsanction        res := false.B
8486102875Ssinsanction      }.elsewhen (!io.validInfo(row) && io.validInfo(col)) {
8586102875Ssinsanction        res := true.B
8686102875Ssinsanction      }.otherwise {
87*f25e75d9Ssinsanction        res := Cat(ageTimerNext(row), ageTimerExtra(row / (numEntries / 4))) >= Cat(ageTimerNext(col), ageTimerExtra(col / (numEntries / 4)))
8886102875Ssinsanction      }
8986102875Ssinsanction      res
9086102875Ssinsanction    }
9186102875Ssinsanction    else
9286102875Ssinsanction      !age_cmp_func(col, row)
9386102875Ssinsanction  }
9486102875Ssinsanction
9586102875Ssinsanction  for (i <- 0 until numEntries) {
9686102875Ssinsanction    for (j <- 0 until numEntries) {
9786102875Ssinsanction      io.ageInfo(i)(j) := age_cmp_func(i, j)
9886102875Ssinsanction    }
9986102875Ssinsanction  }
10086102875Ssinsanction}
101