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