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

#ifndef __DRAM_INTERFACE_HH__
#define __DRAM_INTERFACE_HH__

#include "mem/drampower.hh"
#include "mem/mem_interface.hh"
#include "params/DRAMInterface.hh"

namespace gem5
{

namespace memory
{

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

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

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

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

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

    /**
     * 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.
     * The arguments are NVM-specific and will be ignored by DRAM.
     * return boolean if all ranks are in refresh and therefore busy
     */
    bool isBusy(bool read_queue_empty, bool all_writes_nvm) override;

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

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

    /**
     * The next three functions are NVM-specific and will be ignored by DRAM.
     */
    bool readsWaitingToIssue() const override { return false;}
    void chooseRead(MemPacketQueue& queue) override { }
    bool writeRespQueueFull() const override { return false;}

    DRAMInterface(const DRAMInterfaceParams &_p);
};

} // namespace memory
} // namespace gem5

#endif //__DRAM_INTERFACE_HH__
