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.hh160
1 files changed, 23 insertions, 137 deletions
diff --git a/src/mem/tport.hh b/src/mem/tport.hh
index d720f227c..c77166386 100644
--- a/src/mem/tport.hh
+++ b/src/mem/tport.hh
@@ -50,117 +50,20 @@
* Declaration of SimpleTimingPort.
*/
-#include <list>
-#include <string>
-
-#include "mem/port.hh"
-#include "sim/eventq.hh"
+#include "mem/qport.hh"
/**
- * A simple port for interfacing objects that basically have only
- * functional memory behavior (e.g. I/O devices) to the memory system.
- * Both timing and functional accesses are implemented in terms of
- * atomic accesses. A derived port class thus only needs to provide
- * recvAtomic() to support all memory access modes.
- *
- * The tricky part is handling recvTiming(), where the response must
- * be scheduled separately via a later call to sendTiming(). This
- * feature is handled by scheduling an internal event that calls
- * sendTiming() after a delay, and optionally rescheduling the
- * response if it is nacked.
+ * The simple timing port uses a queued port to implement
+ * recvFunctional and recvTiming through recvAtomic. It is always a
+ * slave port.
*/
-class SimpleTimingPort : public Port
+class SimpleTimingPort : public QueuedPort
{
- 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. */
- DeferredPacketList transmitList;
-
- /** Label to use for print request packets label stack. */
- const std::string label;
-
- /** 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
- * a delay is requested a the event is scheduled if it isn't already.
- * When the event time expires it attempts to send the packet.
- * If it cannot, the packet sent when recvRetry() is called.
- **/
- EventWrapper<SimpleTimingPort,
- &SimpleTimingPort::processSendEvent> 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 whether we have a packet ready to go on the transmit list. */
- bool deferredPacketReady()
- { return !transmitList.empty() && transmitList.front().tick <= curTick(); }
-
- Tick deferredPacketReadyTime()
- { return transmitList.empty() ? MaxTick : transmitList.front().tick; }
-
- /**
- * Schedule a send even if not already waiting for a retry. If the
- * requested time is before an already scheduled send event it
- * will be rescheduled.
- *
- * @param when
- */
- void schedSendEvent(Tick when);
-
- /** Schedule a sendTiming() event to be called in the future.
- * @param pkt packet to send
- * @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).
- */
- virtual void sendDeferredPacket();
-
- /**
- * Attempt to send the packet at the front of the transmit list,
- * and set waitingOnRetry accordingly. The packet is temporarily
- * taken off the list, but put back at the front if not
- * successfully sent.
- */
- void trySendTiming();
-
- /**
- * Based on the transmit list, or the provided time, schedule a
- * send event if there are packets to send. If we are idle and
- * asked to drain then do so.
- *
- * @param time an alternative time for the next send event
- */
- void scheduleSend(Tick time = MaxTick);
+ protected:
- /** This function is notification that the device should attempt to send a
- * packet again. */
- virtual void recvRetry();
+ /** The packet queue used to store outgoing responses. */
+ PacketQueue queue;
/** Implemented using recvAtomic(). */
void recvFunctional(PacketPtr pkt);
@@ -168,42 +71,25 @@ class SimpleTimingPort : public Port
/** Implemented using recvAtomic(). */
bool recvTiming(PacketPtr pkt);
- /**
- * Simple ports are generally used as slave ports (i.e. the
- * respond to requests) and thus do not expect to receive any
- * range changes (as the neighbouring port has a master role and
- * do not have any address ranges. A subclass can override the
- * default behaviuor if needed.
- */
- virtual void recvRangeChange() { }
-
+ virtual Tick recvAtomic(PacketPtr pkt) = 0;
public:
- SimpleTimingPort(const std::string &_name, MemObject *_owner,
- const std::string _label = "SimpleTimingPort");
- ~SimpleTimingPort();
- /** Check the list of buffered packets against the supplied
- * functional request. */
- bool checkFunctional(PacketPtr pkt);
+ /**
+ * Create a new SimpleTimingPort that relies on a packet queue to
+ * hold responses, and implements recvTiming and recvFunctional
+ * through calls to recvAtomic. Once a request arrives, it is
+ * passed to recvAtomic, and in the case of a timing access any
+ * response is scheduled to be sent after the delay of the atomic
+ * operation.
+ *
+ * @param name port name
+ * @param owner structural owner
+ */
+ SimpleTimingPort(const std::string& name, MemObject* owner);
+
+ virtual ~SimpleTimingPort() { }
- /** 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:
- \code
- PioDevice::drain(Event *de)
- {
- unsigned int count;
- count = SimpleTimingPort->drain(de);
- if (count)
- changeState(Draining);
- else
- changeState(Drained);
- return count;
- }
- \endcode
- */
- unsigned int drain(Event *de);
};
#endif // __MEM_TPORT_HH__