Lsroq.scala 32.8 KB
Newer Older
Y
Yinan Xu 已提交
1
package xiangshan.mem
W
William Wang 已提交
2 3 4

import chisel3._
import chisel3.util._
5
import utils._
Y
Yinan Xu 已提交
6 7
import xiangshan._
import xiangshan.cache._
8
import xiangshan.cache.{DCacheWordIO, DCacheLineIO, TlbRequestIO, MemoryOpConstants}
9
import xiangshan.backend.LSUOpType
L
linjiawei 已提交
10
import xiangshan.backend.fu.fpu.boxF32ToF64
Y
Yinan Xu 已提交
11
import xiangshan.backend.roq.RoqPtr
W
William Wang 已提交
12 13

class LsRoqEntry extends XSBundle {
W
William Wang 已提交
14
  val vaddr = UInt(VAddrBits.W) // TODO: need opt
W
William Wang 已提交
15
  val paddr = UInt(PAddrBits.W)
W
William Wang 已提交
16
  val mask = UInt(8.W)
W
William Wang 已提交
17
  val data = UInt(XLEN.W)
18
  val exception = UInt(16.W) // TODO: opt size
W
William Wang 已提交
19
  val mmio = Bool()
20 21
  val fwdMask = Vec(8, Bool())
  val fwdData = Vec(8, UInt(8.W))
W
William Wang 已提交
22 23
}

24 25 26 27 28 29
// inflight miss block reqs
class InflightBlockInfo extends XSBundle {
  val block_addr = UInt(PAddrBits.W)
  val valid = Bool()
}

Y
Yinan Xu 已提交
30
// Load/Store Roq (Lsroq) for XiangShan Out of Order LSU
Y
Yinan Xu 已提交
31
class Lsroq extends XSModule with HasDCacheParameters with HasCircularQueuePtrHelper{
W
William Wang 已提交
32 33
  val io = IO(new Bundle() {
    val dp1Req = Vec(RenameWidth, Flipped(DecoupledIO(new MicroOp)))
Y
Yinan Xu 已提交
34
    val lsroqIdxs = Output(Vec(RenameWidth, UInt(LsroqIdxWidth.W)))
35
    val oldestStore = Output(Valid(new RoqPtr))
W
William Wang 已提交
36
    val brqRedirect = Input(Valid(new Redirect))
W
William Wang 已提交
37 38
    val loadIn = Vec(LoadPipelineWidth, Flipped(Valid(new LsPipelineBundle)))
    val storeIn = Vec(StorePipelineWidth, Flipped(Valid(new LsPipelineBundle)))
39
    val sbuffer = Vec(StorePipelineWidth, Decoupled(new DCacheWordReq))
W
William Wang 已提交
40 41
    val ldout = Vec(2, DecoupledIO(new ExuOutput)) // writeback store
    val stout = Vec(2, DecoupledIO(new ExuOutput)) // writeback store
W
William Wang 已提交
42
    val forward = Vec(LoadPipelineWidth, Flipped(new LoadForwardQueryIO))
43
    val commits = Flipped(Vec(CommitWidth, Valid(new RoqCommit)))
W
William Wang 已提交
44
    val rollback = Output(Valid(new Redirect))
45 46
    val dcache = new DCacheLineIO
    val uncache = new DCacheWordIO
Y
Yinan Xu 已提交
47
    val roqDeqPtr = Input(new RoqPtr)
48
    val exceptionAddr = new ExceptionAddrIO
49
    // val refill = Flipped(Valid(new DCacheLineReq ))
W
William Wang 已提交
50
  })
51
  
Y
Yinan Xu 已提交
52 53 54 55 56 57 58 59
  val uop = Reg(Vec(LsroqSize, new MicroOp))
  val data = Reg(Vec(LsroqSize, new LsRoqEntry))
  val allocated = RegInit(VecInit(List.fill(LsroqSize)(false.B))) // lsroq entry has been allocated
  val valid = RegInit(VecInit(List.fill(LsroqSize)(false.B))) // data is valid
  val writebacked = RegInit(VecInit(List.fill(LsroqSize)(false.B))) // inst has been writebacked to CDB
  val commited = Reg(Vec(LsroqSize, Bool())) // inst has been writebacked to CDB
  val store = Reg(Vec(LsroqSize, Bool())) // inst is a store inst
  val miss = Reg(Vec(LsroqSize, Bool())) // load inst missed, waiting for miss queue to accept miss request
W
William Wang 已提交
60 61
  val listening = Reg(Vec(LsroqSize, Bool())) // waiting for refill result
  val pending = Reg(Vec(LsroqSize, Bool())) // mmio pending: inst is an mmio inst, it will not be executed until it reachs the end of roq
62
  
Y
Yinan Xu 已提交
63 64 65 66
  val ringBufferHeadExtended = RegInit(0.U(LsroqIdxWidth.W))
  val ringBufferTailExtended = RegInit(0.U(LsroqIdxWidth.W))
  val ringBufferHead = ringBufferHeadExtended(InnerLsroqIdxWidth - 1, 0)
  val ringBufferTail = ringBufferTailExtended(InnerLsroqIdxWidth - 1, 0)
67 68 69
  val ringBufferSameFlag = ringBufferHeadExtended(InnerLsroqIdxWidth) === ringBufferTailExtended(InnerLsroqIdxWidth)
  val ringBufferEmpty = ringBufferHead === ringBufferTail && ringBufferSameFlag
  val ringBufferFull = ringBufferHead === ringBufferTail && !ringBufferSameFlag
W
William Wang 已提交
70
  val ringBufferAllowin = !ringBufferFull
71
  
72 73 74
  val storeCommit = (0 until CommitWidth).map(i => io.commits(i).valid && !io.commits(i).bits.isWalk && io.commits(i).bits.uop.ctrl.commitType === CommitType.STORE)
  val loadCommit = (0 until CommitWidth).map(i => io.commits(i).valid && !io.commits(i).bits.isWalk && io.commits(i).bits.uop.ctrl.commitType === CommitType.LOAD)
  val mcommitIdx = (0 until CommitWidth).map(i => io.commits(i).bits.uop.lsroqIdx(InnerLsroqIdxWidth-1,0))
75 76 77 78 79 80

