112967Smatteo.andreozzi@arm.com/*
212967Smatteo.andreozzi@arm.com * Copyright (c) 2018 ARM Limited
312967Smatteo.andreozzi@arm.com * All rights reserved
412967Smatteo.andreozzi@arm.com *
512967Smatteo.andreozzi@arm.com * The license below extends only to copyright in the software and shall
612967Smatteo.andreozzi@arm.com * not be construed as granting a license to any other intellectual
712967Smatteo.andreozzi@arm.com * property including but not limited to intellectual property relating
812967Smatteo.andreozzi@arm.com * to a hardware implementation of the functionality of the software
912967Smatteo.andreozzi@arm.com * licensed hereunder.  You may use the software subject to the license
1012967Smatteo.andreozzi@arm.com * terms below provided that you ensure that this notice is replicated
1112967Smatteo.andreozzi@arm.com * unmodified and in its entirety in all distributions of the software,
1212967Smatteo.andreozzi@arm.com * modified or unmodified, in source code or in binary form.
1312967Smatteo.andreozzi@arm.com *
1412967Smatteo.andreozzi@arm.com * Redistribution and use in source and binary forms, with or without
1512967Smatteo.andreozzi@arm.com * modification, are permitted provided that the following conditions are
1612967Smatteo.andreozzi@arm.com * met: redistributions of source code must retain the above copyright
1712967Smatteo.andreozzi@arm.com * notice, this list of conditions and the following disclaimer;
1812967Smatteo.andreozzi@arm.com * redistributions in binary form must reproduce the above copyright
1912967Smatteo.andreozzi@arm.com * notice, this list of conditions and the following disclaimer in the
2012967Smatteo.andreozzi@arm.com * documentation and/or other materials provided with the distribution;
2112967Smatteo.andreozzi@arm.com * neither the name of the copyright holders nor the names of its
2212967Smatteo.andreozzi@arm.com * contributors may be used to endorse or promote products derived from
2312967Smatteo.andreozzi@arm.com * this software without specific prior written permission.
2412967Smatteo.andreozzi@arm.com *
2512967Smatteo.andreozzi@arm.com * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
2612967Smatteo.andreozzi@arm.com * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
2712967Smatteo.andreozzi@arm.com * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
2812967Smatteo.andreozzi@arm.com * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
2912967Smatteo.andreozzi@arm.com * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
3012967Smatteo.andreozzi@arm.com * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
3112967Smatteo.andreozzi@arm.com * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
3212967Smatteo.andreozzi@arm.com * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
3312967Smatteo.andreozzi@arm.com * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
3412967Smatteo.andreozzi@arm.com * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
3512967Smatteo.andreozzi@arm.com * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
3612967Smatteo.andreozzi@arm.com *
3712967Smatteo.andreozzi@arm.com * Author: Matteo Andreozzi
3812967Smatteo.andreozzi@arm.com */
3912967Smatteo.andreozzi@arm.com
4012967Smatteo.andreozzi@arm.com
4112967Smatteo.andreozzi@arm.com#ifndef __MEM_QOS_MEM_SINK_HH__
4212967Smatteo.andreozzi@arm.com#define __MEM_QOS_MEM_SINK_HH__
4312967Smatteo.andreozzi@arm.com
4412967Smatteo.andreozzi@arm.com#include "mem/qos/mem_ctrl.hh"
4512967Smatteo.andreozzi@arm.com#include "mem/qport.hh"
4612967Smatteo.andreozzi@arm.com#include "params/QoSMemSinkCtrl.hh"
4712967Smatteo.andreozzi@arm.com
4812967Smatteo.andreozzi@arm.comnamespace QoS {
4912967Smatteo.andreozzi@arm.com
5012967Smatteo.andreozzi@arm.com/**
5112967Smatteo.andreozzi@arm.com * QoS Memory Sink
5212967Smatteo.andreozzi@arm.com *
5312967Smatteo.andreozzi@arm.com * The QoS Memory Sink is a lightweight memory controller with QoS
5412967Smatteo.andreozzi@arm.com * support. It is meant to provide a QoS aware simple memory system
5512967Smatteo.andreozzi@arm.com * without the need of using a complex DRAM memory controller
5612967Smatteo.andreozzi@arm.com */
5712967Smatteo.andreozzi@arm.comclass MemSinkCtrl : public MemCtrl
5812967Smatteo.andreozzi@arm.com{
5912967Smatteo.andreozzi@arm.com  protected:
6012967Smatteo.andreozzi@arm.com    /**
6112967Smatteo.andreozzi@arm.com     * The Request packets are store in a multiple dequeue structure,
6212967Smatteo.andreozzi@arm.com     * based on their QoS priority
6312967Smatteo.andreozzi@arm.com     */
6412967Smatteo.andreozzi@arm.com    using PacketQueue = std::deque<PacketPtr>;
6512967Smatteo.andreozzi@arm.com
6612967Smatteo.andreozzi@arm.com  private:
6712967Smatteo.andreozzi@arm.com    class MemoryPort : public QueuedSlavePort
6812967Smatteo.andreozzi@arm.com    {
6912967Smatteo.andreozzi@arm.com      private:
7012967Smatteo.andreozzi@arm.com        /** reference to parent memory object */
7112967Smatteo.andreozzi@arm.com        MemSinkCtrl& memory;
7212967Smatteo.andreozzi@arm.com
7312967Smatteo.andreozzi@arm.com        /** Outgoing packet responses queue */
7412967Smatteo.andreozzi@arm.com        RespPacketQueue queue;
7512967Smatteo.andreozzi@arm.com
7612967Smatteo.andreozzi@arm.com      public:
7712967Smatteo.andreozzi@arm.com       /**
7812967Smatteo.andreozzi@arm.com        * Constructor
7912967Smatteo.andreozzi@arm.com        *
8012967Smatteo.andreozzi@arm.com        * @param n port name
8112967Smatteo.andreozzi@arm.com        * @param m reference to ProfileGen parent object
8212967Smatteo.andreozzi@arm.com        */
8312967Smatteo.andreozzi@arm.com        MemoryPort(const std::string&, MemSinkCtrl&);
8412967Smatteo.andreozzi@arm.com
8512967Smatteo.andreozzi@arm.com      protected:
8612967Smatteo.andreozzi@arm.com       /**
8712967Smatteo.andreozzi@arm.com        * Receive a Packet in Atomic mode
8812967Smatteo.andreozzi@arm.com        *
8912967Smatteo.andreozzi@arm.com        * @param pkt pointer to memory packet
9012967Smatteo.andreozzi@arm.com        * @return packet access latency in ticks
9112967Smatteo.andreozzi@arm.com        */
9212967Smatteo.andreozzi@arm.com        Tick recvAtomic(PacketPtr pkt);
9312967Smatteo.andreozzi@arm.com
9412967Smatteo.andreozzi@arm.com        /**
9512967Smatteo.andreozzi@arm.com        * Receive a Packet in Functional mode
9612967Smatteo.andreozzi@arm.com        *
9712967Smatteo.andreozzi@arm.com        * @param pkt pointer to memory packet
9812967Smatteo.andreozzi@arm.com        */
9912967Smatteo.andreozzi@arm.com        void recvFunctional(PacketPtr pkt);
10012967Smatteo.andreozzi@arm.com
10112967Smatteo.andreozzi@arm.com        /**
10212967Smatteo.andreozzi@arm.com        * Receive a Packet in Timing mode
10312967Smatteo.andreozzi@arm.com        *
10412967Smatteo.andreozzi@arm.com        * @param pkt pointer to memory packet
10512967Smatteo.andreozzi@arm.com        * @return true if the request was accepted
10612967Smatteo.andreozzi@arm.com        */
10712967Smatteo.andreozzi@arm.com        bool recvTimingReq(PacketPtr pkt);
10812967Smatteo.andreozzi@arm.com
10912967Smatteo.andreozzi@arm.com        /**
11012967Smatteo.andreozzi@arm.com         * Gets the configured address ranges for this port
11112967Smatteo.andreozzi@arm.com         * @return the configured address ranges for this port
11212967Smatteo.andreozzi@arm.com         */
11312967Smatteo.andreozzi@arm.com        AddrRangeList getAddrRanges() const;
11412967Smatteo.andreozzi@arm.com
11512967Smatteo.andreozzi@arm.com    };
11612967Smatteo.andreozzi@arm.com
11712967Smatteo.andreozzi@arm.com  public:
11812967Smatteo.andreozzi@arm.com    /**
11912967Smatteo.andreozzi@arm.com     * QoS Memory Sink Constructor
12012967Smatteo.andreozzi@arm.com     *
12112967Smatteo.andreozzi@arm.com     * @param p QoS Memory Sink configuration parameters
12212967Smatteo.andreozzi@arm.com     */
12312967Smatteo.andreozzi@arm.com    MemSinkCtrl(const QoSMemSinkCtrlParams*);
12412967Smatteo.andreozzi@arm.com
12512967Smatteo.andreozzi@arm.com    virtual ~MemSinkCtrl();
12612967Smatteo.andreozzi@arm.com
12712967Smatteo.andreozzi@arm.com    /**
12812967Smatteo.andreozzi@arm.com     * Checks and return the Drain state of this SimObject
12912967Smatteo.andreozzi@arm.com     * @return current Drain state
13012967Smatteo.andreozzi@arm.com     */
13112967Smatteo.andreozzi@arm.com    DrainState drain() override;
13212967Smatteo.andreozzi@arm.com
13312967Smatteo.andreozzi@arm.com    /**
13412967Smatteo.andreozzi@arm.com     * Getter method to access this memory's slave port
13512967Smatteo.andreozzi@arm.com     *
13613784Sgabeblack@google.com     * @param if_name interface name
13712967Smatteo.andreozzi@arm.com     * @param idx port ID number
13812967Smatteo.andreozzi@arm.com     * @return reference to this memory's slave port
13912967Smatteo.andreozzi@arm.com     */
14013784Sgabeblack@google.com    Port &getPort(const std::string &if_name, PortID=InvalidPortID) override;
14112967Smatteo.andreozzi@arm.com
14212967Smatteo.andreozzi@arm.com    /**
14312967Smatteo.andreozzi@arm.com     * Initializes this object
14412967Smatteo.andreozzi@arm.com     */
14512967Smatteo.andreozzi@arm.com    void init() override;
14612967Smatteo.andreozzi@arm.com
14712967Smatteo.andreozzi@arm.com  protected:
14812967Smatteo.andreozzi@arm.com    /** Memory between requests latency (ticks) */
14912967Smatteo.andreozzi@arm.com    const Tick requestLatency;
15012967Smatteo.andreozzi@arm.com
15112967Smatteo.andreozzi@arm.com    /** Memory response latency (ticks) */
15212967Smatteo.andreozzi@arm.com    const Tick responseLatency;
15312967Smatteo.andreozzi@arm.com
15412967Smatteo.andreozzi@arm.com    /** Memory packet size in bytes */
15512967Smatteo.andreozzi@arm.com    const uint64_t memoryPacketSize;
15612967Smatteo.andreozzi@arm.com
15712967Smatteo.andreozzi@arm.com    /** Read request packets queue buffer size in #packets */
15812967Smatteo.andreozzi@arm.com    const uint64_t readBufferSize;
15912967Smatteo.andreozzi@arm.com
16012967Smatteo.andreozzi@arm.com    /** Write request packets queue buffer size in #packets */
16112967Smatteo.andreozzi@arm.com    const uint64_t writeBufferSize;
16212967Smatteo.andreozzi@arm.com
16312967Smatteo.andreozzi@arm.com    /** Memory slave port */
16412967Smatteo.andreozzi@arm.com    MemoryPort port;
16512967Smatteo.andreozzi@arm.com
16612967Smatteo.andreozzi@arm.com    /** Read request pending */
16712967Smatteo.andreozzi@arm.com    bool retryRdReq;
16812967Smatteo.andreozzi@arm.com
16912967Smatteo.andreozzi@arm.com    /** Write request pending */
17012967Smatteo.andreozzi@arm.com    bool retryWrReq;
17112967Smatteo.andreozzi@arm.com
17212967Smatteo.andreozzi@arm.com    /** Next request service time */
17312967Smatteo.andreozzi@arm.com    Tick nextRequest;
17412967Smatteo.andreozzi@arm.com
17512967Smatteo.andreozzi@arm.com    /** Count the number of read retries */
17612967Smatteo.andreozzi@arm.com    Stats::Scalar numReadRetries;
17712967Smatteo.andreozzi@arm.com
17812967Smatteo.andreozzi@arm.com    /** Count the number of write retries */
17912967Smatteo.andreozzi@arm.com    Stats::Scalar numWriteRetries;
18012967Smatteo.andreozzi@arm.com
18112967Smatteo.andreozzi@arm.com    /**
18212967Smatteo.andreozzi@arm.com     * QoS-aware (per priority) incoming read requests packets queue
18312967Smatteo.andreozzi@arm.com     */
18412967Smatteo.andreozzi@arm.com    std::vector<PacketQueue> readQueue;
18512967Smatteo.andreozzi@arm.com
18612967Smatteo.andreozzi@arm.com    /**
18712967Smatteo.andreozzi@arm.com     * QoS-aware (per priority) incoming read requests packets queue
18812967Smatteo.andreozzi@arm.com     */
18912967Smatteo.andreozzi@arm.com    std::vector<PacketQueue> writeQueue;
19012967Smatteo.andreozzi@arm.com
19112967Smatteo.andreozzi@arm.com    /**
19212967Smatteo.andreozzi@arm.com     * Processes the next Request event according to configured
19312967Smatteo.andreozzi@arm.com     * request latency
19412967Smatteo.andreozzi@arm.com     */
19512967Smatteo.andreozzi@arm.com    void processNextReqEvent();
19612967Smatteo.andreozzi@arm.com
19712967Smatteo.andreozzi@arm.com    /** Event wrapper to schedule next request handler function */
19812967Smatteo.andreozzi@arm.com    EventWrapper<
19912967Smatteo.andreozzi@arm.com        MemSinkCtrl,
20012967Smatteo.andreozzi@arm.com        &MemSinkCtrl::processNextReqEvent> nextReqEvent;
20112967Smatteo.andreozzi@arm.com
20212967Smatteo.andreozzi@arm.com    /**
20312967Smatteo.andreozzi@arm.com     * Check if the read queue has room for more entries
20412967Smatteo.andreozzi@arm.com     *
20512967Smatteo.andreozzi@arm.com     * @param packets The number of entries needed in the read queue
20612967Smatteo.andreozzi@arm.com     * @return true if read queue is full, false otherwise
20712967Smatteo.andreozzi@arm.com     */
20812967Smatteo.andreozzi@arm.com    inline bool readQueueFull(const uint64_t packets) const;
20912967Smatteo.andreozzi@arm.com
21012967Smatteo.andreozzi@arm.com    /**
21112967Smatteo.andreozzi@arm.com     * Check if the write queue has room for more entries
21212967Smatteo.andreozzi@arm.com     *
21312967Smatteo.andreozzi@arm.com     * @param packets  The number of entries needed in the write queue
21412967Smatteo.andreozzi@arm.com     * @return true if write queue is full, false otherwise
21512967Smatteo.andreozzi@arm.com     */
21612967Smatteo.andreozzi@arm.com    inline bool writeQueueFull(const uint64_t packets) const;
21712967Smatteo.andreozzi@arm.com
21812967Smatteo.andreozzi@arm.com    /**
21912967Smatteo.andreozzi@arm.com     * Receive a Packet in Atomic mode
22012967Smatteo.andreozzi@arm.com     *
22112967Smatteo.andreozzi@arm.com     * @param pkt pointer to memory packet
22212967Smatteo.andreozzi@arm.com     * @return packet access latency in ticks
22312967Smatteo.andreozzi@arm.com     */
22412967Smatteo.andreozzi@arm.com    Tick recvAtomic(PacketPtr pkt);
22512967Smatteo.andreozzi@arm.com
22612967Smatteo.andreozzi@arm.com    /**
22712967Smatteo.andreozzi@arm.com     * Receive a Packet in Functional mode
22812967Smatteo.andreozzi@arm.com     *
22912967Smatteo.andreozzi@arm.com     * @param pkt pointer to memory packet
23012967Smatteo.andreozzi@arm.com     */
23112967Smatteo.andreozzi@arm.com    void recvFunctional(PacketPtr pkt);
23212967Smatteo.andreozzi@arm.com
23312967Smatteo.andreozzi@arm.com   /**
23412967Smatteo.andreozzi@arm.com    * Receive a Packet in Timing mode
23512967Smatteo.andreozzi@arm.com    *
23612967Smatteo.andreozzi@arm.com    * @param pkt pointer to memory packet
23712967Smatteo.andreozzi@arm.com    * @return true if the request was accepted
23812967Smatteo.andreozzi@arm.com    */
23912967Smatteo.andreozzi@arm.com    bool recvTimingReq(PacketPtr pkt);
24012967Smatteo.andreozzi@arm.com
24112967Smatteo.andreozzi@arm.com    /** Registers statistics */
24212967Smatteo.andreozzi@arm.com    void regStats() override;
24312967Smatteo.andreozzi@arm.com};
24412967Smatteo.andreozzi@arm.com
24512967Smatteo.andreozzi@arm.com} // namespace QoS
24612967Smatteo.andreozzi@arm.com
24712967Smatteo.andreozzi@arm.com#endif /* __MEM_QOS_MEM_SINK_HH__ */
248