1
0

WIP: Fix BufferlessBroadcastHub

This commit is contained in:
Howard Mao 2016-06-29 16:02:31 -07:00
parent ce46f523c9
commit 0eedffa82f
3 changed files with 35 additions and 26 deletions

View File

@ -79,8 +79,7 @@ class BufferlessBroadcastVoluntaryReleaseTracker(trackerId: Int)(implicit p: Par
(!io.irel().hasData() || io.outer.release.ready) (!io.irel().hasData() || io.outer.release.ready)
// Dispatch outer release // Dispatch outer release
outerRelease(coh = outer_coh.onHit(M_XWR)) outerRelease(coh = outer_coh.onHit(M_XWR), buffering = Bool(false))
io.outer.grant.ready := state === s_busy && io.inner.grant.ready // bypass data
quiesce() {} quiesce() {}
} }
@ -128,15 +127,20 @@ class BufferlessBroadcastAcquireTracker(trackerId: Int)(implicit p: Parameters)
// Send outer request for miss // Send outer request for miss
outerAcquire( outerAcquire(
caching = !xact_iacq.isBuiltInType(), caching = !xact_iacq.isBuiltInType(),
block_outer_acquire = vol_ognt_counter.pending,
buffering = Bool(false), buffering = Bool(false),
coh = outer_coh, coh = outer_coh,
next = s_busy) next = s_busy)
// Handle the response from outer memory // Handle the response from outer memory
io.outer.grant.ready := state === s_busy && io.inner.grant.ready // bypass data when (ognt_counter.pending && io.ognt().hasData()) {
io.outer.grant.ready := io.inner.grant.ready // bypass data
}
// Acknowledge or respond with data // Acknowledge or respond with data
innerGrant(external_pending = pending_orel || ognt_counter.pending || vol_ognt_counter.pending) innerGrant(
external_pending = pending_orel || vol_ognt_counter.pending,
buffering = Bool(false))
when(iacq_is_allocating) { initializeProbes() } when(iacq_is_allocating) { initializeProbes() }

View File

@ -955,7 +955,7 @@ class CacheAcquireTracker(trackerId: Int)(implicit p: Parameters)
innerGrant( innerGrant(
data = Mux(xact_iacq.isAtomic(), amo_result, data_buffer(ignt_data_idx)), data = Mux(xact_iacq.isAtomic(), amo_result, data_buffer(ignt_data_idx)),
external_pending = pending_writes.orR || ognt_counter.pending, external_pending = pending_writes.orR || ognt_counter.pending,
add = addPendingBitInternal(io.data.resp)) add_pending_bits = addPendingBitInternal(io.data.resp))
updatePendingCohWhen(io.inner.grant.fire() && io.ignt().last(), pending_coh_on_ignt) updatePendingCohWhen(io.inner.grant.fire() && io.ignt().last(), pending_coh_on_ignt)

View File