  val tailMask = (((1.U((LsroqSize + 1).W)) << ringBufferTail).asUInt - 1.U)(LsroqSize - 1, 0)
  val headMask = (((1.U((LsroqSize + 1).W)) << ringBufferHead).asUInt - 1.U)(LsroqSize - 1, 0)
  val enqDeqMask1 = tailMask ^ headMask
  val enqDeqMask = Mux(ringBufferSameFlag, enqDeqMask1, ~enqDeqMask1)

81
  // TODO: misc arbitor
82

W
William Wang 已提交
83 84 85 86
  // Enqueue at dispatch
  val validDispatch = VecInit((0 until RenameWidth).map(io.dp1Req(_).valid)).asUInt
  XSDebug("(ready, valid): ")
  for (i <- 0 until RenameWidth) {
L
LinJiawei 已提交
87
    val offset = if (i == 0) 0.U else PopCount(validDispatch(i - 1, 0))
Y
Yinan Xu 已提交
88 89
    val lsroqIdx = ringBufferHeadExtended + offset
    val index = lsroqIdx(InnerLsroqIdxWidth - 1, 0)
L
LinJiawei 已提交
90
    when(io.dp1Req(i).fire()) {
Y
Yinan Xu 已提交
91 92 93 94 95 96 97 98 99 100
      uop(index) := io.dp1Req(i).bits
      allocated(index) := true.B
      valid(index) := false.B
      writebacked(index) := false.B
      commited(index) := false.B
      store(index) := false.B
      miss(index) := false.B
      listening(index) := false.B
      pending(index) := false.B
      // data(index).bwdMask := 0.U(8.W).asBools
W
William Wang 已提交
101
    }
L
LinJiawei 已提交
102
    if (i == 0) {
Y
Yinan Xu 已提交
103
      io.dp1Req(i).ready := ringBufferAllowin && !allocated(index)
L
LinJiawei 已提交
104
    } else {
Y
Yinan Xu 已提交
105
      io.dp1Req(i).ready := ringBufferAllowin && !allocated(index) && io.dp1Req(i - 1).ready
106
    }
Y
Yinan Xu 已提交
107
    io.lsroqIdxs(i) := lsroqIdx
W
William Wang 已提交
108 109 110 111 112
    XSDebug(false, true.B, "(%d, %d) ", io.dp1Req(i).ready, io.dp1Req(i).valid)
  }
  XSDebug(false, true.B, "\n")

  val firedDispatch = VecInit((0 until CommitWidth).map(io.dp1Req(_).fire())).asUInt
L
LinJiawei 已提交
113
  when(firedDispatch.orR) {
W
William Wang 已提交
114
    ringBufferHeadExtended := ringBufferHeadExtended + PopCount(firedDispatch)
Y
Yinan Xu 已提交
115
    XSInfo("dispatched %d insts to lsroq\n", PopCount(firedDispatch))
W
William Wang 已提交
116 117 118 119
  }

  // writeback load
  (0 until LoadPipelineWidth).map(i => {
L
LinJiawei 已提交
120 121
    when(io.loadIn(i).fire()) {
      when(io.loadIn(i).bits.miss) {
122
        XSInfo(io.loadIn(i).valid, "load miss write to lsroq idx %d pc 0x%x vaddr %x paddr %x data %x mask %x forwardData %x forwardMask: %x mmio %x roll %x exc %x\n",
Y
Yinan Xu 已提交
123
          io.loadIn(i).bits.uop.lsroqIdx,
W
William Wang 已提交
124 125 126 127
          io.loadIn(i).bits.uop.cf.pc,
          io.loadIn(i).bits.vaddr,
          io.loadIn(i).bits.paddr,
          io.loadIn(i).bits.data,
128 129 130
          io.loadIn(i).bits.mask,
          io.loadIn(i).bits.forwardData.asUInt,
          io.loadIn(i).bits.forwardMask.asUInt,
W
William Wang 已提交
131
          io.loadIn(i).bits.mmio,
132 133 134 135 136
          io.loadIn(i).bits.rollback,
          io.loadIn(i).bits.uop.cf.exceptionVec.asUInt
          )
        }.otherwise {
          XSInfo(io.loadIn(i).valid, "load hit write to cbd idx %d pc 0x%x vaddr %x paddr %x data %x mask %x forwardData %x forwardMask: %x mmio %x roll %x exc %x\n",
Y
Yinan Xu 已提交
137
          io.loadIn(i).bits.uop.lsroqIdx,
138 139 140 141
          io.loadIn(i).bits.uop.cf.pc,
          io.loadIn(i).bits.vaddr,
          io.loadIn(i).bits.paddr,
          io.loadIn(i).bits.data,
142 143 144
          io.loadIn(i).bits.mask,
          io.loadIn(i).bits.forwardData.asUInt,
          io.loadIn(i).bits.forwardMask.asUInt,
145
          io.loadIn(i).bits.mmio,
146 147 148 149 150 151 152 153
          io.loadIn(i).bits.rollback,
          io.loadIn(i).bits.uop.cf.exceptionVec.asUInt
          )
        }
        valid(io.loadIn(i).bits.uop.lsroqIdx) := !io.loadIn(i).bits.miss && !io.loadIn(i).bits.mmio
        writebacked(io.loadIn(i).bits.uop.lsroqIdx) := !io.loadIn(i).bits.miss && !io.loadIn(i).bits.mmio
        // allocated(io.loadIn(i).bits.uop.lsroqIdx) := io.loadIn(i).bits.miss // if hit, lsroq entry can be recycled
        data(io.loadIn(i).bits.uop.lsroqIdx).paddr := io.loadIn(i).bits.paddr
W
William Wang 已提交
154
        data(io.loadIn(i).bits.uop.lsroqIdx).vaddr := io.loadIn(i).bits.vaddr
155 156 157 158 159 160
        data(io.loadIn(i).bits.uop.lsroqIdx).mask := io.loadIn(i).bits.mask
        data(io.loadIn(i).bits.uop.lsroqIdx).data := io.loadIn(i).bits.data // for mmio / misc / debug
        data(io.loadIn(i).bits.uop.lsroqIdx).mmio := io.loadIn(i).bits.mmio
        data(io.loadIn(i).bits.uop.lsroqIdx).fwdMask := io.loadIn(i).bits.forwardMask
        data(io.loadIn(i).bits.uop.lsroqIdx).fwdData := io.loadIn(i).bits.forwardData
        data(io.loadIn(i).bits.uop.lsroqIdx).exception := io.loadIn(i).bits.uop.cf.exceptionVec.asUInt
161 162 163
        val dcacheMissed = io.loadIn(i).bits.miss && !io.loadIn(i).bits.mmio
        miss(io.loadIn(i).bits.uop.lsroqIdx) := dcacheMissed
        listening(io.loadIn(i).bits.uop.lsroqIdx) := dcacheMissed
164 165
        store(io.loadIn(i).bits.uop.lsroqIdx) := false.B
        pending(io.loadIn(i).bits.uop.lsroqIdx) := io.loadIn(i).bits.mmio
166
      }
167
    })
168 169 170 171 172 173

