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.
|
# 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")
|
||||||
|
|
|
@ -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)) {
|
||||||
|
|
|
@ -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
|
||||||
|
|
Loading…
Reference in a new issue