xref: /XiangShan/src/main/scala/xiangshan/mem/lsqueue/LoadQueueData.scala (revision 8a6109569c55f79d4e018b71975a99011d8d75df)
1c6d43980SLemover/***************************************************************************************
2c6d43980SLemover* Copyright (c) 2020-2021 Institute of Computing Technology, Chinese Academy of Sciences
3f320e0f0SYinan Xu* Copyright (c) 2020-2021 Peng Cheng Laboratory
4c6d43980SLemover*
5c6d43980SLemover* XiangShan is licensed under Mulan PSL v2.
6c6d43980SLemover* You can use this software according to the terms and conditions of the Mulan PSL v2.
7c6d43980SLemover* You may obtain a copy of Mulan PSL v2 at:
8c6d43980SLemover*          http://license.coscl.org.cn/MulanPSL2
9c6d43980SLemover*
10c6d43980SLemover* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
11c6d43980SLemover* EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
12c6d43980SLemover* MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
13c6d43980SLemover*
14c6d43980SLemover* See the Mulan PSL v2 for more details.
15c6d43980SLemover***************************************************************************************/
16c6d43980SLemover
177057673cSWilliam Wangpackage xiangshan.mem
187057673cSWilliam Wang
197057673cSWilliam Wangimport chisel3._
207057673cSWilliam Wangimport chisel3.util._
21e4f69d78Ssfencevmaimport chipsalliance.rocketchip.config.Parameters
227057673cSWilliam Wangimport xiangshan._
237057673cSWilliam Wangimport xiangshan.cache._
246d5ddbceSLemoverimport xiangshan.cache.{DCacheWordIO, DCacheLineIO, MemoryOpConstants}
257057673cSWilliam Wangimport xiangshan.mem._
269aca92b9SYinan Xuimport xiangshan.backend.rob.RobPtr
27e4f69d78Ssfencevmaimport utils._
28e4f69d78Ssfencevmaimport utility._
290a47e4a1SWilliam Wang
30bf6b6e21SWilliam Wang// Data module define
31e4f69d78Ssfencevma// These raw data modules are like SyncDataModuleTemplate, but support cam-like ops
32e4f69d78Ssfencevmaabstract class LqRawDataModule[T <: Data] (gen: T, numEntries: Int, numRead: Int, numWrite: Int, numWBank: Int, numWDelay: Int, numCamPort: Int = 0)(implicit p: Parameters) extends XSModule {
33e4f69d78Ssfencevma  val io = IO(new Bundle() {
34*8a610956Ssfencevma    val ren   = Input(Vec(numRead, Bool()))
35f02b5115SWilliam Wang    val raddr = Input(Vec(numRead, UInt(log2Up(numEntries).W)))
36e4f69d78Ssfencevma    val rdata = Output(Vec(numRead, gen))
37f02b5115SWilliam Wang    val wen   = Input(Vec(numWrite, Bool()))
38f02b5115SWilliam Wang    val waddr = Input(Vec(numWrite, UInt(log2Up(numEntries).W)))
39e4f69d78Ssfencevma    val wdata = Input(Vec(numWrite, gen))
40e4f69d78Ssfencevma    // violation cam: hit if addr is in the same cacheline
41e4f69d78Ssfencevma    val violationMdata = Input(Vec(numCamPort, gen)) // addr
42e4f69d78Ssfencevma    val violationMmask = Output(Vec(numCamPort, Vec(numEntries, Bool()))) // cam result mask
43e4f69d78Ssfencevma    // refill cam: hit if addr is in the same cacheline
44e4f69d78Ssfencevma    val releaseMdata = Input(Vec(numCamPort, gen))
45e4f69d78Ssfencevma    val releaseMmask = Output(Vec(numCamPort, Vec(numEntries, Bool())))  // cam result mask
46e4f69d78Ssfencevma    // release violation cam: hit if addr is in the same cacheline
47e4f69d78Ssfencevma    val releaseViolationMdata = Input(Vec(numCamPort, gen))
48e4f69d78Ssfencevma    val releaseViolationMmask = Output(Vec(numCamPort, Vec(numEntries, Bool()))) // cam result mask result
49bf6b6e21SWilliam Wang  })
50bf6b6e21SWilliam Wang
51e4f69d78Ssfencevma  require(isPow2(numWBank), "write bank must be a power of two!")
52e4f69d78Ssfencevma  require(numWBank >= 2, "write bank must be greater than or equal to two!")
53e4f69d78Ssfencevma  require(numWDelay >= 1, "write delay must be greater than or equal to one!")
54e4f69d78Ssfencevma  require(numCamPort >= 0, "camport must be greater than or equal to zero!")
550a47e4a1SWilliam Wang
56e4f69d78Ssfencevma  val numEntryPerBank = numEntries / numWBank
570a47e4a1SWilliam Wang
58e4f69d78Ssfencevma  val data = Reg(Vec(numEntries, gen))
59bf6b6e21SWilliam Wang  // read ports
60bf6b6e21SWilliam Wang  for (i <- 0 until numRead) {
61*8a610956Ssfencevma    io.rdata(i) := RegEnable(data(io.raddr(i)), io.ren(i))
62bf6b6e21SWilliam Wang  }
63bf6b6e21SWilliam Wang
640a47e4a1SWilliam Wang  // write ports
65e4f69d78Ssfencevma  val writeAddrDec = io.waddr.map(a => UIntToOH(a))
660a47e4a1SWilliam Wang  def selectBankMask(in: UInt, bank: Int): UInt = {
670a47e4a1SWilliam Wang    in((bank + 1) * numEntryPerBank - 1, bank * numEntryPerBank)
680a47e4a1SWilliam Wang  }
69e4f69d78Ssfencevma  for (bank <- 0 until numWBank) {
700a47e4a1SWilliam Wang    // write ports
710a47e4a1SWilliam Wang    // s0: write to bank level buffer
72e4f69d78Ssfencevma    val s0_bankWriteAddrDec = writeAddrDec.map(a => selectBankMask(a, bank))
73e4f69d78Ssfencevma    val s0_bankWriteEn = io.wen.zip(s0_bankWriteAddrDec).map(w => w._1 && w._2.orR)
74e4f69d78Ssfencevma    s0_bankWriteAddrDec.zipWithIndex.map(a =>
75e4f69d78Ssfencevma      a._1.suggestName("s0_bankWriteAddrDec" + bank + "_" + a._2)
760a47e4a1SWilliam Wang    )
77e4f69d78Ssfencevma    s0_bankWriteEn.zipWithIndex.map(a =>
78e4f69d78Ssfencevma      a._1.suggestName("s0_bankWriteEn" + bank + "_" + a._2)
790a47e4a1SWilliam Wang    )
80e4f69d78Ssfencevma    // sx: write data to entries
81e4f69d78Ssfencevma    val sx_bankWriteAddrDec = s0_bankWriteAddrDec.map(w => DelayN(w, numWDelay - 1))
82e4f69d78Ssfencevma    val sx_bankWriteEn = s0_bankWriteEn.map(w => DelayN(w, numWDelay - 1))
83e4f69d78Ssfencevma    val sx_writeData = io.wdata.map(w => DelayN(w, numWDelay - 1))
84e4f69d78Ssfencevma    sx_bankWriteAddrDec.zipWithIndex.map(a =>
85e4f69d78Ssfencevma      a._1.suggestName("sx_bankWriteAddrDec" + bank + "_" + a._2)
860a47e4a1SWilliam Wang    )
87e4f69d78Ssfencevma    sx_bankWriteEn.zipWithIndex.map(a =>
88e4f69d78Ssfencevma      a._1.suggestName("sx_bankWriteEn" + bank + "_" + a._2)
890a47e4a1SWilliam Wang    )
90e4f69d78Ssfencevma    sx_writeData.zipWithIndex.map(a =>
91e4f69d78Ssfencevma      a._1.suggestName("sx_writeData" + bank + "_" + a._2)
920a47e4a1SWilliam Wang    )
930a47e4a1SWilliam Wang
940a47e4a1SWilliam Wang    // entry write
950a47e4a1SWilliam Wang    for (entry <- 0 until numEntryPerBank) {
960a47e4a1SWilliam Wang      // write ports
97e4f69d78Ssfencevma      val sx_entryWriteEnVec = sx_bankWriteEn.zip(sx_bankWriteAddrDec).map(w => w._1 && w._2(entry))
98e4f69d78Ssfencevma      val sx_entryWriteEn = VecInit(sx_entryWriteEnVec).asUInt.orR
99e4f69d78Ssfencevma      val sx_entryWriteData = Mux1H(sx_entryWriteEnVec, sx_writeData)
100e4f69d78Ssfencevma      when (sx_entryWriteEn) {
101e4f69d78Ssfencevma        data(bank * numEntryPerBank + entry) := sx_entryWriteData
1020a47e4a1SWilliam Wang      }
103e4f69d78Ssfencevma      sx_entryWriteEnVec.zipWithIndex.map(a =>
104e4f69d78Ssfencevma        a._1.suggestName("sx_entryWriteEnVec" + bank + "_" + entry + "_" + a._2)
1050a47e4a1SWilliam Wang      )
106e4f69d78Ssfencevma      sx_entryWriteEn.suggestName("sx_entryWriteEn" + bank + "_" + entry)
107e4f69d78Ssfencevma      sx_entryWriteData.suggestName("sx_entryWriteData" + bank + "_" + entry)
108e4f69d78Ssfencevma    }
109e4f69d78Ssfencevma  }
110e4f69d78Ssfencevma
111e4f69d78Ssfencevma  // DataModuleTemplate should not be used when there're any write conflicts
112e4f69d78Ssfencevma  for (i <- 0 until numWrite) {
113e4f69d78Ssfencevma    for (j <- i+1 until numWrite) {
114e4f69d78Ssfencevma      assert(!(io.wen(i) && io.wen(j) && io.waddr(i) === io.waddr(j)))
115e4f69d78Ssfencevma    }
116e4f69d78Ssfencevma  }
117e4f69d78Ssfencevma}
118e4f69d78Ssfencevma
119e4f69d78Ssfencevma// Load queue physical address module
120e4f69d78Ssfencevmaclass LqPAddrModule[T <: UInt](
121e4f69d78Ssfencevma  gen: T,
122e4f69d78Ssfencevma  numEntries: Int,
123e4f69d78Ssfencevma  numRead: Int,
124e4f69d78Ssfencevma  numWrite: Int,
125e4f69d78Ssfencevma  numWBank: Int,
126e4f69d78Ssfencevma  numWDelay: Int = 1,
127e4f69d78Ssfencevma  numCamPort: Int = 1)(implicit p: Parameters) extends LqRawDataModule(gen, numEntries, numRead, numWrite, numWBank, numWDelay, numCamPort)
128e4f69d78Ssfencevma  with HasDCacheParameters
129e4f69d78Ssfencevma{
130e4f69d78Ssfencevma  // content addressed match
131e4f69d78Ssfencevma  // word aligned
132e4f69d78Ssfencevma  for (i <- 0 until numCamPort) {
133e4f69d78Ssfencevma    for (j <- 0 until numEntries) {
134e4f69d78Ssfencevma      io.violationMmask(i)(j) := io.violationMdata(i)(PAddrBits-1, 3) === data(j)(PAddrBits-1, 3)
135bf6b6e21SWilliam Wang    }
136bf6b6e21SWilliam Wang  }
137bf6b6e21SWilliam Wang
138bf6b6e21SWilliam Wang  // content addressed match
139e4f69d78Ssfencevma  // cacheline aligned
140e4f69d78Ssfencevma  for (i <- 0 until numCamPort) {
141bf6b6e21SWilliam Wang    for (j <- 0 until numEntries) {
142e4f69d78Ssfencevma      io.releaseViolationMmask(i)(j) := io.releaseViolationMdata(i)(PAddrBits-1, DCacheLineOffset) === data(j)(PAddrBits-1, DCacheLineOffset)
14367682d05SWilliam Wang    }
14467682d05SWilliam Wang  }
145e4f69d78Ssfencevma
146e4f69d78Ssfencevma  // content addressed match
147e4f69d78Ssfencevma  // cacheline aligned
148e4f69d78Ssfencevma  for (i <- 0 until numCamPort) {
14967682d05SWilliam Wang    for (j <- 0 until numEntries) {
150ef3b5b96SWilliam Wang      io.releaseMmask(i)(j) := io.releaseMdata(i)(PAddrBits-1, DCacheLineOffset) === data(j)(PAddrBits-1, DCacheLineOffset)
151bf6b6e21SWilliam Wang    }
152bf6b6e21SWilliam Wang  }
153bf6b6e21SWilliam Wang}
154bf6b6e21SWilliam Wang
155e4f69d78Ssfencevma// Load queue data module
156e4f69d78Ssfencevmaclass LqVAddrModule[T <: UInt](
157e4f69d78Ssfencevma  gen: T,
158e4f69d78Ssfencevma  numEntries: Int,
159e4f69d78Ssfencevma  numRead: Int,
160e4f69d78Ssfencevma  numWrite: Int,
161e4f69d78Ssfencevma  numWBank: Int,
162e4f69d78Ssfencevma  numWDelay: Int = 1,
163e4f69d78Ssfencevma  numCamPort: Int = 1)(implicit p: Parameters) extends LqRawDataModule(gen, numEntries, numRead, numWrite, numWBank, numWDelay, numCamPort)
164e4f69d78Ssfencevma  with HasDCacheParameters
165e4f69d78Ssfencevma{
166e4f69d78Ssfencevma  // content addressed match
167e4f69d78Ssfencevma  for (i <- 0 until numCamPort) {
1680a47e4a1SWilliam Wang    for (j <- 0 until numEntries) {
169e4f69d78Ssfencevma      io.violationMmask(i)(j) := io.violationMdata(i)(VAddrBits-1, 3) === data(j)(VAddrBits-1, 3)
170bf6b6e21SWilliam Wang    }
171bf6b6e21SWilliam Wang  }
172bf6b6e21SWilliam Wang
173e4f69d78Ssfencevma  // content addressed match
174e4f69d78Ssfencevma  for (i <- 0 until numCamPort) {
175e4f69d78Ssfencevma    for (j <- 0 until numEntries) {
176e4f69d78Ssfencevma      io.releaseMmask(i)(j) := io.releaseMdata(i)(VAddrBits-1, 0) === data(j)(VAddrBits-1, 0)
177e4f69d78Ssfencevma    }
178e4f69d78Ssfencevma  }
179e4f69d78Ssfencevma}
180e4f69d78Ssfencevma
181e4f69d78Ssfencevma// Load queue mask module
182e4f69d78Ssfencevmaclass LqMaskModule[T <: UInt](
183e4f69d78Ssfencevma  gen: T,
184e4f69d78Ssfencevma  numEntries: Int,
185e4f69d78Ssfencevma  numRead: Int,
186e4f69d78Ssfencevma  numWrite: Int,
187e4f69d78Ssfencevma  numWBank: Int,
188e4f69d78Ssfencevma  numWDelay: Int = 1,
189e4f69d78Ssfencevma  numCamPort: Int = 1)(implicit p: Parameters) extends LqRawDataModule(gen, numEntries, numRead, numWrite, numWBank, numWDelay, numCamPort)
190e4f69d78Ssfencevma  with HasDCacheParameters
191e4f69d78Ssfencevma{
192e4f69d78Ssfencevma  // content addressed match
193e4f69d78Ssfencevma  for (i <- 0 until numCamPort) {
194bf6b6e21SWilliam Wang    for (j <- 0 until numEntries) {
195f02b5115SWilliam Wang      io.violationMmask(i)(j) := (io.violationMdata(i) & data(j)).orR
196bf6b6e21SWilliam Wang    }
197bf6b6e21SWilliam Wang  }
198e4f69d78Ssfencevma  // content addressed match
199e4f69d78Ssfencevma  // cacheline aligned
200e4f69d78Ssfencevma  for (i <- 0 until numCamPort) {
201e4f69d78Ssfencevma    for (j <- 0 until numEntries) {
202e4f69d78Ssfencevma      io.releaseViolationMmask(i)(j) := (io.releaseViolationMdata(i) & data(j)).orR
203f02b5115SWilliam Wang    }
204f02b5115SWilliam Wang  }
205f02b5115SWilliam Wang
206e4f69d78Ssfencevma  // content addressed match
207e4f69d78Ssfencevma  for (i <- 0 until numCamPort) {
208e4f69d78Ssfencevma    for (j <- 0 until numEntries) {
209e4f69d78Ssfencevma      io.releaseMmask(i)(j) := (io.releaseMdata(i) & data(j)).orR
2101c2ecc42SWilliam Wang    }
2111c2ecc42SWilliam Wang  }
2127057673cSWilliam Wang}
213