Fix not respecting invalidate.valid from coalescer

This commit is contained in:
Hansung Kim
2023-04-27 21:35:26 -07:00
parent 7f821a66f5
commit edc05d51e6
2 changed files with 17 additions and 12 deletions

View File

@@ -581,6 +581,9 @@ class CoalescingUnitImp(outer: CoalescingUnit, config: CoalescerConfig) extends
// requests that didn't get coalesced, and M is the maximum number of // requests that didn't get coalesced, and M is the maximum number of
// single-lane requests that can go into a coalesced request. // single-lane requests that can go into a coalesced request.
// (`numPerLaneReqs`). // (`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, 1 + numPerLaneReqs,
// deq_lanes = 1 because we're serializing all responses to 1 port that // deq_lanes = 1 because we're serializing all responses to 1 port that
// goes back to the core. // goes back to the core.
@@ -597,7 +600,7 @@ class CoalescingUnitImp(outer: CoalescingUnit, config: CoalescerConfig) extends
) )
} }
val respQueueNoncoalPort = 0 val respQueueNoncoalPort = 0
val respQueueCoalPortOffset = 1 val respQueueUncoalPortOffset = 1
(outer.node.in zip outer.node.out).zipWithIndex.foreach { (outer.node.in zip outer.node.out).zipWithIndex.foreach {
case (((tlIn, edgeIn), (tlOut, _)), 0) => // TODO: not necessarily 1 master edge 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 (newEntry.lanes zip coalescer.io.invalidate.bits).zipWithIndex
.foreach { case ((laneEntry, laneInv), lane) => .foreach { case ((laneEntry, laneInv), lane) =>
(laneEntry.reqs zip laneInv.asBools).foreach { case (reqEntry, inv) => (laneEntry.reqs zip laneInv.asBools).foreach { case (reqEntry, inv) =>
// TODO: this part needs the actual coalescing logic to work reqEntry.valid := (coalescer.io.invalidate.valid && inv)
reqEntry.valid := inv when ((coalescer.io.invalidate.valid && inv)) {
when (inv) {
printf(s"entry for reqQueue(${lane}) got invalidated\n") printf(s"entry for reqQueue(${lane}) got invalidated\n")
} }
// FIXME: copying over queue heads out of laziness // FIXME: copying over queue heads out of laziness
@@ -730,7 +732,7 @@ class CoalescingUnitImp(outer: CoalescingUnit, config: CoalescerConfig) extends
dontTouch(newEntry) dontTouch(newEntry)
// Uncoalescer module uncoalesces responses back to each lane // 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.coalReqValid := coalescer.io.coalReq.valid
uncoalescer.io.newEntry := newEntry 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 // TODO: rather than crashing, deassert tlOut.d.ready to stall downtream
// cache. This should ideally not happen though. // cache. This should ideally not happen though.
assert( assert(
q.io.enq(respQueueCoalPortOffset + i).ready, q.io.enq(respQueueUncoalPortOffset + i).ready,
s"respQueue: enq port for coalesced response is blocked for lane ${lane}" 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(respQueueUncoalPortOffset + i).valid := resp.valid
q.io.enq(respQueueCoalPortOffset + i).bits := resp.bits 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)) // dontTouch(q.io.enq(respQueueCoalPortOffset))
} }
} }
@@ -776,7 +781,7 @@ class CoalescedResponseBundle(config: CoalescerConfig) extends Bundle {
val data = UInt((8 * (1 << config.maxCoalLogSize)).W) val data = UInt((8 * (1 << config.maxCoalLogSize)).W)
} }
class UncoalescingUnit(config: CoalescerConfig) extends Module { class Uncoalescer(config: CoalescerConfig) extends Module {
// notes to hansung: // notes to hansung:
// val numLanes: Int, <-> config.NUM_LANES // val numLanes: Int, <-> config.NUM_LANES
// val numPerLaneReqs: Int, <-> config.DEPTH // val numPerLaneReqs: Int, <-> config.DEPTH

View File

@@ -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" behavior of "uncoalescer"
val numLanes = 4 val numLanes = 4
val numPerLaneReqs = 2 val numPerLaneReqs = 2
@@ -451,7 +451,7 @@ class UncoalescingUnitTest extends AnyFlatSpec with ChiselScalatestTester {
val numInflightCoalRequests = 4 val numInflightCoalRequests = 4
it should "work" in { it should "work" in {
test(new UncoalescingUnit(testConfig)) test(new Uncoalescer(testConfig))
// vcs helps with simulation time, but sometimes errors with // vcs helps with simulation time, but sometimes errors with
// "mutation occurred during iteration" java error // "mutation occurred during iteration" java error
// .withAnnotations(Seq(VcsBackendAnnotation)) // .withAnnotations(Seq(VcsBackendAnnotation))