diff --git a/uncore/src/main/scala/broadcast.scala b/uncore/src/main/scala/broadcast.scala index 9f996c23..a0ed179f 100644 --- a/uncore/src/main/scala/broadcast.scala +++ b/uncore/src/main/scala/broadcast.scala @@ -113,14 +113,13 @@ class BufferedBroadcastVoluntaryReleaseTracker(trackerId: Int)(implicit p: Param // A release beat can be accepted if we are idle, if its a mergeable transaction, or if its a tail beat io.inner.release.ready := state === s_idle || irel_can_merge || irel_same_xact - when(irel_is_allocating) { pending_orel := io.irel().hasData() } - when(io.inner.release.fire()) { data_buffer(io.irel().addr_beat) := io.irel().data } // Dispatch outer release outerRelease( coh = outer_coh.onHit(M_XWR), - data = data_buffer(vol_ognt_counter.up.idx)) + data = data_buffer(vol_ognt_counter.up.idx), + add_pending_send_bit = irel_is_allocating) quiesce() {} } diff --git a/uncore/src/main/scala/cache.scala b/uncore/src/main/scala/cache.scala index b67f2621..ecaa3dc7 100644 --- a/uncore/src/main/scala/cache.scala +++ b/uncore/src/main/scala/cache.scala @@ -1045,11 +1045,16 @@ class L2WritebackUnit(val trackerId: Int)(implicit p: Parameters) extends XactTr // If a release didn't write back data, have to read it from data array readDataArray(drop_pending_bit = dropPendingBitWhenBeatHasData(io.inner.release)) + val coh = io.wb.req.bits.coh + val needs_inner_probes = coh.inner.requiresProbesOnVoluntaryWriteback() + val needs_outer_release = coh.outer.requiresVoluntaryWriteback() + // Once the data is buffered we can write it back to outer memory outerRelease( coh = outer_coh, data = data_buffer(vol_ognt_counter.up.idx), - add_pending_bit = addPendingBitInternal(io.data.resp)) + add_pending_data_bits = addPendingBitInternal(io.data.resp), + add_pending_send_bit = io.wb.req.fire() && needs_outer_release) // Respond to the initiating transaction handler signalling completion of the writeback io.wb.resp.valid := state === s_busy && all_pending_done @@ -1064,14 +1069,9 @@ class L2WritebackUnit(val trackerId: Int)(implicit p: Parameters) extends XactTr xact_way_en := io.wb.req.bits.way_en xact_addr_block := (if (cacheIdBits == 0) Cat(io.wb.req.bits.tag, io.wb.req.bits.idx) else Cat(io.wb.req.bits.tag, io.wb.req.bits.idx, UInt(cacheId, cacheIdBits))) - val coh = io.wb.req.bits.coh - val needs_inner_probes = coh.inner.requiresProbesOnVoluntaryWriteback() - val needs_outer_release = coh.outer.requiresVoluntaryWriteback() when(needs_inner_probes) { initializeProbes() } pending_reads := Mux(needs_outer_release, ~UInt(0, width = innerDataBeats), UInt(0)) pending_resps := UInt(0) - pending_orel := needs_outer_release - //pending_orel_data := UInt(0) pending_coh := coh state := Mux(needs_inner_probes, s_inner_probe, s_busy) } diff --git a/uncore/src/main/scala/trackers.scala b/uncore/src/main/scala/trackers.scala index 5852b070..25f2f57e 100644 --- a/uncore/src/main/scala/trackers.scala +++ b/uncore/src/main/scala/trackers.scala @@ -264,18 +264,23 @@ trait AcceptsVoluntaryReleases extends HasVoluntaryReleaseMetadataBuffer { } trait EmitsVoluntaryReleases extends HasVoluntaryReleaseMetadataBuffer { - val pending_orel = Reg(init=Bool(false)) + val pending_orel_send = Reg(init=Bool(false)) val pending_orel_data = Reg(init=Bits(0, width = innerDataBeats)) val vol_ognt_counter = Wire(new TwoWayBeatCounterStatus) + val pending_orel = pending_orel_send || pending_orel_data.orR || vol_ognt_counter.pending def outerRelease( coh: ClientMetadata, buffering: Bool = Bool(true), data: UInt = io.irel().data, - add_pending_bit: UInt = UInt(0)) { + add_pending_data_bits: UInt = UInt(0), + add_pending_send_bit: Bool = Bool(false)) { + pending_orel_data := (pending_orel_data & dropPendingBitWhenBeatHasData(io.outer.release)) | addPendingBitWhenBeatHasData(io.inner.release) | - add_pending_bit + add_pending_data_bits + when (add_pending_send_bit) { pending_orel_send := Bool(true) } + when (io.outer.release.fire()) { pending_orel_send := Bool(false) } connectTwoWayBeatCounters( status = vol_ognt_counter, @@ -290,7 +295,7 @@ trait EmitsVoluntaryReleases extends HasVoluntaryReleaseMetadataBuffer { pending_orel_data(vol_ognt_counter.up.idx), io.inner.release.valid), pending_orel) - + io.outer.release.bits := coh.makeVoluntaryWriteback( client_xact_id = UInt(0), // TODO was tracker id, but not needed? @@ -298,9 +303,6 @@ trait EmitsVoluntaryReleases extends HasVoluntaryReleaseMetadataBuffer { addr_beat = vol_ognt_counter.up.idx, data = data) - when(pending_orel_data.orR) { pending_orel := Bool(true) } - when(vol_ognt_counter.up.done) { pending_orel := Bool(false) } - io.outer.grant.ready := state === s_busy scoreboard += (pending_orel, vol_ognt_counter.pending)