From 3b927489371d61ef8b4d0ca9d7a2ca6a5c85f38b Mon Sep 17 00:00:00 2001 From: Andreas Hansson Date: Thu, 27 Jun 2013 05:49:49 -0400 Subject: [PATCH] mem: Tidy up the bridge with const and additional checks This patch does a bit of tidying up in the bridge code, adding const where appropriate and also removing redundant checks and adding a few new ones. There are no changes to the behaviour of any regressions. --- src/mem/Bridge.py | 6 ++--- src/mem/bridge.cc | 66 +++++++++++++++++++++++------------------------ src/mem/bridge.hh | 32 ++++++++++++----------- 3 files changed, 53 insertions(+), 51 deletions(-) diff --git a/src/mem/Bridge.py b/src/mem/Bridge.py index 5f2cc9f40..e488871a4 100644 --- a/src/mem/Bridge.py +++ b/src/mem/Bridge.py @@ -1,4 +1,4 @@ -# Copyright (c) 2012 ARM Limited +# Copyright (c) 2012-2013 ARM Limited # All rights reserved. # # The license below extends only to copyright in the software and shall @@ -47,8 +47,8 @@ class Bridge(MemObject): cxx_header = "mem/bridge.hh" slave = SlavePort('Slave port') master = MasterPort('Master port') - req_size = Param.Int(16, "The number of requests to buffer") - resp_size = Param.Int(16, "The number of responses to buffer") + req_size = Param.Unsigned(16, "The number of requests to buffer") + resp_size = Param.Unsigned(16, "The number of responses to buffer") delay = Param.Latency('0ns', "The latency of this bridge") ranges = VectorParam.AddrRange([AllMemory], "Address ranges to pass through the bridge") diff --git a/src/mem/bridge.cc b/src/mem/bridge.cc index 91bef2757..f8258086c 100644 --- a/src/mem/bridge.cc +++ b/src/mem/bridge.cc @@ -1,5 +1,5 @@ /* - * Copyright (c) 2011-2012 ARM Limited + * Copyright (c) 2011-2013 ARM Limited * All rights reserved * * The license below extends only to copyright in the software and shall @@ -120,13 +120,13 @@ Bridge::init() } bool -Bridge::BridgeSlavePort::respQueueFull() +Bridge::BridgeSlavePort::respQueueFull() const { return outstandingResponses == respQueueLimit; } bool -Bridge::BridgeMasterPort::reqQueueFull() +Bridge::BridgeMasterPort::reqQueueFull() const { return transmitList.size() == reqQueueLimit; } @@ -155,26 +155,36 @@ Bridge::BridgeSlavePort::recvTimingReq(PacketPtr pkt) DPRINTF(Bridge, "recvTimingReq: %s addr 0x%x\n", pkt->cmdString(), pkt->getAddr()); - // ensure we do not have something waiting to retry - if(retryReq) - return false; + // we should not see a timing request if we are already in a retry + assert(!retryReq); DPRINTF(Bridge, "Response queue size: %d outresp: %d\n", transmitList.size(), outstandingResponses); + // if the request queue is full then there is no hope if (masterPort.reqQueueFull()) { DPRINTF(Bridge, "Request queue full\n"); retryReq = true; - } else if (pkt->needsResponse()) { - if (respQueueFull()) { - DPRINTF(Bridge, "Response queue full\n"); - retryReq = true; - } else { - DPRINTF(Bridge, "Reserving space for response\n"); - assert(outstandingResponses != respQueueLimit); - ++outstandingResponses; - retryReq = false; + } else { + // look at the response queue if we expect to see a response + bool expects_response = pkt->needsResponse() && + !pkt->memInhibitAsserted(); + if (expects_response) { + if (respQueueFull()) { + DPRINTF(Bridge, "Response queue full\n"); + retryReq = true; + } else { + // ok to send the request with space for the response + DPRINTF(Bridge, "Reserving space for response\n"); + assert(outstandingResponses != respQueueLimit); + ++outstandingResponses; + // no need to set retryReq to false as this is already the + // case + } + } + + if (!retryReq) { // @todo: We need to pay for this and not just zero it out pkt->busFirstWordDelay = pkt->busLastWordDelay = 0; @@ -274,9 +284,9 @@ Bridge::BridgeMasterPort::trySendTiming() // If there are more packets to send, schedule event to try again. if (!transmitList.empty()) { - req = transmitList.front(); + DeferredPacket next_req = transmitList.front(); DPRINTF(Bridge, "Scheduling next send\n"); - bridge.schedule(sendEvent, std::max(req.tick, + bridge.schedule(sendEvent, std::max(next_req.tick, bridge.clockEdge())); } @@ -315,9 +325,9 @@ Bridge::BridgeSlavePort::trySendTiming() // If there are more packets to send, schedule event to try again. if (!transmitList.empty()) { - resp = transmitList.front(); + DeferredPacket next_resp = transmitList.front(); DPRINTF(Bridge, "Scheduling next send\n"); - bridge.schedule(sendEvent, std::max(resp.tick, + bridge.schedule(sendEvent, std::max(next_resp.tick, bridge.clockEdge())); } @@ -338,21 +348,13 @@ Bridge::BridgeSlavePort::trySendTiming() void Bridge::BridgeMasterPort::recvRetry() { - Tick nextReady = transmitList.front().tick; - if (nextReady <= curTick()) - trySendTiming(); - else - bridge.schedule(sendEvent, nextReady); + trySendTiming(); } void Bridge::BridgeSlavePort::recvRetry() { - Tick nextReady = transmitList.front().tick; - if (nextReady <= curTick()) - trySendTiming(); - else - bridge.schedule(sendEvent, nextReady); + trySendTiming(); } Tick @@ -364,12 +366,10 @@ Bridge::BridgeSlavePort::recvAtomic(PacketPtr pkt) void Bridge::BridgeSlavePort::recvFunctional(PacketPtr pkt) { - std::list::iterator i; - pkt->pushLabel(name()); // check the response queue - for (i = transmitList.begin(); i != transmitList.end(); ++i) { + for (auto i = transmitList.begin(); i != transmitList.end(); ++i) { if (pkt->checkFunctional((*i).pkt)) { pkt->makeResponse(); return; @@ -391,7 +391,7 @@ bool Bridge::BridgeMasterPort::checkFunctional(PacketPtr pkt) { bool found = false; - std::list::iterator i = transmitList.begin(); + auto i = transmitList.begin(); while(i != transmitList.end() && !found) { if (pkt->checkFunctional((*i).pkt)) { diff --git a/src/mem/bridge.hh b/src/mem/bridge.hh index 2e594a30a..e672c1f7a 100644 --- a/src/mem/bridge.hh +++ b/src/mem/bridge.hh @@ -1,5 +1,5 @@ /* - * Copyright (c) 2011-2012 ARM Limited + * Copyright (c) 2011-2013 ARM Limited * All rights reserved * * The license below extends only to copyright in the software and shall @@ -51,7 +51,7 @@ #ifndef __MEM_BRIDGE_HH__ #define __MEM_BRIDGE_HH__ -#include +#include #include "base/types.hh" #include "mem/mem_object.hh" @@ -84,7 +84,7 @@ class Bridge : public MemObject public: - PortID origSrc; + const PortID origSrc; RequestState(PortID orig_src) : origSrc(orig_src) { } @@ -100,8 +100,8 @@ class Bridge : public MemObject public: - Tick tick; - PacketPtr pkt; + const Tick tick; + const PacketPtr pkt; DeferredPacket(PacketPtr _pkt, Tick _tick) : tick(_tick), pkt(_pkt) { } @@ -131,17 +131,18 @@ class Bridge : public MemObject BridgeMasterPort& masterPort; /** Minimum request delay though this bridge. */ - Cycles delay; + const Cycles delay; /** Address ranges to pass through the bridge */ - AddrRangeList ranges; + const AddrRangeList ranges; /** * Response packet queue. Response packets are held in this * queue for a specified delay to model the processing delay - * of the bridge. + * of the bridge. We use a deque as we need to iterate over + * the items for functional accesses. */ - std::list transmitList; + std::deque transmitList; /** Counter to track the outstanding responses. */ unsigned int outstandingResponses; @@ -157,7 +158,7 @@ class Bridge : public MemObject * * @return true if the reserved space has reached the set limit */ - bool respQueueFull(); + bool respQueueFull() const; /** * Handle send event, scheduled when the packet at the head of @@ -246,17 +247,18 @@ class Bridge : public MemObject BridgeSlavePort& slavePort; /** Minimum delay though this bridge. */ - Cycles delay; + const Cycles delay; /** * Request packet queue. Request packets are held in this * queue for a specified delay to model the processing delay - * of the bridge. + * of the bridge. We use a deque as we need to iterate over + * the items for functional accesses. */ - std::list transmitList; + std::deque transmitList; /** Max queue size for request packets */ - unsigned int reqQueueLimit; + const unsigned int reqQueueLimit; /** * Handle send event, scheduled when the packet at the head of @@ -289,7 +291,7 @@ class Bridge : public MemObject * * @return true if the occupied space has reached the set limit */ - bool reqQueueFull(); + bool reqQueueFull() const; /** * Queue a request packet to be sent out later and also schedule