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 val writePorts = Wire(chiselTypeOf(io.writePorts)) 79 80 IntRegCache.io.writePorts.zip(writePorts.take(IntRegCacheWriteSize)).foreach{ case (w_int, w_in) => 81 w_int.wen := w_in.wen 82 w_int.addr := w_in.addr(RegCacheIdxWidth - 2, 0) 83 w_int.data := w_in.data 84 w_int.tag.foreach(_ := w_in.tag.get) 85 } 86 87 MemRegCache.io.writePorts.zip(writePorts.takeRight(MemRegCacheWriteSize)).foreach{ case (w_mem, w_in) => 88 w_mem.wen := w_in.wen 89 w_mem.addr := w_in.addr(RegCacheIdxWidth - 2, 0) 90 w_mem.data := w_in.data 91 w_mem.tag.foreach(_ := w_in.tag.get) 92 } 93 94 IntRegCacheAgeTimer.io.writePorts.zip(writePorts.take(IntRegCacheWriteSize)).foreach{ case (w_int, w_in) => 95 w_int.wen := w_in.wen 96 w_int.addr := w_in.addr(RegCacheIdxWidth - 2, 0) 97 } 98 99 MemRegCacheAgeTimer.io.writePorts.zip(writePorts.takeRight(MemRegCacheWriteSize)).foreach{ case (w_mem, w_in) => 100 w_mem.wen := w_in.wen 101 w_mem.addr := w_in.addr(RegCacheIdxWidth - 2, 0) 102 } 103 104 io.toWakeupQueueRCIdx.zipWithIndex.foreach{ case (rcIdx, i) => 105 if (i < IntRegCacheWriteSize) { 106 rcIdx := Cat("b0".U, IntRegCacheRepRCIdx(i)) 107 } 108 else { 109 rcIdx := Cat("b1".U, MemRegCacheRepRCIdx(i - IntRegCacheWriteSize)) 110 } 111 } 112 113 val delayToWakeupQueueRCIdx = RegNextN(io.toWakeupQueueRCIdx, 3) 114 writePorts := io.writePorts 115 writePorts.zip(delayToWakeupQueueRCIdx).foreach{ case (w, rcIdx) => 116 w.addr := rcIdx 117 } 118} 119 120class RegCacheIO()(implicit p: Parameters, params: BackendParams) extends XSBundle { 121 122 val readPorts = Vec(params.getIntExuRCReadSize + params.getMemExuRCReadSize, 123 new RCReadPort(params.intSchdParams.get.rfDataWidth, RegCacheIdxWidth)) 124 125 val writePorts = Vec(params.getIntExuRCWriteSize + params.getMemExuRCWriteSize, 126 new RCWritePort(params.intSchdParams.get.rfDataWidth, RegCacheIdxWidth, params.intSchdParams.get.pregIdxWidth, params.debugEn)) 127 128 val toWakeupQueueRCIdx = Vec(params.getIntExuRCWriteSize + params.getMemExuRCWriteSize, 129 Output(UInt(RegCacheIdxWidth.W))) 130} 131