/*
 * Copyright (c) 2018 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/qos/mem_ctrl.hh"
#include "mem/qport.hh"
#include "params/QoSMemSinkCtrl.hh"

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 interface interface name
     * @param idx port ID number
     * @return reference to this memory's slave port
     */
    BaseSlavePort& getSlavePort(const std::string&,
            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;

    /** 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

#endif /* __MEM_QOS_MEM_SINK_HH__ */
