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.
#
# 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")

View file

@ -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<DeferredPacket>::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<DeferredPacket>::iterator i = transmitList.begin();
auto i = transmitList.begin();
while(i != transmitList.end() && !found) {
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
*
* 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 <list>
#include <deque>
#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<DeferredPacket> transmitList;
std::deque<DeferredPacket> 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<DeferredPacket> transmitList;
std::deque<DeferredPacket> 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