Invalidate outgoing per-lane requests that got coalesced
Now the response queue no longer blocks the flow!
This commit is contained in:
@@ -57,6 +57,8 @@ class CoalescingUnitImp(outer: CoalescingUnit, numLanes: Int) extends LazyModule
|
|||||||
val wordSize = 4
|
val wordSize = 4
|
||||||
|
|
||||||
val reqQueueDepth = 4 // FIXME test
|
val reqQueueDepth = 4 // FIXME test
|
||||||
|
val respQueueDepth = 2 // FIXME test
|
||||||
|
|
||||||
val sourceWidth = outer.node.in(1)._1.params.sourceBits
|
val sourceWidth = outer.node.in(1)._1.params.sourceBits
|
||||||
val addressWidth = outer.node.in(1)._1.params.addressBits
|
val addressWidth = outer.node.in(1)._1.params.addressBits
|
||||||
val reqQueueEntryT = new ReqQueueEntry(sourceWidth, addressWidth)
|
val reqQueueEntryT = new ReqQueueEntry(sourceWidth, addressWidth)
|
||||||
@@ -88,13 +90,16 @@ class CoalescingUnitImp(outer: CoalescingUnit, numLanes: Int) extends LazyModule
|
|||||||
// make queue block up in the middle of the simulation. Ideally there
|
// make queue block up in the middle of the simulation. Ideally there
|
||||||
// should be a more logical way to set this, or we should handle
|
// should be a more logical way to set this, or we should handle
|
||||||
// response queue blocking.
|
// response queue blocking.
|
||||||
8
|
respQueueDepth
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
val respQueueNoncoalPort = 0
|
val respQueueNoncoalPort = 0
|
||||||
val respQueueCoalPortOffset = 1
|
val respQueueCoalPortOffset = 1
|
||||||
|
|
||||||
|
// did coalescing succeed at all?
|
||||||
|
val coalReqValid = Wire(Bool())
|
||||||
|
|
||||||
// Per-lane request and response queues
|
// Per-lane request and response queues
|
||||||
//
|
//
|
||||||
// Override IdentityNode implementation so that we can instantiate
|
// Override IdentityNode implementation so that we can instantiate
|
||||||
@@ -114,7 +119,8 @@ class CoalescingUnitImp(outer: CoalescingUnit, numLanes: Int) extends LazyModule
|
|||||||
case (((tlIn, edgeIn), (tlOut, edgeOut)), i) =>
|
case (((tlIn, edgeIn), (tlOut, edgeOut)), i) =>
|
||||||
// Request queue
|
// Request queue
|
||||||
//
|
//
|
||||||
val reqQueue = reqQueues(i - 1)
|
val lane = i - 1
|
||||||
|
val reqQueue = reqQueues(lane)
|
||||||
val req = Wire(reqQueueEntryT)
|
val req = Wire(reqQueueEntryT)
|
||||||
req.source := tlIn.a.bits.source
|
req.source := tlIn.a.bits.source
|
||||||
req.address := tlIn.a.bits.address
|
req.address := tlIn.a.bits.address
|
||||||
@@ -124,8 +130,15 @@ class CoalescingUnitImp(outer: CoalescingUnit, numLanes: Int) extends LazyModule
|
|||||||
reqQueue.io.enq.bits := req
|
reqQueue.io.enq.bits := req
|
||||||
// TODO: deq.ready should respect downstream ready
|
// TODO: deq.ready should respect downstream ready
|
||||||
reqQueue.io.deq.ready := true.B
|
reqQueue.io.deq.ready := true.B
|
||||||
|
reqQueue.io.invalidate := 0.U
|
||||||
|
|
||||||
|
printf(s"reqQueue(${lane}).count=%d\n", reqQueue.io.count)
|
||||||
|
|
||||||
|
// Invalidate coalesced requests
|
||||||
|
// FIXME: hardcoded lanes
|
||||||
|
val invalidate = coalReqValid && (lane == 0 || lane == 2).B
|
||||||
|
tlOut.a.valid := reqQueue.io.deq.valid && !invalidate
|
||||||
|
|
||||||
tlOut.a.valid := reqQueue.io.deq.valid
|
|
||||||
val reqHead = reqQueue.io.deq.bits
|
val reqHead = reqQueue.io.deq.bits
|
||||||
// FIXME: generate Get or Put according to read/write
|
// FIXME: generate Get or Put according to read/write
|
||||||
val (reqLegal, reqBits) = edgeOut.Get(
|
val (reqLegal, reqBits) = edgeOut.Get(
|
||||||
@@ -141,7 +154,7 @@ class CoalescingUnitImp(outer: CoalescingUnit, numLanes: Int) extends LazyModule
|
|||||||
//
|
//
|
||||||
// This queue will serialize non-coalesced responses along with
|
// This queue will serialize non-coalesced responses along with
|
||||||
// coalesced responses and serve them back to the core side.
|
// coalesced responses and serve them back to the core side.
|
||||||
val respQueue = respQueues(i - 1)
|
val respQueue = respQueues(lane)
|
||||||
val resp = Wire(respQueueEntryT)
|
val resp = Wire(respQueueEntryT)
|
||||||
resp.source := tlOut.d.bits.source
|
resp.source := tlOut.d.bits.source
|
||||||
resp.data := tlOut.d.bits.data
|
resp.data := tlOut.d.bits.data
|
||||||
@@ -192,9 +205,13 @@ class CoalescingUnitImp(outer: CoalescingUnit, numLanes: Int) extends LazyModule
|
|||||||
val coalReqAddress = Wire(UInt(tlCoal.params.addressBits.W))
|
val coalReqAddress = Wire(UInt(tlCoal.params.addressBits.W))
|
||||||
// TODO: bogus address
|
// TODO: bogus address
|
||||||
coalReqAddress := (0xabcd.U + coalSourceId) << 4
|
coalReqAddress := (0xabcd.U + coalSourceId) << 4
|
||||||
val coalReqValid = Wire(Bool())
|
// FIXME: coalesce lane 0 and lane 2's queue head whenever they're valid
|
||||||
// FIXME: copy lane 1's valid signal. This is completely bogus
|
coalReqValid := reqQueues(0).io.deq.valid && reqQueues(2).io.deq.valid
|
||||||
coalReqValid := outer.node.in(1)._1.a.valid
|
when(coalReqValid) {
|
||||||
|
// invalidate original requests due to coalescing
|
||||||
|
reqQueues(0).io.invalidate := 0x1.U
|
||||||
|
reqQueues(2).io.invalidate := 0x1.U
|
||||||
|
}
|
||||||
|
|
||||||
val (legal, bits) = edgeCoal.Get(
|
val (legal, bits) = edgeCoal.Get(
|
||||||
fromSource = coalSourceId,
|
fromSource = coalSourceId,
|
||||||
|
|||||||
@@ -26,13 +26,13 @@ class MultiPortQueueUnitTest extends AnyFlatSpec with ChiselScalatestTester {
|
|||||||
for (_ <- 0 until 100) {
|
for (_ <- 0 until 100) {
|
||||||
c.clock.step()
|
c.clock.step()
|
||||||
}
|
}
|
||||||
c.io.deq(0).valid.expect(false.B)
|
// c.io.deq(0).valid.expect(false.B)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
class CoalShiftQueueTest extends AnyFlatSpec with ChiselScalatestTester {
|
class CoalShiftQueueTest extends AnyFlatSpec with ChiselScalatestTester {
|
||||||
behavior of "request queues"
|
behavior of "request shift queues"
|
||||||
|
|
||||||
it should "work like normal shiftqueue when no invalidate" in {
|
it should "work like normal shiftqueue when no invalidate" in {
|
||||||
test(new CoalShiftQueue(UInt(8.W), 4)) { c =>
|
test(new CoalShiftQueue(UInt(8.W), 4)) { c =>
|
||||||
|
|||||||
Reference in New Issue
Block a user