xref: /XiangShan/src/main/scala/xiangshan/mem/lsqueue/LoadQueueData.scala (revision 6d5ddbce72c9c67dcf0ec08cc682a9545ceb5f6c)
1c6d43980SLemover/***************************************************************************************
2c6d43980SLemover* Copyright (c) 2020-2021 Institute of Computing Technology, Chinese Academy of Sciences
3c6d43980SLemover*
4c6d43980SLemover* XiangShan is licensed under Mulan PSL v2.
5c6d43980SLemover* You can use this software according to the terms and conditions of the Mulan PSL v2.
6c6d43980SLemover* You may obtain a copy of Mulan PSL v2 at:
7c6d43980SLemover*          http://license.coscl.org.cn/MulanPSL2
8c6d43980SLemover*
9c6d43980SLemover* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
10c6d43980SLemover* EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
11c6d43980SLemover* MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
12c6d43980SLemover*
13c6d43980SLemover* See the Mulan PSL v2 for more details.
14c6d43980SLemover***************************************************************************************/
15c6d43980SLemover
167057673cSWilliam Wangpackage xiangshan.mem
177057673cSWilliam Wang
182225d46eSJiawei Linimport chipsalliance.rocketchip.config.Parameters
197057673cSWilliam Wangimport chisel3._
207057673cSWilliam Wangimport chisel3.util._
217057673cSWilliam Wangimport utils._
227057673cSWilliam Wangimport xiangshan._
237057673cSWilliam Wangimport xiangshan.cache._
24*6d5ddbceSLemoverimport xiangshan.cache.{DCacheWordIO, DCacheLineIO, MemoryOpConstants}
257057673cSWilliam Wangimport xiangshan.mem._
267057673cSWilliam Wangimport xiangshan.backend.roq.RoqPtr
277057673cSWilliam Wang
282225d46eSJiawei Linclass LQDataEntry(implicit p: Parameters) extends XSBundle {
297057673cSWilliam Wang  // val vaddr = UInt(VAddrBits.W)
307057673cSWilliam Wang  val paddr = UInt(PAddrBits.W)
317057673cSWilliam Wang  val mask = UInt(8.W)
327057673cSWilliam Wang  val data = UInt(XLEN.W)
337057673cSWilliam Wang  val fwdMask = Vec(8, Bool())
347057673cSWilliam Wang}
357057673cSWilliam Wang
36bf6b6e21SWilliam Wang// Data module define
37bf6b6e21SWilliam Wang// These data modules are like SyncDataModuleTemplate, but support cam-like ops
382225d46eSJiawei Linclass LQPaddrModule(numEntries: Int, numRead: Int, numWrite: Int)(implicit p: Parameters) extends XSModule with HasDCacheParameters {
39bf6b6e21SWilliam Wang  val io = IO(new Bundle {
40f02b5115SWilliam Wang    val raddr = Input(Vec(numRead, UInt(log2Up(numEntries).W)))
41f02b5115SWilliam Wang    val rdata = Output(Vec(numRead, UInt((PAddrBits).W)))
42f02b5115SWilliam Wang    val wen   = Input(Vec(numWrite, Bool()))
43f02b5115SWilliam Wang    val waddr = Input(Vec(numWrite, UInt(log2Up(numEntries).W)))
44f02b5115SWilliam Wang    val wdata = Input(Vec(numWrite, UInt((PAddrBits).W)))
45f02b5115SWilliam Wang    val violationMdata = Input(Vec(2, UInt((PAddrBits).W)))
46f02b5115SWilliam Wang    val violationMmask = Output(Vec(2, Vec(numEntries, Bool())))
47f02b5115SWilliam Wang    val refillMdata = Input(UInt((PAddrBits).W))
48f02b5115SWilliam Wang    val refillMmask = Output(Vec(numEntries, Bool()))
49bf6b6e21SWilliam Wang  })
50bf6b6e21SWilliam Wang
51f02b5115SWilliam Wang  val data = Reg(Vec(numEntries, UInt((PAddrBits).W)))
52bf6b6e21SWilliam Wang
53bf6b6e21SWilliam Wang  // read ports
54bf6b6e21SWilliam Wang  for (i <- 0 until numRead) {
5559a7acd8SWilliam Wang    io.rdata(i) := data(RegNext(io.raddr(i)))
56bf6b6e21SWilliam Wang  }
57bf6b6e21SWilliam Wang
58bf6b6e21SWilliam Wang  // below is the write ports (with priorities)
59bf6b6e21SWilliam Wang  for (i <- 0 until numWrite) {
60bf6b6e21SWilliam Wang    when (io.wen(i)) {
61bf6b6e21SWilliam Wang      data(io.waddr(i)) := io.wdata(i)
62bf6b6e21SWilliam Wang    }
63bf6b6e21SWilliam Wang  }
64bf6b6e21SWilliam Wang
65bf6b6e21SWilliam Wang  // content addressed match
66f02b5115SWilliam Wang  for (i <- 0 until 2) {
67bf6b6e21SWilliam Wang    for (j <- 0 until numEntries) {
68f02b5115SWilliam Wang      io.violationMmask(i)(j) := io.violationMdata(i)(PAddrBits-1, 3) === data(j)(PAddrBits-1, 3)
69bf6b6e21SWilliam Wang    }
70bf6b6e21SWilliam Wang  }
71f02b5115SWilliam Wang
72f02b5115SWilliam Wang  for (j <- 0 until numEntries) {
73f02b5115SWilliam Wang    io.refillMmask(j) := get_block_addr(io.refillMdata) === get_block_addr(data(j))
74bf6b6e21SWilliam Wang  }
75bf6b6e21SWilliam Wang
76bf6b6e21SWilliam Wang  // DataModuleTemplate should not be used when there're any write conflicts
77bf6b6e21SWilliam Wang  for (i <- 0 until numWrite) {
78bf6b6e21SWilliam Wang    for (j <- i+1 until numWrite) {
79bf6b6e21SWilliam Wang      assert(!(io.wen(i) && io.wen(j) && io.waddr(i) === io.waddr(j)))
80bf6b6e21SWilliam Wang    }
81bf6b6e21SWilliam Wang  }
82bf6b6e21SWilliam Wang}
83bf6b6e21SWilliam Wang
842225d46eSJiawei Linclass MaskModule(numEntries: Int, numRead: Int, numWrite: Int)(implicit p: Parameters) extends XSModule {
85bf6b6e21SWilliam Wang  val io = IO(new Bundle {
86f02b5115SWilliam Wang    val raddr = Input(Vec(numRead, UInt(log2Up(numEntries).W)))
87f02b5115SWilliam Wang    val rdata = Output(Vec(numRead, UInt(8.W)))
88f02b5115SWilliam Wang    val wen   = Input(Vec(numWrite, Bool()))
89f02b5115SWilliam Wang    val waddr = Input(Vec(numWrite, UInt(log2Up(numEntries).W)))
90f02b5115SWilliam Wang    val wdata = Input(Vec(numWrite, UInt(8.W)))
91f02b5115SWilliam Wang    val violationMdata = Input(Vec(2, UInt((PAddrBits).W)))
92f02b5115SWilliam Wang    val violationMmask = Output(Vec(2, Vec(numEntries, Bool())))
93bf6b6e21SWilliam Wang  })
94bf6b6e21SWilliam Wang
95f02b5115SWilliam Wang  val data = Reg(Vec(numEntries, UInt(8.W)))
96bf6b6e21SWilliam Wang
97bf6b6e21SWilliam Wang  // read ports
98bf6b6e21SWilliam Wang  for (i <- 0 until numRead) {
9959a7acd8SWilliam Wang    io.rdata(i) := data(RegNext(io.raddr(i)))
100bf6b6e21SWilliam Wang  }
101bf6b6e21SWilliam Wang
102bf6b6e21SWilliam Wang  // below is the write ports (with priorities)
103bf6b6e21SWilliam Wang  for (i <- 0 until numWrite) {
104bf6b6e21SWilliam Wang    when (io.wen(i)) {
105bf6b6e21SWilliam Wang      data(io.waddr(i)) := io.wdata(i)
106bf6b6e21SWilliam Wang    }
107bf6b6e21SWilliam Wang  }
108bf6b6e21SWilliam Wang
109bf6b6e21SWilliam Wang  // content addressed match
110f02b5115SWilliam Wang  for (i <- 0 until 2) {
111bf6b6e21SWilliam Wang    for (j <- 0 until numEntries) {
112f02b5115SWilliam Wang      io.violationMmask(i)(j) := (io.violationMdata(i) & data(j)).orR
113bf6b6e21SWilliam Wang    }
114bf6b6e21SWilliam Wang  }
115bf6b6e21SWilliam Wang
116bf6b6e21SWilliam Wang  // DataModuleTemplate should not be used when there're any write conflicts
117bf6b6e21SWilliam Wang  for (i <- 0 until numWrite) {
118bf6b6e21SWilliam Wang    for (j <- i+1 until numWrite) {
119bf6b6e21SWilliam Wang      assert(!(io.wen(i) && io.wen(j) && io.waddr(i) === io.waddr(j)))
120bf6b6e21SWilliam Wang    }
121bf6b6e21SWilliam Wang  }
122bf6b6e21SWilliam Wang}
123bf6b6e21SWilliam Wang
1240f22ee7cSWilliam Wang// class LQData8Module(numEntries: Int, numRead: Int, numWrite: Int) extends XSModule with HasDCacheParameters {
1250f22ee7cSWilliam Wang//   val io = IO(new Bundle {
1260f22ee7cSWilliam Wang//     // read
1270f22ee7cSWilliam Wang//     val raddr = Input(Vec(numRead, UInt(log2Up(numEntries).W)))
1280f22ee7cSWilliam Wang//     val rdata = Output(Vec(numRead, UInt(8.W)))
1290f22ee7cSWilliam Wang//     // address indexed write
1300f22ee7cSWilliam Wang//     val wen   = Input(Vec(numWrite, Bool()))
1310f22ee7cSWilliam Wang//     val waddr = Input(Vec(numWrite, UInt(log2Up(numEntries).W)))
1320f22ee7cSWilliam Wang//     val wdata = Input(Vec(numWrite, UInt(8.W)))
1330f22ee7cSWilliam Wang//     // masked write
1340f22ee7cSWilliam Wang//     val mwmask = Input(Vec(blockWords, Vec(numEntries, Bool())))
1350f22ee7cSWilliam Wang//     val mwdata = Input(Vec(blockWords, UInt(8.W)))
1360f22ee7cSWilliam Wang//   })
1371c2ecc42SWilliam Wang
1380f22ee7cSWilliam Wang//   val data = Reg(Vec(numEntries, UInt(8.W)))
1391c2ecc42SWilliam Wang
1400f22ee7cSWilliam Wang//   // read ports
1410f22ee7cSWilliam Wang//   for (i <- 0 until numRead) {
1420f22ee7cSWilliam Wang//     io.rdata(i) := data(RegNext(io.raddr(i)))
1430f22ee7cSWilliam Wang//   }
1441c2ecc42SWilliam Wang
1450f22ee7cSWilliam Wang//   // below is the write ports (with priorities)
1460f22ee7cSWilliam Wang//   for (i <- 0 until numWrite) {
1470f22ee7cSWilliam Wang//     when (io.wen(i)) {
1480f22ee7cSWilliam Wang//       data(io.waddr(i)) := io.wdata(i)
1490f22ee7cSWilliam Wang//     }
1500f22ee7cSWilliam Wang//   }
1511c2ecc42SWilliam Wang
1520f22ee7cSWilliam Wang//   // masked write
1530f22ee7cSWilliam Wang//   for (j <- 0 until numEntries) {
1540f22ee7cSWilliam Wang//     val wen = VecInit((0 until blockWords).map(i => io.mwmask(i)(j))).asUInt.orR
1550f22ee7cSWilliam Wang//     when (wen) {
1560f22ee7cSWilliam Wang//       data(j) := VecInit((0 until blockWords).map(i => {
1570f22ee7cSWilliam Wang//         Mux(io.mwmask(i)(j), io.mwdata(i), 0.U)
1580f22ee7cSWilliam Wang//       })).reduce(_ | _)
1590f22ee7cSWilliam Wang//     }
1600f22ee7cSWilliam Wang//   }
1611c2ecc42SWilliam Wang
1620f22ee7cSWilliam Wang//   // DataModuleTemplate should not be used when there're any write conflicts
1630f22ee7cSWilliam Wang//   for (i <- 0 until numWrite) {
1640f22ee7cSWilliam Wang//     for (j <- i+1 until numWrite) {
1650f22ee7cSWilliam Wang//       assert(!(io.wen(i) && io.wen(j) && io.waddr(i) === io.waddr(j)))
1660f22ee7cSWilliam Wang//     }
1670f22ee7cSWilliam Wang//   }
1680f22ee7cSWilliam Wang// }
1691c2ecc42SWilliam Wang
1702225d46eSJiawei Linclass CoredataModule(numEntries: Int, numRead: Int, numWrite: Int)(implicit p: Parameters) extends XSModule with HasDCacheParameters {
171bf6b6e21SWilliam Wang  val io = IO(new Bundle {
172bf6b6e21SWilliam Wang    // data io
173bf6b6e21SWilliam Wang    // read
174f02b5115SWilliam Wang    val raddr = Input(Vec(numRead, UInt(log2Up(numEntries).W)))
175f02b5115SWilliam Wang    val rdata = Output(Vec(numRead, UInt(XLEN.W)))
176bf6b6e21SWilliam Wang    // address indexed write
177f02b5115SWilliam Wang    val wen   = Input(Vec(numWrite, Bool()))
178f02b5115SWilliam Wang    val waddr = Input(Vec(numWrite, UInt(log2Up(numEntries).W)))
179f02b5115SWilliam Wang    val wdata = Input(Vec(numWrite, UInt(XLEN.W)))
180bf6b6e21SWilliam Wang    // masked write
181bf6b6e21SWilliam Wang    val mwmask = Input(Vec(numEntries, Bool()))
182f02b5115SWilliam Wang    val refillData = Input(UInt((cfg.blockBytes * 8).W))
183bf6b6e21SWilliam Wang
184bf6b6e21SWilliam Wang    // fwdMask io
185f02b5115SWilliam Wang    val fwdMaskWdata = Input(Vec(numWrite, UInt(8.W)))
186f02b5115SWilliam Wang    val fwdMaskWen = Input(Vec(numWrite, Bool()))
187f02b5115SWilliam Wang    // fwdMaskWaddr = waddr
188f02b5115SWilliam Wang
189f02b5115SWilliam Wang    // paddr io
190f02b5115SWilliam Wang    // 3 bits in paddr need to be stored in CoredataModule for refilling
191f02b5115SWilliam Wang    val paddrWdata = Input(Vec(numWrite, UInt((PAddrBits).W)))
192f02b5115SWilliam Wang    val paddrWen = Input(Vec(numWrite, Bool()))
193bf6b6e21SWilliam Wang  })
194bf6b6e21SWilliam Wang
1950f22ee7cSWilliam Wang  val data8 = Seq.fill(8)(Module(new MaskedSyncDataModuleTemplate(UInt(8.W), numEntries, numRead, numWrite, numMWrite = blockWords)))
196f02b5115SWilliam Wang  val fwdMask = Reg(Vec(numEntries, UInt(8.W)))
197f02b5115SWilliam Wang  val wordIndex = Reg(Vec(numEntries, UInt((blockOffBits - wordOffBits).W)))
198bf6b6e21SWilliam Wang
199bf6b6e21SWilliam Wang  // read ports
200bf6b6e21SWilliam Wang  for (i <- 0 until numRead) {
2011c2ecc42SWilliam Wang    for (j <- 0 until 8) {
2021c2ecc42SWilliam Wang      data8(j).io.raddr(i) := io.raddr(i)
2031c2ecc42SWilliam Wang    }
2041c2ecc42SWilliam Wang    io.rdata(i) := VecInit((0 until 8).map(j => data8(j).io.rdata(i))).asUInt
205bf6b6e21SWilliam Wang  }
206bf6b6e21SWilliam Wang
207bf6b6e21SWilliam Wang  // below is the write ports (with priorities)
208bf6b6e21SWilliam Wang  for (i <- 0 until numWrite) {
2091c2ecc42SWilliam Wang    // write to data8
2101c2ecc42SWilliam Wang    for (j <- 0 until 8) {
2111c2ecc42SWilliam Wang      data8(j).io.waddr(i) := io.waddr(i)
2121c2ecc42SWilliam Wang      data8(j).io.wdata(i) := io.wdata(i)(8*(j+1)-1, 8*j)
2131c2ecc42SWilliam Wang      data8(j).io.wen(i) := io.wen(i)
214bf6b6e21SWilliam Wang    }
2151c2ecc42SWilliam Wang
2161c2ecc42SWilliam Wang    // write ctrl info
217f02b5115SWilliam Wang    when (io.fwdMaskWen(i)) {
218f02b5115SWilliam Wang      fwdMask(io.waddr(i)) := io.fwdMaskWdata(i)
219bf6b6e21SWilliam Wang    }
220f02b5115SWilliam Wang    when (io.paddrWen(i)) {
221f02b5115SWilliam Wang      wordIndex(io.waddr(i)) := get_word(io.paddrWdata(i))
222f02b5115SWilliam Wang    }
223f02b5115SWilliam Wang  }
224f02b5115SWilliam Wang
2251c2ecc42SWilliam Wang  // write refilled data to data8
226bf6b6e21SWilliam Wang
2271c2ecc42SWilliam Wang  // select refill data
228f02b5115SWilliam Wang  // split dcache result into words
229f02b5115SWilliam Wang  val words = VecInit((0 until blockWords) map { i => io.refillData(DataBits * (i + 1) - 1, DataBits * i)})
2301c2ecc42SWilliam Wang  // select refill data according to wordIndex (paddr)
2311c2ecc42SWilliam Wang  for (i <- 0 until 8) {
2326251d905SWilliam Wang    for (j <- 0 until blockWords) {
2336251d905SWilliam Wang      data8(i).io.mwdata(j) := words(j)(8*(i+1)-1, 8*i)
2341c2ecc42SWilliam Wang    }
2351c2ecc42SWilliam Wang  }
2366251d905SWilliam Wang
2371c2ecc42SWilliam Wang  // gen refill wmask
2386251d905SWilliam Wang  for (j <- 0 until blockWords) {
2396251d905SWilliam Wang    for (k <- 0 until numEntries) {
2406251d905SWilliam Wang      val wordMatch = wordIndex(k) === j.U
2411c2ecc42SWilliam Wang      for (i <- 0 until 8) {
2426251d905SWilliam Wang        data8(i).io.mwmask(j)(k) := wordMatch && io.mwmask(k) && !fwdMask(k)(i)
2436251d905SWilliam Wang      }
244bf6b6e21SWilliam Wang    }
245bf6b6e21SWilliam Wang  }
246bf6b6e21SWilliam Wang
247bf6b6e21SWilliam Wang  // DataModuleTemplate should not be used when there're any write conflicts
248bf6b6e21SWilliam Wang  for (i <- 0 until numWrite) {
249bf6b6e21SWilliam Wang    for (j <- i+1 until numWrite) {
250bf6b6e21SWilliam Wang      assert(!(io.wen(i) && io.wen(j) && io.waddr(i) === io.waddr(j)))
251bf6b6e21SWilliam Wang    }
252bf6b6e21SWilliam Wang  }
253bf6b6e21SWilliam Wang}
2547057673cSWilliam Wang
2552225d46eSJiawei Linclass LoadQueueData(size: Int, wbNumRead: Int, wbNumWrite: Int)(implicit p: Parameters) extends XSModule with HasDCacheParameters with HasCircularQueuePtrHelper {
2567057673cSWilliam Wang  val io = IO(new Bundle() {
2577d91f790SWilliam Wang    val wb = new Bundle() {
2587d91f790SWilliam Wang      val wen = Vec(wbNumWrite, Input(Bool()))
2597d91f790SWilliam Wang      val waddr = Input(Vec(wbNumWrite, UInt(log2Up(size).W)))
2607d91f790SWilliam Wang      val wdata = Input(Vec(wbNumWrite, new LQDataEntry))
2617d91f790SWilliam Wang      val raddr = Input(Vec(wbNumRead, UInt(log2Up(size).W)))
2627d91f790SWilliam Wang      val rdata = Output(Vec(wbNumRead, new LQDataEntry))
2637d91f790SWilliam Wang    }
2647057673cSWilliam Wang    val uncache = new Bundle() {
2657057673cSWilliam Wang      val wen = Input(Bool())
2667d91f790SWilliam Wang      val waddr = Input(UInt(log2Up(size).W))
2677d91f790SWilliam Wang      val wdata = Input(UInt(XLEN.W)) // only write back uncache data
2687d91f790SWilliam Wang      val raddr = Input(UInt(log2Up(size).W))
2697d91f790SWilliam Wang      val rdata = Output(new LQDataEntry)
2707057673cSWilliam Wang    }
2717057673cSWilliam Wang    val refill = new Bundle() {
2727d91f790SWilliam Wang      val valid = Input(Bool())
2737d91f790SWilliam Wang      val paddr = Input(UInt(PAddrBits.W))
2747057673cSWilliam Wang      val data = Input(UInt((cfg.blockBytes * 8).W))
2757d91f790SWilliam Wang      val refillMask = Input(Vec(size, Bool()))
2767d91f790SWilliam Wang      val matchMask = Output(Vec(size, Bool()))
2777057673cSWilliam Wang    }
2787d91f790SWilliam Wang    val violation = Vec(StorePipelineWidth, new Bundle() {
2797d91f790SWilliam Wang      val paddr = Input(UInt(PAddrBits.W))
2807d91f790SWilliam Wang      val mask = Input(UInt(8.W))
2817d91f790SWilliam Wang      val violationMask = Output(Vec(size, Bool()))
2827d91f790SWilliam Wang    })
2837d91f790SWilliam Wang    val debug = Output(Vec(size, new LQDataEntry))
2847057673cSWilliam Wang
2857d91f790SWilliam Wang    def wbWrite(channel: Int, waddr: UInt, wdata: LQDataEntry): Unit = {
2867d91f790SWilliam Wang      require(channel < wbNumWrite && wbNumWrite >= 0)
2877057673cSWilliam Wang      // need extra "this.wb(channel).wen := true.B"
2887d91f790SWilliam Wang      this.wb.waddr(channel) := waddr
2897d91f790SWilliam Wang      this.wb.wdata(channel) := wdata
2907057673cSWilliam Wang    }
2917057673cSWilliam Wang
2927d91f790SWilliam Wang    def uncacheWrite(waddr: UInt, wdata: UInt): Unit = {
2937057673cSWilliam Wang      // need extra "this.uncache.wen := true.B"
2947d91f790SWilliam Wang      this.uncache.waddr := waddr
2957057673cSWilliam Wang      this.uncache.wdata := wdata
2967057673cSWilliam Wang    }
2977057673cSWilliam Wang
2987057673cSWilliam Wang    // def refillWrite(ldIdx: Int): Unit = {
2997057673cSWilliam Wang    // }
3007057673cSWilliam Wang    // use "this.refill.wen(ldIdx) := true.B" instead
3017057673cSWilliam Wang  })
3027057673cSWilliam Wang
303f02b5115SWilliam Wang  // val data = Reg(Vec(size, new LQDataEntry))
304f02b5115SWilliam Wang  // data module
305b5b78226SWilliam Wang  val paddrModule = Module(new LQPaddrModule(size, numRead = 3, numWrite = 2))
306f02b5115SWilliam Wang  val maskModule = Module(new MaskModule(size, numRead = 3, numWrite = 2))
307f02b5115SWilliam Wang  val coredataModule = Module(new CoredataModule(size, numRead = 3, numWrite = 3))
3087057673cSWilliam Wang
309a266fd76SWilliam Wang  // read data
310f02b5115SWilliam Wang  // read port 0 -> wbNumRead-1
311a266fd76SWilliam Wang  (0 until wbNumRead).map(i => {
312f02b5115SWilliam Wang    paddrModule.io.raddr(i) := io.wb.raddr(i)
313f02b5115SWilliam Wang    maskModule.io.raddr(i) := io.wb.raddr(i)
314f02b5115SWilliam Wang    coredataModule.io.raddr(i) := io.wb.raddr(i)
315f02b5115SWilliam Wang
316f02b5115SWilliam Wang    io.wb.rdata(i).paddr := paddrModule.io.rdata(i)
317f02b5115SWilliam Wang    io.wb.rdata(i).mask := maskModule.io.rdata(i)
318f02b5115SWilliam Wang    io.wb.rdata(i).data := coredataModule.io.rdata(i)
319f02b5115SWilliam Wang    io.wb.rdata(i).fwdMask := DontCare
320a266fd76SWilliam Wang  })
321a266fd76SWilliam Wang
322f02b5115SWilliam Wang  // read port wbNumRead
323f02b5115SWilliam Wang  paddrModule.io.raddr(wbNumRead) := io.uncache.raddr
324f02b5115SWilliam Wang  maskModule.io.raddr(wbNumRead) := io.uncache.raddr
325f02b5115SWilliam Wang  coredataModule.io.raddr(wbNumRead) := io.uncache.raddr
326a266fd76SWilliam Wang
327f02b5115SWilliam Wang  io.uncache.rdata.paddr := paddrModule.io.rdata(wbNumRead)
328f02b5115SWilliam Wang  io.uncache.rdata.mask := maskModule.io.rdata(wbNumRead)
329baf8def6SYinan Xu  io.uncache.rdata.data := coredataModule.io.rdata(wbNumRead)
330f02b5115SWilliam Wang  io.uncache.rdata.fwdMask := DontCare
331f02b5115SWilliam Wang
332f02b5115SWilliam Wang  // write data
333f02b5115SWilliam Wang  // write port 0 -> wbNumWrite-1
3347d91f790SWilliam Wang  (0 until wbNumWrite).map(i => {
335f02b5115SWilliam Wang    paddrModule.io.wen(i) := false.B
336f02b5115SWilliam Wang    maskModule.io.wen(i) := false.B
337f02b5115SWilliam Wang    coredataModule.io.wen(i) := false.B
338f02b5115SWilliam Wang    coredataModule.io.fwdMaskWen(i) := false.B
339f02b5115SWilliam Wang    coredataModule.io.paddrWen(i) := false.B
340f02b5115SWilliam Wang
341f02b5115SWilliam Wang    paddrModule.io.waddr(i) := io.wb.waddr(i)
342f02b5115SWilliam Wang    maskModule.io.waddr(i) := io.wb.waddr(i)
343f02b5115SWilliam Wang    coredataModule.io.waddr(i) := io.wb.waddr(i)
344f02b5115SWilliam Wang
345f02b5115SWilliam Wang    paddrModule.io.wdata(i) := io.wb.wdata(i).paddr
346f02b5115SWilliam Wang    maskModule.io.wdata(i) := io.wb.wdata(i).mask
347f02b5115SWilliam Wang    coredataModule.io.wdata(i) := io.wb.wdata(i).data
348f02b5115SWilliam Wang    coredataModule.io.fwdMaskWdata(i) := io.wb.wdata(i).fwdMask.asUInt
349f02b5115SWilliam Wang    coredataModule.io.paddrWdata(i) := io.wb.wdata(i).paddr
350f02b5115SWilliam Wang
3517d91f790SWilliam Wang    when(io.wb.wen(i)){
352f02b5115SWilliam Wang      paddrModule.io.wen(i) := true.B
353f02b5115SWilliam Wang      maskModule.io.wen(i) := true.B
354f02b5115SWilliam Wang      coredataModule.io.wen(i) := true.B
355f02b5115SWilliam Wang      coredataModule.io.fwdMaskWen(i) := true.B
356f02b5115SWilliam Wang      coredataModule.io.paddrWen(i) := true.B
3577057673cSWilliam Wang    }
3587057673cSWilliam Wang  })
3597057673cSWilliam Wang
360f02b5115SWilliam Wang  // write port wbNumWrite
361f02b5115SWilliam Wang  // exceptionModule.io.wen(wbNumWrite) := false.B
362f02b5115SWilliam Wang  coredataModule.io.wen(wbNumWrite) := io.uncache.wen
363f02b5115SWilliam Wang  coredataModule.io.fwdMaskWen(wbNumWrite) := false.B
364f02b5115SWilliam Wang  coredataModule.io.paddrWen(wbNumWrite) := false.B
365f02b5115SWilliam Wang
366f02b5115SWilliam Wang  coredataModule.io.waddr(wbNumWrite) := io.uncache.waddr
367f02b5115SWilliam Wang
368f02b5115SWilliam Wang  coredataModule.io.fwdMaskWdata(wbNumWrite) := DontCare
369f02b5115SWilliam Wang  coredataModule.io.paddrWdata(wbNumWrite) := DontCare
370f02b5115SWilliam Wang  coredataModule.io.wdata(wbNumWrite) := io.uncache.wdata
371f02b5115SWilliam Wang
372f02b5115SWilliam Wang  // mem access violation check, gen violationMask
373f02b5115SWilliam Wang  (0 until StorePipelineWidth).map(i => {
374f02b5115SWilliam Wang    paddrModule.io.violationMdata(i) := io.violation(i).paddr
375f02b5115SWilliam Wang    maskModule.io.violationMdata(i) := io.violation(i).mask
376f02b5115SWilliam Wang    io.violation(i).violationMask := (paddrModule.io.violationMmask(i).asUInt & maskModule.io.violationMmask(i).asUInt).asBools
377f02b5115SWilliam Wang    // VecInit((0 until size).map(j => {
378f02b5115SWilliam Wang      // val addrMatch = io.violation(i).paddr(PAddrBits - 1, 3) === data(j).paddr(PAddrBits - 1, 3)
379f02b5115SWilliam Wang      // val violationVec = (0 until 8).map(k => data(j).mask(k) && io.violation(i).mask(k))
380f02b5115SWilliam Wang      // Cat(violationVec).orR() && addrMatch
381f02b5115SWilliam Wang    // }))
382f02b5115SWilliam Wang  })
3837057673cSWilliam Wang
3847057673cSWilliam Wang  // refill missed load
3857057673cSWilliam Wang  def mergeRefillData(refill: UInt, fwd: UInt, fwdMask: UInt): UInt = {
3867057673cSWilliam Wang    val res = Wire(Vec(8, UInt(8.W)))
3877057673cSWilliam Wang    (0 until 8).foreach(i => {
3887057673cSWilliam Wang      res(i) := Mux(fwdMask(i), fwd(8 * (i + 1) - 1, 8 * i), refill(8 * (i + 1) - 1, 8 * i))
3897057673cSWilliam Wang    })
3907057673cSWilliam Wang    res.asUInt
3917057673cSWilliam Wang  }
3927057673cSWilliam Wang
3937d91f790SWilliam Wang  // gen paddr match mask
394f02b5115SWilliam Wang  paddrModule.io.refillMdata := io.refill.paddr
3957057673cSWilliam Wang  (0 until size).map(i => {
396f02b5115SWilliam Wang    io.refill.matchMask := paddrModule.io.refillMmask
397f02b5115SWilliam Wang    // io.refill.matchMask(i) := get_block_addr(data(i).paddr) === get_block_addr(io.refill.paddr)
3987d91f790SWilliam Wang  })
3997d91f790SWilliam Wang
4007d91f790SWilliam Wang  // refill data according to matchMask, refillMask and refill.valid
401f02b5115SWilliam Wang  coredataModule.io.refillData := io.refill.data
4027d91f790SWilliam Wang  (0 until size).map(i => {
403f02b5115SWilliam Wang    coredataModule.io.mwmask(i) := io.refill.valid && io.refill.matchMask(i) && io.refill.refillMask(i)
4047d91f790SWilliam Wang  })
4057d91f790SWilliam Wang
4067d91f790SWilliam Wang  // debug data read
407f02b5115SWilliam Wang  io.debug := DontCare
4087057673cSWilliam Wang}
409