From 174da8e2da6a896d2e97bc264f9c827a0f4c35ac Mon Sep 17 00:00:00 2001 From: "Daniel R. Carvalho" Date: Wed, 28 Nov 2018 13:54:42 +0100 Subject: mem-cache: Add getter and setter to CacheBlk::whenReady Add a getter and a setter function to access CacheBlk::whenReady to encapsulate the variable and allow error checking. This error checking consists on verifying that writes to a block after it has been inserted follow a chronological order. As a side effect, tickInserted retain its value until updated, that is, it is not reset in invalidate(). Change-Id: Idc3c5a99c3f002ee9acc2424f00e554877fd3a69 Signed-off-by: Daniel R. Carvalho Reviewed-on: https://gem5-review.googlesource.com/c/14715 Reviewed-by: Nikos Nikoleris Maintainer: Nikos Nikoleris --- src/mem/cache/base.cc | 20 ++++++++++---------- src/mem/cache/cache_blk.hh | 37 +++++++++++++++++++++++++++++++++---- 2 files changed, 43 insertions(+), 14 deletions(-) (limited to 'src') diff --git a/src/mem/cache/base.cc b/src/mem/cache/base.cc index 244d7ce4e..bad24f7ee 100644 --- a/src/mem/cache/base.cc +++ b/src/mem/cache/base.cc @@ -900,10 +900,11 @@ BaseCache::calculateAccessLatency(const CacheBlk* blk, } // Check if the block to be accessed is available. If not, apply the - // access latency on top of block->whenReady. - if (blk->whenReady > curTick() && - ticksToCycles(blk->whenReady - curTick()) > lat) { - lat += ticksToCycles(blk->whenReady - curTick()); + // access latency on top of when the block is ready to be accessed. + const Tick when_ready = blk->getWhenReady(); + if (when_ready > curTick() && + ticksToCycles(when_ready - curTick()) > lat) { + lat += ticksToCycles(when_ready - curTick()); } } @@ -1024,8 +1025,8 @@ BaseCache::access(PacketPtr pkt, CacheBlk *&blk, Cycles &lat, DPRINTF(Cache, "%s new state is %s\n", __func__, blk->print()); incHitCount(pkt); // populate the time when the block will be ready to access. - blk->whenReady = clockEdge(fillLatency) + pkt->headerDelay + - pkt->payloadDelay; + blk->setWhenReady(clockEdge(fillLatency) + pkt->headerDelay + + pkt->payloadDelay); return true; } else if (pkt->cmd == MemCmd::CleanEvict) { if (blk) { @@ -1081,8 +1082,8 @@ BaseCache::access(PacketPtr pkt, CacheBlk *&blk, Cycles &lat, incHitCount(pkt); // populate the time when the block will be ready to access. - blk->whenReady = clockEdge(fillLatency) + pkt->headerDelay + - pkt->payloadDelay; + blk->setWhenReady(clockEdge(fillLatency) + pkt->headerDelay + + pkt->payloadDelay); // if this a write-through packet it will be sent to cache // below return !pkt->writeThrough(); @@ -1212,8 +1213,7 @@ BaseCache::handleFill(PacketPtr pkt, CacheBlk *blk, PacketList &writebacks, pkt->writeDataToBlock(blk->data, blkSize); } // We pay for fillLatency here. - blk->whenReady = clockEdge() + fillLatency * clockPeriod() + - pkt->payloadDelay; + blk->setWhenReady(clockEdge(fillLatency) + pkt->payloadDelay); return blk; } diff --git a/src/mem/cache/cache_blk.hh b/src/mem/cache/cache_blk.hh index d7530d656..9ace496ce 100644 --- a/src/mem/cache/cache_blk.hh +++ b/src/mem/cache/cache_blk.hh @@ -105,7 +105,10 @@ class CacheBlk : public ReplaceableEntry /** The current status of this block. @sa CacheBlockStatusBits */ State status; - /** Which curTick() will this block be accessible */ + /** + * Which curTick() will this block be accessible. Its value is only + * meaningful if the block is valid. + */ Tick whenReady; /** Number of references to this block since it was brought in. */ @@ -114,7 +117,10 @@ class CacheBlk : public ReplaceableEntry /** holds the source requestor ID for this block. */ int srcMasterId; - /** Tick on which the block was inserted in the cache. */ + /** + * Tick on which the block was inserted in the cache. Its value is only + * meaningful if the block is valid. + */ Tick tickInserted; protected: @@ -160,7 +166,7 @@ class CacheBlk : public ReplaceableEntry std::list lockList; public: - CacheBlk() : data(nullptr) + CacheBlk() : data(nullptr), tickInserted(0) { invalidate(); } @@ -211,7 +217,6 @@ class CacheBlk : public ReplaceableEntry whenReady = MaxTick; refCount = 0; srcMasterId = Request::invldMasterId; - tickInserted = MaxTick; lockList.clear(); } @@ -260,6 +265,30 @@ class CacheBlk : public ReplaceableEntry status |= BlkSecure; } + /** + * Get tick at which block's data will be available for access. + * + * @return Data ready tick. + */ + Tick getWhenReady() const + { + return whenReady; + } + + /** + * Set tick at which block's data will be available for access. The new + * tick must be chronologically sequential with respect to previous + * accesses. + * + * @param tick New data ready tick. + */ + void setWhenReady(const Tick tick) + { + assert((whenReady == MaxTick) || (tick >= whenReady)); + assert(tick >= tickInserted); + whenReady = tick; + } + /** * Set member variables when a block insertion occurs. Resets reference * count to 1 (the insertion counts as a reference), and touch block if -- cgit v1.2.3