xref: /XiangShan/src/main/scala/xiangshan/backend/regcache/RegCache.scala (revision f8b278aa7f5c894b2f00114935bd4d8edb8a885c)
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 utils._
2386102875Ssinsanctionimport utility._
2486102875Ssinsanctionimport xiangshan._
2586102875Ssinsanctionimport xiangshan.backend.BackendParams
2686102875Ssinsanction
2786102875Ssinsanctionclass RegCache()(implicit p: Parameters, params: BackendParams) extends XSModule {
2886102875Ssinsanction
2986102875Ssinsanction  val io = IO(new RegCacheIO())
3086102875Ssinsanction
3186102875Ssinsanction  println(s"[RegCache] readPorts: ${params.getIntExuRCReadSize} + ${params.getMemExuRCReadSize}, " +
3286102875Ssinsanction    s"writePorts: ${params.getIntExuRCWriteSize} + ${params.getMemExuRCWriteSize}")
3386102875Ssinsanction
3486102875Ssinsanction  println(s"[RegCache] dataWidth: ${params.intSchdParams.get.rfDataWidth}, addrWidth: ${RegCacheIdxWidth}, tagWidth: ${params.intSchdParams.get.pregIdxWidth}")
3586102875Ssinsanction
3686102875Ssinsanction  require(RegCacheIdxWidth == (log2Up(IntRegCacheSize) + 1), "IntRegCache should be half of the whole RegCache")
3786102875Ssinsanction  require(RegCacheIdxWidth == (log2Up(MemRegCacheSize) + 1), "MemRegCache should be half of the whole RegCache")
3886102875Ssinsanction
3986102875Ssinsanction  private val IntRegCacheReadSize = params.getIntExuRCReadSize + params.getMemExuRCReadSize
4086102875Ssinsanction  private val IntRegCacheWriteSize = params.getIntExuRCWriteSize
4186102875Ssinsanction  private val MemRegCacheReadSize = params.getIntExuRCReadSize + params.getMemExuRCReadSize
4286102875Ssinsanction  private val MemRegCacheWriteSize = params.getMemExuRCWriteSize
4386102875Ssinsanction
4486102875Ssinsanction  val IntRegCache = Module(new RegCacheDataModule("IntRegCache", IntRegCacheSize, IntRegCacheReadSize, IntRegCacheWriteSize,
4586102875Ssinsanction                                                  params.intSchdParams.get.rfDataWidth, RegCacheIdxWidth - 1, params.intSchdParams.get.pregIdxWidth))
4686102875Ssinsanction
4786102875Ssinsanction  val MemRegCache = Module(new RegCacheDataModule("MemRegCache", MemRegCacheSize, MemRegCacheReadSize, MemRegCacheWriteSize,
4886102875Ssinsanction                                                  params.intSchdParams.get.rfDataWidth, RegCacheIdxWidth - 1, params.intSchdParams.get.pregIdxWidth))
4986102875Ssinsanction
5086102875Ssinsanction  val IntRegCacheAgeTimer = Module(new RegCacheAgeTimer(IntRegCacheSize, IntRegCacheReadSize, IntRegCacheWriteSize, RegCacheIdxWidth - 1))
5186102875Ssinsanction
5286102875Ssinsanction  val MemRegCacheAgeTimer = Module(new RegCacheAgeTimer(MemRegCacheSize, MemRegCacheReadSize, MemRegCacheWriteSize, RegCacheIdxWidth - 1))
5386102875Ssinsanction
5486102875Ssinsanction  val IntRegCacheRepRCIdx = RegCacheAgeDetector(IntRegCacheSize, IntRegCacheWriteSize, IntRegCacheAgeTimer.io.ageInfo)
5586102875Ssinsanction  val MemRegCacheRepRCIdx = RegCacheAgeDetector(MemRegCacheSize, MemRegCacheWriteSize, MemRegCacheAgeTimer.io.ageInfo)
5686102875Ssinsanction
5786102875Ssinsanction  IntRegCacheAgeTimer.io.validInfo := IntRegCache.io.validInfo
5886102875Ssinsanction  MemRegCacheAgeTimer.io.validInfo := MemRegCache.io.validInfo
5986102875Ssinsanction
6086102875Ssinsanction  io.readPorts
6186102875Ssinsanction  .lazyZip(IntRegCache.io.readPorts.lazyZip(MemRegCache.io.readPorts))
6286102875Ssinsanction  .lazyZip(IntRegCacheAgeTimer.io.readPorts.lazyZip(MemRegCacheAgeTimer.io.readPorts))
6386102875Ssinsanction  .foreach{ case (r_in, (r_int, r_mem), (r_int_at, r_mem_at)) =>
6486102875Ssinsanction    val in_addr = RegEnable(r_in.addr, r_in.ren)
6586102875Ssinsanction    val int_ren = GatedValidRegNext(r_in.ren & ~r_in.addr(RegCacheIdxWidth - 1))
6686102875Ssinsanction    val mem_ren = GatedValidRegNext(r_in.ren & r_in.addr(RegCacheIdxWidth - 1))
6786102875Ssinsanction    r_int.ren  := int_ren
6886102875Ssinsanction    r_mem.ren  := mem_ren
6986102875Ssinsanction    r_int.addr := in_addr(RegCacheIdxWidth - 2, 0)
7086102875Ssinsanction    r_mem.addr := in_addr(RegCacheIdxWidth - 2, 0)
7186102875Ssinsanction    r_in.data  := Mux(in_addr(RegCacheIdxWidth - 1), r_mem.data, r_int.data)
7286102875Ssinsanction    r_int_at.ren  := int_ren
7386102875Ssinsanction    r_mem_at.ren  := mem_ren
7486102875Ssinsanction    r_int_at.addr := in_addr(RegCacheIdxWidth - 2, 0)
7586102875Ssinsanction    r_mem_at.addr := in_addr(RegCacheIdxWidth - 2, 0)
7686102875Ssinsanction  }
7786102875Ssinsanction
78*f8b278aaSsinsanction  val writePorts = Wire(chiselTypeOf(io.writePorts))
79*f8b278aaSsinsanction
80*f8b278aaSsinsanction  IntRegCache.io.writePorts.zip(writePorts.take(IntRegCacheWriteSize)).foreach{ case (w_int, w_in) =>
8186102875Ssinsanction    w_int.wen  := w_in.wen
8286102875Ssinsanction    w_int.addr := w_in.addr(RegCacheIdxWidth - 2, 0)
8386102875Ssinsanction    w_int.data := w_in.data
8486102875Ssinsanction    w_int.tag.foreach(_ := w_in.tag.get)
8586102875Ssinsanction  }
8686102875Ssinsanction
87*f8b278aaSsinsanction  MemRegCache.io.writePorts.zip(writePorts.takeRight(MemRegCacheWriteSize)).foreach{ case (w_mem, w_in) =>
8886102875Ssinsanction    w_mem.wen  := w_in.wen
8986102875Ssinsanction    w_mem.addr := w_in.addr(RegCacheIdxWidth - 2, 0)
9086102875Ssinsanction    w_mem.data := w_in.data
9186102875Ssinsanction    w_mem.tag.foreach(_ := w_in.tag.get)
9286102875Ssinsanction  }
9386102875Ssinsanction
94*f8b278aaSsinsanction  IntRegCacheAgeTimer.io.writePorts.zip(writePorts.take(IntRegCacheWriteSize)).foreach{ case (w_int, w_in) =>
9586102875Ssinsanction    w_int.wen  := w_in.wen
9686102875Ssinsanction    w_int.addr := w_in.addr(RegCacheIdxWidth - 2, 0)
9786102875Ssinsanction  }
9886102875Ssinsanction
99*f8b278aaSsinsanction  MemRegCacheAgeTimer.io.writePorts.zip(writePorts.takeRight(MemRegCacheWriteSize)).foreach{ case (w_mem, w_in) =>
10086102875Ssinsanction    w_mem.wen  := w_in.wen
10186102875Ssinsanction    w_mem.addr := w_in.addr(RegCacheIdxWidth - 2, 0)
10286102875Ssinsanction  }
10386102875Ssinsanction
10486102875Ssinsanction  io.toWakeupQueueRCIdx.zipWithIndex.foreach{ case (rcIdx, i) =>
10586102875Ssinsanction    if (i < IntRegCacheWriteSize) {
10686102875Ssinsanction      rcIdx := Cat("b0".U, IntRegCacheRepRCIdx(i))
10786102875Ssinsanction    }
10886102875Ssinsanction    else {
10986102875Ssinsanction      rcIdx := Cat("b1".U, MemRegCacheRepRCIdx(i - IntRegCacheWriteSize))
11086102875Ssinsanction    }
11186102875Ssinsanction  }
112*f8b278aaSsinsanction
113*f8b278aaSsinsanction  val delayToWakeupQueueRCIdx = RegNextN(io.toWakeupQueueRCIdx, 3)
114*f8b278aaSsinsanction  writePorts := io.writePorts
115*f8b278aaSsinsanction  writePorts.zip(delayToWakeupQueueRCIdx).foreach{ case (w, rcIdx) =>
116*f8b278aaSsinsanction    w.addr := rcIdx
117*f8b278aaSsinsanction  }
11886102875Ssinsanction}
11986102875Ssinsanction
12086102875Ssinsanctionclass RegCacheIO()(implicit p: Parameters, params: BackendParams) extends XSBundle {
12186102875Ssinsanction
12286102875Ssinsanction  val readPorts = Vec(params.getIntExuRCReadSize + params.getMemExuRCReadSize,
12386102875Ssinsanction    new RCReadPort(params.intSchdParams.get.rfDataWidth, RegCacheIdxWidth))
12486102875Ssinsanction
12586102875Ssinsanction  val writePorts = Vec(params.getIntExuRCWriteSize + params.getMemExuRCWriteSize,
12686102875Ssinsanction    new RCWritePort(params.intSchdParams.get.rfDataWidth, RegCacheIdxWidth, params.intSchdParams.get.pregIdxWidth, params.debugEn))
12786102875Ssinsanction
12886102875Ssinsanction  val toWakeupQueueRCIdx = Vec(params.getIntExuRCWriteSize + params.getMemExuRCWriteSize,
12986102875Ssinsanction     Output(UInt(RegCacheIdxWidth.W)))
13086102875Ssinsanction}
131