summaryrefslogtreecommitdiff
path: root/src/mem/bus.hh
diff options
context:
space:
mode:
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.