From f34b0b0447f9baae7a24e58d4a2c839a3b00e26e Mon Sep 17 00:00:00 2001 From: Howard Mao Date: Fri, 29 Jul 2016 16:47:31 -0700 Subject: [PATCH] make sure L2 tracker doesn't read data array again if data buffer already filled --- uncore/src/main/scala/agents/Cache.scala | 14 ++++++++------ uncore/src/main/scala/agents/Trackers.scala | 17 ++++++++++------- 2 files changed, 18 insertions(+), 13 deletions(-) diff --git a/uncore/src/main/scala/agents/Cache.scala b/uncore/src/main/scala/agents/Cache.scala index 80f8f8dd..38b2a32a 100644 --- a/uncore/src/main/scala/agents/Cache.scala +++ b/uncore/src/main/scala/agents/Cache.scala @@ -612,9 +612,8 @@ trait ReadsFromOuterCacheDataArray extends HasCoherenceMetadataBuffer can_update_pending: Bool = Bool(true)) { val port = io.data when (can_update_pending) { - pending_reads := (pending_reads & - dropPendingBit(port.read) & drop_pending_bit) | - add_pending_bit + pending_reads := (pending_reads | add_pending_bit) & + dropPendingBit(port.read) & drop_pending_bit } port.read.valid := state === s_busy && pending_reads.orR && !block_pending_read port.read.bits := L2DataReadReq( @@ -690,6 +689,7 @@ trait HasAMOALU extends HasAcquireMetadataBuffer val wmask = FillInterleaved(8, wmask_buffer(beat)) data_buffer(beat) := ~wmask & old_data | wmask & Mux(xact_iacq.isAtomic(), amoalu.io.out << amo_shift_bits, new_data) + wmask_buffer(beat) := ~UInt(0, innerWriteMaskBits) when(xact_iacq.isAtomic() && xact_addr_beat === beat) { amo_result := old_data } } } @@ -795,7 +795,7 @@ class CacheVoluntaryReleaseTracker(trackerId: Int)(implicit p: Parameters) xact_old_meta.coh.outer)), s_idle) - when(io.inner.release.fire()) { data_buffer(io.irel().addr_beat) := io.irel().data } + mergeDataInner(io.inner.release) when(irel_is_allocating) { pending_writes := addPendingBitWhenBeatHasData(io.inner.release) @@ -966,7 +966,10 @@ class CacheAcquireTracker(trackerId: Int)(implicit p: Parameters) readDataArray( drop_pending_bit = (dropPendingBitWhenBeatHasData(io.inner.release) & dropPendingBitWhenBeatHasData(io.outer.grant)), - add_pending_bit = addPendingBitWhenBeatNeedsRead(io.inner.acquire, Bool(alwaysWriteFullBeat)), + add_pending_bit = addPendingBitWhenBeatNeedsRead( + io.inner.acquire, + always = Bool(alwaysWriteFullBeat), + unless = data_valid(io.iacq().addr_beat)), block_pending_read = ognt_counter.pending, can_update_pending = state =/= s_idle || io.alloc.irel.should) @@ -1119,7 +1122,6 @@ class L2WritebackUnit(val trackerId: Int)(implicit p: Parameters) extends XactTr add_pending_data_bits = addPendingBitInternal(io.data.resp), add_pending_send_bit = io.meta.resp.valid && needs_outer_release) - // Respond to the initiating transaction handler signalling completion of the writeback io.wb.resp.valid := state === s_busy && all_pending_done io.wb.resp.bits.id := xact_id diff --git a/uncore/src/main/scala/agents/Trackers.scala b/uncore/src/main/scala/agents/Trackers.scala index 80d7a409..05b63089 100644 --- a/uncore/src/main/scala/agents/Trackers.scala +++ b/uncore/src/main/scala/agents/Trackers.scala @@ -105,9 +105,10 @@ trait HasPendingBitHelpers extends HasDataBeatCounters { alloc_override: Bool = Bool(false)): UInt = addPendingBitWhenBeatHasData(in, in.bits.allocate() || alloc_override) - def addPendingBitWhenBeatNeedsRead(in: DecoupledIO[AcquireFromSrc], inc: Bool = Bool(true)): UInt = { + def addPendingBitWhenBeatNeedsRead(in: DecoupledIO[AcquireFromSrc], + always: Bool = Bool(true), unless: Bool = Bool(false)): UInt = { val a = in.bits - val needs_read = (a.isGet() || a.isAtomic() || a.hasPartialWritemask()) || inc + val needs_read = !unless && (a.isGet() || a.isAtomic() || a.hasPartialWritemask()) || always addPendingBitWhenBeat(in.fire() && needs_read, a) } @@ -176,6 +177,7 @@ trait HasDataBuffer extends HasCoherenceAgentParameters { trait HasByteWriteMaskBuffer extends HasDataBuffer { val wmask_buffer = Reg(init=Vec.fill(innerDataBeats)(UInt(0, width = innerWriteMaskBits))) + val data_valid = Vec(wmask_buffer.map(wmask => wmask.andR)) override def initDataInner[T <: Acquire](in: DecoupledIO[T], alloc: Bool) { when(in.fire() && in.bits.hasData() && alloc) { @@ -190,7 +192,8 @@ trait HasByteWriteMaskBuffer extends HasDataBuffer { val old_data = incoming // Refilled, written back, or de-cached data val new_data = data_buffer(beat) // Newly Put data is already in the buffer val wmask = FillInterleaved(8, wmask_buffer(beat)) - data_buffer(beat) := ~wmask & old_data | wmask & new_data + data_buffer(beat) := (~wmask & old_data) | (wmask & new_data) + wmask_buffer(beat) := ~UInt(0, innerWriteMaskBits) } def clearWmaskBuffer() { @@ -520,10 +523,10 @@ trait AcceptsInnerAcquires extends HasAcquireMetadataBuffer // Track which beats are ready for response when(!iacq_is_allocating) { - pending_ignt_data := (pending_ignt_data & dropPendingBitWhenBeatHasData(io.inner.grant)) | - addPendingBitWhenBeatHasData(io.inner.release) | - addPendingBitWhenBeatHasData(io.outer.grant) | - add_pending_bits + pending_ignt_data := pending_ignt_data | + addPendingBitWhenBeatHasData(io.inner.release) | + addPendingBitWhenBeatHasData(io.outer.grant) | + add_pending_bits } if (p(EnableL2Logging)) {