diff --git a/src/main/scala/tilelink/Coalescing.scala b/src/main/scala/tilelink/Coalescing.scala index 2029cb3..eca4044 100644 --- a/src/main/scala/tilelink/Coalescing.scala +++ b/src/main/scala/tilelink/Coalescing.scala @@ -258,9 +258,10 @@ class InflightCoalReqTable( // If entry with a lower index is empty, it always takes priority cascadeMatchIndex(i) := Mux(match_, i.U, cascadeMatchIndex(i + 1)) } - val matchIndex = cascadeMatchIndex(0) - val matchValid = Wire(Bool()) - matchValid := table(matchIndex).bits.respSourceId === io.lookupSourceId + val matchIndex = Wire(UInt()) + matchIndex := cascadeMatchIndex(0) + val matchValid = table(matchIndex).valid && + (table(matchIndex).bits.respSourceId === io.lookupSourceId) io.lookup.valid := matchValid // TODO: return something actually useful io.lookup.bits := table(matchIndex).bits.respSourceId @@ -272,7 +273,6 @@ class InflightCoalReqTable( } dontTouch(io.lookup) dontTouch(matchIndex) - dontTouch(matchValid) } class InflightCoalReqTableEntry(val numLanes: Int, val sourceWidth: Int) diff --git a/src/test/scala/CoalescingUnitTest.scala b/src/test/scala/CoalescingUnitTest.scala index 0fd3ce4..3596e21 100644 --- a/src/test/scala/CoalescingUnitTest.scala +++ b/src/test/scala/CoalescingUnitTest.scala @@ -38,19 +38,64 @@ class CoalescingUnitTest extends AnyFlatSpec with ChiselScalatestTester { val inflightCoalReqTableEntry = new InflightCoalReqTableEntry(numLanes, sourceWidth) - it should "whatever" in { + it should "stop enqueueing when full" in { test(new InflightCoalReqTable(numLanes, sourceWidth, entries)) { c => - // val tableEntry = new InflightCoalReqTableEntry(numLanes, sourceWidth) - val respSourceId = 0.U + for (i <- 0 until entries) { + c.io.enq.ready.expect(true.B) + c.io.enq.valid.poke(true.B) + c.io.enq.bits.fromLane.poke(0.U) + c.io.enq.bits.respSourceId.poke(i.U) + c.io.enq.bits.reqSourceIds.foreach { id => id.poke(0.U) } + + c.clock.step() + } + + c.io.enq.ready.expect(false.B) c.io.enq.valid.poke(true.B) c.io.enq.bits.fromLane.poke(0.U) - c.io.enq.bits.respSourceId.poke(respSourceId) + c.io.enq.bits.respSourceId.poke(0.U) c.io.enq.bits.reqSourceIds.foreach { id => id.poke(0.U) } + c.clock.step() - c.io.lookup.ready.poke(true.B) - c.io.lookupSourceId.poke(respSourceId) - c.io.lookup.valid.expect(true.B) - c.io.lookup.bits.expect(respSourceId) + c.io.enq.ready.expect(false.B) } } + it should "lookup matching entry" in { + test(new InflightCoalReqTable(numLanes, sourceWidth, entries)) + .withAnnotations(Seq(VcsBackendAnnotation, WriteFsdbAnnotation)) { c => + c.reset.poke(true.B) + c.clock.step(10) + c.reset.poke(false.B) + + // enqueue one entry to not match at 0th index + c.io.enq.ready.expect(true.B) + c.io.enq.valid.poke(true.B) + c.io.enq.bits.fromLane.poke(0.U) + c.io.enq.bits.respSourceId.poke(0.U) + c.io.enq.bits.reqSourceIds.foreach { id => id.poke(0.U) } + + c.clock.step() + + val targetSourceId = 1.U + c.io.enq.ready.expect(true.B) + c.io.enq.valid.poke(true.B) + c.io.enq.bits.fromLane.poke(0.U) + c.io.enq.bits.respSourceId.poke(targetSourceId) + c.io.enq.bits.reqSourceIds.foreach { id => id.poke(0.U) } + + c.clock.step() + + c.io.lookup.ready.poke(true.B) + c.io.lookupSourceId.poke(targetSourceId) + c.io.lookup.valid.expect(true.B) + c.io.lookup.bits.expect(targetSourceId) + + c.clock.step() + + // test if matching entry dequeues after 1 cycle + c.io.lookup.ready.poke(true.B) + c.io.lookupSourceId.poke(targetSourceId) + c.io.lookup.valid.expect(false.B) + } + } }