packet_queue.hh revision 13564:9bbd53a77887
112810Sandreas.sandberg@arm.com/* 212810Sandreas.sandberg@arm.com * Copyright (c) 2012,2015,2018 ARM Limited 312810Sandreas.sandberg@arm.com * All rights reserved. 412810Sandreas.sandberg@arm.com * 512810Sandreas.sandberg@arm.com * The license below extends only to copyright in the software and shall 612810Sandreas.sandberg@arm.com * not be construed as granting a license to any other intellectual 712810Sandreas.sandberg@arm.com * property including but not limited to intellectual property relating 812810Sandreas.sandberg@arm.com * to a hardware implementation of the functionality of the software 912810Sandreas.sandberg@arm.com * licensed hereunder. You may use the software subject to the license 1012810Sandreas.sandberg@arm.com * terms below provided that you ensure that this notice is replicated 1112810Sandreas.sandberg@arm.com * unmodified and in its entirety in all distributions of the software, 1212810Sandreas.sandberg@arm.com * modified or unmodified, in source code or in binary form. 1312810Sandreas.sandberg@arm.com * 1412810Sandreas.sandberg@arm.com * Copyright (c) 2006 The Regents of The University of Michigan 1512810Sandreas.sandberg@arm.com * All rights reserved. 1612810Sandreas.sandberg@arm.com * 1712810Sandreas.sandberg@arm.com * Redistribution and use in source and binary forms, with or without 1812810Sandreas.sandberg@arm.com * modification, are permitted provided that the following conditions are 1912810Sandreas.sandberg@arm.com * met: redistributions of source code must retain the above copyright 2012810Sandreas.sandberg@arm.com * notice, this list of conditions and the following disclaimer; 2112810Sandreas.sandberg@arm.com * redistributions in binary form must reproduce the above copyright 2212810Sandreas.sandberg@arm.com * notice, this list of conditions and the following disclaimer in the 2312810Sandreas.sandberg@arm.com * documentation and/or other materials provided with the distribution; 2412810Sandreas.sandberg@arm.com * neither the name of the copyright holders nor the names of its 2512810Sandreas.sandberg@arm.com * contributors may be used to endorse or promote products derived from 2612810Sandreas.sandberg@arm.com * this software without specific prior written permission. 2712810Sandreas.sandberg@arm.com * 2812810Sandreas.sandberg@arm.com * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 2912810Sandreas.sandberg@arm.com * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 3012810Sandreas.sandberg@arm.com * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 3112810Sandreas.sandberg@arm.com * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 3212810Sandreas.sandberg@arm.com * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 3312810Sandreas.sandberg@arm.com * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 3412810Sandreas.sandberg@arm.com * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 3512810Sandreas.sandberg@arm.com * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 3612810Sandreas.sandberg@arm.com * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 3712810Sandreas.sandberg@arm.com * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 3812810Sandreas.sandberg@arm.com * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 3912810Sandreas.sandberg@arm.com * 4012810Sandreas.sandberg@arm.com * Authors: Ali Saidi 4112810Sandreas.sandberg@arm.com * Andreas Hansson 4212810Sandreas.sandberg@arm.com */ 4312810Sandreas.sandberg@arm.com 4412810Sandreas.sandberg@arm.com#ifndef __MEM_PACKET_QUEUE_HH__ 4512810Sandreas.sandberg@arm.com#define __MEM_PACKET_QUEUE_HH__ 4612810Sandreas.sandberg@arm.com 4712810Sandreas.sandberg@arm.com/** 4812810Sandreas.sandberg@arm.com * @file 4912810Sandreas.sandberg@arm.com * Declaration of a simple PacketQueue that is associated with 5012810Sandreas.sandberg@arm.com * a port on which it attempts to send packets according to the time 5112810Sandreas.sandberg@arm.com * stamp given to them at insertion. The packet queue is responsible 5212810Sandreas.sandberg@arm.com * for the flow control of the port. 5312810Sandreas.sandberg@arm.com */ 5412810Sandreas.sandberg@arm.com 5512810Sandreas.sandberg@arm.com#include <list> 5612810Sandreas.sandberg@arm.com 5712810Sandreas.sandberg@arm.com#include "mem/port.hh" 5812810Sandreas.sandberg@arm.com#include "sim/drain.hh" 5912810Sandreas.sandberg@arm.com#include "sim/eventq_impl.hh" 6012810Sandreas.sandberg@arm.com 6112810Sandreas.sandberg@arm.com/** 6212810Sandreas.sandberg@arm.com * A packet queue is a class that holds deferred packets and later 6312810Sandreas.sandberg@arm.com * sends them using the associated slave port or master port. 6412810Sandreas.sandberg@arm.com */ 6512810Sandreas.sandberg@arm.comclass PacketQueue : public Drainable 6612810Sandreas.sandberg@arm.com{ 6712810Sandreas.sandberg@arm.com private: 6812810Sandreas.sandberg@arm.com /** A deferred packet, buffered to transmit later. */ 6912810Sandreas.sandberg@arm.com class DeferredPacket { 7012810Sandreas.sandberg@arm.com public: 7112810Sandreas.sandberg@arm.com Tick tick; ///< The tick when the packet is ready to transmit 7212810Sandreas.sandberg@arm.com PacketPtr pkt; ///< Pointer to the packet to transmit 7312810Sandreas.sandberg@arm.com DeferredPacket(Tick t, PacketPtr p) 7412810Sandreas.sandberg@arm.com : tick(t), pkt(p) 7512810Sandreas.sandberg@arm.com {} 7612810Sandreas.sandberg@arm.com }; 7712810Sandreas.sandberg@arm.com 7812810Sandreas.sandberg@arm.com typedef std::list<DeferredPacket> DeferredPacketList; 7912810Sandreas.sandberg@arm.com 8012810Sandreas.sandberg@arm.com /** A list of outgoing packets. */ 8112810Sandreas.sandberg@arm.com DeferredPacketList transmitList; 8212810Sandreas.sandberg@arm.com 8312810Sandreas.sandberg@arm.com /** The manager which is used for the event queue */ 8412810Sandreas.sandberg@arm.com EventManager& em; 8512810Sandreas.sandberg@arm.com 8612810Sandreas.sandberg@arm.com /** Used to schedule sending of deferred packets. */ 8712810Sandreas.sandberg@arm.com void processSendEvent(); 8812810Sandreas.sandberg@arm.com 8912810Sandreas.sandberg@arm.com /** Event used to call processSendEvent. */ 9012810Sandreas.sandberg@arm.com EventFunctionWrapper sendEvent; 9112810Sandreas.sandberg@arm.com 9212810Sandreas.sandberg@arm.com /* 9312810Sandreas.sandberg@arm.com * Optionally disable the sanity check 9412810Sandreas.sandberg@arm.com * on the size of the transmitList. The 9512810Sandreas.sandberg@arm.com * sanity check will be enabled by default. 9612810Sandreas.sandberg@arm.com */ 9712810Sandreas.sandberg@arm.com bool _disableSanityCheck; 9812810Sandreas.sandberg@arm.com 9912810Sandreas.sandberg@arm.com /** 10012810Sandreas.sandberg@arm.com * if true, inserted packets have to be unconditionally scheduled 10112810Sandreas.sandberg@arm.com * after the last packet in the queue that references the same 10212810Sandreas.sandberg@arm.com * address 10312810Sandreas.sandberg@arm.com */ 10412810Sandreas.sandberg@arm.com bool forceOrder; 10512810Sandreas.sandberg@arm.com 10612810Sandreas.sandberg@arm.com protected: 10712810Sandreas.sandberg@arm.com 10812810Sandreas.sandberg@arm.com /** Label to use for print request packets label stack. */ 10912810Sandreas.sandberg@arm.com const std::string label; 11012810Sandreas.sandberg@arm.com 11112810Sandreas.sandberg@arm.com /** Remember whether we're awaiting a retry. */ 11212810Sandreas.sandberg@arm.com bool waitingOnRetry; 11312810Sandreas.sandberg@arm.com 11412810Sandreas.sandberg@arm.com /** Check whether we have a packet ready to go on the transmit list. */ 11512810Sandreas.sandberg@arm.com bool deferredPacketReady() const 11612810Sandreas.sandberg@arm.com { return !transmitList.empty() && transmitList.front().tick <= curTick(); } 11712810Sandreas.sandberg@arm.com 11812810Sandreas.sandberg@arm.com /** 11912810Sandreas.sandberg@arm.com * Attempt to send a packet. Note that a subclass of the 12012810Sandreas.sandberg@arm.com * PacketQueue can override this method and thus change the 12112810Sandreas.sandberg@arm.com * behaviour (as done by the cache for the request queue). The 12212810Sandreas.sandberg@arm.com * default implementation sends the head of the transmit list. The 12312810Sandreas.sandberg@arm.com * caller must guarantee that the list is non-empty and that the 12412810Sandreas.sandberg@arm.com * head packet is scheduled for curTick() (or earlier). 12512810Sandreas.sandberg@arm.com */ 12612810Sandreas.sandberg@arm.com virtual void sendDeferredPacket(); 12712810Sandreas.sandberg@arm.com 12812810Sandreas.sandberg@arm.com /** 12912810Sandreas.sandberg@arm.com * Send a packet using the appropriate method for the specific 13012810Sandreas.sandberg@arm.com * subclass (reuest, response or snoop response). 13112810Sandreas.sandberg@arm.com */ 13212810Sandreas.sandberg@arm.com virtual bool sendTiming(PacketPtr pkt) = 0; 13312810Sandreas.sandberg@arm.com 13412810Sandreas.sandberg@arm.com /** 13512810Sandreas.sandberg@arm.com * Create a packet queue, linked to an event manager, and a label 13612810Sandreas.sandberg@arm.com * that will be used for functional print request packets. 13712810Sandreas.sandberg@arm.com * 13812810Sandreas.sandberg@arm.com * @param _em Event manager used for scheduling this queue 13912810Sandreas.sandberg@arm.com * @param _label Label to push on the label stack for print request packets 14012810Sandreas.sandberg@arm.com * @param force_order Force insertion order for packets with same address 14112810Sandreas.sandberg@arm.com * @param disable_sanity_check Flag used to disable the sanity check 14212810Sandreas.sandberg@arm.com * on the size of the transmitList. The check is enabled by default. 14312810Sandreas.sandberg@arm.com */ 14412810Sandreas.sandberg@arm.com PacketQueue(EventManager& _em, const std::string& _label, 14512810Sandreas.sandberg@arm.com const std::string& _sendEventName, 14612810Sandreas.sandberg@arm.com bool force_order = false, 14712810Sandreas.sandberg@arm.com bool disable_sanity_check = false); 14812810Sandreas.sandberg@arm.com 14912810Sandreas.sandberg@arm.com /** 15012810Sandreas.sandberg@arm.com * Virtual desctructor since the class may be used as a base class. 15112810Sandreas.sandberg@arm.com */ 15212810Sandreas.sandberg@arm.com virtual ~PacketQueue(); 15312810Sandreas.sandberg@arm.com 15412810Sandreas.sandberg@arm.com public: 15512810Sandreas.sandberg@arm.com 15612810Sandreas.sandberg@arm.com /** 15712810Sandreas.sandberg@arm.com * Provide a name to simplify debugging. 15812810Sandreas.sandberg@arm.com * 15912810Sandreas.sandberg@arm.com * @return A complete name, appended to module and port 16012810Sandreas.sandberg@arm.com */ 16112810Sandreas.sandberg@arm.com virtual const std::string name() const = 0; 16212810Sandreas.sandberg@arm.com 16312810Sandreas.sandberg@arm.com /** 16412810Sandreas.sandberg@arm.com * Get the size of the queue. 16512810Sandreas.sandberg@arm.com */ 16612810Sandreas.sandberg@arm.com size_t size() const { return transmitList.size(); } 16712810Sandreas.sandberg@arm.com 16812810Sandreas.sandberg@arm.com /** 16912810Sandreas.sandberg@arm.com * Get the next packet ready time. 17012810Sandreas.sandberg@arm.com */ 17112810Sandreas.sandberg@arm.com Tick deferredPacketReadyTime() const 17212810Sandreas.sandberg@arm.com { return transmitList.empty() ? MaxTick : transmitList.front().tick; } 17312810Sandreas.sandberg@arm.com 17412810Sandreas.sandberg@arm.com /** 17512810Sandreas.sandberg@arm.com * Check if a packets address exists in the queue. 17612810Sandreas.sandberg@arm.com */ 17712810Sandreas.sandberg@arm.com bool hasAddr(Addr addr) const; 17812810Sandreas.sandberg@arm.com 17912810Sandreas.sandberg@arm.com /** Check the list of buffered packets against the supplied 18012810Sandreas.sandberg@arm.com * functional request. */ 18112810Sandreas.sandberg@arm.com bool trySatisfyFunctional(PacketPtr pkt); 18212810Sandreas.sandberg@arm.com 18312810Sandreas.sandberg@arm.com /** 18412810Sandreas.sandberg@arm.com * Schedule a send event if we are not already waiting for a 18512810Sandreas.sandberg@arm.com * retry. If the requested time is before an already scheduled 18612810Sandreas.sandberg@arm.com * send event, the event will be rescheduled. If MaxTick is 18712810Sandreas.sandberg@arm.com * passed, no event is scheduled. Instead, if we are idle and 18812810Sandreas.sandberg@arm.com * asked to drain then check and signal drained. 18912810Sandreas.sandberg@arm.com * 19012810Sandreas.sandberg@arm.com * @param when time to schedule an event 19112810Sandreas.sandberg@arm.com */ 19212810Sandreas.sandberg@arm.com void schedSendEvent(Tick when); 19312810Sandreas.sandberg@arm.com 19412810Sandreas.sandberg@arm.com /** 19512810Sandreas.sandberg@arm.com * Add a packet to the transmit list, and schedule a send event. 19612810Sandreas.sandberg@arm.com * 19712810Sandreas.sandberg@arm.com * @param pkt Packet to send 19812810Sandreas.sandberg@arm.com * @param when Absolute time (in ticks) to send packet 19912810Sandreas.sandberg@arm.com */ 20012810Sandreas.sandberg@arm.com void schedSendTiming(PacketPtr pkt, Tick when); 20112810Sandreas.sandberg@arm.com 20212810Sandreas.sandberg@arm.com /** 20312810Sandreas.sandberg@arm.com * Retry sending a packet from the queue. Note that this is not 20412810Sandreas.sandberg@arm.com * necessarily the same packet if something has been added with an 20512810Sandreas.sandberg@arm.com * earlier time stamp. 20612810Sandreas.sandberg@arm.com */ 20712810Sandreas.sandberg@arm.com void retry(); 20812810Sandreas.sandberg@arm.com 20912810Sandreas.sandberg@arm.com /** 21012810Sandreas.sandberg@arm.com * This allows a user to explicitly disable the sanity check 21112810Sandreas.sandberg@arm.com * on the size of the transmitList, which is enabled by default. 21212810Sandreas.sandberg@arm.com * Users must use this function to explicitly disable the sanity 21312810Sandreas.sandberg@arm.com * check. 21412810Sandreas.sandberg@arm.com */ 21512810Sandreas.sandberg@arm.com void disableSanityCheck() { _disableSanityCheck = true; } 21612810Sandreas.sandberg@arm.com 21712810Sandreas.sandberg@arm.com DrainState drain() override; 21812810Sandreas.sandberg@arm.com}; 21912810Sandreas.sandberg@arm.com 22012810Sandreas.sandberg@arm.comclass ReqPacketQueue : public PacketQueue 22112810Sandreas.sandberg@arm.com{ 22212810Sandreas.sandberg@arm.com 22312810Sandreas.sandberg@arm.com protected: 22412810Sandreas.sandberg@arm.com 22512810Sandreas.sandberg@arm.com MasterPort& masterPort; 22612810Sandreas.sandberg@arm.com 22712810Sandreas.sandberg@arm.com // Static definition so it can be called when constructing the parent 22812810Sandreas.sandberg@arm.com // without us being completely initialized. 22912810Sandreas.sandberg@arm.com static const std::string name(const MasterPort& masterPort, 23012810Sandreas.sandberg@arm.com const std::string& label) 23112810Sandreas.sandberg@arm.com { return masterPort.name() + "-" + label; } 23212810Sandreas.sandberg@arm.com 23312810Sandreas.sandberg@arm.com public: 23412810Sandreas.sandberg@arm.com 23512810Sandreas.sandberg@arm.com /** 23612810Sandreas.sandberg@arm.com * Create a request packet queue, linked to an event manager, a 23712810Sandreas.sandberg@arm.com * master port, and a label that will be used for functional print 23812810Sandreas.sandberg@arm.com * request packets. 23912810Sandreas.sandberg@arm.com * 24012810Sandreas.sandberg@arm.com * @param _em Event manager used for scheduling this queue 24112810Sandreas.sandberg@arm.com * @param _masterPort Master port used to send the packets 24212810Sandreas.sandberg@arm.com * @param _label Label to push on the label stack for print request packets 24312810Sandreas.sandberg@arm.com */ 24412810Sandreas.sandberg@arm.com ReqPacketQueue(EventManager& _em, MasterPort& _masterPort, 24512810Sandreas.sandberg@arm.com const std::string _label = "ReqPacketQueue"); 24612810Sandreas.sandberg@arm.com 24712810Sandreas.sandberg@arm.com virtual ~ReqPacketQueue() { } 24812810Sandreas.sandberg@arm.com 24912810Sandreas.sandberg@arm.com const std::string name() const 25012810Sandreas.sandberg@arm.com { return name(masterPort, label); } 25112810Sandreas.sandberg@arm.com 25212810Sandreas.sandberg@arm.com bool sendTiming(PacketPtr pkt); 25312810Sandreas.sandberg@arm.com 25412810Sandreas.sandberg@arm.com}; 25512810Sandreas.sandberg@arm.com 25612810Sandreas.sandberg@arm.comclass SnoopRespPacketQueue : public PacketQueue 25712810Sandreas.sandberg@arm.com{ 25812810Sandreas.sandberg@arm.com 25912810Sandreas.sandberg@arm.com protected: 26012810Sandreas.sandberg@arm.com 26112810Sandreas.sandberg@arm.com MasterPort& masterPort; 26212810Sandreas.sandberg@arm.com 26312810Sandreas.sandberg@arm.com // Static definition so it can be called when constructing the parent 26412810Sandreas.sandberg@arm.com // without us being completely initialized. 26512810Sandreas.sandberg@arm.com static const std::string name(const MasterPort& masterPort, 26612810Sandreas.sandberg@arm.com const std::string& label) 26712810Sandreas.sandberg@arm.com { return masterPort.name() + "-" + label; } 26812810Sandreas.sandberg@arm.com 26912810Sandreas.sandberg@arm.com public: 27012810Sandreas.sandberg@arm.com 27112810Sandreas.sandberg@arm.com /** 27212810Sandreas.sandberg@arm.com * Create a snoop response packet queue, linked to an event 27312810Sandreas.sandberg@arm.com * manager, a master port, and a label that will be used for 27412810Sandreas.sandberg@arm.com * functional print request packets. 27512810Sandreas.sandberg@arm.com * 27612810Sandreas.sandberg@arm.com * @param _em Event manager used for scheduling this queue 27712810Sandreas.sandberg@arm.com * @param _masterPort Master port used to send the packets 27812810Sandreas.sandberg@arm.com * @param force_order Force insertion order for packets with same address 27912810Sandreas.sandberg@arm.com * @param _label Label to push on the label stack for print request packets 28012810Sandreas.sandberg@arm.com */ 28112810Sandreas.sandberg@arm.com SnoopRespPacketQueue(EventManager& _em, MasterPort& _masterPort, 28212810Sandreas.sandberg@arm.com bool force_order = false, 28312810Sandreas.sandberg@arm.com const std::string _label = "SnoopRespPacketQueue"); 28412810Sandreas.sandberg@arm.com 28512810Sandreas.sandberg@arm.com virtual ~SnoopRespPacketQueue() { } 28612810Sandreas.sandberg@arm.com 28712810Sandreas.sandberg@arm.com const std::string name() const 28812810Sandreas.sandberg@arm.com { return name(masterPort, label); } 28912810Sandreas.sandberg@arm.com 29012810Sandreas.sandberg@arm.com bool sendTiming(PacketPtr pkt); 29112810Sandreas.sandberg@arm.com 29212810Sandreas.sandberg@arm.com}; 29312810Sandreas.sandberg@arm.com 29412810Sandreas.sandberg@arm.comclass RespPacketQueue : public PacketQueue 29512810Sandreas.sandberg@arm.com{ 29612810Sandreas.sandberg@arm.com 29712810Sandreas.sandberg@arm.com protected: 29812810Sandreas.sandberg@arm.com 29912810Sandreas.sandberg@arm.com SlavePort& slavePort; 30012810Sandreas.sandberg@arm.com 30112810Sandreas.sandberg@arm.com // Static definition so it can be called when constructing the parent 30212810Sandreas.sandberg@arm.com // without us being completely initialized. 30312810Sandreas.sandberg@arm.com static const std::string name(const SlavePort& slavePort, 30412810Sandreas.sandberg@arm.com const std::string& label) 30512810Sandreas.sandberg@arm.com { return slavePort.name() + "-" + label; } 30612810Sandreas.sandberg@arm.com 307 public: 308 309 /** 310 * Create a response packet queue, linked to an event manager, a 311 * slave port, and a label that will be used for functional print 312 * request packets. 313 * 314 * @param _em Event manager used for scheduling this queue 315 * @param _slavePort Slave port used to send the packets 316 * @param force_order Force insertion order for packets with same address 317 * @param _label Label to push on the label stack for print request packets 318 */ 319 RespPacketQueue(EventManager& _em, SlavePort& _slavePort, 320 bool force_order = false, 321 const std::string _label = "RespPacketQueue"); 322 323 virtual ~RespPacketQueue() { } 324 325 const std::string name() const 326 { return name(slavePort, label); } 327 328 bool sendTiming(PacketPtr pkt); 329 330}; 331 332#endif // __MEM_PACKET_QUEUE_HH__ 333