| /* |
| * Copyright (c) 2018-2020 ARM Limited |
| * All rights reserved |
| * |
| * The license below extends only to copyright in the software and shall |
| * not be construed as granting a license to any other intellectual |
| * property including but not limited to intellectual property relating |
| * to a hardware implementation of the functionality of the software |
| * licensed hereunder. You may use the software subject to the license |
| * terms below provided that you ensure that this notice is replicated |
| * unmodified and in its entirety in all distributions of the software, |
| * modified or unmodified, in source code or in binary form. |
| * |
| * Redistribution and use in source and binary forms, with or without |
| * modification, are permitted provided that the following conditions are |
| * met: redistributions of source code must retain the above copyright |
| * notice, this list of conditions and the following disclaimer; |
| * redistributions in binary form must reproduce the above copyright |
| * notice, this list of conditions and the following disclaimer in the |
| * documentation and/or other materials provided with the distribution; |
| * neither the name of the copyright holders nor the names of its |
| * contributors may be used to endorse or promote products derived from |
| * this software without specific prior written permission. |
| * |
| * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS |
| * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT |
| * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR |
| * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT |
| * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, |
| * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT |
| * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, |
| * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY |
| * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
| * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE |
| * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
| * |
| * Author: Matteo Andreozzi |
| */ |
| |
| |
| #ifndef __MEM_QOS_MEM_SINK_HH__ |
| #define __MEM_QOS_MEM_SINK_HH__ |
| |
| #include "mem/abstract_mem.hh" |
| #include "mem/qos/mem_ctrl.hh" |
| #include "mem/qport.hh" |
| #include "params/QoSMemSinkCtrl.hh" |
| |
| class QoSMemSinkInterfaceParams; |
| class QoSMemSinkInterface; |
| |
| namespace QoS { |
| |
| /** |
| * QoS Memory Sink |
| * |
| * The QoS Memory Sink is a lightweight memory controller with QoS |
| * support. It is meant to provide a QoS aware simple memory system |
| * without the need of using a complex DRAM memory controller |
| */ |
| class MemSinkCtrl : public MemCtrl |
| { |
| protected: |
| /** |
| * The Request packets are store in a multiple dequeue structure, |
| * based on their QoS priority |
| */ |
| using PacketQueue = std::deque<PacketPtr>; |
| |
| private: |
| class MemoryPort : public QueuedSlavePort |
| { |
| private: |
| /** reference to parent memory object */ |
| MemSinkCtrl& memory; |
| |
| /** Outgoing packet responses queue */ |
| RespPacketQueue queue; |
| |
| public: |
| /** |
| * Constructor |
| * |
| * @param n port name |
| * @param m reference to ProfileGen parent object |
| */ |
| MemoryPort(const std::string&, MemSinkCtrl&); |
| |
| protected: |
| /** |
| * Receive a Packet in Atomic mode |
| * |
| * @param pkt pointer to memory packet |
| * @return packet access latency in ticks |
| */ |
| Tick recvAtomic(PacketPtr pkt); |
| |
| /** |
| * Receive a Packet in Functional mode |
| * |
| * @param pkt pointer to memory packet |
| */ |
| void recvFunctional(PacketPtr pkt); |
| |
| /** |
| * Receive a Packet in Timing mode |
| * |
| * @param pkt pointer to memory packet |
| * @return true if the request was accepted |
| */ |
| bool recvTimingReq(PacketPtr pkt); |
| |
| /** |
| * Gets the configured address ranges for this port |
| * @return the configured address ranges for this port |
| */ |
| AddrRangeList getAddrRanges() const; |
| |
| }; |
| |
| public: |
| /** |
| * QoS Memory Sink Constructor |
| * |
| * @param p QoS Memory Sink configuration parameters |
| */ |
| MemSinkCtrl(const QoSMemSinkCtrlParams*); |
| |
| virtual ~MemSinkCtrl(); |
| |
| /** |
| * Checks and return the Drain state of this SimObject |
| * @return current Drain state |
| */ |
| DrainState drain() override; |
| |
| /** |
| * Getter method to access this memory's slave port |
| * |
| * @param if_name interface name |
| * @param idx port ID number |
| * @return reference to this memory's slave port |
| */ |
| Port &getPort(const std::string &if_name, PortID=InvalidPortID) override; |
| |
| /** |
| * Initializes this object |
| */ |
| void init() override; |
| |
| protected: |
| /** Memory between requests latency (ticks) */ |
| const Tick requestLatency; |
| |
| /** Memory response latency (ticks) */ |
| const Tick responseLatency; |
| |
| /** Memory packet size in bytes */ |
| const uint64_t memoryPacketSize; |
| |
| /** Read request packets queue buffer size in #packets */ |
| const uint64_t readBufferSize; |
| |
| /** Write request packets queue buffer size in #packets */ |
| const uint64_t writeBufferSize; |
| |
| /** Memory slave port */ |
| MemoryPort port; |
| |
| /** |
| * Create pointer to interface of actual media |
| */ |
| QoSMemSinkInterface* const interface; |
| |
| /** Read request pending */ |
| bool retryRdReq; |
| |
| /** Write request pending */ |
| bool retryWrReq; |
| |
| /** Next request service time */ |
| Tick nextRequest; |
| |
| /** Count the number of read retries */ |
| Stats::Scalar numReadRetries; |
| |
| /** Count the number of write retries */ |
| Stats::Scalar numWriteRetries; |
| |
| /** |
| * QoS-aware (per priority) incoming read requests packets queue |
| */ |
| std::vector<PacketQueue> readQueue; |
| |
| /** |
| * QoS-aware (per priority) incoming read requests packets queue |
| */ |
| std::vector<PacketQueue> writeQueue; |
| |
| /** |
| * Processes the next Request event according to configured |
| * request latency |
| */ |
| void processNextReqEvent(); |
| |
| /** Event wrapper to schedule next request handler function */ |
| EventWrapper< |
| MemSinkCtrl, |
| &MemSinkCtrl::processNextReqEvent> nextReqEvent; |
| |
| /** |
| * Check if the read queue has room for more entries |
| * |
| * @param packets The number of entries needed in the read queue |
| * @return true if read queue is full, false otherwise |
| */ |
| inline bool readQueueFull(const uint64_t packets) const; |
| |
| /** |
| * Check if the write queue has room for more entries |
| * |
| * @param packets The number of entries needed in the write queue |
| * @return true if write queue is full, false otherwise |
| */ |
| inline bool writeQueueFull(const uint64_t packets) const; |
| |
| /** |
| * Receive a Packet in Atomic mode |
| * |
| * @param pkt pointer to memory packet |
| * @return packet access latency in ticks |
| */ |
| Tick recvAtomic(PacketPtr pkt); |
| |
| /** |
| * Receive a Packet in Functional mode |
| * |
| * @param pkt pointer to memory packet |
| */ |
| void recvFunctional(PacketPtr pkt); |
| |
| /** |
| * Receive a Packet in Timing mode |
| * |
| * @param pkt pointer to memory packet |
| * @return true if the request was accepted |
| */ |
| bool recvTimingReq(PacketPtr pkt); |
| |
| /** Registers statistics */ |
| void regStats() override; |
| }; |
| |
| } // namespace QoS |
| |
| class QoSMemSinkInterface : public AbstractMemory |
| { |
| public: |
| /** Setting a pointer to the interface */ |
| void setMemCtrl(QoS::MemSinkCtrl* _ctrl) { ctrl = _ctrl; }; |
| |
| /** Pointer to the controller */ |
| QoS::MemSinkCtrl* ctrl; |
| |
| QoSMemSinkInterface(const QoSMemSinkInterfaceParams* _p); |
| }; |
| |
| |
| #endif /* __MEM_QOS_MEM_SINK_HH__ */ |