fix lockup from back to back releases with data
This commit is contained in:
parent
fa8317fec1
commit
86e31be820
@ -160,7 +160,8 @@ class BufferedBroadcastAcquireTracker(trackerId: Int)(implicit p: Parameters)
|
|||||||
!all_pending_done &&
|
!all_pending_done &&
|
||||||
!io.outer.grant.fire() &&
|
!io.outer.grant.fire() &&
|
||||||
!io.inner.grant.fire() &&
|
!io.inner.grant.fire() &&
|
||||||
!vol_ignt_counter.pending
|
!vol_ignt_counter.pending &&
|
||||||
|
!blockInnerRelease()
|
||||||
|
|
||||||
innerRelease(block_vol_ignt = vol_ognt_counter.pending)
|
innerRelease(block_vol_ignt = vol_ognt_counter.pending)
|
||||||
|
|
||||||
|
@ -120,6 +120,7 @@ class BufferlessBroadcastAcquireTracker(trackerId: Int)(implicit p: Parameters)
|
|||||||
def irel_can_merge = io.irel().conflicts(xact_addr_block) &&
|
def irel_can_merge = io.irel().conflicts(xact_addr_block) &&
|
||||||
io.irel().isVoluntary() &&
|
io.irel().isVoluntary() &&
|
||||||
!vol_ignt_counter.pending &&
|
!vol_ignt_counter.pending &&
|
||||||
|
!(io.irel().hasData() && ognt_counter.pending) &&
|
||||||
(state =/= s_idle)
|
(state =/= s_idle)
|
||||||
|
|
||||||
innerRelease(block_vol_ignt = vol_ognt_counter.pending)
|
innerRelease(block_vol_ignt = vol_ognt_counter.pending)
|
||||||
@ -131,7 +132,8 @@ class BufferlessBroadcastAcquireTracker(trackerId: Int)(implicit p: Parameters)
|
|||||||
// If there was a writeback, forward it outwards
|
// If there was a writeback, forward it outwards
|
||||||
outerRelease(
|
outerRelease(
|
||||||
coh = outer_coh.onHit(M_XWR),
|
coh = outer_coh.onHit(M_XWR),
|
||||||
buffering = Bool(false))
|
buffering = Bool(false),
|
||||||
|
block_orel = !irel_could_accept)
|
||||||
|
|
||||||
// Send outer request for miss
|
// Send outer request for miss
|
||||||
outerAcquire(
|
outerAcquire(
|
||||||
|
@ -1050,7 +1050,8 @@ class L2WritebackUnit(val trackerId: Int)(implicit p: Parameters) extends XactTr
|
|||||||
io.irel().isVoluntary() &&
|
io.irel().isVoluntary() &&
|
||||||
(state =/= s_idle) &&
|
(state =/= s_idle) &&
|
||||||
!(state === s_busy && all_pending_done) &&
|
!(state === s_busy && all_pending_done) &&
|
||||||
!vol_ignt_counter.pending
|
!vol_ignt_counter.pending &&
|
||||||
|
!blockInnerRelease()
|
||||||
|
|
||||||
io.inner.release.ready := irel_can_merge || irel_same_xact
|
io.inner.release.ready := irel_can_merge || irel_same_xact
|
||||||
|
|
||||||
|
@ -294,13 +294,28 @@ trait EmitsVoluntaryReleases extends HasVoluntaryReleaseMetadataBuffer {
|
|||||||
val pending_orel_data = Reg(init=Bits(0, width = innerDataBeats))
|
val pending_orel_data = Reg(init=Bits(0, width = innerDataBeats))
|
||||||
val vol_ognt_counter = Wire(new TwoWayBeatCounterStatus)
|
val vol_ognt_counter = Wire(new TwoWayBeatCounterStatus)
|
||||||
val pending_orel = pending_orel_send || pending_orel_data.orR || vol_ognt_counter.pending
|
val pending_orel = pending_orel_send || pending_orel_data.orR || vol_ognt_counter.pending
|
||||||
|
val sending_orel = Reg(init = Bool(false))
|
||||||
|
|
||||||
|
// Block acceptance of inner releases if we have already started sending
|
||||||
|
// outer releases, but have not yet sent out the beat corresponding to the
|
||||||
|
// inner release. This function must be included in io.inner.release.ready
|
||||||
|
// if it is possible to start accepting a new inner release as the previous
|
||||||
|
// outer release is still being sent. DO NOT include this in the
|
||||||
|
// io.inner.release.ready if the releases are not buffered
|
||||||
|
// (i.e. io.inner.release and io.outer.release combinationally linked).
|
||||||
|
def blockInnerRelease(rel: ReleaseMetadata = io.irel()): Bool = {
|
||||||
|
val waiting_to_send = sending_orel && pending_orel_data(rel.addr_beat)
|
||||||
|
val sending_now = io.outer.release.fire() && rel.addr_beat === io.orel().addr_beat
|
||||||
|
rel.hasData() && (waiting_to_send || sending_now)
|
||||||
|
}
|
||||||
|
|
||||||
def outerRelease(
|
def outerRelease(
|
||||||
coh: ClientMetadata,
|
coh: ClientMetadata,
|
||||||
buffering: Bool = Bool(true),
|
buffering: Bool = Bool(true),
|
||||||
data: UInt = io.irel().data,
|
data: UInt = io.irel().data,
|
||||||
add_pending_data_bits: UInt = UInt(0),
|
add_pending_data_bits: UInt = UInt(0),
|
||||||
add_pending_send_bit: Bool = Bool(false)) {
|
add_pending_send_bit: Bool = Bool(false),
|
||||||
|
block_orel: Bool = Bool(false)) {
|
||||||
|
|
||||||
when (state =/= s_idle || io.alloc.irel.should) {
|
when (state =/= s_idle || io.alloc.irel.should) {
|
||||||
pending_orel_data := (pending_orel_data |
|
pending_orel_data := (pending_orel_data |
|
||||||
@ -309,7 +324,11 @@ trait EmitsVoluntaryReleases extends HasVoluntaryReleaseMetadataBuffer {
|
|||||||
dropPendingBitWhenBeatHasData(io.outer.release)
|
dropPendingBitWhenBeatHasData(io.outer.release)
|
||||||
}
|
}
|
||||||
when (add_pending_send_bit) { pending_orel_send := Bool(true) }
|
when (add_pending_send_bit) { pending_orel_send := Bool(true) }
|
||||||
when (io.outer.release.fire()) { pending_orel_send := Bool(false) }
|
when (io.outer.release.fire()) {
|
||||||
|
when (io.outer.release.bits.first()) { sending_orel := Bool(true) }
|
||||||
|
when (io.outer.release.bits.last()) { sending_orel := Bool(false) }
|
||||||
|
pending_orel_send := Bool(false)
|
||||||
|
}
|
||||||
|
|
||||||
connectTwoWayBeatCounters(
|
connectTwoWayBeatCounters(
|
||||||
status = vol_ognt_counter,
|
status = vol_ognt_counter,
|
||||||
@ -318,7 +337,7 @@ trait EmitsVoluntaryReleases extends HasVoluntaryReleaseMetadataBuffer {
|
|||||||
trackUp = (r: Release) => r.isVoluntary() && r.requiresAck(),
|
trackUp = (r: Release) => r.isVoluntary() && r.requiresAck(),
|
||||||
trackDown = (g: Grant) => g.isVoluntary())
|
trackDown = (g: Grant) => g.isVoluntary())
|
||||||
|
|
||||||
io.outer.release.valid := Mux(buffering,
|
io.outer.release.valid := !block_orel && Mux(buffering,
|
||||||
(state === s_busy) && Mux(io.orel().hasData(),
|
(state === s_busy) && Mux(io.orel().hasData(),
|
||||||
pending_orel_data(vol_ognt_counter.up.idx),
|
pending_orel_data(vol_ognt_counter.up.idx),
|
||||||
pending_orel_send),
|
pending_orel_send),
|
||||||
|
Loading…
Reference in New Issue
Block a user