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.Bundles._ 26import xiangshan.backend.BackendParams 27import xiangshan.backend.issue.SchdBlockParams 28import freechips.rocketchip.util.SeqToAugmentedSeq 29 30class RegCacheTagTable(numReadPorts: Int)(implicit p: Parameters) extends XSModule { 31 32 val io = IO(new RegCacheTagTableIO(numReadPorts)) 33 34 println(s"[RegCacheTagTable] readPorts: ${numReadPorts}, " + 35 s"writePorts: ${backendParams.getIntExuRCWriteSize} + ${backendParams.getMemExuRCWriteSize}") 36 37 println(s"[RegCacheTagTable] addrWidth: ${RegCacheIdxWidth}, tagWidth: ${IntPhyRegIdxWidth}") 38 39 private val IntRegCacheReadSize = numReadPorts 40 private val IntRegCacheWriteSize = backendParams.getIntExuRCWriteSize 41 private val MemRegCacheReadSize = numReadPorts 42 private val MemRegCacheWriteSize = backendParams.getMemExuRCWriteSize 43 44 val IntRCTagTable = Module(new RegCacheTagModule("IntRCTagTable", IntRegCacheSize, IntRegCacheReadSize, IntRegCacheWriteSize, 45 RegCacheIdxWidth - 1, IntPhyRegIdxWidth)) 46 47 val MemRCTagTable = Module(new RegCacheTagModule("MemRCTagTable", MemRegCacheSize, MemRegCacheReadSize, MemRegCacheWriteSize, 48 RegCacheIdxWidth - 1, IntPhyRegIdxWidth)) 49 50 // read 51 io.readPorts 52 .lazyZip(IntRCTagTable.io.readPorts.lazyZip(MemRCTagTable.io.readPorts)) 53 .foreach{ case (r_in, (r_int, r_mem)) => 54 r_int.ren := r_in.ren 55 r_mem.ren := r_in.ren 56 r_int.tag := r_in.tag 57 r_mem.tag := r_in.tag 58 val matchAlloc = io.allocPregs.map(x => x.valid && r_in.tag === x.bits).reduce(_ || _) 59 r_in.valid := (r_int.valid || r_mem.valid) && !matchAlloc 60 r_in.addr := Mux(r_int.valid, Cat("b0".U, r_int.addr), Cat("b1".U, r_mem.addr)) 61 } 62 63 // write 64 val wakeupFromIQNeedWriteRC = io.wakeupFromIQ.filter(_.bits.params.needWriteRegCache) 65 val shiftLoadDependency = Wire(Vec(wakeupFromIQNeedWriteRC.size, Vec(LoadPipelineWidth, UInt(LoadDependencyWidth.W)))) 66 67 require(wakeupFromIQNeedWriteRC.size == IntRegCacheWriteSize + MemRegCacheWriteSize, "wakeup size should be equal to RC write size") 68 69 shiftLoadDependency.zip(wakeupFromIQNeedWriteRC.map(_.bits.loadDependency)).zip(backendParams.intSchdParams.get.wakeUpInExuSources.map(_.name)).foreach { 70 case ((deps, originalDeps), name) => deps.zip(originalDeps).zipWithIndex.foreach { 71 case ((dep, originalDep), deqPortIdx) => 72 if (backendParams.getLdExuIdx(backendParams.allExuParams.find(_.name == name).get) == deqPortIdx) 73 dep := 1.U 74 else 75 dep := originalDep << 1 76 } 77 } 78 79 (IntRCTagTable.io.writePorts ++ MemRCTagTable.io.writePorts).lazyZip(wakeupFromIQNeedWriteRC).lazyZip(shiftLoadDependency) 80 .foreach{ case (w, wakeup, ldDp) => 81 w.wen := wakeup.valid && wakeup.bits.rfWen && !LoadShouldCancel(Some(wakeup.bits.loadDependency), io.ldCancel) && !(wakeup.bits.is0Lat && io.og0Cancel(wakeup.bits.params.exuIdx)) 82 w.addr := wakeup.bits.rcDest.get(RegCacheIdxWidth - 2, 0) 83 w.tag := wakeup.bits.pdest 84 w.loadDependency := ldDp 85 } 86 87 // cancel 88 val allocVec = (IntRCTagTable.io.tagVec ++ MemRCTagTable.io.tagVec).map{ t => 89 io.allocPregs.map(a => a.valid && a.bits === t).asUInt.orR 90 } 91 92 val replaceVec = IntRCTagTable.io.tagVec.map{ t => 93 IntRCTagTable.io.writePorts.map(w => w.wen && w.tag === t).asUInt.orR 94 } ++ MemRCTagTable.io.tagVec.map{ t => 95 MemRCTagTable.io.writePorts.map(w => w.wen && w.tag === t).asUInt.orR 96 } 97 98 val ldCancelVec = (IntRCTagTable.io.loadDependencyVec ++ MemRCTagTable.io.loadDependencyVec).map{ ldDp => 99 LoadShouldCancel(Some(ldDp), io.ldCancel) 100 } 101 102 val cancelVec = allocVec.lazyZip(replaceVec).lazyZip(ldCancelVec).lazyZip((IntRCTagTable.io.validVec ++ MemRCTagTable.io.validVec)) 103 .map{ case (alloc, rep, ldCancel, v) => 104 (alloc || rep || ldCancel) && v 105 } 106 107 (IntRCTagTable.io.cancelVec ++ MemRCTagTable.io.cancelVec).zip(cancelVec).foreach{ case (cancelIn, cancel) => 108 cancelIn := cancel 109 } 110} 111 112class RegCacheTagTableIO(numReadPorts: Int)(implicit p: Parameters) extends XSBundle { 113 114 val readPorts = Vec(numReadPorts, new RCTagTableReadPort(RegCacheIdxWidth, IntPhyRegIdxWidth)) 115 116 val wakeupFromIQ: MixedVec[ValidIO[IssueQueueIQWakeUpBundle]] = Flipped(backendParams.intSchdParams.get.genIQWakeUpInValidBundle) 117 118 // set preg state to invalid 119 val allocPregs = Vec(RenameWidth, Flipped(ValidIO(UInt(IntPhyRegIdxWidth.W)))) 120 121 // cancelFromDatapath 122 val og0Cancel = Input(ExuVec()) 123 124 // cancelFromMem 125 val ldCancel = Vec(backendParams.LdExuCnt, Flipped(new LoadCancelIO)) 126} 127