diff -r 438f37f51ba2 -r 1f65fc6d046a src/mem/cache/base.hh --- a/src/mem/cache/base.hh Thu Aug 01 00:23:01 2013 -0700 +++ b/src/mem/cache/base.hh Thu Aug 01 00:29:52 2013 -0700 @@ -139,7 +139,8 @@ CacheMasterPort(const std::string &_name, BaseCache *_cache, MasterPacketQueue &_queue) : - QueuedMasterPort(_name, _cache, _queue) + QueuedMasterPort(_name, _cache, _queue), + sendRetryEvent(this) { } /** @@ -148,6 +149,8 @@ * @return always true */ virtual bool isSnooping() const { return true; } + + EventWrapper sendRetryEvent; }; /** @@ -208,9 +211,6 @@ /** Check and unmark this cache bank in-service if necessary */ void checkAndUnmarkInService(); - /** Extend this cache bank's in-service time by extraTick */ - void extendService(Tick extraTick); - CacheBank(const std::string &_name) : bankName(_name), inService(false), diff -r 438f37f51ba2 -r 1f65fc6d046a src/mem/cache/base.cc --- a/src/mem/cache/base.cc Thu Aug 01 00:23:01 2013 -0700 +++ b/src/mem/cache/base.cc Thu Aug 01 00:29:52 2013 -0700 @@ -131,16 +131,6 @@ } void -BaseCache::CacheBank::extendService(Tick extraTick) -{ - assert(inService); - assert(nextIdleTick > curTick()); - nextIdleTick += extraTick; - DPRINTF(CacheBank, "Extend service to Tick %ld\n", - nextIdleTick); -} - -void BaseCache::CacheSlavePort::setBlocked() { assert(!blocked); diff -r 438f37f51ba2 -r 1f65fc6d046a src/mem/cache/cache_impl.hh --- a/src/mem/cache/cache_impl.hh Thu Aug 01 00:23:01 2013 -0700 +++ b/src/mem/cache/cache_impl.hh Thu Aug 01 00:29:52 2013 -0700 @@ -927,11 +927,8 @@ if (enableBankModel) { // mark the corresponding bank in service unsigned bank_id = getBankId(pkt->getAddr()); - if (bank[bank_id]->isBusy()) { - bank[bank_id]->extendService(writeLatency * clockPeriod()); - } else { - bank[bank_id]->markInService(clockEdge(writeLatency)); - } + assert(!(bank[bank_id]->isBusy())); + bank[bank_id]->markInService(clockEdge(writeLatency)); } } @@ -1872,6 +1869,20 @@ for (auto b = cache->bank.begin(); b != cache->bank.end(); ++b) ((*b)->checkAndUnmarkInService()); + unsigned bank_id = cache->getBankId(pkt->getAddr()); + bool bank_busy = cache->enableBankModel && cache->bank[bank_id]->isBusy(); + bool isFill = pkt->isRead() || pkt->cmd == MemCmd::UpgradeResp; + + // Check if the cache bank is busy for a cache line operations. + // If so, block the cache port. + if (bank_busy && isFill) { + DPRINTF(CachePort, "Cache port %s denying new cache fills because the " + "accessing bank is busy\n", name()); + if (!sendRetryEvent.scheduled()) + owner.schedule(sendRetryEvent, cache->bank[bank_id]->finishTick()); + return false; + } + cache->recvTimingResp(pkt); return true; } diff -r 438f37f51ba2 -r 1f65fc6d046a src/mem/coherent_bus.hh --- a/src/mem/coherent_bus.hh Thu Aug 01 00:23:01 2013 -0700 +++ b/src/mem/coherent_bus.hh Thu Aug 01 00:29:52 2013 -0700 @@ -132,7 +132,10 @@ * When receiving a retry, pass it to the bus. */ virtual void recvRetry() +/* NOTE: tentatively let the port handle retry { panic("Bus slave ports always succeed and should never retry.\n"); } +*/ + { bus.respLayers[id]->recvRetry(); } /** * Return the union of all adress ranges seen by this bus. diff -r 438f37f51ba2 -r 1f65fc6d046a src/mem/coherent_bus.cc --- a/src/mem/coherent_bus.cc Thu Aug 01 00:23:01 2013 -0700 +++ b/src/mem/coherent_bus.cc Thu Aug 01 00:29:52 2013 -0700 @@ -265,7 +265,7 @@ // the packet is a normal response to a request that we should // have seen passing through the bus assert(outstandingReq.find(pkt->req) != outstandingReq.end()); - +/* NOTE: tentatively let the port handle retry // remove it as outstanding outstandingReq.erase(pkt->req); @@ -285,6 +285,40 @@ transDist[pkt_cmd]++; return true; +*/ + + // send the packet to the destination through one of our slave + // ports, as determined by the destination field + bool success = slavePorts[pkt->getDest()]->sendTimingResp(pkt); + + if (!success) { + + // undo the calculation so we can check for 0 again + pkt->busFirstWordDelay = pkt->busLastWordDelay = 0; + + DPRINTF(CoherentBus, "recvTimingResp: src %s %s 0x%x RETRY\n", + src_port->name(), pkt->cmdString(), pkt->getAddr()); + + // update the bus state and schedule an idle event + respLayers[slave_port_id]->failedTiming(src_port, + clockEdge(Cycles(headerCycles))); + + } else { + + // remove it as outstanding + outstandingReq.erase(pkt->req); + + // update the bus state and schedule an idle event + respLayers[slave_port_id]->succeededTiming(packetFinishTime); + + // stats updates + dataThroughBus += pkt_size; + pktCount[slave_port_id][master_port_id]++; + totPktSize[slave_port_id][master_port_id] += pkt_size; + transDist[pkt_cmd]++; + } + + return success; } void