/*
 * 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,
                           uint8_t pseudo_channel = 0) 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__
