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.
This commit is contained in:
Andreas Hansson 2013-06-27 05:49:49 -04:00
parent f25ea3fd56
commit 3b92748937
3 changed files with 53 additions and 51 deletions

View file

@ -1,4 +1,4 @@
# Copyright (c) 2012 ARM Limited # Copyright (c) 2012-2013 ARM Limited
# All rights reserved. # All rights reserved.
# #
# The license below extends only to copyright in the software and shall # The license below extends only to copyright in the software and shall
@ -47,8 +47,8 @@ class Bridge(MemObject):
cxx_header = "mem/bridge.hh" cxx_header = "mem/bridge.hh"
slave = SlavePort('Slave port') slave = SlavePort('Slave port')
master = MasterPort('Master port') master = MasterPort('Master port')
req_size = Param.Int(16, "The number of requests to buffer") req_size = Param.Unsigned(16, "The number of requests to buffer")
resp_size = Param.Int(16, "The number of responses to buffer") resp_size = Param.Unsigned(16, "The number of responses to buffer")
delay = Param.Latency('0ns', "The latency of this bridge") delay = Param.Latency('0ns', "The latency of this bridge")
ranges = VectorParam.AddrRange([AllMemory], ranges = VectorParam.AddrRange([AllMemory],
"Address ranges to pass through the bridge") "Address ranges to pass through the bridge")

View file