    // find first store req that has not been writebacked
    val storeNotWritebacked = VecInit((0 until LsroqSize).map(i => store(i) && !writebacked(i)))
    val firstStore = getFirstOne(storeNotWritebacked, tailMask)
    io.oldestStore.valid := false.B
    io.oldestStore.bits := DontCare
174 175 176 177 178
    // writeback store
    (0 until StorePipelineWidth).map(i => {
      when(io.storeIn(i).fire()) {
        valid(io.storeIn(i).bits.uop.lsroqIdx) := !io.storeIn(i).bits.mmio
        data(io.storeIn(i).bits.uop.lsroqIdx).paddr := io.storeIn(i).bits.paddr
W
William Wang 已提交
179
        data(io.storeIn(i).bits.uop.lsroqIdx).vaddr := io.storeIn(i).bits.vaddr
180 181 182 183 184 185 186 187
        data(io.storeIn(i).bits.uop.lsroqIdx).mask := io.storeIn(i).bits.mask
        data(io.storeIn(i).bits.uop.lsroqIdx).data := io.storeIn(i).bits.data
        data(io.storeIn(i).bits.uop.lsroqIdx).mmio := io.storeIn(i).bits.mmio
        data(io.storeIn(i).bits.uop.lsroqIdx).exception := io.storeIn(i).bits.uop.cf.exceptionVec.asUInt
        miss(io.storeIn(i).bits.uop.lsroqIdx) := io.storeIn(i).bits.miss
        store(io.storeIn(i).bits.uop.lsroqIdx) := true.B
        pending(io.storeIn(i).bits.uop.lsroqIdx) := io.storeIn(i).bits.mmio
        XSInfo("store write to lsroq idx %d pc 0x%x vaddr %x paddr %x data %x miss %x mmio %x roll %x exc %x\n",
188 189 190 191 192 193 194 195 196
          io.storeIn(i).bits.uop.lsroqIdx(InnerLsroqIdxWidth - 1, 0),
          io.storeIn(i).bits.uop.cf.pc,
          io.storeIn(i).bits.vaddr,
          io.storeIn(i).bits.paddr,
          io.storeIn(i).bits.data,
          io.storeIn(i).bits.miss,
          io.storeIn(i).bits.mmio,
          io.storeIn(i).bits.rollback,
          io.storeIn(i).bits.uop.cf.exceptionVec.asUInt
197
        )
198 199 200 201
        when (io.storeIn(i).bits.uop.lsroqIdx(InnerLsroqIdxWidth - 1, 0) === firstStore) {
          io.oldestStore.valid := true.B
          io.oldestStore.bits := io.storeIn(i).bits.uop.roqIdx
        }
202
      }
W
William Wang 已提交
203 204
  })

W
William Wang 已提交
205
  // cache miss request
206 207 208 209
  val inflightReqs = RegInit(VecInit(Seq.fill(cfg.nLoadMissEntries)(0.U.asTypeOf(new InflightBlockInfo))))
  val inflightReqFull = inflightReqs.map(req => req.valid).reduce(_&&_)
  val reqBlockIndex = PriorityEncoder(~VecInit(inflightReqs.map(req => req.valid)).asUInt)

W
William Wang 已提交
210
  val missRefillSelVec = VecInit(
211 212 213 214 215
    (0 until LsroqSize).map{ i =>
      val inflight = inflightReqs.map(req => req.valid && req.block_addr === get_block_addr(data(i).paddr)).reduce(_||_)
      allocated(i) && miss(i) && !inflight
    })

216
  val missRefillSel = getFirstOne(missRefillSelVec, tailMask)
217
  val missRefillBlockAddr = get_block_addr(data(missRefillSel).paddr)
218 219
  io.dcache.req.valid := missRefillSelVec.asUInt.orR
  io.dcache.req.bits.cmd := MemoryOpConstants.M_XRD
220
  io.dcache.req.bits.addr := missRefillBlockAddr
221
  io.dcache.req.bits.data := DontCare
222
  io.dcache.req.bits.mask := DontCare
223

224
  io.dcache.req.bits.meta.id       := DontCare // TODO: // FIXME
225
  io.dcache.req.bits.meta.vaddr    := DontCare // data(missRefillSel).vaddr
226
  io.dcache.req.bits.meta.paddr    := missRefillBlockAddr
227 228 229
  io.dcache.req.bits.meta.uop      := uop(missRefillSel)
  io.dcache.req.bits.meta.mmio     := false.B // data(missRefillSel).mmio
  io.dcache.req.bits.meta.tlb_miss := false.B
230
  io.dcache.req.bits.meta.mask     := DontCare
231 232 233 234 235 236 237
  io.dcache.req.bits.meta.replay   := false.B

  io.dcache.resp.ready := true.B

  assert(!(data(missRefillSel).mmio && io.dcache.req.valid))

  when(io.dcache.req.fire()) {
W
William Wang 已提交
238 239
    miss(missRefillSel) := false.B
    listening(missRefillSel) := true.B
240 241 242 243 244

    // mark this block as inflight
    inflightReqs(reqBlockIndex).valid := true.B
    inflightReqs(reqBlockIndex).block_addr := missRefillBlockAddr
    assert(!inflightReqs(reqBlockIndex).valid)
W
William Wang 已提交
245 246
  }

247 248 249 250 251 252 253 254 255 256 257
  when(io.dcache.resp.fire()) {
    val inflight = inflightReqs.map(req => req.valid && req.block_addr === get_block_addr(io.dcache.resp.bits.meta.paddr)).reduce(_||_)
    assert(inflight)
    for (i <- 0 until cfg.nLoadMissEntries) {
      when (inflightReqs(i).valid && inflightReqs(i).block_addr === get_block_addr(io.dcache.resp.bits.meta.paddr)) {
        inflightReqs(i).valid := false.B
      }
    }
  }


258
  when(io.dcache.req.fire()){
Y
Yinan Xu 已提交
259 260 261 262
    XSDebug("miss req: pc:0x%x roqIdx:%d lsroqIdx:%d (p)addr:0x%x vaddr:0x%x\n",
      io.dcache.req.bits.meta.uop.cf.pc, io.dcache.req.bits.meta.uop.roqIdx.asUInt, io.dcache.req.bits.meta.uop.lsroqIdx,
      io.dcache.req.bits.addr, io.dcache.req.bits.meta.vaddr
    )
263 264 265
  }

