LSQWrapper.scala 5.2 KB
Newer Older
Y
Yinan Xu 已提交
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18
package xiangshan.mem

import chisel3._
import chisel3.util._
import utils._
import xiangshan._
import xiangshan.cache._
import xiangshan.cache.{DCacheWordIO, DCacheLineIO, TlbRequestIO, MemoryOpConstants}
import xiangshan.backend.LSUOpType
import xiangshan.mem._
import xiangshan.backend.roq.RoqPtr

class ExceptionAddrIO extends XSBundle {
  val lsIdx = Input(new LSIdx)
  val isStore = Input(Bool())
  val vaddr = Output(UInt(VAddrBits.W))
}

W
William Wang 已提交
19 20 21 22 23
class FwdEntry extends XSBundle {
  val mask = Vec(8, Bool())
  val data = Vec(8, UInt(8.W))
}

Y
Yinan Xu 已提交
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 31 32 33 34 35 36
class LsqEnqIO extends XSBundle {
  val canAccept = Output(Bool())
  val needAlloc = Vec(RenameWidth, Input(Bool()))
  val req = Vec(RenameWidth, Flipped(ValidIO(new MicroOp)))
  val resp = Vec(RenameWidth, Output(new LSIdx))
}

Y
Yinan Xu 已提交
37 38 39
// Load / Store Queue Wrapper for XiangShan Out of Order LSU
class LsqWrappper extends XSModule with HasDCacheParameters {
  val io = IO(new Bundle() {
Y
Yinan Xu 已提交
40
    val enq = new LsqEnqIO
Y
Yinan Xu 已提交
41 42 43 44
    val brqRedirect = Input(Valid(new Redirect))
    val loadIn = Vec(LoadPipelineWidth, Flipped(Valid(new LsPipelineBundle)))
    val storeIn = Vec(StorePipelineWidth, Flipped(Valid(new LsPipelineBundle)))
    val sbuffer = Vec(StorePipelineWidth, Decoupled(new DCacheWordReq))
45
    val ldout = Vec(2, DecoupledIO(new ExuOutput)) // writeback int load
46
    val mmioStout = DecoupledIO(new ExuOutput) // writeback uncached store
Y
Yinan Xu 已提交
47
    val forward = Vec(LoadPipelineWidth, Flipped(new LoadForwardQueryIO))
Y
Yinan Xu 已提交
48
    val commits = Flipped(new RoqCommitIO)
Y
Yinan Xu 已提交
49
    val rollback = Output(Valid(new Redirect))
50
    val dcache = Flipped(ValidIO(new Refill))
Y
Yinan Xu 已提交
51 52 53
    val uncache = new DCacheWordIO
    val roqDeqPtr = Input(new RoqPtr)
    val exceptionAddr = new ExceptionAddrIO
W
William Wang 已提交
54
    val sqempty = Output(Bool())
Y
Yinan Xu 已提交
55 56 57 58 59
  })