@ -1,5 +1,5 @@
/* /*
* Copyright (c) 2011-2012 ARM Limited * Copyright (c) 2011-2013 ARM Limited
* All rights reserved * All rights reserved
* *
* The license below extends only to copyright in the software and shall * The license below extends only to copyright in the software and shall
@ -120,13 +120,13 @@ Bridge::init()
} }
bool bool
Bridge::BridgeSlavePort::respQueueFull() Bridge::BridgeSlavePort::respQueueFull() const
{ {
return outstandingResponses == respQueueLimit; return outstandingResponses == respQueueLimit;
} }
bool bool
Bridge::BridgeMasterPort::reqQueueFull() Bridge::BridgeMasterPort::reqQueueFull() const
{ {
return transmitList.size() == reqQueueLimit; return transmitList.size() == reqQueueLimit;
} }
@ -155,26 +155,36 @@ Bridge::BridgeSlavePort::recvTimingReq(PacketPtr pkt)
DPRINTF(Bridge, "recvTimingReq: %s addr 0x%x\n", DPRINTF(Bridge, "recvTimingReq: %s addr 0x%x\n",
pkt->cmdString(), pkt->getAddr()); pkt->cmdString(), pkt->getAddr());
// ensure we do not have something waiting to retry // we should not see a timing request if we are already in a retry
if(retryReq) assert(!retryReq);
return false;
DPRINTF(Bridge, "Response queue size: %d outresp: %d\n", DPRINTF(Bridge, "Response queue size: %d outresp: %d\n",
transmitList.size(), outstandingResponses); transmitList.size(), outstandingResponses);
// if the request queue is full then there is no hope
if (masterPort.reqQueueFull()) { if (masterPort.reqQueueFull()) {
DPRINTF(Bridge, "Request queue full\n"); DPRINTF(Bridge, "Request queue full\n");
retryReq = true; retryReq = true;
} else if (pkt->needsResponse()) { } else {
if (respQueueFull()) { // look at the response queue if we expect to see a response
DPRINTF(Bridge, "Response queue full\n"); bool expects_response = pkt->needsResponse() &&
retryReq = true; !pkt->memInhibitAsserted();
} else { if (expects_response) {
DPRINTF(Bridge, "Reserving space for response\n"); if (respQueueFull()) {
assert(outstandingResponses != respQueueLimit); DPRINTF(Bridge, "Response queue full\n");
++outstandingResponses; retryReq = true;
retryReq = false; } 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 // @todo: We need to pay for this and not just zero it out
pkt->busFirstWordDelay = pkt->busLastWordDelay = 0; 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 there are more packets to send, schedule event to try again.
if (!transmitList.empty()) { if (!transmitList.empty()) {
req = transmitList.front(); DeferredPacket next_req = transmitList.front();
DPRINTF(Bridge, "Scheduling next send\n"); DPRINTF(Bridge, "Scheduling next send\n");
bridge.schedule(sendEvent, std::max(req.tick, bridge.schedule(sendEvent, std::max(next_req.tick,
bridge.clockEdge())); bridge.clockEdge()));
} }
@ -315,9 +325,9 @@ Bridge::BridgeSlavePort::trySendTiming()
// If there are more packets to send, schedule event to try again. // If there are more packets to send, schedule event to try again.
if (!transmitList.empty()) { if (!transmitList.empty()) {
resp = transmitList.front(); DeferredPacket next_resp = transmitList.front();
DPRINTF(Bridge, "Scheduling next send\n"); DPRINTF(Bridge, "Scheduling next send\n");
bridge.schedule(sendEvent, std::max(resp.tick, bridge.schedule(sendEvent, std::max(next_resp.tick,
bridge.clockEdge())); bridge.clockEdge()));
} }
@ -338,21 +348,13 @@ Bridge::BridgeSlavePort::trySendTiming()
void void
Bridge::BridgeMasterPort::recvRetry() Bridge::BridgeMasterPort::recvRetry()
{ {
Tick nextReady = transmitList.front().tick; trySendTiming();
if (nextReady <= curTick())
trySendTiming();
else
bridge.schedule(sendEvent, nextReady);
} }
void void
Bridge::BridgeSlavePort::recvRetry() Bridge::BridgeSlavePort::recvRetry()
{ {
Tick nextReady = transmitList.front().tick; trySendTiming();
if (nextReady <= curTick())
trySendTiming();
else
bridge.schedule(sendEvent, nextReady);
} }
Tick Tick
@ -364,12 +366,10 @@ Bridge::BridgeSlavePort::recvAtomic(PacketPtr pkt)
void void
Bridge::BridgeSlavePort::recvFunctional(PacketPtr pkt) Bridge::BridgeSlavePort::recvFunctional(PacketPtr pkt)
{ {
std::list<DeferredPacket>::iterator i;
pkt->pushLabel(name()); pkt->pushLabel(name());
// check the response queue // 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)) { if (pkt->checkFunctional((*i).pkt)) {
pkt->makeResponse(); pkt->makeResponse();
return; return;
@ -391,7 +391,7 @@ bool
Bridge::BridgeMasterPort::checkFunctional(PacketPtr pkt) Bridge::BridgeMasterPort::checkFunctional(PacketPtr pkt)
{ {
bool found = false; bool found = false;
std::list<DeferredPacket>::iterator i = transmitList.begin(); auto i = transmitList.begin();
while(i != transmitList.end() && !found) { while(i != transmitList.end() && !found) {
if (pkt->checkFunctional((*i).pkt)) { if (pkt->checkFunctional((*i).pkt)) {

View file

@ -1,5 +1,5 @@
/* /*
* Copyright (c) 2011-2012 ARM Limited * Copyright (c) 2011-2013 ARM Limited
* All rights reserved * All rights reserved
* *
* The license below extends only to copyright in the software and shall * The license below extends only to copyright in the software and shall
@ -51,7 +51,7 @@
#ifndef __MEM_BRIDGE_HH__ #ifndef __MEM_BRIDGE_HH__
#define __MEM_BRIDGE_HH__ #define __MEM_BRIDGE_HH__
#include <list> #include <deque>
#include "base/types.hh" #include "base/types.hh"
#include "mem/mem_object.hh" #include "mem/mem_object.hh"
@ -84,7 +84,7 @@ class Bridge : public MemObject
public: public:
PortID origSrc; const PortID origSrc;
RequestState(PortID orig_src) : origSrc(orig_src) RequestState(PortID orig_src) : origSrc(orig_src)
{ } { }
@ -100,8 +100,8 @@ class Bridge : public MemObject
public: public:
Tick tick; const Tick tick;
PacketPtr pkt; const PacketPtr pkt;
DeferredPacket(PacketPtr _pkt, Tick _tick) : tick(_tick), pkt(_pkt) DeferredPacket(PacketPtr _pkt, Tick _tick) : tick(_tick), pkt(_pkt)
{ } { }
@ -131,17 +131,18 @@ class Bridge : public MemObject
BridgeMasterPort& masterPort; BridgeMasterPort& masterPort;
/** Minimum request delay though this bridge. */ /** Minimum request delay though this bridge. */
Cycles delay; const Cycles delay;
/** Address ranges to pass through the bridge */ /** Address ranges to pass through the bridge */
AddrRangeList ranges; const AddrRangeList ranges;
/** /**
* Response packet queue. Response packets are held in this * Response packet queue. Response packets are held in this
* queue for a specified delay to model the processing delay * 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<DeferredPacket> transmitList; std::deque<DeferredPacket> transmitList;
/** Counter to track the outstanding responses. */ /** Counter to track the outstanding responses. */
unsigned int outstandingResponses; unsigned int outstandingResponses;
@ -157,7 +158,7 @@ class Bridge : public MemObject
* *
* @return true if the reserved space has reached the set limit * @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 * Handle send event, scheduled when the packet at the head of
@ -246,17 +247,18 @@ class Bridge : public MemObject
BridgeSlavePort& slavePort; BridgeSlavePort& slavePort;
/** Minimum delay though this bridge. */ /** Minimum delay though this bridge. */
Cycles delay; const Cycles delay;
/** /**
* Request packet queue. Request packets are held in this * Request packet queue. Request packets are held in this
* queue for a specified delay to model the processing delay * 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<DeferredPacket> transmitList; std::deque<DeferredPacket> transmitList;
/** Max queue size for request packets */ /** Max queue size for request packets */
unsigned int reqQueueLimit; const unsigned int reqQueueLimit;
/** /**
* Handle send event, scheduled when the packet at the head of * 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 * @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 * Queue a request packet to be sent out later and also schedule