  when(io.dcache.resp.fire()){
Y
Yinan Xu 已提交
266 267 268 269
    XSDebug("miss resp: pc:0x%x roqIdx:%d lsroqIdx:%d (p)addr:0x%x data %x\n",
      io.dcache.resp.bits.meta.uop.cf.pc, io.dcache.resp.bits.meta.uop.roqIdx.asUInt, io.dcache.resp.bits.meta.uop.lsroqIdx,
      io.dcache.resp.bits.meta.paddr, io.dcache.resp.bits.data
    )
270 271
  }

272
  // Refill 64 bit in a cycle
273
  // Refill data comes back from io.dcache.resp
274 275
  def mergeRefillData(refill: UInt, fwd: UInt, fwdMask: UInt): UInt = {
    val res = Wire(Vec(8, UInt(8.W)))
L
LinJiawei 已提交
276 277
    (0 until 8).foreach(i => {
      res(i) := Mux(fwdMask(i), fwd(8 * (i + 1) - 1, 8 * i), refill(8 * (i + 1) - 1, 8 * i))
278 279
    })
    res.asUInt
W
William Wang 已提交
280 281
  }

Y
Yinan Xu 已提交
282
  (0 until LsroqSize).map(i => {
283 284 285 286 287 288 289 290
    val blockMatch = get_block_addr(data(i).paddr) === io.dcache.resp.bits.meta.paddr
    when(allocated(i) && listening(i) && blockMatch && io.dcache.resp.fire()) {
      // split them into words
      val words = VecInit((0 until blockWords) map { i =>
        io.dcache.resp.bits.data(DataBits * (i + 1) - 1, DataBits * i)
      })

      val refillData = words(get_word(data(i).paddr))
291
      data(i).data := mergeRefillData(refillData, data(i).fwdData.asUInt, data(i).fwdMask.asUInt)
W
William Wang 已提交
292 293
      valid(i) := true.B
      listening(i) := false.B
294
      XSDebug("miss resp: pos %d addr %x data %x + %x(%b)\n", i.U, data(i).paddr, refillData, data(i).fwdData.asUInt, data(i).fwdMask.asUInt) 
W
William Wang 已提交
295 296
    }
  })
W
William Wang 已提交
297 298 299

  // writeback up to 2 missed load insts to CDB
  // just randomly pick 2 missed load (data refilled), write them back to cdb
Y
Yinan Xu 已提交
300
  val loadWbSelVec = VecInit((0 until LsroqSize).map(i => {
W
William Wang 已提交
301
    allocated(i) && valid(i) && !writebacked(i) && !store(i)
L
LinJiawei 已提交
302
  })).asUInt() // use uint instead vec to reduce verilog lines
303
  val loadWbSel = Wire(Vec(LoadPipelineWidth, UInt(log2Up(LsroqSize).W)))
L
LinJiawei 已提交
304 305 306 307
  val lselvec0 = PriorityEncoderOH(loadWbSelVec)
  val lselvec1 = PriorityEncoderOH(loadWbSelVec & (~lselvec0).asUInt)
  loadWbSel(0) := OHToUInt(lselvec0)
  loadWbSel(1) := OHToUInt(lselvec1)
308
  (0 until LoadPipelineWidth).map(i => {
309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326
    // data select
    val rdata = data(loadWbSel(i)).data
    val func = uop(loadWbSel(i)).ctrl.fuOpType
    val raddr = data(loadWbSel(i)).paddr
    val rdataSel = LookupTree(raddr(2, 0), List(
      "b000".U -> rdata(63, 0),
      "b001".U -> rdata(63, 8),
      "b010".U -> rdata(63, 16),
      "b011".U -> rdata(63, 24),
      "b100".U -> rdata(63, 32),
      "b101".U -> rdata(63, 40),
      "b110".U -> rdata(63, 48),
      "b111".U -> rdata(63, 56)
    ))
    val rdataPartialLoad = LookupTree(func, List(
        LSUOpType.lb   -> SignExt(rdataSel(7, 0) , XLEN),
        LSUOpType.lh   -> SignExt(rdataSel(15, 0), XLEN),
        LSUOpType.lw   -> SignExt(rdataSel(31, 0), XLEN),
L
linjiawei 已提交
327
        LSUOpType.flw  -> boxF32ToF64(rdataSel(31, 0)),
328 329 330
        LSUOpType.ld   -> SignExt(rdataSel(63, 0), XLEN),
        LSUOpType.lbu  -> ZeroExt(rdataSel(7, 0) , XLEN),
        LSUOpType.lhu  -> ZeroExt(rdataSel(15, 0), XLEN),
A
Allen 已提交
331
        LSUOpType.lwu  -> ZeroExt(rdataSel(31, 0), XLEN)
332
    ))
W
William Wang 已提交
333
    io.ldout(i).bits.uop := uop(loadWbSel(i))
334
    io.ldout(i).bits.uop.cf.exceptionVec := data(loadWbSel(i)).exception.asBools
L
LinJiawei 已提交
335
    io.ldout(i).bits.uop.lsroqIdx := loadWbSel(i)
336
    io.ldout(i).bits.data := rdataPartialLoad
L
linjiawei 已提交
337
    io.ldout(i).bits.fflags := DontCare
W
William Wang 已提交
338 339 340 341 342
    io.ldout(i).bits.redirectValid := false.B
    io.ldout(i).bits.redirect := DontCare
    io.ldout(i).bits.brUpdate := DontCare
    io.ldout(i).bits.debug.isMMIO := data(loadWbSel(i)).mmio
    io.ldout(i).valid := loadWbSelVec(loadWbSel(i))
L
LinJiawei 已提交
343
    when(io.ldout(i).fire()) {
344
      writebacked(loadWbSel(i)) := true.B
345 346 347 348 349 350 351
      XSInfo(io.loadIn(i).valid, "load miss write to cbd idx %d pc 0x%x paddr %x data %x mmio %x\n",
        io.ldout(i).bits.uop.lsroqIdx,
        io.ldout(i).bits.uop.cf.pc,
        data(loadWbSel(i)).paddr,
        data(loadWbSel(i)).data,
        data(loadWbSel(i)).mmio
      )
W
William Wang 已提交
352 353 354 355
    }
  })

  // writeback up to 2 store insts to CDB
356
  // choose the first two valid store requests from deqPtr
Y
Yinan Xu 已提交
357
  val storeWbSelVec = VecInit((0 until LsroqSize).map(i => {
W
William Wang 已提交
358
    allocated(i) && valid(i) && !writebacked(i) && store(i)
359
  }))
Y
Yinan Xu 已提交
360
  val storeWbSel = Wire(Vec(StorePipelineWidth, UInt(log2Up(LsroqSize).W)))
361
  val storeWbValid = Wire(Vec(StorePipelineWidth, Bool()))
362
  storeWbSel(0) := getFirstOne(storeWbSelVec, tailMask)
363 364
  val firstSelMask = UIntToOH(storeWbSel(0))
  val secondWbSelVec = VecInit((0 until LsroqSize).map(i => storeWbSelVec(i) && !firstSelMask(i)))
365
  storeWbSel(1) := getFirstOne(secondWbSelVec, tailMask)
366 367
  storeWbValid(0) := Cat(storeWbSelVec).orR
  storeWbValid(1) := Cat(secondWbSelVec).orR
W
William Wang 已提交
368 369

