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

#ifndef __MEM_INTERFACE_HH__
#define __MEM_INTERFACE_HH__

#include <deque>
#include <string>
#include <unordered_set>
#include <utility>
#include <vector>

#include "base/compiler.hh"
#include "base/statistics.hh"
#include "enums/AddrMap.hh"
#include "enums/PageManage.hh"
#include "mem/abstract_mem.hh"
#include "mem/drampower.hh"
#include "mem/mem_ctrl.hh"
#include "params/DRAMInterface.hh"
#include "params/MemInterface.hh"
#include "params/NVMInterface.hh"
#include "sim/eventq.hh"

namespace gem5
{

namespace memory
{

/**
 * General interface to memory device
 * Includes functions and parameters shared across media types
 */
class MemInterface : public AbstractMemory
{
  protected:
    /**
     * A basic class to track the bank state, i.e. what row is
     * currently open (if any), when is the bank free to accept a new
     * column (read/write) command, when can it be precharged, and
     * when can it be activated.
     *
     * The bank also keeps track of how many bytes have been accessed
     * in the open row since it was opened.
     */
    class Bank
    {

      public:
        static const uint32_t NO_ROW = -1;

        uint32_t openRow;
        uint8_t bank;
        uint8_t bankgr;

        Tick rdAllowedAt;
        Tick wrAllowedAt;
        Tick preAllowedAt;
        Tick actAllowedAt;

        uint32_t rowAccesses;
        uint32_t bytesAccessed;

        Bank() :
            openRow(NO_ROW), bank(0), bankgr(0),
            rdAllowedAt(0), wrAllowedAt(0), preAllowedAt(0), actAllowedAt(0),
            rowAccesses(0), bytesAccessed(0)
        { }
    };

    /**
     * A pointer to the parent MemCtrl instance
     */
    MemCtrl* ctrl;

    /**
     * Number of commands that can issue in the defined controller
     * command window, used to verify command bandwidth
     */
    unsigned int maxCommandsPerWindow;

    /**
     * Memory controller configuration initialized based on parameter
     * values.
     */
    enums::AddrMap addrMapping;

    /**
     * General device and channel characteristics
     * The rowsPerBank is determined based on the capacity, number of
     * ranks and banks, the burst size, and the row buffer size.
     */
    const uint32_t burstSize;
    const uint32_t deviceSize;
    const uint32_t deviceRowBufferSize;
    const uint32_t devicesPerRank;
    const uint32_t rowBufferSize;
    const uint32_t burstsPerRowBuffer;
    const uint32_t burstsPerStripe;
    const uint32_t ranksPerChannel;
    const uint32_t banksPerRank;
    uint32_t rowsPerBank;

    /**
     * General timing requirements
     */
    GEM5_CLASS_VAR_USED const Tick tCK;
    const Tick tCS;
    const Tick tBURST;
    const Tick tRTW;
    const Tick tWTR;

    /*
     * @return delay between write and read commands
     */
    virtual Tick writeToReadDelay() const { return tBURST + tWTR; }

    /*
     * @return delay between write and read commands
     */
    Tick readToWriteDelay() const { return tBURST + tRTW; }

    /*
     * @return delay between accesses to different ranks
     */
    Tick rankToRankDelay() const { return tBURST + tCS; }


  public:

    /**
      * Buffer sizes for read and write queues in the controller
      * These are passed to the controller on instantiation
      * Defining them here allows for buffers to be resized based
      * on memory type / configuration.
      */
    const uint32_t readBufferSize;
    const uint32_t writeBufferSize;

    /** Set a pointer to the controller and initialize
     * interface based on controller parameters
     * @param _ctrl pointer to the parent controller
     * @param command_window size of command window used to
     *                       check command bandwidth
     */
    void setCtrl(MemCtrl* _ctrl, unsigned int command_window);

    /**
     * Get an address in a dense range which starts from 0. The input
     * address is the physical address of the request in an address
     * space that contains other SimObjects apart from this
     * controller.
     *
     * @param addr The intput address which should be in the addrRange
     * @return An address in the continues range [0, max)
     */
    Addr getCtrlAddr(Addr addr) { return range.getOffset(addr); }

    /**
     * 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?
     */
    virtual void setupRank(const uint8_t rank, const bool is_read) = 0;

