Invalidate head when dequeued but allowShift was false
This commit is contained in:
@@ -213,6 +213,11 @@ class CoalShiftQueue[T <: Data]( gen: T,
|
||||
(io.queue.enq.fire && !paddedUsed(i + 1) && used(i)) || pad(validAfterInv)(i + 1),
|
||||
(io.queue.enq.fire && paddedUsed(i - 1) && !used(i)) || validAfterInv(i)
|
||||
)
|
||||
// additionally, head entry should get invalidated when dequeue fired
|
||||
// but queue didn't shift (e.g. because allowShift was false)
|
||||
when (io.queue.deq.fire && !shift) {
|
||||
valid(0) := false.B
|
||||
}
|
||||
}
|
||||
|
||||
when(io.queue.enq.fire) {
|
||||
|
||||
@@ -302,6 +302,43 @@ class CoalShiftQueueTest extends AnyFlatSpec with ChiselScalatestTester {
|
||||
}
|
||||
}
|
||||
|
||||
it should "not shift entries when allowShift is false" in {
|
||||
test(new CoalShiftQueue(UInt(8.W), 4)) { c =>
|
||||
c.io.invalidate.valid.poke(false.B)
|
||||
c.io.queue.deq.ready.poke(false.B)
|
||||
|
||||
c.io.allowShift.poke(false.B)
|
||||
|
||||
// prepare
|
||||
c.io.queue.enq.ready.expect(true.B)
|
||||
c.io.queue.enq.valid.poke(true.B)
|
||||
c.io.queue.enq.bits.poke(0x12.U)
|
||||
c.clock.step()
|
||||
c.io.queue.enq.ready.expect(true.B)
|
||||
c.io.queue.enq.valid.poke(true.B)
|
||||
c.io.queue.enq.bits.poke(0x34.U)
|
||||
c.clock.step()
|
||||
c.io.queue.enq.valid.poke(false.B)
|
||||
|
||||
// dequeueing should work normally when allowShift is false...
|
||||
c.io.queue.deq.ready.poke(true.B)
|
||||
c.io.queue.deq.valid.expect(true.B)
|
||||
c.io.queue.deq.bits.expect(0x12.U)
|
||||
c.clock.step()
|
||||
// but should stop there and not dequeue the next entry
|
||||
c.io.queue.deq.ready.poke(true.B)
|
||||
c.io.queue.deq.valid.expect(false.B)
|
||||
c.clock.step()
|
||||
// when allowShift is back one, dequeueing should start working from next
|
||||
// cycle
|
||||
c.io.allowShift.poke(true.B)
|
||||
c.clock.step()
|
||||
c.io.queue.deq.ready.poke(true.B)
|
||||
c.io.queue.deq.valid.expect(true.B)
|
||||
c.io.queue.deq.bits.expect(0x34.U)
|
||||
}
|
||||
}
|
||||
|
||||
it should "work when enqueing and dequeueing simultaneously to a depth=1 queue" in {
|
||||
test(new CoalShiftQueue(UInt(8.W), 1)) { c =>
|
||||
c.io.invalidate.valid.poke(false.B)
|
||||
@@ -358,9 +395,9 @@ class CoalShiftQueueTest extends AnyFlatSpec with ChiselScalatestTester {
|
||||
c.io.allowShift.poke(false.B)
|
||||
c.io.invalidate.valid.poke(true.B)
|
||||
c.io.invalidate.bits.poke(0x1.U)
|
||||
// TODO: we might be able to enqueue to a depth=1 queue whose entry
|
||||
// just got invalidated, so that enq.ready is true.B here, but it is a
|
||||
// niche case
|
||||
// TODO: we might be able to enqueue to a full depth=1 queue whose only
|
||||
// entry just got invalidated, so that enq.ready is true here, but
|
||||
// it is a niche case
|
||||
c.io.queue.enq.ready.expect(false.B)
|
||||
c.clock.step()
|
||||
// now try enqueueing now that we have space
|
||||
@@ -379,7 +416,7 @@ class CoalShiftQueueTest extends AnyFlatSpec with ChiselScalatestTester {
|
||||
}
|
||||
}
|
||||
|
||||
it should "invalidate head being dequeued" in {
|
||||
it should "invalidate head that is also being dequeued" in {
|
||||
test(new CoalShiftQueue(UInt(8.W), 4)) { c =>
|
||||
c.io.invalidate.valid.poke(false.B)
|
||||
c.io.allowShift.poke(true.B)
|
||||
|
||||
Reference in New Issue
Block a user