diff --git a/src/main/scala/tilelink/Coalescing.scala b/src/main/scala/tilelink/Coalescing.scala index 01b0ff0..fc87ad2 100644 --- a/src/main/scala/tilelink/Coalescing.scala +++ b/src/main/scala/tilelink/Coalescing.scala @@ -581,6 +581,9 @@ class CoalescingUnitImp(outer: CoalescingUnit, config: CoalescerConfig) extends // requests that didn't get coalesced, and M is the maximum number of // single-lane requests that can go into a coalesced request. // (`numPerLaneReqs`). + // TODO: potentially expensive, because this generates more FFs. + // Rather than enqueueing all responses in a single cycle, consider + // enqueueing one by one (at the cost of possibly stalling downstream). 1 + numPerLaneReqs, // deq_lanes = 1 because we're serializing all responses to 1 port that // goes back to the core. @@ -597,7 +600,7 @@ class CoalescingUnitImp(outer: CoalescingUnit, config: CoalescerConfig) extends ) } val respQueueNoncoalPort = 0 - val respQueueCoalPortOffset = 1 + val respQueueUncoalPortOffset = 1 (outer.node.in zip outer.node.out).zipWithIndex.foreach { case (((tlIn, edgeIn), (tlOut, _)), 0) => // TODO: not necessarily 1 master edge @@ -716,9 +719,8 @@ class CoalescingUnitImp(outer: CoalescingUnit, config: CoalescerConfig) extends (newEntry.lanes zip coalescer.io.invalidate.bits).zipWithIndex .foreach { case ((laneEntry, laneInv), lane) => (laneEntry.reqs zip laneInv.asBools).foreach { case (reqEntry, inv) => - // TODO: this part needs the actual coalescing logic to work - reqEntry.valid := inv - when (inv) { + reqEntry.valid := (coalescer.io.invalidate.valid && inv) + when ((coalescer.io.invalidate.valid && inv)) { printf(s"entry for reqQueue(${lane}) got invalidated\n") } // FIXME: copying over queue heads out of laziness @@ -730,7 +732,7 @@ class CoalescingUnitImp(outer: CoalescingUnit, config: CoalescerConfig) extends dontTouch(newEntry) // Uncoalescer module uncoalesces responses back to each lane - val uncoalescer = Module(new UncoalescingUnit(config)) + val uncoalescer = Module(new Uncoalescer(config)) uncoalescer.io.coalReqValid := coalescer.io.coalReq.valid uncoalescer.io.newEntry := newEntry @@ -746,11 +748,14 @@ class CoalescingUnitImp(outer: CoalescingUnit, config: CoalescerConfig) extends // TODO: rather than crashing, deassert tlOut.d.ready to stall downtream // cache. This should ideally not happen though. assert( - q.io.enq(respQueueCoalPortOffset + i).ready, - s"respQueue: enq port for coalesced response is blocked for lane ${lane}" + q.io.enq(respQueueUncoalPortOffset + i).ready, + s"respQueue: enq port for ${i}-th uncoalesced response is blocked for lane ${lane}" ) - q.io.enq(respQueueCoalPortOffset + i).valid := resp.valid - q.io.enq(respQueueCoalPortOffset + i).bits := resp.bits + q.io.enq(respQueueUncoalPortOffset + i).valid := resp.valid + q.io.enq(respQueueUncoalPortOffset + i).bits := resp.bits + when (resp.valid) { + printf(s"${i}-th uncoalesced response came back from lane ${lane}\n") + } // dontTouch(q.io.enq(respQueueCoalPortOffset)) } } @@ -776,7 +781,7 @@ class CoalescedResponseBundle(config: CoalescerConfig) extends Bundle { val data = UInt((8 * (1 << config.maxCoalLogSize)).W) } -class UncoalescingUnit(config: CoalescerConfig) extends Module { +class Uncoalescer(config: CoalescerConfig) extends Module { // notes to hansung: // val numLanes: Int, <-> config.NUM_LANES // val numPerLaneReqs: Int, <-> config.DEPTH diff --git a/src/test/scala/coalescing/CoalescingUnitTest.scala b/src/test/scala/coalescing/CoalescingUnitTest.scala index 799a164..3a2e4a5 100644 --- a/src/test/scala/coalescing/CoalescingUnitTest.scala +++ b/src/test/scala/coalescing/CoalescingUnitTest.scala @@ -440,7 +440,7 @@ class CoalShiftQueueTest extends AnyFlatSpec with ChiselScalatestTester { } } -class UncoalescingUnitTest extends AnyFlatSpec with ChiselScalatestTester { +class UncoalescerUnitTest extends AnyFlatSpec with ChiselScalatestTester { behavior of "uncoalescer" val numLanes = 4 val numPerLaneReqs = 2 @@ -451,7 +451,7 @@ class UncoalescingUnitTest extends AnyFlatSpec with ChiselScalatestTester { val numInflightCoalRequests = 4 it should "work" in { - test(new UncoalescingUnit(testConfig)) + test(new Uncoalescer(testConfig)) // vcs helps with simulation time, but sometimes errors with // "mutation occurred during iteration" java error // .withAnnotations(Seq(VcsBackendAnnotation))