/*
 * Copyright (c) 2012-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.
 *
 * Copyright (c) 2013 Amin Farmahini-Farahani
 * All rights reserved.
 *
 * 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.
 */

/**
 * @file
 * NVMInterface declaration
 */

#ifndef __NVM_INTERFACE_HH__
#define __NVM_INTERFACE_HH__

#include "mem/mem_interface.hh"
#include "params/NVMInterface.hh"

namespace gem5
{

namespace memory
{

/**
 * Interface to NVM devices with media specific parameters,
 * statistics, and functions.
 * The NVMInterface includes a class for individual ranks
 * and per rank functions.
 */
class NVMInterface : public MemInterface
{
  private:
    /**
     * NVM rank class simply includes a vector of banks.
     */
    class Rank : public EventManager
    {
      public:

        /**
         * Current Rank index
         */
        uint8_t rank;

        /**
         * Vector of NVM banks. Each rank is made of several banks
         * that can be accessed in parallel.
         */
        std::vector<Bank> banks;

        Rank(const NVMInterfaceParams &_p, int _rank,
             NVMInterface& _nvm);
    };

    /**
     * NVM specific device and channel characteristics
     */
    const uint32_t maxPendingWrites;
    const uint32_t maxPendingReads;
    const bool twoCycleRdWr;

    /**
     * NVM specific timing requirements
     */
    const Tick tREAD;
    const Tick tWRITE;
    const Tick tSEND;

    struct NVMStats : public statistics::Group
    {
        NVMStats(NVMInterface &nvm);

        void regStats() override;

        NVMInterface &nvm;

        /** NVM stats */
        statistics::Scalar readBursts;
        statistics::Scalar writeBursts;

        statistics::Vector perBankRdBursts;
        statistics::Vector perBankWrBursts;

        // Latencies summed over all requests
        statistics::Scalar totQLat;
        statistics::Scalar totBusLat;
        statistics::Scalar totMemAccLat;

        // Average latencies per request
        statistics::Formula avgQLat;
        statistics::Formula avgBusLat;
        statistics::Formula avgMemAccLat;

        statistics::Scalar bytesRead;
        statistics::Scalar bytesWritten;

        // Average bandwidth
        statistics::Formula avgRdBW;
        statistics::Formula avgWrBW;
        statistics::Formula peakBW;
        statistics::Formula busUtil;
        statistics::Formula busUtilRead;
        statistics::Formula busUtilWrite;

        /** NVM stats */
        statistics::Histogram pendingReads;
        statistics::Histogram pendingWrites;
        statistics::Histogram bytesPerBank;
    };
    NVMStats stats;

    void processWriteRespondEvent();
    EventFunctionWrapper writeRespondEvent;

    void processReadReadyEvent();
    EventFunctionWrapper readReadyEvent;

    /**
      * Vector of nvm ranks
      */
    std::vector<Rank*> ranks;

    /**
     * Holding queue for non-deterministic write commands, which
     * maintains writes that have been issued but have not completed
     * Stored seperately mostly to keep the code clean and help with
     * events scheduling.
     * This mimics a buffer on the media controller and therefore is
     * not added to the main write queue for sizing
     */
    std::list<Tick> writeRespQueue;

    std::deque<Tick> readReadyQueue;

    /**
     * Check if the write response queue is empty
     *
     * @param Return true if empty
     */
    bool writeRespQueueEmpty() const { return writeRespQueue.empty(); }

    /**
     * Till when must we wait before issuing next read command?
     */
    Tick nextReadAt;

    // keep track of reads that have issued for which data is either
    // not yet ready or has not yet been transferred to the ctrl
    uint16_t numPendingReads;
    uint16_t numReadDataReady;

  public:
    // keep track of the number of reads that have yet to be issued
    uint16_t numReadsToIssue;

    /**
     * Initialize the NVM interface and verify parameters
     */
    void init() override;

    /**
     * Setup the rank based on packet received
     *
     * @param integer value of rank to be setup. used to index ranks vector
     * @param are we setting up rank for read or write packet?
     */
    void setupRank(const uint8_t rank, const bool is_read) override;

    MemPacket* decodePacket(const PacketPtr pkt, Addr pkt_addr,
                           unsigned int size, bool is_read) override;

    /**
     * Check drain state of NVM interface
     *
     * @return true if write response queue is empty
     *
     */
    bool allRanksDrained() const override { return writeRespQueueEmpty(); }

    /*
     * @return time to offset next command
     */
    Tick commandOffset() const override { return tBURST; }

    /**
     * Check if a burst operation can be issued to the NVM
     *
     * @param Return true if RD/WR can issue
     *                    for reads, also verfy that ready count
     *                    has been updated to a non-zero value to
     *                    account for race conditions between events
     */
    bool burstReady(MemPacket* pkt) const override;

    /**
     * This function checks if ranks are busy.
     * This state is true when either:
     * 1) There is no command with read data ready to transmit or
     * 2) The NVM inteface has reached the maximum number of outstanding
     *    writes commands.
     * @param read_queue_empty There are no read queued
     * @param all_writes_nvm   All writes in queue are for NVM interface
     * @return true of NVM is busy
     *
     */
    bool isBusy(bool read_queue_empty, bool all_writes_nvm) override;
    /**
     * For FR-FCFS policy, find first NVM command that can issue
     * default to first command to prepped region
     *
     * @param queue Queued requests to consider
     * @param min_col_at Minimum tick for 'seamless' issue
     * @return an iterator to the selected packet, else queue.end()
     * @return the tick when the packet selected will issue
     */
    std::pair<MemPacketQueue::iterator, Tick>
    chooseNextFRFCFS(MemPacketQueue& queue, Tick min_col_at) const override;

    /**
     *  Add rank to rank delay to bus timing to all NVM banks in alli ranks
     *  when access to an alternate interface is issued
     *
     *  param cmd_at Time of current command used as starting point for
     *               addition of rank-to-rank delay
     */
    void addRankToRankDelay(Tick cmd_at) override;

    /**
     * Following two functions are not required for nvm interface
     */
    void respondEvent(uint8_t rank) override { };

    void checkRefreshState(uint8_t rank) override { };

    /**
     * Select read command to issue asynchronously
     */
    void chooseRead(MemPacketQueue& queue) override;

    /*
     * Function to calulate unloaded access latency
     */
    Tick accessLatency() const override { return (tREAD + tSEND); }

    /**
     * Check if the write response queue has reached defined threshold
     *
     * @param Return true if full
     */
    bool
    writeRespQueueFull() const override
    {
        return writeRespQueue.size() == maxPendingWrites;
    }

    bool
    readsWaitingToIssue() const override
    {
        return ((numReadsToIssue != 0) &&
                (numPendingReads < maxPendingReads));
    }

    /**
     * Actually do the burst and update stats.
     *
     * @param pkt The packet created from the outside world pkt
     * @param next_burst_at Minimum bus timing requirement from controller
     * @return pair, tick when current burst is issued and
     *               tick when next burst can issue
     */
    std::pair<Tick, Tick>
    doBurstAccess(MemPacket* pkt, Tick next_burst_at,
                  const std::vector<MemPacketQueue>& queue) override;

    /**
     * The next three functions are DRAM-specific and will be ignored by NVM.
     */
    void drainRanks() override { }
    void suspend() override { }
    void startup() override { }

    NVMInterface(const NVMInterfaceParams &_p);
};

} // namespace memory
} // namespace gem5

#endif //__NVM_INTERFACE_HH__
