summaryrefslogtreecommitdiff
path: root/src/mem/bus.hh
diff options
context:
space:
mode:
authorAndreas Hansson <andreas.hansson@arm.com>2013-03-26 14:46:47 -0400
committerAndreas Hansson <andreas.hansson@arm.com>2013-03-26 14:46:47 -0400
commit93a8423dea8f8194d83df85a5b3043f9beaf0a1e (patch)
treeec1ea615c270a0e8524d4bc3ab442781a0c4f043 /src/mem/bus.hh
parent362f6f1a16a68a99c962628bcda00c7c576f935c (diff)
downloadgem5-93a8423dea8f8194d83df85a5b3043f9beaf0a1e.tar.xz
mem: Separate waiting for the bus and waiting for a peer
This patch splits the retryList into a list of ports that are waiting for the bus itself to become available, and a map that tracks the ports where forwarding failed due to a peer not accepting the packet. Thus, when a retry reaches the bus, it can be sent to the appropriate port that initiated that transaction. As a consequence of this patch, only ports that are really ready to go will get a retry, thus reducing the amount of redundant failed attempts. This patch also makes it easier to reason about the order of servicing requests as the ports waiting for the bus are now clearly FIFO and much easier to change if desired.
Diffstat (limited to 'src/mem/bus.hh')
-rw-r--r--src/mem/bus.hh46
1 files changed, 32 insertions, 14 deletions
diff --git a/src/mem/bus.hh b/src/mem/bus.hh
index 2cd21ff85..16345537a 100644
--- a/src/mem/bus.hh
+++ b/src/mem/bus.hh
@@ -105,8 +105,9 @@ class BaseBus : public MemObject
*
* @param _bus the bus this layer belongs to
* @param _name the layer's name
+ * @param num_dest_ports number of destination ports
*/
- Layer(BaseBus& _bus, const std::string& _name);
+ Layer(BaseBus& _bus, const std::string& _name, uint16_t num_dest_ports);
/**
* Drain according to the normal semantics, so that the bus
@@ -128,14 +129,16 @@ class BaseBus : public MemObject
/**
* Determine if the bus layer accepts a packet from a specific
* port. If not, the port in question is also added to the
- * retry list. In either case the state of the layer is updated
- * accordingly.
+ * retry list. In either case the state of the layer is
+ * updated accordingly. To ignore checking the destination
+ * port (used by snoops), pass InvalidPortID.
*
- * @param port Source port resenting the packet
+ * @param port Source port presenting the packet
+ * @param dest_port_id Destination port id
*
* @return True if the bus layer accepts the packet
*/
- bool tryTiming(PortClass* port);
+ bool tryTiming(PortClass* port, PortID dest_port_id);
/**
* Deal with a destination port accepting a packet by potentially
@@ -152,26 +155,30 @@ class BaseBus : public MemObject
* not already at the front) and occupying the bus layer
* accordingly.
*
+ * @param src_port Source port
+ * @param dest_port_id Destination port id
* @param busy_time Time to spend as a result of a failed send
*/
- void failedTiming(PortClass* port, Tick busy_time);
+ void failedTiming(PortClass* src_port, PortID dest_port_id,
+ Tick busy_time);
/** Occupy the bus layer until until */
void occupyLayer(Tick until);
/**
- * Send a retry to the port at the head of the retryList. The
+ * Send a retry to the port at the head of waitingForLayer. The
* caller must ensure that the list is not empty.
*/
void retryWaiting();
/**
- * Handler a retry from a neighbouring module. Eventually this
- * should be all encapsulated in the bus. This wraps
+ * Handle a retry from a neighbouring module. This wraps
* retryWaiting by verifying that there are ports waiting
* before calling retryWaiting.
+ *
+ * @param port_id Id of the port that received the retry
*/
- void recvRetry();
+ void recvRetry(PortID port_id);
private:
@@ -190,7 +197,7 @@ class BaseBus : public MemObject
* spent. Once the bus layer leaves the busy state, it can
* either go back to idle, if no packets have arrived while it
* was busy, or the bus layer goes on to retry the first port
- * on the retryList. A similar transition takes place from
+ * in waitingForLayer. A similar transition takes place from
* idle to retry if the bus layer receives a retry from one of
* its connected ports. The retry state lasts until the port
* in questions calls sendTiming and returns control to the
@@ -206,10 +213,10 @@ class BaseBus : public MemObject
DrainManager *drainManager;
/**
- * An array of ports that retry should be called
- * on because the original send failed for whatever reason.
+ * A deque of ports that retry should be called on because
+ * the original send was delayed due to a busy layer.
*/
- std::deque<PortClass*> retryList;
+ std::deque<PortClass*> waitingForLayer;
/**
* Port that we are currently in the process of telling to
@@ -220,6 +227,17 @@ class BaseBus : public MemObject
PortClass* retryingPort;
/**
+ * A vector that tracks who is waiting for the retry when
+ * receiving it from a peer. The vector indices are port ids
+ * of the outgoing ports for the specific layer. The values
+ * are the incoming ports that tried to forward something to
+ * the outgoing port, but was told to wait and is now waiting
+ * for a retry. If no port is waiting NULL is stored on the
+ * location in question.
+ */
+ std::vector<PortClass*> waitingForPeer;
+
+ /**
* Release the bus layer after being occupied and return to an
* idle state where we proceed to send a retry to any
* potential waiting port, or drain if asked to do so.