Fix used bit logic when invalidating but not dequeueing
This commit is contained in:
@@ -216,10 +216,10 @@ class CoalShiftQueue[T <: Data]( gen: T,
|
|||||||
}
|
}
|
||||||
|
|
||||||
when(io.queue.enq.fire) {
|
when(io.queue.enq.fire) {
|
||||||
when(!io.queue.deq.fire) {
|
when(!shift) {
|
||||||
used := (used << 1.U) | 1.U
|
used := (used << 1.U) | 1.U
|
||||||
}
|
}
|
||||||
}.elsewhen(io.queue.deq.fire) {
|
}.elsewhen(shift) {
|
||||||
used := used >> 1.U
|
used := used >> 1.U
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -229,6 +229,7 @@ class CoalShiftQueue[T <: Data]( gen: T,
|
|||||||
|
|
||||||
assert(!flow, "flow-through is not implemented")
|
assert(!flow, "flow-through is not implemented")
|
||||||
if (flow) {
|
if (flow) {
|
||||||
|
// FIXME old code
|
||||||
when(io.queue.enq.valid) { io.queue.deq.valid := true.B }
|
when(io.queue.enq.valid) { io.queue.deq.valid := true.B }
|
||||||
when(!valid(0)) { io.queue.deq.bits := io.queue.enq.bits }
|
when(!valid(0)) { io.queue.deq.bits := io.queue.enq.bits }
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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 =>
|
test(new CoalShiftQueue(gen = UInt(8.W), entries = 4)) { c =>
|
||||||
c.io.invalidate.valid.poke(false.B)
|
c.io.invalidate.valid.poke(false.B)
|
||||||
|
|
||||||
c.io.allowShift.poke(true.B)
|
c.io.allowShift.poke(true.B)
|
||||||
|
|
||||||
// prepare
|
// prepare
|
||||||
@@ -399,19 +400,33 @@ class CoalShiftQueueTest extends AnyFlatSpec with ChiselScalatestTester {
|
|||||||
// invalidate two entries at head
|
// invalidate two entries at head
|
||||||
c.io.invalidate.valid.poke(true.B)
|
c.io.invalidate.valid.poke(true.B)
|
||||||
c.io.invalidate.bits.poke(0x3.U)
|
c.io.invalidate.bits.poke(0x3.U)
|
||||||
|
c.io.queue.deq.ready.poke(false.B)
|
||||||
// [ 0x56 | 0x34(inv) | 0x12(inv) ]
|
// [ 0x56 | 0x34(inv) | 0x12(inv) ]
|
||||||
c.clock.step()
|
c.clock.step()
|
||||||
// [ 0x56 | 0x34(inv) ]
|
// [ 0x56 | 0x34(inv) ]
|
||||||
c.io.invalidate.valid.poke(false.B)
|
c.io.invalidate.valid.poke(false.B)
|
||||||
c.io.queue.deq.ready.poke(false.B)
|
c.io.queue.deq.ready.poke(false.B)
|
||||||
c.clock.step()
|
c.clock.step()
|
||||||
// [ 0x56 ]
|
// [ 0x56 ]
|
||||||
c.io.queue.deq.ready.poke(true.B)
|
c.io.queue.deq.ready.poke(true.B)
|
||||||
c.io.queue.deq.valid.expect(true.B)
|
c.io.queue.deq.valid.expect(true.B)
|
||||||
c.io.queue.deq.bits.expect(0x56.U)
|
c.io.queue.deq.bits.expect(0x56.U)
|
||||||
c.clock.step()
|
c.clock.step()
|
||||||
c.io.queue.deq.ready.poke(true.B)
|
c.io.queue.deq.ready.poke(true.B)
|
||||||
c.io.queue.deq.valid.expect(false.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)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user