diff --git a/src/main/scala/tilelink/Coalescing.scala b/src/main/scala/tilelink/Coalescing.scala index 0cb7c91..2590884 100644 --- a/src/main/scala/tilelink/Coalescing.scala +++ b/src/main/scala/tilelink/Coalescing.scala @@ -216,10 +216,10 @@ class CoalShiftQueue[T <: Data]( gen: T, } when(io.queue.enq.fire) { - when(!io.queue.deq.fire) { + when(!shift) { used := (used << 1.U) | 1.U } - }.elsewhen(io.queue.deq.fire) { + }.elsewhen(shift) { used := used >> 1.U } @@ -229,6 +229,7 @@ class CoalShiftQueue[T <: Data]( gen: T, assert(!flow, "flow-through is not implemented") if (flow) { + // FIXME old code when(io.queue.enq.valid) { io.queue.deq.valid := true.B } when(!valid(0)) { io.queue.deq.bits := io.queue.enq.bits } } diff --git a/src/test/scala/coalescing/CoalescingUnitTest.scala b/src/test/scala/coalescing/CoalescingUnitTest.scala index 66f6b9f..41017e5 100644 --- a/src/test/scala/coalescing/CoalescingUnitTest.scala +++ b/src/test/scala/coalescing/CoalescingUnitTest.scala @@ -375,9 +375,10 @@ class CoalShiftQueueTest extends AnyFlatSpec with ChiselScalatestTester { } } - it should "dequeue invalidated entries by itself" in { + it should "dequeue invalidated head on its own when allowShift" in { test(new CoalShiftQueue(gen = UInt(8.W), entries = 4)) { c => c.io.invalidate.valid.poke(false.B) + c.io.allowShift.poke(true.B) // prepare @@ -399,19 +400,33 @@ class CoalShiftQueueTest extends AnyFlatSpec with ChiselScalatestTester { // invalidate two entries at head c.io.invalidate.valid.poke(true.B) c.io.invalidate.bits.poke(0x3.U) + c.io.queue.deq.ready.poke(false.B) // [ 0x56 | 0x34(inv) | 0x12(inv) ] c.clock.step() - // [ 0x56 | 0x34(inv) ] + // [ 0x56 | 0x34(inv) ] c.io.invalidate.valid.poke(false.B) c.io.queue.deq.ready.poke(false.B) c.clock.step() - // [ 0x56 ] + // [ 0x56 ] c.io.queue.deq.ready.poke(true.B) c.io.queue.deq.valid.expect(true.B) c.io.queue.deq.bits.expect(0x56.U) c.clock.step() c.io.queue.deq.ready.poke(true.B) c.io.queue.deq.valid.expect(false.B) + c.clock.step() + + // do one more enqueue-then-dequeue to see if used bit was properly cleared + c.io.queue.deq.ready.poke(false.B) + c.io.queue.enq.ready.expect(true.B) + c.io.queue.enq.valid.poke(true.B) + c.io.queue.enq.bits.poke(0x78.U) + c.clock.step() + // should dequeue right away + c.io.queue.enq.valid.poke(false.B) + c.io.queue.deq.ready.poke(true.B) + c.io.queue.deq.valid.expect(true.B) + c.io.queue.deq.bits.expect(0x78.U) } }