From 6ca22a39e0482655a0115d405d7297bdc4d8e159 Mon Sep 17 00:00:00 2001 From: Hansung Kim Date: Fri, 31 Mar 2023 19:40:10 -0700 Subject: [PATCH] Implement automatic dequeuing of invalid entries --- src/main/scala/tilelink/Coalescing.scala | 5 +++-- src/test/scala/CoalescingUnitTest.scala | 18 +++++++++++++++--- 2 files changed, 18 insertions(+), 5 deletions(-) diff --git a/src/main/scala/tilelink/Coalescing.scala b/src/main/scala/tilelink/Coalescing.scala index 3504061..95baf88 100644 --- a/src/main/scala/tilelink/Coalescing.scala +++ b/src/main/scala/tilelink/Coalescing.scala @@ -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) diff --git a/src/test/scala/CoalescingUnitTest.scala b/src/test/scala/CoalescingUnitTest.scala index d18041b..c267998 100644 --- a/src/test/scala/CoalescingUnitTest.scala +++ b/src/test/scala/CoalescingUnitTest.scala @@ -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) } } }