    /**
     * Check drain state of interface
     *
     * @return true if all ranks are drained and idle
     *
     */
    virtual bool allRanksDrained() const = 0;

    /**
     * For FR-FCFS policy, find first command that can issue
     * Function will be overriden by interface to select based
     * on media characteristics, used to determine when read
     * or write can issue.
     *
     * @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
     */
    virtual std::pair<MemPacketQueue::iterator, Tick>
    chooseNextFRFCFS(MemPacketQueue& queue, Tick min_col_at) const = 0;

    /*
     * Function to calulate unloaded latency
     */
    virtual Tick accessLatency() const = 0;

    /**
     * @return number of bytes in a burst for this interface
     */
    uint32_t bytesPerBurst() const { return burstSize; }

    /*
     * @return time to offset next command
     */
    virtual Tick commandOffset() const = 0;

    /**
     * Check if a burst operation can be issued to the interface
     *
     * @param Return true if RD/WR can issue
     */
    virtual bool burstReady(MemPacket* pkt) const = 0;

    /**
     * Determine the required delay for an access to a different rank
     *
     * @return required rank to rank delay
     */
    Tick rankDelay() const { return tCS; }

    /**
     *
     * @return minimum additional bus turnaround required for read-to-write
     */
    Tick minReadToWriteDataGap() const { return std::min(tRTW, tCS); }

    /**
     *
     * @return minimum additional bus turnaround required for write-to-read
     */
    Tick minWriteToReadDataGap() const { return std::min(tWTR, tCS); }

    /**
     * Address decoder to figure out physical mapping onto ranks,
     * banks, and rows. This function is called multiple times on the same
     * system packet if the pakcet is larger than burst of the memory. The
     * pkt_addr is used for the offset within the packet.
     *
     * @param pkt The packet from the outside world
     * @param pkt_addr The starting address of the packet
     * @param size The size of the packet in bytes
     * @param is_read Is the request for a read or a write to memory
     * @param is_dram Is the request to a DRAM interface
     * @return A MemPacket pointer with the decoded information
     */
    MemPacket* decodePacket(const PacketPtr pkt, Addr pkt_addr,
                           unsigned int size, bool is_read, bool is_dram);

    /**
     *  Add rank to rank delay to bus timing to all banks in all 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
     */
    virtual void addRankToRankDelay(Tick cmd_at) = 0;

    typedef MemInterfaceParams Params;
    MemInterface(const Params &_p);
};

/**
 * Interface to DRAM devices with media specific parameters,
 * statistics, and functions.
 * The DRAMInterface includes a class for individual ranks
 * and per rank functions.
 */
class DRAMInterface : public MemInterface
{
  private:
    /**
     * Simple structure to hold the values needed to keep track of
     * commands for DRAMPower
     */
    struct Command
    {
       Data::MemCommand::cmds type;
       uint8_t bank;
       Tick timeStamp;

       constexpr Command(Data::MemCommand::cmds _type, uint8_t _bank,
                         Tick time_stamp)
            : type(_type), bank(_bank), timeStamp(time_stamp)
        { }
    };

    /**
     * The power state captures the different operational states of
     * the DRAM and interacts with the bus read/write state machine,
     * and the refresh state machine.
     *
     * PWR_IDLE      : The idle state in which all banks are closed
     *                 From here can transition to:  PWR_REF, PWR_ACT,
     *                 PWR_PRE_PDN
     *
     * PWR_REF       : Auto-refresh state.  Will transition when refresh is
     *                 complete based on power state prior to PWR_REF
     *                 From here can transition to:  PWR_IDLE, PWR_PRE_PDN,
     *                 PWR_SREF
     *
     * PWR_SREF      : Self-refresh state.  Entered after refresh if
     *                 previous state was PWR_PRE_PDN
     *                 From here can transition to:  PWR_IDLE
     *
     * PWR_PRE_PDN   : Precharge power down state
     *                 From here can transition to:  PWR_REF, PWR_IDLE
     *
     * PWR_ACT       : Activate state in which one or more banks are open
     *                 From here can transition to:  PWR_IDLE, PWR_ACT_PDN
     *
     * PWR_ACT_PDN   : Activate power down state
     *                 From here can transition to:  PWR_ACT
     */
    enum PowerState
    {
        PWR_IDLE = 0,
        PWR_REF,
        PWR_SREF,
        PWR_PRE_PDN,
        PWR_ACT,
        PWR_ACT_PDN
    };

