Do not deassert deq.valid right after invalidate(head)
... to avoid combinational cycle.
This commit is contained in:
@@ -460,7 +460,8 @@ class InflightCoalReqTableEntry(
|
|||||||
// Mostly copied from freechips.rocketchip.util.ShiftQueue, except that every
|
// Mostly copied from freechips.rocketchip.util.ShiftQueue, except that every
|
||||||
// queue entry and its valid signal are exposed as output IO.
|
// queue entry and its valid signal are exposed as output IO.
|
||||||
// If `pipe` is true, support enqueueing to a full queue when also dequeueing.
|
// If `pipe` is true, support enqueueing to a full queue when also dequeueing.
|
||||||
// TODO: support invalidate and deadline
|
//
|
||||||
|
// TODO: support deadline
|
||||||
class CoalShiftQueue[T <: Data](
|
class CoalShiftQueue[T <: Data](
|
||||||
gen: T,
|
gen: T,
|
||||||
val entries: Int,
|
val entries: Int,
|
||||||
@@ -522,7 +523,12 @@ class CoalShiftQueue[T <: Data](
|
|||||||
}
|
}
|
||||||
|
|
||||||
io.enq.ready := !valid(entries - 1)
|
io.enq.ready := !valid(entries - 1)
|
||||||
io.deq.valid := validAfterInv(0)
|
// We don't want to invalidate deq.valid response right away even when
|
||||||
|
// io.invalidate(head) is true.
|
||||||
|
// Coalescing unit consumes queue head's validity, and produces its new
|
||||||
|
// validity. Deasserting deq.valid right away will result in a combinational
|
||||||
|
// cycle.
|
||||||
|
io.deq.valid := valid(0)
|
||||||
io.deq.bits := elts.head
|
io.deq.bits := elts.head
|
||||||
|
|
||||||
assert(!flow, "flow-through is not implemented")
|
assert(!flow, "flow-through is not implemented")
|
||||||
@@ -540,19 +546,6 @@ class CoalShiftQueue[T <: Data](
|
|||||||
io.count := PopCount(io.mask)
|
io.count := PopCount(io.mask)
|
||||||
}
|
}
|
||||||
|
|
||||||
object CoalShiftQueue {
|
|
||||||
def apply[T <: Data](
|
|
||||||
enq: DecoupledIO[T],
|
|
||||||
entries: Int = 2,
|
|
||||||
pipe: Boolean = false,
|
|
||||||
flow: Boolean = false
|
|
||||||
): DecoupledIO[T] = {
|
|
||||||
val q = Module(new CoalShiftQueue(enq.bits.cloneType, entries, pipe, flow))
|
|
||||||
q.io.enq <> enq
|
|
||||||
q.io.deq
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
class MemTraceDriver(numLanes: Int = 1)(implicit p: Parameters) extends LazyModule {
|
class MemTraceDriver(numLanes: Int = 1)(implicit p: Parameters) extends LazyModule {
|
||||||
// Create N client nodes together
|
// Create N client nodes together
|
||||||
val laneNodes = Seq.tabulate(numLanes) { i =>
|
val laneNodes = Seq.tabulate(numLanes) { i =>
|
||||||
|
|||||||
@@ -111,7 +111,7 @@ class CoalShiftQueueTest extends AnyFlatSpec with ChiselScalatestTester {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
it should "invalidate entry being dequeued combinationally" in {
|
it should "invalidate head being dequeued" in {
|
||||||
test(new CoalShiftQueue(UInt(8.W), 4)) { c =>
|
test(new CoalShiftQueue(UInt(8.W), 4)) { c =>
|
||||||
c.io.invalidate.poke(0.U)
|
c.io.invalidate.poke(0.U)
|
||||||
|
|
||||||
@@ -128,13 +128,14 @@ class CoalShiftQueueTest extends AnyFlatSpec with ChiselScalatestTester {
|
|||||||
c.clock.step()
|
c.clock.step()
|
||||||
c.io.enq.valid.poke(false.B)
|
c.io.enq.valid.poke(false.B)
|
||||||
|
|
||||||
// invalidate should work for the entry just being dequeued at the same
|
// invalidate should work for the head just being dequeued at the same
|
||||||
// cycle
|
// cycle. However, it should not change deq.valid right away to avoid
|
||||||
|
// combinational cycles (see definition).
|
||||||
c.io.invalidate.poke(0x1.U)
|
c.io.invalidate.poke(0x1.U)
|
||||||
c.io.deq.ready.poke(true.B)
|
c.io.deq.ready.poke(true.B)
|
||||||
c.io.deq.valid.expect(false.B)
|
c.io.deq.valid.expect(true.B)
|
||||||
c.clock.step()
|
c.clock.step()
|
||||||
// rest are unchanged
|
// 0x12 should have been dequeued
|
||||||
c.io.invalidate.poke(0.U)
|
c.io.invalidate.poke(0.U)
|
||||||
c.io.deq.ready.poke(true.B)
|
c.io.deq.ready.poke(true.B)
|
||||||
c.io.deq.valid.expect(true.B)
|
c.io.deq.valid.expect(true.B)
|
||||||
|
|||||||
Reference in New Issue
Block a user