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 {