xref: /XiangShan/src/main/scala/xiangshan/mem/lsqueue/LoadQueueData.scala (revision 7d91f790aaa9c68ba1ab24f6fe1993ad3583bbca)
17057673cSWilliam Wangpackage xiangshan.mem
27057673cSWilliam Wang
37057673cSWilliam Wangimport chisel3._
47057673cSWilliam Wangimport chisel3.util._
57057673cSWilliam Wangimport utils._
67057673cSWilliam Wangimport xiangshan._
77057673cSWilliam Wangimport xiangshan.cache._
87057673cSWilliam Wangimport xiangshan.cache.{DCacheWordIO, DCacheLineIO, TlbRequestIO, MemoryOpConstants}
97057673cSWilliam Wangimport xiangshan.backend.LSUOpType
107057673cSWilliam Wangimport xiangshan.mem._
117057673cSWilliam Wangimport xiangshan.backend.roq.RoqPtr
127057673cSWilliam Wang
137057673cSWilliam Wangclass LQDataEntry extends XSBundle {
147057673cSWilliam Wang  // val vaddr = UInt(VAddrBits.W)
157057673cSWilliam Wang  val paddr = UInt(PAddrBits.W)
167057673cSWilliam Wang  val mask = UInt(8.W)
177057673cSWilliam Wang  val data = UInt(XLEN.W)
187057673cSWilliam Wang  val exception = UInt(16.W) // TODO: opt size
197057673cSWilliam Wang  val fwdMask = Vec(8, Bool())
207057673cSWilliam Wang}
217057673cSWilliam Wang
227057673cSWilliam Wang
23*7d91f790SWilliam Wangclass LoadQueueData(size: Int, wbNumRead: Int, wbNumWrite: Int) extends XSModule with HasDCacheParameters with HasCircularQueuePtrHelper {
247057673cSWilliam Wang  val io = IO(new Bundle() {
25*7d91f790SWilliam Wang    val wb = new Bundle() {
26*7d91f790SWilliam Wang      val wen = Vec(wbNumWrite, Input(Bool()))
27*7d91f790SWilliam Wang      val waddr = Input(Vec(wbNumWrite, UInt(log2Up(size).W)))
28*7d91f790SWilliam Wang      val wdata = Input(Vec(wbNumWrite, new LQDataEntry))
29*7d91f790SWilliam Wang      val raddr = Input(Vec(wbNumRead, UInt(log2Up(size).W)))
30*7d91f790SWilliam Wang      val rdata = Output(Vec(wbNumRead, new LQDataEntry))
31*7d91f790SWilliam Wang    }
327057673cSWilliam Wang    val uncache = new Bundle() {
337057673cSWilliam Wang      val wen = Input(Bool())
34*7d91f790SWilliam Wang      val waddr = Input(UInt(log2Up(size).W))
35*7d91f790SWilliam Wang      val wdata = Input(UInt(XLEN.W)) // only write back uncache data
36*7d91f790SWilliam Wang      val raddr = Input(UInt(log2Up(size).W))
37*7d91f790SWilliam Wang      val rdata = Output(new LQDataEntry)
387057673cSWilliam Wang    }
397057673cSWilliam Wang    val refill = new Bundle() {
40*7d91f790SWilliam Wang      val valid = Input(Bool())
41*7d91f790SWilliam Wang      val paddr = Input(UInt(PAddrBits.W))
427057673cSWilliam Wang      val data = Input(UInt((cfg.blockBytes * 8).W))
43*7d91f790SWilliam Wang      val refillMask = Input(Vec(size, Bool()))
44*7d91f790SWilliam Wang      val matchMask = Output(Vec(size, Bool()))
457057673cSWilliam Wang    }
46*7d91f790SWilliam Wang    val violation = Vec(StorePipelineWidth, new Bundle() {
47*7d91f790SWilliam Wang      val paddr = Input(UInt(PAddrBits.W))
48*7d91f790SWilliam Wang      val mask = Input(UInt(8.W))
49*7d91f790SWilliam Wang      val violationMask = Output(Vec(size, Bool()))
50*7d91f790SWilliam Wang    })
51*7d91f790SWilliam Wang    val debug = Output(Vec(size, new LQDataEntry))
527057673cSWilliam Wang
53*7d91f790SWilliam Wang    def wbWrite(channel: Int, waddr: UInt, wdata: LQDataEntry): Unit = {
54*7d91f790SWilliam Wang      require(channel < wbNumWrite && wbNumWrite >= 0)
557057673cSWilliam Wang      // need extra "this.wb(channel).wen := true.B"
56*7d91f790SWilliam Wang      this.wb.waddr(channel) := waddr
57*7d91f790SWilliam Wang      this.wb.wdata(channel) := wdata
587057673cSWilliam Wang    }
597057673cSWilliam Wang
60*7d91f790SWilliam Wang    def uncacheWrite(waddr: UInt, wdata: UInt): Unit = {
617057673cSWilliam Wang      // need extra "this.uncache.wen := true.B"
62*7d91f790SWilliam Wang      this.uncache.waddr := waddr
637057673cSWilliam Wang      this.uncache.wdata := wdata
647057673cSWilliam Wang    }
657057673cSWilliam Wang
667057673cSWilliam Wang    // def refillWrite(ldIdx: Int): Unit = {
677057673cSWilliam Wang    // }
687057673cSWilliam Wang    // use "this.refill.wen(ldIdx) := true.B" instead
697057673cSWilliam Wang  })
707057673cSWilliam Wang
717057673cSWilliam Wang  io := DontCare
727057673cSWilliam Wang
737057673cSWilliam Wang  val data = Reg(Vec(size, new LQDataEntry))
747057673cSWilliam Wang
757057673cSWilliam Wang  // writeback to lq/sq
76*7d91f790SWilliam Wang  (0 until wbNumWrite).map(i => {
77*7d91f790SWilliam Wang    when(io.wb.wen(i)){
78*7d91f790SWilliam Wang      data(io.wb.waddr(i)) := io.wb.wdata(i)
797057673cSWilliam Wang    }
807057673cSWilliam Wang  })
817057673cSWilliam Wang
827057673cSWilliam Wang  when(io.uncache.wen){
83*7d91f790SWilliam Wang    data(io.uncache.waddr).data := io.uncache.wdata
847057673cSWilliam Wang  }
857057673cSWilliam Wang
867057673cSWilliam Wang  // refill missed load
877057673cSWilliam Wang  def mergeRefillData(refill: UInt, fwd: UInt, fwdMask: UInt): UInt = {
887057673cSWilliam Wang    val res = Wire(Vec(8, UInt(8.W)))
897057673cSWilliam Wang    (0 until 8).foreach(i => {
907057673cSWilliam Wang      res(i) := Mux(fwdMask(i), fwd(8 * (i + 1) - 1, 8 * i), refill(8 * (i + 1) - 1, 8 * i))
917057673cSWilliam Wang    })
927057673cSWilliam Wang    res.asUInt
937057673cSWilliam Wang  }
947057673cSWilliam Wang
957057673cSWilliam Wang  // split dcache result into words
967057673cSWilliam Wang  val words = VecInit((0 until blockWords) map { i => io.refill.data(DataBits * (i + 1) - 1, DataBits * i)})
977057673cSWilliam Wang
98*7d91f790SWilliam Wang  // gen paddr match mask
997057673cSWilliam Wang  (0 until size).map(i => {
100*7d91f790SWilliam Wang    io.refill.matchMask(i) := get_block_addr(data(i).paddr) === get_block_addr(io.refill.paddr)
101*7d91f790SWilliam Wang  })
102*7d91f790SWilliam Wang
103*7d91f790SWilliam Wang  // refill data according to matchMask, refillMask and refill.valid
104*7d91f790SWilliam Wang  (0 until size).map(i => {
105*7d91f790SWilliam Wang    when(io.refill.valid && io.refill.matchMask(i) && io.refill.refillMask(i)){
1067057673cSWilliam Wang      val refillData = words(get_word(data(i).paddr))
1077057673cSWilliam Wang      data(i).data := mergeRefillData(refillData, data(i).data.asUInt, data(i).fwdMask.asUInt)
1087057673cSWilliam Wang      XSDebug("miss resp: pos %d addr %x data %x + %x(%b)\n", i.U, data(i).paddr, refillData, data(i).data.asUInt, data(i).fwdMask.asUInt)
1097057673cSWilliam Wang    }
1107057673cSWilliam Wang  })
1117057673cSWilliam Wang
112*7d91f790SWilliam Wang  // mem access violation check, gen violationMask
113*7d91f790SWilliam Wang  (0 until StorePipelineWidth).map(i => {
114*7d91f790SWilliam Wang    io.violation(i).violationMask := VecInit((0 until size).map(j => {
115*7d91f790SWilliam Wang      val addrMatch = io.violation(i).paddr(PAddrBits - 1, 3) === data(j).paddr(PAddrBits - 1, 3)
116*7d91f790SWilliam Wang      val violationVec = (0 until 8).map(k => data(j).mask(k) && io.violation(i).mask(k))
117*7d91f790SWilliam Wang      Cat(violationVec).orR() && addrMatch
118*7d91f790SWilliam Wang    }))
119*7d91f790SWilliam Wang  })
120*7d91f790SWilliam Wang
121*7d91f790SWilliam Wang  // debug data read
122*7d91f790SWilliam Wang  io.debug := data
1237057673cSWilliam Wang}
124