packet_queue.hh revision 10322
113540Sandrea.mondelli@ucf.edu/*
21376Sbinkertn@umich.edu * Copyright (c) 2012 ARM Limited
31376Sbinkertn@umich.edu * All rights reserved.
41376Sbinkertn@umich.edu *
51376Sbinkertn@umich.edu * The license below extends only to copyright in the software and shall
61376Sbinkertn@umich.edu * not be construed as granting a license to any other intellectual
71376Sbinkertn@umich.edu * property including but not limited to intellectual property relating
81376Sbinkertn@umich.edu * to a hardware implementation of the functionality of the software
91376Sbinkertn@umich.edu * licensed hereunder.  You may use the software subject to the license
101376Sbinkertn@umich.edu * terms below provided that you ensure that this notice is replicated
111376Sbinkertn@umich.edu * unmodified and in its entirety in all distributions of the software,
121376Sbinkertn@umich.edu * modified or unmodified, in source code or in binary form.
131376Sbinkertn@umich.edu *
141376Sbinkertn@umich.edu * Copyright (c) 2006 The Regents of The University of Michigan
151376Sbinkertn@umich.edu * All rights reserved.
161376Sbinkertn@umich.edu *
171376Sbinkertn@umich.edu * Redistribution and use in source and binary forms, with or without
181376Sbinkertn@umich.edu * modification, are permitted provided that the following conditions are
191376Sbinkertn@umich.edu * met: redistributions of source code must retain the above copyright
201376Sbinkertn@umich.edu * notice, this list of conditions and the following disclaimer;
211376Sbinkertn@umich.edu * redistributions in binary form must reproduce the above copyright
221376Sbinkertn@umich.edu * notice, this list of conditions and the following disclaimer in the
231376Sbinkertn@umich.edu * documentation and/or other materials provided with the distribution;
241376Sbinkertn@umich.edu * neither the name of the copyright holders nor the names of its
251376Sbinkertn@umich.edu * contributors may be used to endorse or promote products derived from
261376Sbinkertn@umich.edu * this software without specific prior written permission.
271376Sbinkertn@umich.edu *
281376Sbinkertn@umich.edu * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
291376Sbinkertn@umich.edu * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
301376Sbinkertn@umich.edu * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
311385Sbinkertn@umich.edu * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
321376Sbinkertn@umich.edu * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
331816Sbinkertn@umich.edu * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
341376Sbinkertn@umich.edu * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
351816Sbinkertn@umich.edu * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
361376Sbinkertn@umich.edu * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
371385Sbinkertn@umich.edu * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
381385Sbinkertn@umich.edu * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
391385Sbinkertn@umich.edu *
401385Sbinkertn@umich.edu * Authors: Ali Saidi
411385Sbinkertn@umich.edu *          Andreas Hansson
421385Sbinkertn@umich.edu */
431385Sbinkertn@umich.edu
441816Sbinkertn@umich.edu#ifndef __MEM_PACKET_QUEUE_HH__
451816Sbinkertn@umich.edu#define __MEM_PACKET_QUEUE_HH__
461816Sbinkertn@umich.edu
471816Sbinkertn@umich.edu/**
481816Sbinkertn@umich.edu * @file
491816Sbinkertn@umich.edu * Declaration of a simple PacketQueue that is associated with
501816Sbinkertn@umich.edu * a port on which it attempts to send packets according to the time
511816Sbinkertn@umich.edu * stamp given to them at insertion. The packet queue is responsible
521816Sbinkertn@umich.edu * for the flow control of the port, but relies on the module
531816Sbinkertn@umich.edu * notifying the queue when a transfer ends.
541816Sbinkertn@umich.edu */
551816Sbinkertn@umich.edu
561816Sbinkertn@umich.edu#include <list>
571816Sbinkertn@umich.edu
581816Sbinkertn@umich.edu#include "mem/port.hh"
591816Sbinkertn@umich.edu#include "sim/drain.hh"
601816Sbinkertn@umich.edu#include "sim/eventq_impl.hh"
611816Sbinkertn@umich.edu
621816Sbinkertn@umich.edu/**
631816Sbinkertn@umich.edu * A packet queue is a class that holds deferred packets and later
641816Sbinkertn@umich.edu * sends them using the associated slave port or master port.
651816Sbinkertn@umich.edu */
661816Sbinkertn@umich.educlass PacketQueue : public Drainable
671816Sbinkertn@umich.edu{
681816Sbinkertn@umich.edu  private:
691816Sbinkertn@umich.edu    /** A deferred packet, buffered to transmit later. */
701816Sbinkertn@umich.edu    class DeferredPacket {
711816Sbinkertn@umich.edu      public:
721816Sbinkertn@umich.edu        Tick tick;      ///< The tick when the packet is ready to transmit
731816Sbinkertn@umich.edu        PacketPtr pkt;  ///< Pointer to the packet to transmit
741816Sbinkertn@umich.edu        bool sendAsSnoop; ///< Should it be sent as a snoop or not
751816Sbinkertn@umich.edu        DeferredPacket(Tick t, PacketPtr p, bool send_as_snoop)
761385Sbinkertn@umich.edu            : tick(t), pkt(p), sendAsSnoop(send_as_snoop)
771376Sbinkertn@umich.edu        {}
781376Sbinkertn@umich.edu    };
791376Sbinkertn@umich.edu
801602Sbinkertn@umich.edu    typedef std::list<DeferredPacket> DeferredPacketList;
811376Sbinkertn@umich.edu
821956Ssaidi@eecs.umich.edu    /** A list of outgoing timing response packets that haven't been
831956Ssaidi@eecs.umich.edu     * serviced yet. */
841376Sbinkertn@umich.edu    DeferredPacketList transmitList;
851376Sbinkertn@umich.edu
861376Sbinkertn@umich.edu    /** The manager which is used for the event queue */
871916Sbinkertn@umich.edu    EventManager& em;
881376Sbinkertn@umich.edu
891376Sbinkertn@umich.edu    /** This function attempts to send deferred packets.  Scheduled to
901602Sbinkertn@umich.edu     * be called in the future via SendEvent. */
911916Sbinkertn@umich.edu    void processSendEvent();
921376Sbinkertn@umich.edu
931376Sbinkertn@umich.edu    /**
941376Sbinkertn@umich.edu     * Event used to call processSendEvent.
951376Sbinkertn@umich.edu     **/
961376Sbinkertn@umich.edu    EventWrapper<PacketQueue, &PacketQueue::processSendEvent> sendEvent;
971376Sbinkertn@umich.edu
981376Sbinkertn@umich.edu    /** If we need to drain, keep the drain manager around until we're done
991376Sbinkertn@umich.edu     * here.*/
1001376Sbinkertn@umich.edu    DrainManager *drainManager;
1011948Sbinkertn@umich.edu
1021376Sbinkertn@umich.edu  protected:
1031376Sbinkertn@umich.edu
1041376Sbinkertn@umich.edu    /** Label to use for print request packets label stack. */
1051916Sbinkertn@umich.edu    const std::string label;
1061376Sbinkertn@umich.edu
1071376Sbinkertn@umich.edu    /** Remember whether we're awaiting a retry from the bus. */
1081376Sbinkertn@umich.edu    bool waitingOnRetry;
1091376Sbinkertn@umich.edu
1101376Sbinkertn@umich.edu    /** Check whether we have a packet ready to go on the transmit list. */
1111376Sbinkertn@umich.edu    bool deferredPacketReady() const
1121376Sbinkertn@umich.edu    { return !transmitList.empty() && transmitList.front().tick <= curTick(); }
1131916Sbinkertn@umich.edu
1141881Sbinkertn@umich.edu    Tick deferredPacketReadyTime() const
1151881Sbinkertn@umich.edu    { return transmitList.empty() ? MaxTick : transmitList.front().tick; }
1161881Sbinkertn@umich.edu
1171916Sbinkertn@umich.edu    /**
1181948Sbinkertn@umich.edu     * Attempt to send the packet at the head of the transmit
1191881Sbinkertn@umich.edu     * list. Caller must guarantee that the list is non-empty and that
1201381Sbinkertn@umich.edu     * the head packet is scheduled for curTick() (or earlier). Note
1211881Sbinkertn@umich.edu     * that a subclass of the PacketQueue can override this method and
1221881Sbinkertn@umich.edu     * thus change the behaviour (as done by the cache).
1231381Sbinkertn@umich.edu     */
1241376Sbinkertn@umich.edu    virtual void sendDeferredPacket();
1251916Sbinkertn@umich.edu
1261916Sbinkertn@umich.edu    /**
1271381Sbinkertn@umich.edu     * Attempt to send the packet at the front of the transmit list,
1281376Sbinkertn@umich.edu     * and set waitingOnRetry accordingly. The packet is temporarily
1291381Sbinkertn@umich.edu     * taken off the list, but put back at the front if not
1301376Sbinkertn@umich.edu     * successfully sent.
1311381Sbinkertn@umich.edu     */
1321376Sbinkertn@umich.edu    void trySendTiming();
1331376Sbinkertn@umich.edu
1341602Sbinkertn@umich.edu    /**
1351602Sbinkertn@umich.edu     *
1361381Sbinkertn@umich.edu     */
1371376Sbinkertn@umich.edu    virtual bool sendTiming(PacketPtr pkt, bool send_as_snoop) = 0;
1381948Sbinkertn@umich.edu
1391948Sbinkertn@umich.edu    /**
1401381Sbinkertn@umich.edu     * Based on the transmit list, or the provided time, schedule a
1411381Sbinkertn@umich.edu     * send event if there are packets to send. If we are idle and
1421916Sbinkertn@umich.edu     * asked to drain then do so.
1431916Sbinkertn@umich.edu     *
1441916Sbinkertn@umich.edu     * @param time an alternative time for the next send event
1451916Sbinkertn@umich.edu     */
1461381Sbinkertn@umich.edu    void scheduleSend(Tick time = MaxTick);
1471376Sbinkertn@umich.edu
1481376Sbinkertn@umich.edu    /**
1491881Sbinkertn@umich.edu     * Simple ports are generally used as slave ports (i.e. the
1501881Sbinkertn@umich.edu     * respond to requests) and thus do not expect to receive any
1511381Sbinkertn@umich.edu     * range changes (as the neighbouring port has a master role and
1521376Sbinkertn@umich.edu     * do not have any address ranges. A subclass can override the
1531376Sbinkertn@umich.edu     * default behaviuor if needed.
1541376Sbinkertn@umich.edu     */
1551881Sbinkertn@umich.edu    virtual void recvRangeChange() { }
1561881Sbinkertn@umich.edu
1571881Sbinkertn@umich.edu    /**
1581881Sbinkertn@umich.edu     * Create a packet queue, linked to an event manager, and a label
1591881Sbinkertn@umich.edu     * that will be used for functional print request packets.
1601948Sbinkertn@umich.edu     *
1611385Sbinkertn@umich.edu     * @param _em Event manager used for scheduling this queue
1621385Sbinkertn@umich.edu     * @param _label Label to push on the label stack for print request packets
1631916Sbinkertn@umich.edu     */
1641916Sbinkertn@umich.edu    PacketQueue(EventManager& _em, const std::string& _label);
1651881Sbinkertn@umich.edu
1661376Sbinkertn@umich.edu    /**
1671881Sbinkertn@umich.edu     * Virtual desctructor since the class may be used as a base class.
1681881Sbinkertn@umich.edu     */
1691376Sbinkertn@umich.edu    virtual ~PacketQueue();
1701881Sbinkertn@umich.edu
1711881Sbinkertn@umich.edu  public:
1721881Sbinkertn@umich.edu
1731881Sbinkertn@umich.edu    /**
1741881Sbinkertn@umich.edu     * Provide a name to simplify debugging.
1751881Sbinkertn@umich.edu     *
1761376Sbinkertn@umich.edu     * @return A complete name, appended to module and port
1771881Sbinkertn@umich.edu     */
1781881Sbinkertn@umich.edu    virtual const std::string name() const = 0;
1791376Sbinkertn@umich.edu
1801376Sbinkertn@umich.edu    /** Check the list of buffered packets against the supplied
1811881Sbinkertn@umich.edu     * functional request. */
1821881Sbinkertn@umich.edu    bool checkFunctional(PacketPtr pkt);
1831881Sbinkertn@umich.edu
1841881Sbinkertn@umich.edu    /**
1851881Sbinkertn@umich.edu     * Schedule a send even if not already waiting for a retry. If the
1861881Sbinkertn@umich.edu     * requested time is before an already scheduled send event it
1871881Sbinkertn@umich.edu     * will be rescheduled.
1881376Sbinkertn@umich.edu     *
1891376Sbinkertn@umich.edu     * @param when
1901376Sbinkertn@umich.edu     */
1911881Sbinkertn@umich.edu    void schedSendEvent(Tick when);
1921881Sbinkertn@umich.edu
1931376Sbinkertn@umich.edu    /**
1941881Sbinkertn@umich.edu     * Add a packet to the transmit list, and ensure that a
1951881Sbinkertn@umich.edu     * processSendEvent is called in the future.
1961376Sbinkertn@umich.edu     *
1971376Sbinkertn@umich.edu     * @param pkt Packet to send
1981376Sbinkertn@umich.edu     * @param when Absolute time (in ticks) to send packet
1991881Sbinkertn@umich.edu     * @param send_as_snoop Send the packet as a snoop or not
2001881Sbinkertn@umich.edu     */
2011881Sbinkertn@umich.edu    void schedSendTiming(PacketPtr pkt, Tick when, bool send_as_snoop = false);
2021881Sbinkertn@umich.edu
2031376Sbinkertn@umich.edu    /**
2041881Sbinkertn@umich.edu     * Used by a port to notify the queue that a retry was received
2051881Sbinkertn@umich.edu     * and that the queue can proceed and retry sending the packet
2061376Sbinkertn@umich.edu     * that caused the wait.
2071376Sbinkertn@umich.edu     */
2081881Sbinkertn@umich.edu    void retry();
2091881Sbinkertn@umich.edu
2101881Sbinkertn@umich.edu    unsigned int drain(DrainManager *dm);
2111881Sbinkertn@umich.edu};
2121376Sbinkertn@umich.edu
2131376Sbinkertn@umich.educlass MasterPacketQueue : public PacketQueue
2141376Sbinkertn@umich.edu{
2151881Sbinkertn@umich.edu
2161376Sbinkertn@umich.edu  protected:
2171881Sbinkertn@umich.edu
2181881Sbinkertn@umich.edu    MasterPort& masterPort;
2191881Sbinkertn@umich.edu
2201376Sbinkertn@umich.edu  public:
2211881Sbinkertn@umich.edu
2221881Sbinkertn@umich.edu    /**
2231881Sbinkertn@umich.edu     * Create a master packet queue, linked to an event manager, a
2241881Sbinkertn@umich.edu     * master port, and a label that will be used for functional print
2251881Sbinkertn@umich.edu     * request packets.
2261816Sbinkertn@umich.edu     *
2271881Sbinkertn@umich.edu     * @param _em Event manager used for scheduling this queue
2281881Sbinkertn@umich.edu     * @param _masterPort Master port used to send the packets
2291881Sbinkertn@umich.edu     * @param _label Label to push on the label stack for print request packets
2301881Sbinkertn@umich.edu     */
2311881Sbinkertn@umich.edu    MasterPacketQueue(EventManager& _em, MasterPort& _masterPort,
2321816Sbinkertn@umich.edu                      const std::string _label = "MasterPacketQueue");
2331881Sbinkertn@umich.edu
2341881Sbinkertn@umich.edu    virtual ~MasterPacketQueue() { }
2351881Sbinkertn@umich.edu
2361881Sbinkertn@umich.edu    const std::string name() const
2371881Sbinkertn@umich.edu    { return masterPort.name() + "-" + label; }
2381376Sbinkertn@umich.edu
2391881Sbinkertn@umich.edu    bool sendTiming(PacketPtr pkt, bool send_as_snoop);
2401881Sbinkertn@umich.edu};
2411881Sbinkertn@umich.edu
2421881Sbinkertn@umich.educlass SlavePacketQueue : public PacketQueue
2431881Sbinkertn@umich.edu{
2441881Sbinkertn@umich.edu
2451881Sbinkertn@umich.edu  protected:
2461376Sbinkertn@umich.edu
2471881Sbinkertn@umich.edu    SlavePort& slavePort;
2481881Sbinkertn@umich.edu
2491881Sbinkertn@umich.edu  public:
2501881Sbinkertn@umich.edu
2511881Sbinkertn@umich.edu    /**
2521881Sbinkertn@umich.edu     * Create a slave packet queue, linked to an event manager, a
2531916Sbinkertn@umich.edu     * slave port, and a label that will be used for functional print
2541916Sbinkertn@umich.edu     * request packets.
2551916Sbinkertn@umich.edu     *
2561881Sbinkertn@umich.edu     * @param _em Event manager used for scheduling this queue
2571881Sbinkertn@umich.edu     * @param _slavePort Slave port used to send the packets
2581881Sbinkertn@umich.edu     * @param _label Label to push on the label stack for print request packets
2591881Sbinkertn@umich.edu     */
2601881Sbinkertn@umich.edu    SlavePacketQueue(EventManager& _em, SlavePort& _slavePort,
2611385Sbinkertn@umich.edu                     const std::string _label = "SlavePacketQueue");
2621376Sbinkertn@umich.edu
2631376Sbinkertn@umich.edu    virtual ~SlavePacketQueue() { }
2641376Sbinkertn@umich.edu
2651881Sbinkertn@umich.edu    const std::string name() const
2661881Sbinkertn@umich.edu    { return slavePort.name() + "-" + label; }
2671376Sbinkertn@umich.edu
2681916Sbinkertn@umich.edu    bool sendTiming(PacketPtr pkt, bool send_as_snoop);
2691881Sbinkertn@umich.edu
2701881Sbinkertn@umich.edu};
2711916Sbinkertn@umich.edu
2721916Sbinkertn@umich.edu#endif // __MEM_PACKET_QUEUE_HH__
2731916Sbinkertn@umich.edu