    /**
     * The refresh state is used to control the progress of the
     * refresh scheduling. When normal operation is in progress the
     * refresh state is idle. Once tREFI has elasped, a refresh event
     * is triggered to start the following STM transitions which are
     * used to issue a refresh and return back to normal operation
     *
     * REF_IDLE      : IDLE state used during normal operation
     *                 From here can transition to:  REF_DRAIN
     *
     * REF_SREF_EXIT : Exiting a self-refresh; refresh event scheduled
     *                 after self-refresh exit completes
     *                 From here can transition to:  REF_DRAIN
     *
     * REF_DRAIN     : Drain state in which on going accesses complete.
     *                 From here can transition to:  REF_PD_EXIT
     *
     * REF_PD_EXIT   : Evaluate pwrState and issue wakeup if needed
     *                 Next state dependent on whether banks are open
     *                 From here can transition to:  REF_PRE, REF_START
     *
     * REF_PRE       : Close (precharge) all open banks
     *                 From here can transition to:  REF_START
     *
     * REF_START     : Issue refresh command and update DRAMPower stats
     *                 From here can transition to:  REF_RUN
     *
     * REF_RUN       : Refresh running, waiting for tRFC to expire
     *                 From here can transition to:  REF_IDLE, REF_SREF_EXIT
     */
    enum RefreshState
    {
        REF_IDLE = 0,
        REF_DRAIN,
        REF_PD_EXIT,
        REF_SREF_EXIT,
        REF_PRE,
        REF_START,
        REF_RUN
    };

    class Rank;
    struct RankStats : public statistics::Group
    {
        RankStats(DRAMInterface &dram, Rank &rank);

        void regStats() override;
        void resetStats() override;
        void preDumpStats() override;

        Rank &rank;

        /*
         * Command energies
         */
        statistics::Scalar actEnergy;
        statistics::Scalar preEnergy;
        statistics::Scalar readEnergy;
        statistics::Scalar writeEnergy;
        statistics::Scalar refreshEnergy;

        /*
         * Active Background Energy
         */
        statistics::Scalar actBackEnergy;

        /*
         * Precharge Background Energy
         */
        statistics::Scalar preBackEnergy;

        /*
         * Active Power-Down Energy
         */
        statistics::Scalar actPowerDownEnergy;

        /*
         * Precharge Power-Down Energy
         */
        statistics::Scalar prePowerDownEnergy;

        /*
         * self Refresh Energy
         */
        statistics::Scalar selfRefreshEnergy;

        statistics::Scalar totalEnergy;
        statistics::Scalar averagePower;

        /**
         * Stat to track total DRAM idle time
         *
         */
        statistics::Scalar totalIdleTime;

        /**
         * Track time spent in each power state.
         */
        statistics::Vector pwrStateTime;
    };

    /**
     * Rank class includes a vector of banks. Refresh and Power state
     * machines are defined per rank. Events required to change the
     * state of the refresh and power state machine are scheduled per
     * rank. This class allows the implementation of rank-wise refresh
     * and rank-wise power-down.
     */
    class Rank : public EventManager
    {
      private:

        /**
         * A reference to the parent DRAMInterface instance
         */
        DRAMInterface& dram;

        /**
         * Since we are taking decisions out of order, we need to keep
         * track of what power transition is happening at what time
         */
        PowerState pwrStateTrans;

        /**
         * Previous low-power state, which will be re-entered after refresh.
         */
        PowerState pwrStatePostRefresh;

        /**
         * Track when we transitioned to the current power state
         */
        Tick pwrStateTick;

        /**
         * Keep track of when a refresh is due.
         */
        Tick refreshDueAt;

        /**
         * Function to update Power Stats
         */
        void updatePowerStats();

        /**
         * Schedule a power state transition in the future, and
         * potentially override an already scheduled transition.
         *
         * @param pwr_state Power state to transition to
         * @param tick Tick when transition should take place
         */
        void schedulePowerEvent(PowerState pwr_state, Tick tick);