  (0 until StorePipelineWidth).map(i => {
W
William Wang 已提交
370
    io.stout(i).bits.uop := uop(storeWbSel(i))
L
LinJiawei 已提交
371
    io.stout(i).bits.uop.lsroqIdx := storeWbSel(i)
372
    io.stout(i).bits.uop.cf.exceptionVec := data(storeWbSel(i)).exception.asBools
W
William Wang 已提交
373
    io.stout(i).bits.data := data(storeWbSel(i)).data
L
linjiawei 已提交
374
    io.stout(i).bits.fflags := DontCare
W
William Wang 已提交
375 376
    io.stout(i).bits.redirectValid := false.B
    io.stout(i).bits.redirect := DontCare
L
LinJiawei 已提交
377
    io.stout(i).bits.brUpdate := DontCare
W
William Wang 已提交
378
    io.stout(i).bits.debug.isMMIO := data(storeWbSel(i)).mmio
379
    io.stout(i).valid := storeWbSelVec(storeWbSel(i)) && storeWbValid(i)
L
LinJiawei 已提交
380
    when(io.stout(i).fire()) {
W
William Wang 已提交
381 382
      writebacked(storeWbSel(i)) := true.B
    }
W
William Wang 已提交
383
  })
W
William Wang 已提交
384 385 386

  // remove retired insts from lsroq, add retired store to sbuffer

W
William Wang 已提交
387
  // move tailPtr
388 389 390
  // allocatedMask: dequeuePtr can go to the next 1-bit
  val allocatedMask = VecInit((0 until LsroqSize).map(i => allocated(i) || !enqDeqMask(i)))
  // find the first one from deqPtr (ringBufferTail)
391
  val nextTail1 = getFirstOneWithFlag(allocatedMask, tailMask, ringBufferTailExtended(InnerLsroqIdxWidth))
392 393
  val nextTail = Mux(Cat(allocatedMask).orR, nextTail1, ringBufferHeadExtended)
  ringBufferTailExtended := nextTail
W
William Wang 已提交
394 395 396

