diff options
Diffstat (limited to 'src/mem/tport.hh')
-rw-r--r-- | src/mem/tport.hh | 160 |
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__ |