xref: /XiangShan/src/main/scala/xiangshan/backend/regcache/RegCacheTagTable.scala (revision 0a7d1d5cc74078a0d2fe9270a78ac80db6cb1ad0)
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