      public:

        /**
         * Current power state.
         */
        PowerState pwrState;

       /**
         * current refresh state
         */
        RefreshState refreshState;

        /**
         * rank is in or transitioning to power-down or self-refresh
         */
        bool inLowPowerState;

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

       /**
         * Track number of packets in read queue going to this rank
         */
        uint32_t readEntries;

       /**
         * Track number of packets in write queue going to this rank
         */
        uint32_t writeEntries;

        /**
         * Number of ACT, RD, and WR events currently scheduled
         * Incremented when a refresh event is started as well
         * Used to determine when a low-power state can be entered
         */
        uint8_t outstandingEvents;

        /**
         * delay low-power exit until this requirement is met
         */
        Tick wakeUpAllowedAt;

        /**
         * One DRAMPower instance per rank
         */
        DRAMPower power;

        /**
         * List of commands issued, to be sent to DRAMPpower at refresh
         * and stats dump.  Keep commands here since commands to different
         * banks are added out of order.  Will only pass commands up to
         * curTick() to DRAMPower after sorting.
         */
        std::vector<Command> cmdList;

        /**
         * Vector of Banks. Each rank is made of several devices which in
         * term are made from several banks.
         */
        std::vector<Bank> banks;

        /**
         *  To track number of banks which are currently active for
         *  this rank.
         */
        unsigned int numBanksActive;

        /** List to keep track of activate ticks */
        std::deque<Tick> actTicks;

        /**
         * Track when we issued the last read/write burst
         */
        Tick lastBurstTick;

        Rank(const DRAMInterfaceParams &_p, int _rank,
             DRAMInterface& _dram);

        const std::string name() const { return csprintf("%d", rank); }

        /**
         * Kick off accounting for power and refresh states and
         * schedule initial refresh.
         *
         * @param ref_tick Tick for first refresh
         */
        void startup(Tick ref_tick);

        /**
         * Stop the refresh events.
         */
        void suspend();

        /**
         * Check if there is no refresh and no preparation of refresh ongoing
         * i.e. the refresh state machine is in idle
         *
         * @param Return true if the rank is idle from a refresh point of view
         */
        bool inRefIdleState() const { return refreshState == REF_IDLE; }

        /**
         * Check if the current rank has all banks closed and is not
         * in a low power state
         *
         * @param Return true if the rank is idle from a bank
         *        and power point of view
         */
        bool inPwrIdleState() const { return pwrState == PWR_IDLE; }

        /**
         * Trigger a self-refresh exit if there are entries enqueued
         * Exit if there are any read entries regardless of the bus state.
         * If we are currently issuing write commands, exit if we have any
         * write commands enqueued as well.
         * Could expand this in the future to analyze state of entire queue
         * if needed.
         *
         * @return boolean indicating self-refresh exit should be scheduled
         */
        bool forceSelfRefreshExit() const;

        /**
         * Check if the command queue of current rank is idle
         *
         * @param Return true if the there are no commands in Q.
         *                    Bus direction determines queue checked.
         */
        bool isQueueEmpty() const;

        /**
         * Let the rank check if it was waiting for requests to drain
         * to allow it to transition states.
         */
        void checkDrainDone();

        /**
         * Push command out of cmdList queue that are scheduled at
         * or before curTick() to DRAMPower library
         * All commands before curTick are guaranteed to be complete
         * and can safely be flushed.
         */
        void flushCmdList();

        /**
         * Computes stats just prior to dump event
         */
        void computeStats();

        /**
         * Reset stats on a stats event
         */
        void resetStats();

        /**
         * Schedule a transition to power-down (sleep)
         *
         * @param pwr_state Power state to transition to
         * @param tick Absolute tick when transition should take place
         */
        void powerDownSleep(PowerState pwr_state, Tick tick);

       /**
         * schedule and event to wake-up from power-down or self-refresh
         * and update bank timing parameters
         *
         * @param exit_delay Relative tick defining the delay required between
         *                   low-power exit and the next command
         */
        void scheduleWakeUpEvent(Tick exit_delay);

        void processWriteDoneEvent();
        EventFunctionWrapper writeDoneEvent;

        void processActivateEvent();
        EventFunctionWrapper activateEvent;

