From 3ee639f37613d542aeabb8983e28da426706304f Mon Sep 17 00:00:00 2001 From: Hansung Kim Date: Fri, 31 Mar 2023 19:55:11 -0700 Subject: [PATCH] Eliminate unnecessary delay when invalidating head When invalidate signal is given for queue head, that head should be gone immediately at the next cycle, regardless of what deq.ready was at the previous cycle. --- src/main/scala/tilelink/Coalescing.scala | 2 +- src/test/scala/CoalescingUnitTest.scala | 25 ++++++++++++++++++++---- 2 files changed, 22 insertions(+), 5 deletions(-) diff --git a/src/main/scala/tilelink/Coalescing.scala b/src/main/scala/tilelink/Coalescing.scala index 95baf88..81b78fe 100644 --- a/src/main/scala/tilelink/Coalescing.scala +++ b/src/main/scala/tilelink/Coalescing.scala @@ -495,7 +495,7 @@ 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) + val shift = io.deq.ready || (used =/= 0.U) && !paddedValidAfterInvalidate(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( diff --git a/src/test/scala/CoalescingUnitTest.scala b/src/test/scala/CoalescingUnitTest.scala index c267998..a931494 100644 --- a/src/test/scala/CoalescingUnitTest.scala +++ b/src/test/scala/CoalescingUnitTest.scala @@ -1,7 +1,6 @@ import chisel3._ import chiseltest._ import org.scalatest.flatspec.AnyFlatSpec -import org.scalatest._ import freechips.rocketchip.tilelink._ import freechips.rocketchip.util.MultiPortQueue @@ -168,12 +167,11 @@ class CoalShiftQueueTest extends AnyFlatSpec with ChiselScalatestTester { // invalidate two entries at head c.io.invalidate.poke(0x3.U) c.clock.step() + // 0x12 should have been dequeued now c.io.invalidate.poke(0x0.U) c.io.deq.ready.poke(false.B) - // 0x12 should be dequeued now - c.clock.step() - // 0x34 should be dequeued now c.clock.step() + // 0x34 should have been dequeued now c.io.deq.ready.poke(true.B) c.io.deq.valid.expect(true.B) c.io.deq.bits.expect(0x56.U) @@ -182,6 +180,25 @@ class CoalShiftQueueTest extends AnyFlatSpec with ChiselScalatestTester { c.io.deq.valid.expect(false.B) } } + + it should "overwrite invalidated tail when enqueuing" in { + test(new CoalShiftQueue(UInt(8.W), 4)) { c => + c.io.invalidate.poke(0.U) + + // prepare + 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(0x12.U) + c.clock.step() + // invalidate and enqueue at the tail at the same time + c.io.invalidate.poke(0x1.U) + 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(0x34.U) + } + } } class UncoalescingUnitTest extends AnyFlatSpec with ChiselScalatestTester {