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 utils._ 23import utility._ 24import xiangshan._ 25import xiangshan.backend.BackendParams 26 27class RegCache()(implicit p: Parameters, params: BackendParams) extends XSModule { 28 29 val io = IO(new RegCacheIO()) 30 31 println(s"[RegCache] readPorts: ${params.getIntExuRCReadSize} + ${params.getMemExuRCReadSize}, " + 32 s"writePorts: ${params.getIntExuRCWriteSize} + ${params.getMemExuRCWriteSize}") 33 34 println(s"[RegCache] dataWidth: ${params.intSchdParams.get.rfDataWidth}, addrWidth: ${RegCacheIdxWidth}, tagWidth: ${params.intSchdParams.get.pregIdxWidth}") 35 36 require(RegCacheIdxWidth == (log2Up(IntRegCacheSize) + 1), "IntRegCache should be half of the whole RegCache") 37 require(RegCacheIdxWidth == (log2Up(MemRegCacheSize) + 1), "MemRegCache should be half of the whole RegCache") 38 39 private val IntRegCacheReadSize = params.getIntExuRCReadSize + params.getMemExuRCReadSize 40 private val IntRegCacheWriteSize = params.getIntExuRCWriteSize 41 private val MemRegCacheReadSize = params.getIntExuRCReadSize + params.getMemExuRCReadSize 42 private val MemRegCacheWriteSize = params.getMemExuRCWriteSize 43 44 val IntRegCache = Module(new RegCacheDataModule("IntRegCache", IntRegCacheSize, IntRegCacheReadSize, IntRegCacheWriteSize, 45 params.intSchdParams.get.rfDataWidth, RegCacheIdxWidth - 1, params.intSchdParams.get.pregIdxWidth)) 46 47 val MemRegCache = Module(new RegCacheDataModule("MemRegCache", MemRegCacheSize, MemRegCacheReadSize, MemRegCacheWriteSize, 48 params.intSchdParams.get.rfDataWidth, RegCacheIdxWidth - 1, params.intSchdParams.get.pregIdxWidth)) 49 50 val IntRegCacheAgeTimer = Module(new RegCacheAgeTimer(IntRegCacheSize, IntRegCacheReadSize, IntRegCacheWriteSize, RegCacheIdxWidth - 1)) 51 52 val MemRegCacheAgeTimer = Module(new RegCacheAgeTimer(MemRegCacheSize, MemRegCacheReadSize, MemRegCacheWriteSize, RegCacheIdxWidth - 1)) 53 54 val IntRegCacheRepRCIdx = RegCacheAgeDetector(IntRegCacheSize, IntRegCacheWriteSize, IntRegCacheAgeTimer.io.ageInfo) 55 val MemRegCacheRepRCIdx = RegCacheAgeDetector(MemRegCacheSize, MemRegCacheWriteSize, MemRegCacheAgeTimer.io.ageInfo) 56 57 IntRegCacheAgeTimer.io.validInfo := IntRegCache.io.validInfo 58 MemRegCacheAgeTimer.io.validInfo := MemRegCache.io.validInfo 59 60 io.readPorts 61 .lazyZip(IntRegCache.io.readPorts.lazyZip(MemRegCache.io.readPorts)) 62 .lazyZip(IntRegCacheAgeTimer.io.readPorts.lazyZip(MemRegCacheAgeTimer.io.readPorts)) 63 .foreach{ case (r_in, (r_int, r_mem), (r_int_at, r_mem_at)) => 64 val in_addr = RegEnable(r_in.addr, r_in.ren) 65 val int_ren = GatedValidRegNext(r_in.ren & ~r_in.addr(RegCacheIdxWidth - 1)) 66 val mem_ren = GatedValidRegNext(r_in.ren & r_in.addr(RegCacheIdxWidth - 1)) 67 r_int.ren := int_ren 68 r_mem.ren := mem_ren 69 r_int.addr := in_addr(RegCacheIdxWidth - 2, 0) 70 r_mem.addr := in_addr(RegCacheIdxWidth - 2, 0) 71 r_in.data := Mux(in_addr(RegCacheIdxWidth - 1), r_mem.data, r_int.data) 72 r_int_at.ren := int_ren 73 r_mem_at.ren := mem_ren 74 r_int_at.addr := in_addr(RegCacheIdxWidth - 2, 0) 75 r_mem_at.addr := in_addr(RegCacheIdxWidth - 2, 0) 76 } 77 78 IntRegCache.io.writePorts.zip(io.writePorts.take(IntRegCacheWriteSize)).foreach{ case (w_int, w_in) => 79 w_int.wen := w_in.wen 80 w_int.addr := w_in.addr(RegCacheIdxWidth - 2, 0) 81 w_int.data := w_in.data 82 w_int.tag.foreach(_ := w_in.tag.get) 83 } 84 85 MemRegCache.io.writePorts.zip(io.writePorts.takeRight(MemRegCacheWriteSize)).foreach{ case (w_mem, w_in) => 86 w_mem.wen := w_in.wen 87 w_mem.addr := w_in.addr(RegCacheIdxWidth - 2, 0) 88 w_mem.data := w_in.data 89 w_mem.tag.foreach(_ := w_in.tag.get) 90 } 91 92 IntRegCacheAgeTimer.io.writePorts.zip(io.writePorts.take(IntRegCacheWriteSize)).foreach{ case (w_int, w_in) => 93 w_int.wen := w_in.wen 94 w_int.addr := w_in.addr(RegCacheIdxWidth - 2, 0) 95 } 96 97 MemRegCacheAgeTimer.io.writePorts.zip(io.writePorts.takeRight(MemRegCacheWriteSize)).foreach{ case (w_mem, w_in) => 98 w_mem.wen := w_in.wen 99 w_mem.addr := w_in.addr(RegCacheIdxWidth - 2, 0) 100 } 101 102 io.toWakeupQueueRCIdx.zipWithIndex.foreach{ case (rcIdx, i) => 103 if (i < IntRegCacheWriteSize) { 104 rcIdx := Cat("b0".U, IntRegCacheRepRCIdx(i)) 105 } 106 else { 107 rcIdx := Cat("b1".U, MemRegCacheRepRCIdx(i - IntRegCacheWriteSize)) 108 } 109 } 110} 111 112class RegCacheIO()(implicit p: Parameters, params: BackendParams) extends XSBundle { 113 114 val readPorts = Vec(params.getIntExuRCReadSize + params.getMemExuRCReadSize, 115 new RCReadPort(params.intSchdParams.get.rfDataWidth, RegCacheIdxWidth)) 116 117 val writePorts = Vec(params.getIntExuRCWriteSize + params.getMemExuRCWriteSize, 118 new RCWritePort(params.intSchdParams.get.rfDataWidth, RegCacheIdxWidth, params.intSchdParams.get.pregIdxWidth, params.debugEn)) 119 120 val toWakeupQueueRCIdx = Vec(params.getIntExuRCWriteSize + params.getMemExuRCWriteSize, 121 Output(UInt(RegCacheIdxWidth.W))) 122} 123