@@ -26,8 +26,8 @@ class MshrInfoIO(nCores: Int, nMshrs: Int, nWays: Int, indexWidth: Int, tagWidth
2626 val currentTags = Output (Vec (nMshrs, UInt (tagWidth.W )))
2727 val replacementWays = Output (Vec (nMshrs, UInt (log2Up(nWays).W )))
2828 val incidentCoreIds = Output (Vec (nMshrs, UInt (log2Up(nCores).W )))
29- val isCritCores = Output (Vec (nMshrs, Bool ()))
30- val validMSHRs = Output (Vec (nMshrs, Bool ()))
29+ val critMshrs = Output (Vec (nMshrs, Bool ()))
30+ val validMshrs = Output (Vec (nMshrs, Bool ()))
3131 val fullCmds = Output (Vec (nMshrs, Bool ()))
3232 val wrPtr = Output (UInt (log2Ceil(nMshrs).W ))
3333 val elementCnt = Output (UInt (log2Up(nMshrs + 1 ).W ))
@@ -36,7 +36,6 @@ class MshrInfoIO(nCores: Int, nMshrs: Int, nWays: Int, indexWidth: Int, tagWidth
3636class MshrPushIO (nCores : Int , nMshrs : Int , nWays : Int , reqIdWidth : Int , tagWidth : Int , indexWidth : Int , blockOffsetWidth : Int , subBlockWidth : Int ) extends Bundle () {
3737 // For inserting a new MSHR entry
3838 val pushReq = Input (Bool ())
39- val withCmd = Input (Bool ()) // If true, the pushReqEntry will be pushed with a command
4039 val pushReqEntry = new LineRequestIO (nCores, nWays, tagWidth, indexWidth, subBlockWidth)
4140 // For pushing new command into MSHR entry
4241 val pushCmd = Input (Bool ())
@@ -234,7 +233,6 @@ class CmdMshrQueue(nCmds: Int, nCores: Int, nMshrs: Int, reqIdWidth: Int, blockO
234233
235234 val io = IO (new Bundle {
236235 val push = Input (Bool ())
237- val withCmd = Input (Bool ())
238236 val update = Input (Bool ())
239237 val rdPtr = Input (UInt (log2Up(nMshrs).W ))
240238 val wrPtr = Input (UInt (log2Up(nMshrs).W ))
@@ -249,7 +247,7 @@ class CmdMshrQueue(nCmds: Int, nCores: Int, nMshrs: Int, reqIdWidth: Int, blockO
249247 val cntRegs = RegInit (VecInit (Seq .fill(nMshrs)(0 .U ((log2Up(nCmds) + 1 ).W ))))
250248
251249 when(io.push) {
252- cntRegs(io.wrPtr) := Mux (io.withCmd, 1 .U , 0 . U )
250+ cntRegs(io.wrPtr) := 1 .U
253251 }.elsewhen(io.update) {
254252 cntRegs(io.updtPtr) := cntRegs(io.updtPtr) + 1 .U
255253 }
@@ -260,7 +258,7 @@ class CmdMshrQueue(nCmds: Int, nCores: Int, nMshrs: Int, reqIdWidth: Int, blockO
260258 cmdBlockQueue.io.update := io.update
261259 cmdBlockQueue.io.rdPtr := io.rdPtr
262260 cmdBlockQueue.io.wrPtr := io.wrPtr
263- cmdBlockQueue.io.wrData := Mux ( io.withCmd, io. wrData, 0 . U )
261+ cmdBlockQueue.io.wrData := io.wrData
264262 cmdBlockQueue.io.updtPtr := io.updtPtr
265263 cmdBlockQueue.io.updtBlockIdx := cntRegs(io.updtPtr)
266264 cmdBlockQueue.io.updtData := io.updtData
@@ -295,7 +293,6 @@ class MshrQueue(nCores: Int, nCmds: Int, nMshrs: Int, nWays: Int, reqIdWidth: In
295293 reqQueue.io.pop := io.pop.pop
296294
297295 cmdQueue.io.push := io.push.pushReq
298- cmdQueue.io.withCmd := io.push.withCmd
299296 cmdQueue.io.update := io.push.pushCmd
300297 cmdQueue.io.rdPtr := reqQueue.io.rdPtr
301298 cmdQueue.io.wrPtr := reqQueue.io.wrPtr
@@ -320,12 +317,12 @@ class MshrQueue(nCores: Int, nCmds: Int, nMshrs: Int, nWays: Int, reqIdWidth: In
320317 io.push.full := reqQueue.io.full
321318
322319 io.info.wrPtr := reqQueue.io.wrPtr
323- io.info.validMSHRs := validMshrs
320+ io.info.validMshrs := validMshrs
324321 io.info.currentTags := reqQueue.io.currentTags
325322 io.info.currentIndexes := reqQueue.io.currentIndexes
326323 io.info.replacementWays := reqQueue.io.replacementWays
327324 io.info.incidentCoreIds := reqQueue.io.incidentCoreIds
328- io.info.isCritCores := reqQueue.io.isCritCores
325+ io.info.critMshrs := reqQueue.io.isCritCores
329326 io.info.fullCmds := cmdQueue.io.full
330327 io.info.elementCnt := queueElementCntReg
331328
@@ -335,53 +332,67 @@ class MshrQueue(nCores: Int, nCmds: Int, nMshrs: Int, nWays: Int, reqIdWidth: In
335332 io.pop.cmds := cmdQueue.io.rdCmds
336333}
337334
338- class MissFifo (nCores : Int , nCmds : Int , nMshrs : Int , nWays : Int , reqIdWidth : Int , tagWidth : Int , indexWidth : Int , blockOffsetWidth : Int , subBlockWidth : Int , blockWidth : Int ) extends Module {
335+ class MissFifo (nCores : Int , nCmds : Int , nMshrs : Int , nWays : Int , reqIdWidth : Int , tagWidth : Int , indexWidth : Int , blockOffsetWidth : Int , subBlockWidth : Int , blockWidth : Int , enCritMisses : Boolean = false ) extends Module {
339336 val io = IO (new MissFifoIO (nCores, nMshrs, nCmds, nWays, reqIdWidth, tagWidth, indexWidth, blockOffsetWidth, blockWidth, subBlockWidth))
340337
341- val critQueue = Module (new MshrQueue (nCores, nCmds, nMshrs, nWays, reqIdWidth, tagWidth, indexWidth, blockOffsetWidth, subBlockWidth, blockWidth))
342- val nonCritQueue = Module (new MshrQueue (nCores, nCmds, nMshrs, nWays, reqIdWidth, tagWidth, indexWidth, blockOffsetWidth, subBlockWidth, blockWidth))
343-
344- // De-multiplex the push interface to the two queues
345- val mshrPushDemux = Module (new MshrPushDemux (nCores, nCmds, nWays, reqIdWidth, tagWidth, indexWidth, blockOffsetWidth, blockWidth))
346-
347- mshrPushDemux.io.sel := io.pushCrit
348- mshrPushDemux.io.in <> io.push
349- nonCritQueue.io.push <> mshrPushDemux.io.out1
350- critQueue.io.push <> mshrPushDemux.io.out2
351-
352- // Multiplex between the two queues for popping
353- val mshrPopDemux = Module (new MshrPopMux (nCores, nCmds, nWays, reqIdWidth, tagWidth, indexWidth, blockOffsetWidth, blockWidth))
354-
355- // Choose to always pop the critical queue as long as it is not empty
356- mshrPopDemux.io.sel := io.popQSel
357- mshrPopDemux.io.in1 <> nonCritQueue.io.pop
358- mshrPopDemux.io.in2 <> critQueue.io.pop
359- io.pop <> mshrPopDemux.io.out
360-
361- io.critInfo <> critQueue.io.info
362- io.nonCritInfo <> nonCritQueue.io.info
363-
364- // Since the critical queue is always given priority over non-critical queue, a hazards occurs when a replacement policy
365- // instructs a non-critical request to evict a way that then a critical request that has reached contention limit is
366- // told to evict too. For instance, a non-critical request can evict way 2, so it is pushed to non-critical fifo; then
367- // a critical request whose core has reached contention limit is told to evict the same way: 2 (most likely since any
368- // other ways are already owned by critical cores); then the critical way evicts this line first followed by a
369- // non-critical way evicting this line later on. This creates a additional contention, since if this line is later on
370- // needed by a critical core, it will have to refetch again, thus resulting in two line accesses from the main memory
371- // for a critical core.
372- // NOTE: This is a rather rare case.
373-
374- val anyMatchingReqsInNonCrit = VecInit (Seq .fill(nMshrs)(false .B ))
375- val critPopValid = ! critQueue.io.pop.empty
376- for (mshrIdx <- 0 until nMshrs) {
377- val nonCritValid = nonCritQueue.io.info.validMSHRs(mshrIdx)
378- val conflict = critPopValid && nonCritValid && nonCritQueue.io.info.currentIndexes(mshrIdx) === critQueue.io.pop.popEntry.index && nonCritQueue.io.info.replacementWays(mshrIdx) === critQueue.io.pop.popEntry.replaceWay
379- anyMatchingReqsInNonCrit(mshrIdx) := conflict
380- }
338+ if (enCritMisses) {
339+ val critQueue = Module (new MshrQueue (nCores, nCmds, nMshrs, nWays, reqIdWidth, tagWidth, indexWidth, blockOffsetWidth, subBlockWidth, blockWidth))
340+ val nonCritQueue = Module (new MshrQueue (nCores, nCmds, nMshrs, nWays, reqIdWidth, tagWidth, indexWidth, blockOffsetWidth, subBlockWidth, blockWidth))
341+
342+ // De-multiplex the push interface to the two queues
343+ val mshrPushDemux = Module (new MshrPushDemux (nCores, nCmds, nWays, reqIdWidth, tagWidth, indexWidth, blockOffsetWidth, blockWidth))
344+
345+ mshrPushDemux.io.sel := io.pushCrit
346+ mshrPushDemux.io.in <> io.push
347+ nonCritQueue.io.push <> mshrPushDemux.io.out1
348+ critQueue.io.push <> mshrPushDemux.io.out2
349+
350+ // Multiplex between the two queues for popping
351+ val mshrPopDemux = Module (new MshrPopMux (nCores, nCmds, nWays, reqIdWidth, tagWidth, indexWidth, blockOffsetWidth, blockWidth))
352+
353+ // Choose to always pop the critical queue as long as it is not empty
354+ mshrPopDemux.io.sel := io.popQSel
355+ mshrPopDemux.io.in1 <> nonCritQueue.io.pop
356+ mshrPopDemux.io.in2 <> critQueue.io.pop
357+ io.pop <> mshrPopDemux.io.out
358+
359+ io.critInfo <> critQueue.io.info
360+ io.nonCritInfo <> nonCritQueue.io.info
361+
362+ // Since the critical queue is always given priority over non-critical queue, a hazards occurs when a replacement policy
363+ // instructs a non-critical request to evict a way that then a critical request that has reached contention limit is
364+ // told to evict too. For instance, a non-critical request can evict way 2, so it is pushed to non-critical fifo; then
365+ // a critical request whose core has reached contention limit is told to evict the same way: 2 (most likely since any
366+ // other ways are already owned by critical cores); then the critical way evicts this line first followed by a
367+ // non-critical way evicting this line later on. This creates a additional contention, since if this line is later on
368+ // needed by a critical core, it will have to refetch again, thus resulting in two line accesses from the main memory
369+ // for a critical core.
370+ // NOTE: This is a rather rare case.
371+
372+ val anyMatchingReqsInNonCrit = VecInit (Seq .fill(nMshrs)(false .B ))
373+ val critPopValid = ! critQueue.io.pop.empty
374+ for (mshrIdx <- 0 until nMshrs) {
375+ val nonCritValid = nonCritQueue.io.info.validMshrs(mshrIdx)
376+ val conflict = critPopValid && nonCritValid && nonCritQueue.io.info.currentIndexes(mshrIdx) === critQueue.io.pop.popEntry.index && nonCritQueue.io.info.replacementWays(mshrIdx) === critQueue.io.pop.popEntry.replaceWay
377+ anyMatchingReqsInNonCrit(mshrIdx) := conflict
378+ }
379+
380+ val queueConflict = anyMatchingReqsInNonCrit.reduce((x, y) => x || y)
381381
382- val queueConflict = anyMatchingReqsInNonCrit.reduce((x, y) => x || y)
382+ io.full := critQueue.io.push.full || nonCritQueue.io.push.full
383+ io.critEmpty := critQueue.io.pop.empty || queueConflict
384+ io.nonCritEmpty := nonCritQueue.io.pop.empty
385+ } else {
386+ val nonCritQueue = Module (new MshrQueue (nCores, nCmds, nMshrs, nWays, reqIdWidth, tagWidth, indexWidth, blockOffsetWidth, subBlockWidth, blockWidth))
383387
384- io.full := critQueue.io.push.full || nonCritQueue.io.push.full
385- io.critEmpty := critQueue.io.pop.empty || queueConflict
386- io.nonCritEmpty := nonCritQueue.io.pop.empty
388+ nonCritQueue.io.push <> io.push
389+ io.pop <> nonCritQueue.io.pop
390+
391+ io.critInfo <> 0 .U .asTypeOf(io.critInfo)
392+ io.nonCritInfo <> nonCritQueue.io.info
393+
394+ io.full := nonCritQueue.io.push.full
395+ io.critEmpty := true .B
396+ io.nonCritEmpty := nonCritQueue.io.pop.empty
397+ }
387398}
0 commit comments