  // send commited store inst to sbuffer
  // select up to 2 writebacked store insts
397 398
  // scommitPending, scommitIn, scommitOut are for debug only
  val commitedStoreQueue = Module(new MIMOQueue(
Y
Yinan Xu 已提交
399 400
    UInt(InnerLsroqIdxWidth.W),
    entries = LsroqSize,
401 402 403 404 405 406
    inCnt = 6,
    outCnt = 2,
    mem = false,
    perf = true
  ))

W
William Wang 已提交
407 408 409 410 411 412
  // scommit counter for debugging
  val scommitPending = RegInit(0.U(log2Up(LsroqSize).W))
  val scommitIn = PopCount(VecInit(storeCommit).asUInt)
  val scommitOut = PopCount(VecInit((0 until 2).map(i => commitedStoreQueue.io.deq(i).fire())).asUInt)
  scommitPending := scommitPending + scommitIn - scommitOut

413 414
  commitedStoreQueue.io.flush := false.B

415
  // When store commited, mark it as commited (will not be influenced by redirect),
Y
Yinan Xu 已提交
416
  // then add store's lsroq ptr into commitedStoreQueue
417
  (0 until CommitWidth).map(i => {
418 419 420
    when(storeCommit(i)) {
      commited(mcommitIdx(i)) := true.B
      XSDebug("store commit %d: idx %d %x\n", i.U, mcommitIdx(i), uop(mcommitIdx(i)).cf.pc)
421
    }
422 423
    commitedStoreQueue.io.enq(i).valid := storeCommit(i)
    commitedStoreQueue.io.enq(i).bits := mcommitIdx(i)
Y
Yinan Xu 已提交
424
    // We assume commitedStoreQueue.io.enq(i).ready === true.B,
425
    // for commitedStoreQueue.size = 64
426
  })
W
William Wang 已提交
427

428 429 430 431 432 433 434 435
  // When load commited, mark it as !allocated, this entry will be recycled later
  (0 until CommitWidth).map(i => {
    when(loadCommit(i)) {
      allocated(mcommitIdx(i)) := false.B
      XSDebug("load commit %d: idx %d %x\n", i.U, mcommitIdx(i), uop(mcommitIdx(i)).cf.pc)
    }
  })

436
  // get no more than 2 commited store from storeCommitedQueue
W
William Wang 已提交
437
  // send selected store inst to sbuffer
W
William Wang 已提交
438
  (0 until 2).map(i => {
439
    val ptr = commitedStoreQueue.io.deq(i).bits
440 441
    val mmio = data(ptr).mmio
    io.sbuffer(i).valid := commitedStoreQueue.io.deq(i).valid && !mmio
442 443
    io.sbuffer(i).bits.cmd  := MemoryOpConstants.M_XWR
    io.sbuffer(i).bits.addr := data(ptr).paddr
W
William Wang 已提交
444 445
    io.sbuffer(i).bits.data := data(ptr).data
    io.sbuffer(i).bits.mask := data(ptr).mask
W
William Wang 已提交
446
    io.sbuffer(i).bits.meta          := DontCare
447 448
    io.sbuffer(i).bits.meta.tlb_miss := false.B
    io.sbuffer(i).bits.meta.uop      := uop(ptr)
449
    io.sbuffer(i).bits.meta.mmio     := mmio
450
    io.sbuffer(i).bits.meta.mask     := data(ptr).mask
W
William Wang 已提交
451

452 453 454 455
    commitedStoreQueue.io.deq(i).ready := io.sbuffer(i).fire() || mmio

    // update lsroq meta if store inst is send to sbuffer
    when(commitedStoreQueue.io.deq(i).valid && (mmio || io.sbuffer(i).ready)) {
456
      allocated(commitedStoreQueue.io.deq(i).bits) := false.B
W
William Wang 已提交
457 458 459
    }
  })

W
William Wang 已提交
460
  // load forward query
461
  // check over all lsroq entries and forward data from the first matched store
W
William Wang 已提交
462 463 464
  (0 until LoadPipelineWidth).map(i => {
    io.forward(i).forwardMask := 0.U(8.W).asBools
    io.forward(i).forwardData := DontCare
465 466 467 468 469 470

    // Compare ringBufferTail (deqPtr) and forward.lsroqIdx, we have two cases:
    // (1) if they have the same flag, we need to check range(tail, lsroqIdx)
    // (2) if they have different flags, we need to check range(tail, lsroqSize) and range(0, lsroqIdx)
    // Forward1: Mux(same_flag, range(tail, lsroqIdx), range(tail, lsroqSize))
    // Forward2: Mux(same_flag, 0.U,                   range(0, lsroqIdx)    )
471
    // i.e. forward1 is the target entries with the same flag bits and forward2 otherwise
L
LinJiawei 已提交
472 473 474 475 476
    val forwardMask1 = WireInit(VecInit(Seq.fill(8)(false.B)))
    val forwardData1 = WireInit(VecInit(Seq.fill(8)(0.U(8.W))))
    val forwardMask2 = WireInit(VecInit(Seq.fill(8)(false.B)))
    val forwardData2 = WireInit(VecInit(Seq.fill(8)(0.U(8.W))))

477 478 479 480 481
    val differentFlag = ringBufferTailExtended(InnerLsroqIdxWidth) =/= io.forward(i).lsroqIdx(InnerLsroqIdxWidth)
    val forwardMask = ((1.U((LsroqSize + 1).W)) << io.forward(i).lsroqIdx(InnerLsroqIdxWidth - 1, 0)).asUInt - 1.U
    val needForward1 = Mux(differentFlag, ~tailMask, tailMask ^ forwardMask)
    val needForward2 = Mux(differentFlag, forwardMask, 0.U(LsroqSize.W))

482 483 484 485 486 487 488
    // entry with larger index should have higher priority since it's data is younger
    for (j <- 0 until LsroqSize) {
      val needCheck = valid(j) && allocated(j) && store(j) &&
        io.forward(i).paddr(PAddrBits - 1, 3) === data(j).paddr(PAddrBits - 1, 3)
      (0 until XLEN / 8).foreach(k => {
        when (needCheck && data(j).mask(k)) {
          when (needForward1(j)) {
L
LinJiawei 已提交
489 490 491
            forwardMask1(k) := true.B
            forwardData1(k) := data(j).data(8 * (k + 1) - 1, 8 * k)
          }
492 493 494 495 496 497 498
          when (needForward2(j)) {
            forwardMask2(k) := true.B
            forwardData2(k) := data(j).data(8 * (k + 1) - 1, 8 * k)
          }
          XSDebug(needForward1(j) || needForward2(j),
            p"forwarding $k-th byte ${Hexadecimal(data(j).data(8 * (k + 1) - 1, 8 * k))} " +
            p"from ptr $j pc ${Hexadecimal(uop(j).cf.pc)}\n")
499 500 501 502
        }
      })
    }

W
William Wang 已提交
503
    // merge forward lookup results
504
    // forward2 is younger than forward1 and should have higher priority
505
    (0 until XLEN / 8).map(k => {
W
William Wang 已提交
506
      io.forward(i).forwardMask(k) := forwardMask1(k) || forwardMask2(k)
507
      io.forward(i).forwardData(k) := Mux(forwardMask2(k), forwardData2(k), forwardData1(k))
W
William Wang 已提交
508
    })
W
William Wang 已提交
509 510
  })

W
William Wang 已提交
511
  // rollback check
W
William Wang 已提交
512 513
  val rollback = Wire(Vec(StorePipelineWidth, Valid(new Redirect)))

514
  def getFirstOne(mask: Vec[Bool], startMask: UInt) = {
515
    val length = mask.length
516
    val highBits = (0 until length).map(i => mask(i) & ~startMask(i))
Y
Yinan Xu 已提交
517 518
    val highBitsUint = Cat(highBits.reverse)
    PriorityEncoder(Mux(highBitsUint.orR(), highBitsUint, mask.asUInt))
519
  }
W
William Wang 已提交
520

521
  def getFirstOneWithFlag(mask: Vec[Bool], startMask: UInt, startFlag: UInt) = {
522
    val length = mask.length
523
    val highBits = (0 until length).map(i => mask(i) & ~startMask(i))
524 525 526 527 528 529
    val highBitsUint = Cat(highBits.reverse)
    val changeDirection = !highBitsUint.orR()
    val index = PriorityEncoder(Mux(!changeDirection, highBitsUint, mask.asUInt))
    Cat(startFlag ^ changeDirection, index)
  }

530 531 532 533
  def getOldestInTwo(valid: Seq[Bool], uop: Seq[MicroOp]) = {
    assert(valid.length == uop.length)
    assert(valid.length == 2)
    Mux(valid(0) && valid(1),
Y
Yinan Xu 已提交
534
      Mux(isAfter(uop(0).roqIdx, uop(1).roqIdx), uop(1), uop(0)),
535 536 537 538 539 540 541 542 543
      Mux(valid(0) && !valid(1), uop(0), uop(1)))
  }

