summaryrefslogtreecommitdiff
path: root/src/mem/tport.hh
diff options
context:
space:
mode:
Diffstat (limited to 'src/mem/tport.hh')
-rw-r--r--src/mem/tport.hh66
1 files changed, 47 insertions, 19 deletions
diff --git a/src/mem/tport.hh b/src/mem/tport.hh
index 3d28ea3e5..ea0f05ed1 100644
--- a/src/mem/tport.hh
+++ b/src/mem/tport.hh
@@ -58,9 +58,26 @@
class SimpleTimingPort : public Port
{
protected:
+ /** A deferred packet, buffered to transmit later. */
+ class DeferredPacket {
+ public:
+ Tick tick; ///< The tick when the packet is ready to transmit
+ PacketPtr pkt; ///< Pointer to the packet to transmit
+ DeferredPacket(Tick t, PacketPtr p)
+ : tick(t), pkt(p)
+ {}
+ };
+
+ typedef std::list<DeferredPacket> DeferredPacketList;
+ typedef std::list<DeferredPacket>::iterator DeferredPacketIterator;
+
/** A list of outgoing timing response packets that haven't been
* serviced yet. */
- std::list<std::pair<Tick,PacketPtr> > transmitList;
+ DeferredPacketList transmitList;
+
+ /** This function attempts to send deferred packets. Scheduled to
+ * be called in the future via SendEvent. */
+ void processSendEvent();
/**
* This class is used to implemented sendTiming() with a delay. When
@@ -68,32 +85,38 @@ class SimpleTimingPort : public Port
* When the event time expires it attempts to send the packet.
* If it cannot, the packet sent when recvRetry() is called.
**/
- class SendEvent : public Event
- {
- SimpleTimingPort *port;
-
- public:
- SendEvent(SimpleTimingPort *p)
- : Event(&mainEventQueue), port(p)
- { }
-
- virtual void process();
+ typedef EventWrapper<SimpleTimingPort, &SimpleTimingPort::processSendEvent>
+ SendEvent;
- virtual const char *description()
- { return "Future scheduled sendTiming event"; }
- };
-
- SendEvent sendEvent;
+ Event *sendEvent;
/** If we need to drain, keep the drain event around until we're done
* here.*/
Event *drainEvent;
+ /** Remember whether we're awaiting a retry from the bus. */
+ bool waitingOnRetry;
+
+ /** Check the list of buffered packets against the supplied
+ * functional request. */
+ void checkFunctional(PacketPtr funcPkt);
+
+ /** Check whether we have a packet ready to go on the transmit list. */
+ bool deferredPacketReady()
+ { return !transmitList.empty() && transmitList.front().tick <= curTick; }
+
/** Schedule a sendTiming() event to be called in the future.
* @param pkt packet to send
- * @param time increment from now (in ticks) to send packet
+ * @param absolute time (in ticks) to send packet
+ */
+ void schedSendTiming(PacketPtr pkt, Tick when);
+
+ /** Attempt to send the packet at the head of the deferred packet
+ * list. Caller must guarantee that the deferred packet list is
+ * non-empty and that the head packet is scheduled for curTick (or
+ * earlier).
*/
- void sendTiming(PacketPtr pkt, Tick time);
+ void sendDeferredPacket();
/** This function is notification that the device should attempt to send a
* packet again. */
@@ -115,9 +138,14 @@ class SimpleTimingPort : public Port
public:
SimpleTimingPort(std::string pname, MemObject *_owner = NULL)
- : Port(pname, _owner), sendEvent(this), drainEvent(NULL)
+ : Port(pname, _owner),
+ sendEvent(new SendEvent(this)),
+ drainEvent(NULL),
+ waitingOnRetry(false)
{}
+ ~SimpleTimingPort() { delete sendEvent; }
+
/** Hook for draining timing accesses from the system. The
* associated SimObject's drain() functions should be implemented
* something like this when this class is used: