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:
parent
f25ea3fd56
commit
3b92748937
3 changed files with 53 additions and 51 deletions
|
@ -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")
|
||||
|
|
|
@ -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()) {
|
||||
} 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;
|
||||
retryReq = false;
|
||||
|
||||
// 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);
|
||||
}
|
||||
|
||||
void
|
||||
Bridge::BridgeSlavePort::recvRetry()
|
||||
{
|
||||
Tick nextReady = transmitList.front().tick;
|
||||
if (nextReady <= curTick())
|
||||
trySendTiming();
|
||||
else
|
||||
bridge.schedule(sendEvent, nextReady);
|
||||
}
|
||||
|
||||
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)) {
|
||||
|
|
|
@ -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
|
||||
|
|
Loading…
Reference in a new issue