  def getAfterMask(valid: Seq[Bool], uop: Seq[MicroOp]) = {
    assert(valid.length == uop.length)
    val length = valid.length
    (0 until length).map(i => {
      (0 until length).map(j => {
        Mux(valid(i) && valid(j),
Y
Yinan Xu 已提交
544
          isAfter(uop(i).roqIdx, uop(j).roqIdx),
545 546 547 548
          Mux(!valid(i), true.B, false.B))
      })
    })
  }
W
William Wang 已提交
549

Y
Yinan Xu 已提交
550 551 552 553 554 555 556
  def rangeMask(start: UInt, end: UInt): UInt = {
    val startMask = (1.U((LsroqSize + 1).W) << start(InnerLsroqIdxWidth - 1, 0)).asUInt - 1.U
    val endMask = (1.U((LsroqSize + 1).W) << end(InnerLsroqIdxWidth - 1, 0)).asUInt - 1.U
    val xorMask = startMask(LsroqSize - 1, 0) ^ endMask(LsroqSize - 1, 0)
    Mux(start(InnerLsroqIdxWidth) === end(InnerLsroqIdxWidth), xorMask, ~xorMask)
  }

W
William Wang 已提交
557
  // store backward query and rollback
L
LinJiawei 已提交
558 559
  //  val needCheck = Seq.fill(8)(WireInit(true.B))
  (0 until StorePipelineWidth).foreach(i => {
W
William Wang 已提交
560
    rollback(i) := DontCare
561

L
LinJiawei 已提交
562
    when(io.storeIn(i).valid) {
Y
Yinan Xu 已提交
563
      val startIndex = io.storeIn(i).bits.uop.lsroqIdx(InnerLsroqIdxWidth - 1, 0)
564 565 566 567
      val lsroqIdxMask = ((1.U((LsroqSize + 1).W) << startIndex).asUInt - 1.U)(LsroqSize - 1, 0)
      val xorMask = lsroqIdxMask ^ headMask
      val sameFlag = io.storeIn(i).bits.uop.lsroqIdx(InnerLsroqIdxWidth) === ringBufferHeadExtended(InnerLsroqIdxWidth)
      val toEnqPtrMask = Mux(sameFlag, xorMask, ~xorMask)
568
      val lsroqViolationVec = VecInit((0 until LsroqSize).map(j => {
Y
Yinan Xu 已提交
569 570
        val addrMatch = allocated(j) &&
          io.storeIn(i).bits.paddr(PAddrBits - 1, 3) === data(j).paddr(PAddrBits - 1, 3)
571
        val entryNeedCheck = toEnqPtrMask(j) && addrMatch && !store(j) && (valid(j) || listening(j) || miss(j))
Y
Yinan Xu 已提交
572 573 574
        // TODO: update refilled data
        val violationVec = (0 until 8).map(k => data(j).mask(k) && io.storeIn(i).bits.mask(k))
        Cat(violationVec).orR() && entryNeedCheck
575 576
      }))
      val lsroqViolation = lsroqViolationVec.asUInt().orR()
577
      val lsroqViolationIndex = getFirstOne(lsroqViolationVec, lsroqIdxMask)
578
      val lsroqViolationUop = uop(lsroqViolationIndex)
Y
Yinan Xu 已提交
579
      XSDebug(lsroqViolation, p"${Binary(Cat(lsroqViolationVec))}, $startIndex, $lsroqViolationIndex\n")
W
William Wang 已提交
580

W
William Wang 已提交
581
      // when l/s writeback to roq together, check if rollback is needed
582
      val wbViolationVec = VecInit((0 until LoadPipelineWidth).map(j => {
L
LinJiawei 已提交
583
        io.loadIn(j).valid &&
Y
Yinan Xu 已提交
584
          isAfter(io.loadIn(j).bits.uop.roqIdx, io.storeIn(i).bits.uop.roqIdx) &&
L
LinJiawei 已提交
585
          io.storeIn(i).bits.paddr(PAddrBits - 1, 3) === io.loadIn(j).bits.paddr(PAddrBits - 1, 3) &&
586
          (io.storeIn(i).bits.mask & io.loadIn(j).bits.mask).orR
587
      }))
Y
Yinan Xu 已提交
588
      val wbViolation = wbViolationVec.asUInt().orR()
589
      val wbViolationUop = getOldestInTwo(wbViolationVec, io.loadIn.map(_.bits.uop))
Y
Yinan Xu 已提交
590
      XSDebug(wbViolation, p"${Binary(Cat(wbViolationVec))}, $wbViolationUop\n")
L
LinJiawei 已提交
591

592 593
      // check if rollback is needed for load in l1
      val l1ViolationVec = VecInit((0 until LoadPipelineWidth).map(j => {
594
        io.forward(j).valid && // L4 valid\
Y
Yinan Xu 已提交
595
          isAfter(io.forward(j).uop.roqIdx, io.storeIn(i).bits.uop.roqIdx) &&
L
LinJiawei 已提交
596
          io.storeIn(i).bits.paddr(PAddrBits - 1, 3) === io.forward(j).paddr(PAddrBits - 1, 3) &&
597
          (io.storeIn(i).bits.mask & io.forward(j).mask).orR
598
      }))
599 600 601
      val l1Violation = l1ViolationVec.asUInt().orR()
      val l1ViolationUop = getOldestInTwo(l1ViolationVec, io.forward.map(_.uop))
      XSDebug(l1Violation, p"${Binary(Cat(l1ViolationVec))}, $l1ViolationUop\n")
602

603 604
      val rollbackValidVec = Seq(lsroqViolation, wbViolation, l1Violation)
      val rollbackUopVec = Seq(lsroqViolationUop, wbViolationUop, l1ViolationUop)
605 606 607 608 609 610 611
      rollback(i).valid := Cat(rollbackValidVec).orR
      val mask = getAfterMask(rollbackValidVec, rollbackUopVec)
      val oneAfterZero = mask(1)(0)
      val rollbackUop = Mux(oneAfterZero && mask(2)(0),
        rollbackUopVec(0),
        Mux(!oneAfterZero && mask(2)(1), rollbackUopVec(1), rollbackUopVec(2)))
      rollback(i).bits.roqIdx := rollbackUop.roqIdx - 1.U
W
William Wang 已提交
612

613 614 615
      rollback(i).bits.isReplay := true.B
      rollback(i).bits.isMisPred := false.B
      rollback(i).bits.isException := false.B
616
      rollback(i).bits.isFlushPipe := false.B
L
LinJiawei 已提交
617

618 619 620 621 622 623
      XSDebug(
        l1Violation,
        "need rollback (l4 load) pc %x roqidx %d target %x\n",
        io.storeIn(i).bits.uop.cf.pc, io.storeIn(i).bits.uop.roqIdx.asUInt, l1ViolationUop.roqIdx.asUInt
      )

L
LinJiawei 已提交
624
      XSDebug(
Y
Yinan Xu 已提交
625
        lsroqViolation,
Y
Yinan Xu 已提交
626
        "need rollback (ld wb before store) pc %x roqidx %d target %x\n",
Y
Yinan Xu 已提交
627
        io.storeIn(i).bits.uop.cf.pc, io.storeIn(i).bits.uop.roqIdx.asUInt, lsroqViolationUop.roqIdx.asUInt
L
LinJiawei 已提交
628 629 630
      )
      XSDebug(
        wbViolation,
Y
Yinan Xu 已提交
631
        "need rollback (ld/st wb together) pc %x roqidx %d target %x\n",
Y
Yinan Xu 已提交
632
        io.storeIn(i).bits.uop.cf.pc, io.storeIn(i).bits.uop.roqIdx.asUInt, wbViolationUop.roqIdx.asUInt
L
LinJiawei 已提交
633
      )
634
    }.otherwise {
L
LinJiawei 已提交
635
      rollback(i).valid := false.B
636
    }
W
William Wang 已提交
637 638
  })

L
LinJiawei 已提交
639 640 641 642 643
  def rollbackSel(a: Valid[Redirect], b: Valid[Redirect]): ValidIO[Redirect] = {
    Mux(
      a.valid,
      Mux(
        b.valid,
Y
Yinan Xu 已提交
644
        Mux(isAfter(a.bits.roqIdx, b.bits.roqIdx), b, a), // a,b both valid, sel oldest
L
LinJiawei 已提交
645 646 647 648 649 650 651
        a // sel a
      ),
      b // sel b
    )
  }

