Implement automatic dequeuing of invalid entries

This commit is contained in:
Hansung Kim
2023-03-31 19:40:10 -07:00
parent f44dfc8d5a
commit 6ca22a39e0
2 changed files with 18 additions and 5 deletions

View File

@@ -495,10 +495,11 @@ class CoalShiftQueue[T <: Data](
else if (i == entries) false.B
else Mux(io.invalidate(i), false.B, paddedValid(i))
val shift = io.deq.ready || (used =/= 0.U) && !valid(0)
for (i <- 0 until entries) {
val wdata = if (i == entries - 1) io.enq.bits else Mux(!used(i + 1), io.enq.bits, elts(i + 1))
val wen = Mux(
io.deq.ready,
shift,
(io.enq.fire && !paddedUsed(i + 1) && used(i)) || paddedValidAfterInvalidate(i + 1),
// enqueue to the first empty slot above the top
(io.enq.fire && paddedUsed(i - 1) && !used(i)) || !paddedValidAfterInvalidate(i)
@@ -506,7 +507,7 @@ class CoalShiftQueue[T <: Data](
when(wen) { elts(i) := wdata }
valid(i) := Mux(
io.deq.ready,
shift,
(io.enq.fire && !paddedUsed(i + 1) && used(i)) || paddedValidAfterInvalidate(i + 1),
// TODO: handle enqueueing to invalidated tail?
(io.enq.fire && paddedUsed(i - 1) && !used(i)) || paddedValidAfterInvalidate(i)

View File

@@ -158,16 +158,28 @@ class CoalShiftQueueTest extends AnyFlatSpec with ChiselScalatestTester {
c.io.enq.valid.poke(true.B)
c.io.enq.bits.poke(0x34.U)
c.clock.step()
c.io.deq.ready.poke(false.B)
c.io.enq.ready.expect(true.B)
c.io.enq.valid.poke(true.B)
c.io.enq.bits.poke(0x56.U)
c.clock.step()
c.io.enq.valid.poke(false.B)
c.io.invalidate.poke(0x1.U)
// invalidate two entries at head
c.io.invalidate.poke(0x3.U)
c.clock.step()
c.io.invalidate.poke(0x0.U)
c.io.deq.ready.poke(false.B)
// 0x12 should be dequeued
// 0x12 should be dequeued now
c.clock.step()
// 0x34 should be dequeued now
c.clock.step()
c.io.deq.ready.poke(true.B)
c.io.deq.valid.expect(true.B)
c.io.deq.bits.expect(0x34.U)
c.io.deq.bits.expect(0x56.U)
c.clock.step()
c.io.deq.ready.poke(true.B)
c.io.deq.valid.expect(false.B)
}
}
}