packet_queue.hh revision 12083:d6a612791733
110802Srene.dejong@arm.com/* 210802Srene.dejong@arm.com * Copyright (c) 2012,2015 ARM Limited 310802Srene.dejong@arm.com * All rights reserved. 410802Srene.dejong@arm.com * 510802Srene.dejong@arm.com * The license below extends only to copyright in the software and shall 610802Srene.dejong@arm.com * not be construed as granting a license to any other intellectual 710802Srene.dejong@arm.com * property including but not limited to intellectual property relating 810802Srene.dejong@arm.com * to a hardware implementation of the functionality of the software 910802Srene.dejong@arm.com * licensed hereunder. You may use the software subject to the license 1010802Srene.dejong@arm.com * terms below provided that you ensure that this notice is replicated 1110802Srene.dejong@arm.com * unmodified and in its entirety in all distributions of the software, 1210802Srene.dejong@arm.com * modified or unmodified, in source code or in binary form. 1310802Srene.dejong@arm.com * 1410802Srene.dejong@arm.com * Copyright (c) 2006 The Regents of The University of Michigan 1510802Srene.dejong@arm.com * All rights reserved. 1610802Srene.dejong@arm.com * 1710802Srene.dejong@arm.com * Redistribution and use in source and binary forms, with or without 1810802Srene.dejong@arm.com * modification, are permitted provided that the following conditions are 1910802Srene.dejong@arm.com * met: redistributions of source code must retain the above copyright 2010802Srene.dejong@arm.com * notice, this list of conditions and the following disclaimer; 2110802Srene.dejong@arm.com * redistributions in binary form must reproduce the above copyright 2210802Srene.dejong@arm.com * notice, this list of conditions and the following disclaimer in the 2310802Srene.dejong@arm.com * documentation and/or other materials provided with the distribution; 2410802Srene.dejong@arm.com * neither the name of the copyright holders nor the names of its 2510802Srene.dejong@arm.com * contributors may be used to endorse or promote products derived from 2610802Srene.dejong@arm.com * this software without specific prior written permission. 2710802Srene.dejong@arm.com * 2810802Srene.dejong@arm.com * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 2910802Srene.dejong@arm.com * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 3010802Srene.dejong@arm.com * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 3110802Srene.dejong@arm.com * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 3210802Srene.dejong@arm.com * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 3310802Srene.dejong@arm.com * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 3410802Srene.dejong@arm.com * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 3510802Srene.dejong@arm.com * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 3610802Srene.dejong@arm.com * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 3710802Srene.dejong@arm.com * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 3810802Srene.dejong@arm.com * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 3910802Srene.dejong@arm.com * 4010802Srene.dejong@arm.com * Authors: Ali Saidi 4110802Srene.dejong@arm.com * Andreas Hansson 4210802Srene.dejong@arm.com */ 4310802Srene.dejong@arm.com 4410802Srene.dejong@arm.com#ifndef __MEM_PACKET_QUEUE_HH__ 4510802Srene.dejong@arm.com#define __MEM_PACKET_QUEUE_HH__ 4610802Srene.dejong@arm.com 4710802Srene.dejong@arm.com/** 4810802Srene.dejong@arm.com * @file 4910802Srene.dejong@arm.com * Declaration of a simple PacketQueue that is associated with 5010802Srene.dejong@arm.com * a port on which it attempts to send packets according to the time 5110802Srene.dejong@arm.com * stamp given to them at insertion. The packet queue is responsible 5210802Srene.dejong@arm.com * for the flow control of the port. 5310802Srene.dejong@arm.com */ 5410802Srene.dejong@arm.com 5510802Srene.dejong@arm.com#include <list> 5610802Srene.dejong@arm.com 5710802Srene.dejong@arm.com#include "mem/port.hh" 5810802Srene.dejong@arm.com#include "sim/drain.hh" 5910802Srene.dejong@arm.com#include "sim/eventq_impl.hh" 6010802Srene.dejong@arm.com 6110802Srene.dejong@arm.com/** 6210802Srene.dejong@arm.com * A packet queue is a class that holds deferred packets and later 6310802Srene.dejong@arm.com * sends them using the associated slave port or master port. 6410802Srene.dejong@arm.com */ 6510802Srene.dejong@arm.comclass PacketQueue : public Drainable 6610802Srene.dejong@arm.com{ 6710802Srene.dejong@arm.com private: 6810802Srene.dejong@arm.com /** A deferred packet, buffered to transmit later. */ 6910802Srene.dejong@arm.com class DeferredPacket { 7010802Srene.dejong@arm.com public: 7110802Srene.dejong@arm.com Tick tick; ///< The tick when the packet is ready to transmit 7210802Srene.dejong@arm.com PacketPtr pkt; ///< Pointer to the packet to transmit 7310802Srene.dejong@arm.com DeferredPacket(Tick t, PacketPtr p) 7410802Srene.dejong@arm.com : tick(t), pkt(p) 7510802Srene.dejong@arm.com {} 7610802Srene.dejong@arm.com }; 7710802Srene.dejong@arm.com 7810802Srene.dejong@arm.com typedef std::list<DeferredPacket> DeferredPacketList; 7910802Srene.dejong@arm.com 8010802Srene.dejong@arm.com /** A list of outgoing packets. */ 8110802Srene.dejong@arm.com DeferredPacketList transmitList; 8210802Srene.dejong@arm.com 8310802Srene.dejong@arm.com /** The manager which is used for the event queue */ 8410802Srene.dejong@arm.com EventManager& em; 8510802Srene.dejong@arm.com 8610802Srene.dejong@arm.com /** Used to schedule sending of deferred packets. */ 8710802Srene.dejong@arm.com void processSendEvent(); 8810802Srene.dejong@arm.com 8910802Srene.dejong@arm.com /** Event used to call processSendEvent. */ 9010802Srene.dejong@arm.com EventFunctionWrapper sendEvent; 9110802Srene.dejong@arm.com 9210802Srene.dejong@arm.com /* 9310802Srene.dejong@arm.com * Optionally disable the sanity check 9410802Srene.dejong@arm.com * on the size of the transmitList. The 9510802Srene.dejong@arm.com * sanity check will be enabled by default. 9610802Srene.dejong@arm.com */ 9710802Srene.dejong@arm.com bool _disableSanityCheck; 9810802Srene.dejong@arm.com 9910802Srene.dejong@arm.com protected: 10010802Srene.dejong@arm.com 10110802Srene.dejong@arm.com /** Label to use for print request packets label stack. */ 10210802Srene.dejong@arm.com const std::string label; 10310802Srene.dejong@arm.com 10410802Srene.dejong@arm.com /** Remember whether we're awaiting a retry. */ 10510802Srene.dejong@arm.com bool waitingOnRetry; 10610802Srene.dejong@arm.com 10710802Srene.dejong@arm.com /** Check whether we have a packet ready to go on the transmit list. */ 10810802Srene.dejong@arm.com bool deferredPacketReady() const 10910802Srene.dejong@arm.com { return !transmitList.empty() && transmitList.front().tick <= curTick(); } 11010802Srene.dejong@arm.com 11110802Srene.dejong@arm.com /** 11210802Srene.dejong@arm.com * Attempt to send a packet. Note that a subclass of the 11310802Srene.dejong@arm.com * PacketQueue can override this method and thus change the 11410802Srene.dejong@arm.com * behaviour (as done by the cache for the request queue). The 11510802Srene.dejong@arm.com * default implementation sends the head of the transmit list. The 11610802Srene.dejong@arm.com * caller must guarantee that the list is non-empty and that the 11710802Srene.dejong@arm.com * head packet is scheduled for curTick() (or earlier). 11810802Srene.dejong@arm.com */ 11910802Srene.dejong@arm.com virtual void sendDeferredPacket(); 12010802Srene.dejong@arm.com 12110802Srene.dejong@arm.com /** 12210802Srene.dejong@arm.com * Send a packet using the appropriate method for the specific 12310802Srene.dejong@arm.com * subclass (reuest, response or snoop response). 12410802Srene.dejong@arm.com */ 12510802Srene.dejong@arm.com virtual bool sendTiming(PacketPtr pkt) = 0; 12610802Srene.dejong@arm.com 12710802Srene.dejong@arm.com /** 12810802Srene.dejong@arm.com * Create a packet queue, linked to an event manager, and a label 12910802Srene.dejong@arm.com * that will be used for functional print request packets. 13010802Srene.dejong@arm.com * 13110802Srene.dejong@arm.com * @param _em Event manager used for scheduling this queue 13210802Srene.dejong@arm.com * @param _label Label to push on the label stack for print request packets 13310802Srene.dejong@arm.com * @param disable_sanity_check Flag used to disable the sanity check 13410802Srene.dejong@arm.com * on the size of the transmitList. The check is enabled by default. 13510802Srene.dejong@arm.com */ 13610802Srene.dejong@arm.com PacketQueue(EventManager& _em, const std::string& _label, 13710802Srene.dejong@arm.com const std::string& _sendEventName, 13810802Srene.dejong@arm.com bool disable_sanity_check = false); 13910802Srene.dejong@arm.com 14010802Srene.dejong@arm.com /** 14110802Srene.dejong@arm.com * Virtual desctructor since the class may be used as a base class. 14210802Srene.dejong@arm.com */ 14310802Srene.dejong@arm.com virtual ~PacketQueue(); 14410802Srene.dejong@arm.com 14510802Srene.dejong@arm.com public: 14610802Srene.dejong@arm.com 14710802Srene.dejong@arm.com /** 14810802Srene.dejong@arm.com * Provide a name to simplify debugging. 14910802Srene.dejong@arm.com * 15010802Srene.dejong@arm.com * @return A complete name, appended to module and port 15110802Srene.dejong@arm.com */ 15210802Srene.dejong@arm.com virtual const std::string name() const = 0; 15310802Srene.dejong@arm.com 15410802Srene.dejong@arm.com /** 15510802Srene.dejong@arm.com * Get the size of the queue. 15610802Srene.dejong@arm.com */ 15710802Srene.dejong@arm.com size_t size() const { return transmitList.size(); } 15810802Srene.dejong@arm.com 15910802Srene.dejong@arm.com /** 16010802Srene.dejong@arm.com * Get the next packet ready time. 16110802Srene.dejong@arm.com */ 16210802Srene.dejong@arm.com Tick deferredPacketReadyTime() const 16310802Srene.dejong@arm.com { return transmitList.empty() ? MaxTick : transmitList.front().tick; } 16410802Srene.dejong@arm.com 16510802Srene.dejong@arm.com /** 16610802Srene.dejong@arm.com * Check if a packets address exists in the queue. 16710802Srene.dejong@arm.com */ 16810802Srene.dejong@arm.com bool hasAddr(Addr addr) const; 16910802Srene.dejong@arm.com 17010802Srene.dejong@arm.com /** Check the list of buffered packets against the supplied 17110802Srene.dejong@arm.com * functional request. */ 17210802Srene.dejong@arm.com bool checkFunctional(PacketPtr pkt); 17310802Srene.dejong@arm.com 17410802Srene.dejong@arm.com /** 17510802Srene.dejong@arm.com * Schedule a send event if we are not already waiting for a 17610802Srene.dejong@arm.com * retry. If the requested time is before an already scheduled 17710802Srene.dejong@arm.com * send event, the event will be rescheduled. If MaxTick is 17810802Srene.dejong@arm.com * passed, no event is scheduled. Instead, if we are idle and 17910802Srene.dejong@arm.com * asked to drain then check and signal drained. 18010802Srene.dejong@arm.com * 18110802Srene.dejong@arm.com * @param when time to schedule an event 18210802Srene.dejong@arm.com */ 18310802Srene.dejong@arm.com void schedSendEvent(Tick when); 18410802Srene.dejong@arm.com 18510802Srene.dejong@arm.com /** 18610802Srene.dejong@arm.com * Add a packet to the transmit list, and schedule a send event. 18710802Srene.dejong@arm.com * 18810802Srene.dejong@arm.com * @param pkt Packet to send 18910802Srene.dejong@arm.com * @param when Absolute time (in ticks) to send packet 19010802Srene.dejong@arm.com * @param force_order Force insertion order for packets with same address 19110802Srene.dejong@arm.com */ 19210802Srene.dejong@arm.com void schedSendTiming(PacketPtr pkt, Tick when, bool force_order = false); 19310802Srene.dejong@arm.com 19410802Srene.dejong@arm.com /** 19510802Srene.dejong@arm.com * Retry sending a packet from the queue. Note that this is not 19610802Srene.dejong@arm.com * necessarily the same packet if something has been added with an 19710802Srene.dejong@arm.com * earlier time stamp. 19810802Srene.dejong@arm.com */ 19910802Srene.dejong@arm.com void retry(); 20010802Srene.dejong@arm.com 20110802Srene.dejong@arm.com /** 20210802Srene.dejong@arm.com * This allows a user to explicitly disable the sanity check 20310802Srene.dejong@arm.com * on the size of the transmitList, which is enabled by default. 20410802Srene.dejong@arm.com * Users must use this function to explicitly disable the sanity 20510802Srene.dejong@arm.com * check. 20610802Srene.dejong@arm.com */ 20710802Srene.dejong@arm.com void disableSanityCheck() { _disableSanityCheck = true; } 20810802Srene.dejong@arm.com 20910802Srene.dejong@arm.com DrainState drain() override; 21010802Srene.dejong@arm.com}; 21110802Srene.dejong@arm.com 21210802Srene.dejong@arm.comclass ReqPacketQueue : public PacketQueue 21310802Srene.dejong@arm.com{ 21410802Srene.dejong@arm.com 21510802Srene.dejong@arm.com protected: 21610802Srene.dejong@arm.com 21710802Srene.dejong@arm.com MasterPort& masterPort; 21810802Srene.dejong@arm.com 21910802Srene.dejong@arm.com // Static definition so it can be called when constructing the parent 22010802Srene.dejong@arm.com // without us being completely initialized. 22110802Srene.dejong@arm.com static const std::string name(const MasterPort& masterPort, 22210802Srene.dejong@arm.com const std::string& label) 22310802Srene.dejong@arm.com { return masterPort.name() + "-" + label; } 22410802Srene.dejong@arm.com 22510802Srene.dejong@arm.com public: 22610802Srene.dejong@arm.com 22710802Srene.dejong@arm.com /** 22810802Srene.dejong@arm.com * Create a request packet queue, linked to an event manager, a 22910802Srene.dejong@arm.com * master port, and a label that will be used for functional print 23010802Srene.dejong@arm.com * request packets. 23110802Srene.dejong@arm.com * 23210802Srene.dejong@arm.com * @param _em Event manager used for scheduling this queue 23310802Srene.dejong@arm.com * @param _masterPort Master port used to send the packets 23410802Srene.dejong@arm.com * @param _label Label to push on the label stack for print request packets 23510802Srene.dejong@arm.com */ 23610802Srene.dejong@arm.com ReqPacketQueue(EventManager& _em, MasterPort& _masterPort, 23710802Srene.dejong@arm.com const std::string _label = "ReqPacketQueue"); 23810802Srene.dejong@arm.com 23910802Srene.dejong@arm.com virtual ~ReqPacketQueue() { } 24010802Srene.dejong@arm.com 24110802Srene.dejong@arm.com const std::string name() const 24210802Srene.dejong@arm.com { return name(masterPort, label); } 24310802Srene.dejong@arm.com 24410802Srene.dejong@arm.com bool sendTiming(PacketPtr pkt); 24510802Srene.dejong@arm.com 24610802Srene.dejong@arm.com}; 24710802Srene.dejong@arm.com 24810802Srene.dejong@arm.comclass SnoopRespPacketQueue : public PacketQueue 24910802Srene.dejong@arm.com{ 25010802Srene.dejong@arm.com 25110802Srene.dejong@arm.com protected: 25210802Srene.dejong@arm.com 25310802Srene.dejong@arm.com MasterPort& masterPort; 25410802Srene.dejong@arm.com 25510802Srene.dejong@arm.com // Static definition so it can be called when constructing the parent 25610802Srene.dejong@arm.com // without us being completely initialized. 25710802Srene.dejong@arm.com static const std::string name(const MasterPort& masterPort, 25810802Srene.dejong@arm.com const std::string& label) 25910802Srene.dejong@arm.com { return masterPort.name() + "-" + label; } 26010802Srene.dejong@arm.com 26110802Srene.dejong@arm.com public: 26210802Srene.dejong@arm.com 26310802Srene.dejong@arm.com /** 26410802Srene.dejong@arm.com * Create a snoop response packet queue, linked to an event 26510802Srene.dejong@arm.com * manager, a master port, and a label that will be used for 26610802Srene.dejong@arm.com * functional print request packets. 26710802Srene.dejong@arm.com * 26810802Srene.dejong@arm.com * @param _em Event manager used for scheduling this queue 26910802Srene.dejong@arm.com * @param _masterPort Master port used to send the packets 27010802Srene.dejong@arm.com * @param _label Label to push on the label stack for print request packets 27110802Srene.dejong@arm.com */ 27210802Srene.dejong@arm.com SnoopRespPacketQueue(EventManager& _em, MasterPort& _masterPort, 27310802Srene.dejong@arm.com const std::string _label = "SnoopRespPacketQueue"); 27410802Srene.dejong@arm.com 27510802Srene.dejong@arm.com virtual ~SnoopRespPacketQueue() { } 27610802Srene.dejong@arm.com 27710802Srene.dejong@arm.com const std::string name() const 27810802Srene.dejong@arm.com { return name(masterPort, label); } 27910802Srene.dejong@arm.com 28010802Srene.dejong@arm.com bool sendTiming(PacketPtr pkt); 28110802Srene.dejong@arm.com 28210802Srene.dejong@arm.com}; 28310802Srene.dejong@arm.com 28410802Srene.dejong@arm.comclass RespPacketQueue : public PacketQueue 28510802Srene.dejong@arm.com{ 28610802Srene.dejong@arm.com 28710802Srene.dejong@arm.com protected: 28810802Srene.dejong@arm.com 28910802Srene.dejong@arm.com SlavePort& slavePort; 29010802Srene.dejong@arm.com 29110802Srene.dejong@arm.com // Static definition so it can be called when constructing the parent 29210802Srene.dejong@arm.com // without us being completely initialized. 29310802Srene.dejong@arm.com static const std::string name(const SlavePort& slavePort, 29410802Srene.dejong@arm.com const std::string& label) 29510802Srene.dejong@arm.com { return slavePort.name() + "-" + label; } 29610802Srene.dejong@arm.com 29710802Srene.dejong@arm.com public: 29810802Srene.dejong@arm.com 29910802Srene.dejong@arm.com /** 30010802Srene.dejong@arm.com * Create a response packet queue, linked to an event manager, a 30110802Srene.dejong@arm.com * slave port, and a label that will be used for functional print 30210802Srene.dejong@arm.com * request packets. 30310802Srene.dejong@arm.com * 30410802Srene.dejong@arm.com * @param _em Event manager used for scheduling this queue 30510802Srene.dejong@arm.com * @param _slavePort Slave port used to send the packets 30610802Srene.dejong@arm.com * @param _label Label to push on the label stack for print request packets 30710802Srene.dejong@arm.com */ 30810802Srene.dejong@arm.com RespPacketQueue(EventManager& _em, SlavePort& _slavePort, 30910802Srene.dejong@arm.com const std::string _label = "RespPacketQueue"); 31010802Srene.dejong@arm.com 31110802Srene.dejong@arm.com virtual ~RespPacketQueue() { } 31210802Srene.dejong@arm.com 31310802Srene.dejong@arm.com const std::string name() const 31410802Srene.dejong@arm.com { return name(slavePort, label); } 31510802Srene.dejong@arm.com 31610802Srene.dejong@arm.com bool sendTiming(PacketPtr pkt); 31710802Srene.dejong@arm.com 31810802Srene.dejong@arm.com}; 31910802Srene.dejong@arm.com 32010802Srene.dejong@arm.com#endif // __MEM_PACKET_QUEUE_HH__ 32110802Srene.dejong@arm.com