Implement automatic dequeuing of invalid entries
This commit is contained in:
@@ -495,10 +495,11 @@ class CoalShiftQueue[T <: Data](
|
|||||||
else if (i == entries) false.B
|
else if (i == entries) false.B
|
||||||
else Mux(io.invalidate(i), false.B, paddedValid(i))
|
else Mux(io.invalidate(i), false.B, paddedValid(i))
|
||||||
|
|
||||||
|
val shift = io.deq.ready || (used =/= 0.U) && !valid(0)
|
||||||
for (i <- 0 until entries) {
|
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 wdata = if (i == entries - 1) io.enq.bits else Mux(!used(i + 1), io.enq.bits, elts(i + 1))
|
||||||
val wen = Mux(
|
val wen = Mux(
|
||||||
io.deq.ready,
|
shift,
|
||||||
(io.enq.fire && !paddedUsed(i + 1) && used(i)) || paddedValidAfterInvalidate(i + 1),
|
(io.enq.fire && !paddedUsed(i + 1) && used(i)) || paddedValidAfterInvalidate(i + 1),
|
||||||
// enqueue to the first empty slot above the top
|
// enqueue to the first empty slot above the top
|
||||||
(io.enq.fire && paddedUsed(i - 1) && !used(i)) || !paddedValidAfterInvalidate(i)
|
(io.enq.fire && paddedUsed(i - 1) && !used(i)) || !paddedValidAfterInvalidate(i)
|
||||||
@@ -506,7 +507,7 @@ class CoalShiftQueue[T <: Data](
|
|||||||
when(wen) { elts(i) := wdata }
|
when(wen) { elts(i) := wdata }
|
||||||
|
|
||||||
valid(i) := Mux(
|
valid(i) := Mux(
|
||||||
io.deq.ready,
|
shift,
|
||||||
(io.enq.fire && !paddedUsed(i + 1) && used(i)) || paddedValidAfterInvalidate(i + 1),
|
(io.enq.fire && !paddedUsed(i + 1) && used(i)) || paddedValidAfterInvalidate(i + 1),
|
||||||
// TODO: handle enqueueing to invalidated tail?
|
// TODO: handle enqueueing to invalidated tail?
|
||||||
(io.enq.fire && paddedUsed(i - 1) && !used(i)) || paddedValidAfterInvalidate(i)
|
(io.enq.fire && paddedUsed(i - 1) && !used(i)) || paddedValidAfterInvalidate(i)
|
||||||
|
|||||||
@@ -158,16 +158,28 @@ class CoalShiftQueueTest extends AnyFlatSpec with ChiselScalatestTester {
|
|||||||
c.io.enq.valid.poke(true.B)
|
c.io.enq.valid.poke(true.B)
|
||||||
c.io.enq.bits.poke(0x34.U)
|
c.io.enq.bits.poke(0x34.U)
|
||||||
c.clock.step()
|
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.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.clock.step()
|
||||||
|
c.io.invalidate.poke(0x0.U)
|
||||||
c.io.deq.ready.poke(false.B)
|
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.clock.step()
|
||||||
c.io.deq.ready.poke(true.B)
|
c.io.deq.ready.poke(true.B)
|
||||||
c.io.deq.valid.expect(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)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user