  io.rollback := ParallelOperation(rollback, rollbackSel)
W
William Wang 已提交
652

W
William Wang 已提交
653 654
  // Memory mapped IO / other uncached operations

655 656
  // setup misc mem access req
  // mask / paddr / data can be get from lsroq.data
L
linjiawei 已提交
657
  val commitType = io.commits(0).bits.uop.ctrl.commitType 
W
William Wang 已提交
658
  io.uncache.req.valid := pending(ringBufferTail) && allocated(ringBufferTail) &&
L
linjiawei 已提交
659
    (commitType === CommitType.STORE || commitType === CommitType.LOAD) && 
L
LinJiawei 已提交
660
    io.roqDeqPtr === uop(ringBufferTail).roqIdx && 
661 662
    !io.commits(0).bits.isWalk

663 664 665 666 667
  io.uncache.req.bits.cmd  := Mux(store(ringBufferTail), MemoryOpConstants.M_XWR, MemoryOpConstants.M_XRD)
  io.uncache.req.bits.addr := data(ringBufferTail).paddr 
  io.uncache.req.bits.data := data(ringBufferTail).data
  io.uncache.req.bits.mask := data(ringBufferTail).mask

668
  io.uncache.req.bits.meta.id       := DontCare // TODO: // FIXME
669 670 671 672 673 674 675 676 677 678 679
  io.uncache.req.bits.meta.vaddr    := DontCare
  io.uncache.req.bits.meta.paddr    := data(ringBufferTail).paddr
  io.uncache.req.bits.meta.uop      := uop(ringBufferTail)
  io.uncache.req.bits.meta.mmio     := true.B // data(ringBufferTail).mmio
  io.uncache.req.bits.meta.tlb_miss := false.B
  io.uncache.req.bits.meta.mask     := data(ringBufferTail).mask
  io.uncache.req.bits.meta.replay   := false.B

  io.uncache.resp.ready := true.B

  when(io.uncache.req.fire()){
680 681
    pending(ringBufferTail) := false.B
  }
W
William Wang 已提交
682

683
  when(io.uncache.resp.fire()){
684
    valid(ringBufferTail) := true.B
685
    data(ringBufferTail).data := io.uncache.resp.bits.data(XLEN-1, 0)
686 687
    // TODO: write back exception info
  }
W
William Wang 已提交
688

689
  when(io.uncache.req.fire()){
L
linjiawei 已提交
690 691 692 693 694 695 696
    XSDebug("uncache req: pc %x addr %x data %x op %x mask %x\n",
      uop(ringBufferTail).cf.pc,
      io.uncache.req.bits.addr,
      io.uncache.req.bits.data,
      io.uncache.req.bits.cmd,
      io.uncache.req.bits.mask
    )
697 698 699 700 701 702
  }

  when(io.uncache.resp.fire()){
    XSDebug("uncache resp: data %x\n", io.dcache.resp.bits.data) 
  }

W
William Wang 已提交
703
  // Read vaddr for mem exception
704
  io.exceptionAddr.vaddr := data(io.exceptionAddr.lsIdx.lsroqIdx(InnerLsroqIdxWidth - 1, 0)).vaddr
W
William Wang 已提交
705

W
William Wang 已提交
706 707
  // misprediction recovery / exception redirect
  // invalidate lsroq term using robIdx
708 709
  val needCancel = Wire(Vec(LsroqSize, Bool()))
  for (i <- 0 until LsroqSize) {
Y
Yinan Xu 已提交
710
    needCancel(i) := uop(i).roqIdx.needFlush(io.brqRedirect) && allocated(i) && !commited(i)
711
    when(needCancel(i)) {
W
William Wang 已提交
712 713 714 715 716 717
      when(io.brqRedirect.bits.isReplay){
        valid(i) := false.B
        store(i) := false.B
        writebacked(i) := false.B
        listening(i) := false.B
        miss(i) := false.B
W
William Wang 已提交
718
        pending(i) := false.B
W
William Wang 已提交
719 720 721 722
      }.otherwise{
        allocated(i) := false.B
      }
    }
723 724 725 726
  }
  when (io.brqRedirect.valid && io.brqRedirect.bits.isMisPred) {
    ringBufferHeadExtended := ringBufferHeadExtended - PopCount(needCancel)
  }
W
William Wang 已提交
727

W
William Wang 已提交
728
  // assert(!io.rollback.valid)
L
LinJiawei 已提交
729
  when(io.rollback.valid) {
Y
Yinan Xu 已提交
730
    XSDebug("Mem rollback: pc %x roqidx %d\n", io.rollback.bits.pc, io.rollback.bits.roqIdx.asUInt)
W
William Wang 已提交
731
  }
W
William Wang 已提交
732 733

  // debug info
Y
Yinan Xu 已提交
734
  XSDebug("head %d:%d tail %d:%d scommit %d\n", ringBufferHeadExtended(InnerLsroqIdxWidth), ringBufferHead, ringBufferTailExtended(InnerLsroqIdxWidth), ringBufferTail, scommitPending)
W
William Wang 已提交
735 736

  def PrintFlag(flag: Bool, name: String): Unit = {
L
LinJiawei 已提交
737
    when(flag) {
W
William Wang 已提交
738
      XSDebug(false, true.B, name)
L
LinJiawei 已提交
739
    }.otherwise {
W
William Wang 已提交
740 741 742 743
      XSDebug(false, true.B, " ")
    }
  }

Y
Yinan Xu 已提交
744
  for (i <- 0 until LsroqSize) {
L
LinJiawei 已提交
745
    if (i % 4 == 0) XSDebug("")
W
William Wang 已提交
746 747
    XSDebug(false, true.B, "%x ", uop(i).cf.pc)
    PrintFlag(allocated(i), "a")
W
William Wang 已提交
748 749
    PrintFlag(allocated(i) && valid(i), "v")
    PrintFlag(allocated(i) && writebacked(i), "w")
750
    PrintFlag(allocated(i) && commited(i), "c")
W
William Wang 已提交
751 752 753
    PrintFlag(allocated(i) && store(i), "s")
    PrintFlag(allocated(i) && miss(i), "m")
    PrintFlag(allocated(i) && listening(i), "l")
W
William Wang 已提交
754
    PrintFlag(allocated(i) && pending(i), "p")
W
William Wang 已提交
755
    XSDebug(false, true.B, " ")
L
LinJiawei 已提交
756
    if (i % 4 == 3) XSDebug(false, true.B, "\n")
W
William Wang 已提交
757
  }
W
William Wang 已提交
758

W
William Wang 已提交
759
}