#include <list>
#include "mem/port.hh"
-#include "sim/eventq.hh"
+#include "sim/drain.hh"
+#include "sim/eventq_impl.hh"
/**
* A packet queue is a class that holds deferred packets and later
* sends them using the associated slave port or master port.
*/
-class PacketQueue
+class PacketQueue : public Drainable
{
private:
/** A deferred packet, buffered to transmit later. */
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)
+ bool sendAsSnoop; ///< Should it be sent as a snoop or not
+ DeferredPacket(Tick t, PacketPtr p, bool send_as_snoop)
+ : tick(t), pkt(p), sendAsSnoop(send_as_snoop)
{}
};
/** The manager which is used for the event queue */
EventManager& em;
- /** 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();
**/
EventWrapper<PacketQueue, &PacketQueue::processSendEvent> sendEvent;
- /** If we need to drain, keep the drain event around until we're done
+ /** If we need to drain, keep the drain manager around until we're done
* here.*/
- Event *drainEvent;
+ DrainManager *drainManager;
protected:
- /** The port used to send the packets. */
- Port& port;
+ /** Label to use for print request packets label stack. */
+ const std::string label;
/** Remember whether we're awaiting a retry from the bus. */
bool waitingOnRetry;
*/
void trySendTiming();
+ /**
+ *
+ */
+ virtual bool sendTiming(PacketPtr pkt, bool send_as_snoop) = 0;
+
/**
* Based on the transmit list, or the provided time, schedule a
* send event if there are packets to send. If we are idle and
*/
virtual void recvRangeChange() { }
- public:
-
/**
- * Create a packet queue, linked to an event manager, a port used
- * to send the packets, and potentially give it a label that will
- * be used for functional print request packets.
+ * Create a packet queue, linked to an event manager, and a label
+ * that will be used for functional print request packets.
*
* @param _em Event manager used for scheduling this queue
- * @param _port Port used to send the packets
* @param _label Label to push on the label stack for print request packets
*/
- PacketQueue(EventManager& _em, Port& _port,
- const std::string _label = "PacketQueue");
+ PacketQueue(EventManager& _em, const std::string& _label);
/**
* Virtual desctructor since the class may be used as a base class.
*/
virtual ~PacketQueue();
+ public:
+
/**
- * Provide a name to simplify debugging. Base it on the port.
+ * Provide a name to simplify debugging.
*
* @return A complete name, appended to module and port
*/
- const std::string name() const { return port.name() + "-queue"; }
+ virtual const std::string name() const = 0;
/** Check the list of buffered packets against the supplied
* functional request. */
*
* @param pkt Packet to send
* @param when Absolute time (in ticks) to send packet
+ * @param send_as_snoop Send the packet as a snoop or not
*/
- void schedSendTiming(PacketPtr pkt, Tick when);
+ void schedSendTiming(PacketPtr pkt, Tick when, bool send_as_snoop = false);
/**
* Used by a port to notify the queue that a retry was received
*/
void retry();
+ unsigned int drain(DrainManager *dm);
+};
+
+class MasterPacketQueue : public PacketQueue
+{
+
+ protected:
+
+ MasterPort& masterPort;
+
+ public:
+
/**
- * Hook for draining the packet queue.
+ * Create a master packet queue, linked to an event manager, a
+ * master port, and a label that will be used for functional print
+ * request packets.
*
- * @param de An event which is used to signal back to the caller
- * @return A number indicating how many times process will be called
+ * @param _em Event manager used for scheduling this queue
+ * @param _masterPort Master port used to send the packets
+ * @param _label Label to push on the label stack for print request packets
+ */
+ MasterPacketQueue(EventManager& _em, MasterPort& _masterPort,
+ const std::string _label = "MasterPacketQueue");
+
+ virtual ~MasterPacketQueue() { }
+
+ const std::string name() const
+ { return masterPort.name() + "-" + label; }
+
+ bool sendTiming(PacketPtr pkt, bool send_as_snoop);
+};
+
+class SlavePacketQueue : public PacketQueue
+{
+
+ protected:
+
+ SlavePort& slavePort;
+
+ public:
+
+ /**
+ * Create a slave packet queue, linked to an event manager, a
+ * slave port, and a label that will be used for functional print
+ * request packets.
+ *
+ * @param _em Event manager used for scheduling this queue
+ * @param _slavePort Slave port used to send the packets
+ * @param _label Label to push on the label stack for print request packets
*/
- unsigned int drain(Event *de);
+ SlavePacketQueue(EventManager& _em, SlavePort& _slavePort,
+ const std::string _label = "SlavePacketQueue");
+
+ virtual ~SlavePacketQueue() { }
+
+ const std::string name() const
+ { return slavePort.name() + "-" + label; }
+
+ bool sendTiming(PacketPtr pkt, bool send_as_snoop);
+
};
-#endif // __MEM_TPORT_HH__
+#endif // __MEM_PACKET_QUEUE_HH__