        void processPrechargeEvent();
        EventFunctionWrapper prechargeEvent;

        void processRefreshEvent();
        EventFunctionWrapper refreshEvent;

        void processPowerEvent();
        EventFunctionWrapper powerEvent;

        void processWakeUpEvent();
        EventFunctionWrapper wakeUpEvent;

      protected:
        RankStats stats;
    };

    /**
     * Function for sorting Command structures based on timeStamp
     *
     * @param a Memory Command
     * @param next Memory Command
     * @return true if timeStamp of Command 1 < timeStamp of Command 2
     */
    static bool
    sortTime(const Command& cmd, const Command& cmd_next)
    {
        return cmd.timeStamp < cmd_next.timeStamp;
    }

    /**
     * DRAM specific device characteristics
     */
    const uint32_t bankGroupsPerRank;
    const bool bankGroupArch;

    /**
     * DRAM specific timing requirements
     */
    const Tick tCL;
    const Tick tBURST_MIN;
    const Tick tBURST_MAX;
    const Tick tCCD_L_WR;
    const Tick tCCD_L;
    const Tick tRCD;
    const Tick tRP;
    const Tick tRAS;
    const Tick tWR;
    const Tick tRTP;
    const Tick tRFC;
    const Tick tREFI;
    const Tick tRRD;
    const Tick tRRD_L;
    const Tick tPPD;
    const Tick tAAD;
    const Tick tXAW;
    const Tick tXP;
    const Tick tXS;
    const Tick clkResyncDelay;
    const bool dataClockSync;
    const bool burstInterleave;
    const uint8_t twoCycleActivate;
    const uint32_t activationLimit;
    const Tick wrToRdDlySameBG;
    const Tick rdToWrDlySameBG;


    enums::PageManage pageMgmt;
    /**
     * Max column accesses (read and write) per row, before forefully
     * closing it.
     */
    const uint32_t maxAccessesPerRow;

    // timestamp offset
    uint64_t timeStampOffset;

    // Holds the value of the DRAM rank of burst issued
    uint8_t activeRank;

    /** Enable or disable DRAM powerdown states. */
    bool enableDRAMPowerdown;

    /** The time when stats were last reset used to calculate average power */
    Tick lastStatsResetTick;

    /**
     * Keep track of when row activations happen, in order to enforce
     * the maximum number of activations in the activation window. The
     * method updates the time that the banks become available based
     * on the current limits.
     *
     * @param rank_ref Reference to the rank
     * @param bank_ref Reference to the bank
     * @param act_tick Time when the activation takes place
     * @param row Index of the row
     */
    void activateBank(Rank& rank_ref, Bank& bank_ref, Tick act_tick,
                      uint32_t row);

    /**
     * Precharge a given bank and also update when the precharge is
     * done. This will also deal with any stats related to the
     * accesses to the open page.
     *
     * @param rank_ref The rank to precharge
     * @param bank_ref The bank to precharge
     * @param pre_tick Time when the precharge takes place
     * @param auto_or_preall Is this an auto-precharge or precharge all command
     * @param trace Is this an auto precharge then do not add to trace
     */
    void prechargeBank(Rank& rank_ref, Bank& bank_ref,
                       Tick pre_tick, bool auto_or_preall = false,
                       bool trace = true);

    struct DRAMStats : public statistics::Group
    {
        DRAMStats(DRAMInterface &dram);

        void regStats() override;
        void resetStats() override;

        DRAMInterface &dram;

        /** total number of DRAM bursts serviced */
        statistics::Scalar readBursts;
        statistics::Scalar writeBursts;

        /** DRAM per bank stats */
        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;

        // Row hit count and rate
        statistics::Scalar readRowHits;
        statistics::Scalar writeRowHits;
        statistics::Formula readRowHitRate;
        statistics::Formula writeRowHitRate;
        statistics::Histogram bytesPerActivate;
        // Number of bytes transferred to/from DRAM
        statistics::Scalar bytesRead;
        statistics::Scalar bytesWritten;

        // Average bandwidth
        statistics::Formula avgRdBW;
        statistics::Formula avgWrBW;
        statistics::Formula peakBW;
        // bus utilization
        statistics::Formula busUtil;
        statistics::Formula busUtilRead;
        statistics::Formula busUtilWrite;
        statistics::Formula pageHitRate;
    };