  val loadQueue = Module(new LoadQueue)
  val storeQueue = Module(new StoreQueue)

60 61 62 63
  // io.enq logic
  // LSQ: send out canAccept when both load queue and store queue are ready
  // Dispatch: send instructions to LSQ only when they are ready
  io.enq.canAccept := loadQueue.io.enq.canAccept && storeQueue.io.enq.canAccept
64 65
  loadQueue.io.enq.sqCanAccept := storeQueue.io.enq.canAccept
  storeQueue.io.enq.lqCanAccept := loadQueue.io.enq.canAccept
66 67
  for (i <- 0 until RenameWidth) {
    val isStore = CommitType.lsInstIsStore(io.enq.req(i).bits.ctrl.commitType)
Y
Yinan Xu 已提交
68 69

    loadQueue.io.enq.needAlloc(i) := io.enq.needAlloc(i) && !isStore
70 71
    loadQueue.io.enq.req(i).valid  := !isStore && io.enq.req(i).valid
    loadQueue.io.enq.req(i).bits  := io.enq.req(i).bits
Y
Yinan Xu 已提交
72 73 74

    storeQueue.io.enq.needAlloc(i) := io.enq.needAlloc(i) && isStore
    storeQueue.io.enq.req(i).valid :=  isStore && io.enq.req(i).valid
75
    storeQueue.io.enq.req(i).bits := io.enq.req(i).bits
Y
Yinan Xu 已提交
76

77 78 79 80
    io.enq.resp(i).lqIdx := loadQueue.io.enq.resp(i)
    io.enq.resp(i).sqIdx := storeQueue.io.enq.resp(i)
  }

Y
Yinan Xu 已提交
81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97
  // load queue wiring
  loadQueue.io.brqRedirect <> io.brqRedirect
  loadQueue.io.loadIn <> io.loadIn
  loadQueue.io.storeIn <> io.storeIn
  loadQueue.io.ldout <> io.ldout
  loadQueue.io.commits <> io.commits
  loadQueue.io.rollback <> io.rollback
  loadQueue.io.dcache <> io.dcache
  loadQueue.io.roqDeqPtr <> io.roqDeqPtr
  loadQueue.io.exceptionAddr.lsIdx := io.exceptionAddr.lsIdx
  loadQueue.io.exceptionAddr.isStore := DontCare

  // store queue wiring
  // storeQueue.io <> DontCare
  storeQueue.io.brqRedirect <> io.brqRedirect
  storeQueue.io.storeIn <> io.storeIn
  storeQueue.io.sbuffer <> io.sbuffer
98
  storeQueue.io.mmioStout <> io.mmioStout
Y
Yinan Xu 已提交
99 100 101 102 103
  storeQueue.io.commits <> io.commits
  storeQueue.io.roqDeqPtr <> io.roqDeqPtr
  storeQueue.io.exceptionAddr.lsIdx := io.exceptionAddr.lsIdx
  storeQueue.io.exceptionAddr.isStore := DontCare

Y
Yinan Xu 已提交
104
  loadQueue.io.load_s1 <> io.forward
Y
Yinan Xu 已提交
105 106
  storeQueue.io.forward <> io.forward // overlap forwardMask & forwardData, DO NOT CHANGE SEQUENCE

W
William Wang 已提交
107 108
  storeQueue.io.sqempty <> io.sqempty

Y
Yinan Xu 已提交
109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152
  io.exceptionAddr.vaddr := Mux(io.exceptionAddr.isStore, storeQueue.io.exceptionAddr.vaddr, loadQueue.io.exceptionAddr.vaddr)

  // naive uncache arbiter
  val s_idle :: s_load :: s_store :: Nil = Enum(3)
  val uncacheState = RegInit(s_idle)

  switch(uncacheState){
    is(s_idle){
      when(io.uncache.req.fire()){
        uncacheState := Mux(loadQueue.io.uncache.req.valid, s_load, s_store)
      }
    }
    is(s_load){
      when(io.uncache.resp.fire()){
        uncacheState := s_idle
      }
    }
    is(s_store){
      when(io.uncache.resp.fire()){
        uncacheState := s_idle
      }
    }
  }

  loadQueue.io.uncache := DontCare
  storeQueue.io.uncache := DontCare
  loadQueue.io.uncache.resp.valid := false.B
  storeQueue.io.uncache.resp.valid := false.B
  when(loadQueue.io.uncache.req.valid){
    io.uncache.req <> loadQueue.io.uncache.req
  }.otherwise{
    io.uncache.req <> storeQueue.io.uncache.req
  }
  when(uncacheState === s_load){
    io.uncache.resp <> loadQueue.io.uncache.resp
  }.otherwise{
    io.uncache.resp <> storeQueue.io.uncache.resp
  }

  assert(!(loadQueue.io.uncache.req.valid && storeQueue.io.uncache.req.valid))
  assert(!(loadQueue.io.uncache.resp.valid && storeQueue.io.uncache.resp.valid))
  assert(!((loadQueue.io.uncache.resp.valid || storeQueue.io.uncache.resp.valid) && uncacheState === s_idle))

}