@ -287,9 +287,10 @@ trait EmitsVoluntaryReleases extends HasVoluntaryReleaseMetadataBuffer {
add_pending_send_bit: Bool = Bool(false)) { add_pending_send_bit: 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 & dropPendingBitWhenBeatHasData(io.outer.release)) | pending_orel_data := (pending_orel_data |
addPendingBitWhenBeatHasData(io.inner.release) | addPendingBitWhenBeatHasData(io.inner.release) |
add_pending_data_bits add_pending_data_bits) &
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()) { pending_orel_send := Bool(false) }
@ -301,13 +302,13 @@ 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 := state === s_busy && io.outer.release.valid := Mux(buffering,
Mux(io.orel().hasData(), (state === s_busy) && Mux(io.orel().hasData(),
Mux(buffering,
pending_orel_data(vol_ognt_counter.up.idx), pending_orel_data(vol_ognt_counter.up.idx),
io.inner.release.valid), pending_orel_send),
pending_orel) // only writebacks need to be forwarded to the outer interface
(io.alloc.irel.should || io.alloc.irel.matches) &&
io.irel().hasData() && io.inner.release.valid)
io.outer.release.bits := coh.makeVoluntaryWriteback( io.outer.release.bits := coh.makeVoluntaryWriteback(
client_xact_id = UInt(0), // TODO was tracker id, but not needed? client_xact_id = UInt(0), // TODO was tracker id, but not needed?
@ -315,7 +316,7 @@ trait EmitsVoluntaryReleases extends HasVoluntaryReleaseMetadataBuffer {
addr_beat = vol_ognt_counter.up.idx, addr_beat = vol_ognt_counter.up.idx,
data = data) data = data)
io.outer.grant.ready := state === s_busy when (vol_ognt_counter.pending) { io.outer.grant.ready := Bool(true) }
scoreboard += (pending_orel, vol_ognt_counter.pending) scoreboard += (pending_orel, vol_ognt_counter.pending)
} }
@ -457,7 +458,8 @@ trait AcceptsInnerAcquires extends HasAcquireMetadataBuffer
def innerGrant( def innerGrant(
data: UInt = io.ognt().data, data: UInt = io.ognt().data,
external_pending: Bool = Bool(false), external_pending: Bool = Bool(false),
add: UInt = UInt(0)) { buffering: Bool = Bool(true),
add_pending_bits: UInt = UInt(0)) {
// Track the number of outstanding inner.finishes // Track the number of outstanding inner.finishes
connectTwoWayBeatCounters( connectTwoWayBeatCounters(
status = ifin_counter, status = ifin_counter,
@ -471,12 +473,11 @@ trait AcceptsInnerAcquires extends HasAcquireMetadataBuffer
pending_ignt_data := (pending_ignt_data & dropPendingBitWhenBeatHasData(io.inner.grant)) | pending_ignt_data := (pending_ignt_data & dropPendingBitWhenBeatHasData(io.inner.grant)) |
addPendingBitWhenBeatHasData(io.inner.release) | addPendingBitWhenBeatHasData(io.inner.release) |
addPendingBitWhenBeatHasData(io.outer.grant) | addPendingBitWhenBeatHasData(io.outer.grant) |
add add_pending_bits
} }
// We can issue a grant for a pending write once all data is // Have we finished receiving the complete inner acquire transaction?
// received and committed to the data array or outer memory val iacq_finished = !(state === s_idle ||
val ignt_ack_ready = !(state === s_idle ||
state === s_meta_read || state === s_meta_read ||
pending_put_data.orR) pending_put_data.orR)
@ -495,8 +496,10 @@ trait AcceptsInnerAcquires extends HasAcquireMetadataBuffer
io.inner.grant.bits := ignt_from_iacq io.inner.grant.bits := ignt_from_iacq
io.inner.grant.bits.addr_beat := ignt_data_idx // override based on outgoing counter io.inner.grant.bits.addr_beat := ignt_data_idx // override based on outgoing counter
when (state === s_busy && pending_ignt) { when (state === s_busy && pending_ignt) {
io.inner.grant.valid := !external_pending && io.inner.grant.valid := !external_pending && Mux(buffering,
Mux(io.ignt().hasData(), pending_ignt_data(ignt_data_idx), ignt_ack_ready) Mux(io.ignt().hasData(),
pending_ignt_data(ignt_data_idx), iacq_finished),
io.outer.grant.valid)
} }
} }
@ -519,6 +522,7 @@ trait EmitsOuterAcquires extends AcceptsInnerAcquires {
def outerAcquire( def outerAcquire(
caching: Bool, caching: Bool,
coh: ClientMetadata, coh: ClientMetadata,
block_outer_acquire: Bool = Bool(false),
buffering: Bool = Bool(true), buffering: Bool = Bool(true),
data: UInt = io.iacq().data, data: UInt = io.iacq().data,
wmask: UInt = io.iacq().wmask(), wmask: UInt = io.iacq().wmask(),
@ -533,6 +537,7 @@ trait EmitsOuterAcquires extends AcceptsInnerAcquires {
trackDown = (g: Grant) => !g.isVoluntary()) trackDown = (g: Grant) => !g.isVoluntary())
io.outer.acquire.valid := state === s_outer_acquire && io.outer.acquire.valid := state === s_outer_acquire &&
!block_outer_acquire &&
(xact_allocate || (xact_allocate ||
Mux(buffering, Mux(buffering,
!pending_put_data(ognt_counter.up.idx), !pending_put_data(ognt_counter.up.idx),
@ -559,7 +564,7 @@ trait EmitsOuterAcquires extends AcceptsInnerAcquires {
when(state === s_outer_acquire && ognt_counter.up.done) { state := next } when(state === s_outer_acquire && ognt_counter.up.done) { state := next }
io.outer.grant.ready := state === s_busy when (ognt_counter.pending) { io.outer.grant.ready := Bool(true) }
scoreboard += ognt_counter.pending scoreboard += ognt_counter.pending
} }