    DRAMStats stats;

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

    /*
     * @return delay between write and read commands
     */
    Tick writeToReadDelay() const override { return tBURST + tWTR + tCL; }

    /**
     * Find which are the earliest banks ready to issue an activate
     * for the enqueued requests. Assumes maximum of 32 banks per rank
     * Also checks if the bank is already prepped.
     *
     * @param queue Queued requests to consider
     * @param min_col_at time of seamless burst command
     * @return One-hot encoded mask of bank indices
     * @return boolean indicating burst can issue seamlessly, with no gaps
     */
    std::pair<std::vector<uint32_t>, bool>
    minBankPrep(const MemPacketQueue& queue, Tick min_col_at) const;

    /*
     * @return time to send a burst of data without gaps
     */
    Tick
    burstDelay() const
    {
        return (burstInterleave ? tBURST_MAX / 2 : tBURST);
    }

  public:
    /**
     * Initialize the DRAM interface and verify parameters
     */
    void init() override;

    /**
     * Iterate through dram ranks and instantiate per rank startup routine
     */
    void startup() 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;

    /**
     * Iterate through dram ranks to exit self-refresh in order to drain
     */
    void drainRanks();

    /**
     * Return true once refresh is complete for all ranks and there are no
     * additional commands enqueued.  (only evaluated when draining)
     * This will ensure that all banks are closed, power state is IDLE, and
     * power stats have been updated
     *
     * @return true if all ranks have refreshed, with no commands enqueued
     *
     */
    bool allRanksDrained() const override;

    /**
     * Iterate through DRAM ranks and suspend them
     */
    void suspend();

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

    /*
     * Function to calulate unloaded, closed bank access latency
     */
    Tick accessLatency() const override { return (tRP + tRCD + tCL); }

    /**
     * For FR-FCFS policy, find first DRAM command that can issue
     *
     * @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;

    /**
     * Actually do the burst - figure out the latency it
     * will take to service the req based on bank state, channel state etc
     * and then update those states to account for this request. Based
     * on this, update the packet's "readyTime" and move it to the
     * response q from where it will eventually go back to the outside
     * world.
     *
     * @param mem_pkt The packet created from the outside world pkt
     * @param next_burst_at Minimum bus timing requirement from controller
     * @param queue Reference to the read or write queue with the packet
     * @return pair, tick when current burst is issued and
     *               tick when next burst can issue
     */
    std::pair<Tick, Tick>
    doBurstAccess(MemPacket* mem_pkt, Tick next_burst_at,
                  const std::vector<MemPacketQueue>& queue);

    /**
     * Check if a burst operation can be issued to the DRAM
     *
     * @param Return true if RD/WR can issue
     *                    This requires the DRAM to be in the
     *                    REF IDLE state
     */
    bool
    burstReady(MemPacket* pkt) const override
    {
        return ranks[pkt->rank]->inRefIdleState();
    }

    /**
     * This function checks if ranks are actively refreshing and
     * therefore busy. The function also checks if ranks are in
     * the self-refresh state, in which case, a self-refresh exit
     * is initiated.
     *
     * return boolean if all ranks are in refresh and therefore busy
     */
    bool isBusy();

    /**
     *  Add rank to rank delay to bus timing to all DRAM 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;

    /**
     * Complete response process for DRAM when read burst is complete
     * This will update the counters and check if a power down state
     * can be entered.
     *
     * @param rank Specifies rank associated with read burst
     */
    void respondEvent(uint8_t rank);

    /**
     * Check the refresh state to determine if refresh needs
     * to be kicked back into action after a read response
     *
     * @param rank Specifies rank associated with read burst
     */
    void checkRefreshState(uint8_t rank);

    DRAMInterface(const DRAMInterfaceParams &_p);
};

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

    // number of writes in the writeQueue for the NVM interface
    uint32_t numWritesQueued;

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

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


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

    /*
     * 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
    {
        return writeRespQueue.size() == maxPendingWrites;
    }

    bool
    readsWaitingToIssue() const
    {
        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);

    NVMInterface(const NVMInterfaceParams &_p);
};

} // namespace memory
} // namespace gem5

#endif //__MEM_INTERFACE_HH__
