/*
 * Copyright (c) 2012 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.
 *
 * Authors: Thomas Grass
 *          Andreas Hansson
 */

#ifndef __MEM_COMM_MONITOR_HH__
#define __MEM_COMM_MONITOR_HH__

#include "base/statistics.hh"
#include "base/time.hh"
#include "mem/mem_object.hh"
#include "params/CommMonitor.hh"

/**
 * The communication monitor is a MemObject which can monitor statistics of
 * the communication happening between two ports in the memory system.
 *
 * Currently the following stats are implemented: Histograms of read/write
 * transactions, read/write burst lengths, read/write bandwidth,
 * outstanding read/write requests, read latency and inter transaction time
 * (read-read, write-write, read/write-read/write). Furthermore it allows
 * to capture the number of accesses to an address over time ("heat map").
 * All stats can be disabled from Python.
 */
class CommMonitor : public MemObject
{

  public:

    /** Parameters of communication monitor */
    typedef CommMonitorParams Params;
    const Params* params() const
    { return reinterpret_cast<const Params*>(_params); }

    /**
     * Constructor based on the Python params
     *
     * @param params Python parameters
     */
    CommMonitor(Params* params);

    /** Destructor */
    ~CommMonitor() { }

    virtual MasterPort& getMasterPort(const std::string& if_name,
                                      int idx = -1);

    virtual SlavePort& getSlavePort(const std::string& if_name,
                                    int idx = -1);

    virtual void init();

    /** Register statistics */
    void regStats();

  private:

    /**
     * Sender state class for the monitor so that we can annotate
     * packets with a transmit time and receive time.
     */
    class CommMonitorSenderState : public Packet::SenderState
    {

      public:

        /**
         * Construct a new sender state and remember the original one
         * so that we can implement a stack.
         *
         * @param _origSenderState Sender state to remember
         * @param _transmitTime Time of packet transmission
         */
        CommMonitorSenderState(SenderState* _origSenderState,
                               Tick _transmitTime)
            : origSenderState(_origSenderState), transmitTime(_transmitTime)
        { }

        /** Destructor */
        ~CommMonitorSenderState() { }

        /** Pointer to old sender state of packet */
        SenderState* origSenderState;

        /** Tick when request is transmitted */
        Tick transmitTime;

    };

    /**
     * This is the master port of the communication monitor. All recv
     * functions call a function in CommMonitor, where the
     * send function of the slave port is called. Besides this, these
     * functions can also perform actions for capturing statistics.
     */
    class MonitorMasterPort : public MasterPort
    {

      public:

        MonitorMasterPort(const std::string& _name, CommMonitor& _mon)
            : MasterPort(_name, &_mon), mon(_mon)
        { }

      protected:

        void recvFunctionalSnoop(PacketPtr pkt)
        {
            mon.recvFunctionalSnoop(pkt);
        }

        Tick recvAtomicSnoop(PacketPtr pkt)
        {
            return mon.recvAtomicSnoop(pkt);
        }

        bool recvTimingResp(PacketPtr pkt)
        {
            return mon.recvTimingResp(pkt);
        }

        void recvTimingSnoopReq(PacketPtr pkt)
        {
            mon.recvTimingSnoopReq(pkt);
        }

        void recvRangeChange()
        {
            mon.recvRangeChange();
        }

        bool isSnooping() const
        {
            return mon.isSnooping();
        }

        unsigned deviceBlockSize() const
        {
            return mon.deviceBlockSizeMaster();
        }

        void recvRetry()
        {
            mon.recvRetryMaster();
        }

      private:

        CommMonitor& mon;

    };

    /** Instance of master port, facing the memory side */
    MonitorMasterPort masterPort;

    /**
     * This is the slave port of the communication monitor. All recv
     * functions call a function in CommMonitor, where the
     * send function of the master port is called. Besides this, these
     * functions can also perform actions for capturing statistics.
     */
    class MonitorSlavePort : public SlavePort
    {

      public:

        MonitorSlavePort(const std::string& _name, CommMonitor& _mon)
            : SlavePort(_name, &_mon), mon(_mon)
        { }

      protected:

        void recvFunctional(PacketPtr pkt)
        {
            mon.recvFunctional(pkt);
        }

        Tick recvAtomic(PacketPtr pkt)
        {
            return mon.recvAtomic(pkt);
        }

        bool recvTimingReq(PacketPtr pkt)
        {
            return mon.recvTimingReq(pkt);
        }

        bool recvTimingSnoopResp(PacketPtr pkt)
        {
            return mon.recvTimingSnoopResp(pkt);
        }

        unsigned deviceBlockSize() const
        {
            return mon.deviceBlockSizeSlave();
        }

        AddrRangeList getAddrRanges()
        {
            return mon.getAddrRanges();
        }

        void recvRetry()
        {
            mon.recvRetrySlave();
        }

      private:

        CommMonitor& mon;

    };

    /** Instance of slave port, i.e. on the CPU side */
    MonitorSlavePort slavePort;

    void recvFunctional(PacketPtr pkt);

    void recvFunctionalSnoop(PacketPtr pkt);

    Tick recvAtomic(PacketPtr pkt);

    Tick recvAtomicSnoop(PacketPtr pkt);

    bool recvTimingReq(PacketPtr pkt);

    bool recvTimingResp(PacketPtr pkt);

    void recvTimingSnoopReq(PacketPtr pkt);

    bool recvTimingSnoopResp(PacketPtr pkt);

    unsigned deviceBlockSizeMaster();

    unsigned deviceBlockSizeSlave();

    AddrRangeList getAddrRanges();

    bool isSnooping() const;

    void recvRetryMaster();

    void recvRetrySlave();

    void recvRangeChange();

    void periodicTraceDump();

    /** Stats declarations, all in a struct for convenience. */
    struct MonitorStats
    {

        /** Disable flag for burst length historgrams **/
        bool disableBurstLengthHists;

        /** Histogram of read burst lengths */
        Stats::Histogram readBurstLengthHist;

        /** Histogram of write burst lengths */
        Stats::Histogram writeBurstLengthHist;

        /** Disable flag for the bandwidth histograms */
        bool disableBandwidthHists;

        /**
         * Histogram for read bandwidth per sample window. The
         * internal counter is an unsigned int rather than a stat.
         */
        unsigned int readBytes;
        Stats::Histogram readBandwidthHist;
        Stats::Formula averageReadBW;
        Stats::Scalar totalReadBytes;

        /**
         * Histogram for write bandwidth per sample window. The
         * internal counter is an unsigned int rather than a stat.
         */
        unsigned int writtenBytes;
        Stats::Histogram writeBandwidthHist;
        Stats::Formula averageWriteBW;
        Stats::Scalar totalWrittenBytes;

        /** Disable flag for latency histograms. */
        bool disableLatencyHists;

        /** Histogram of read request-to-response latencies */
        Stats::Histogram readLatencyHist;

        /** Histogram of write request-to-response latencies */
        Stats::Histogram writeLatencyHist;

        /** Disable flag for ITT distributions. */
        bool disableITTDists;

        /**
         * Inter transaction time (ITT) distributions. There are
         * histograms of the time between two read, write or arbitrary
         * accesses. The time of a request is the tick at which the
         * request is forwarded by the monitor.
         */
        Stats::Distribution ittReadRead;
        Stats::Distribution ittWriteWrite;
        Stats::Distribution ittReqReq;
        Tick timeOfLastRead;
        Tick timeOfLastWrite;
        Tick timeOfLastReq;

        /** Disable flag for outstanding histograms. */
        bool disableOutstandingHists;

        /**
         * Histogram of outstanding read requests. Counter for
         * outstanding read requests is an unsigned integer because
         * it should not be reset when stats are reset.
         */
        Stats::Histogram outstandingReadsHist;
        unsigned int outstandingReadReqs;

        /**
         * Histogram of outstanding write requests. Counter for
         * outstanding write requests is an unsigned integer because
         * it should not be reset when stats are reset.
         */
        Stats::Histogram outstandingWritesHist;
        unsigned int outstandingWriteReqs;

        /** Disable flag for transaction histograms. */
        bool disableTransactionHists;

        /** Histogram of number of read transactions per time bin */
        Stats::Histogram readTransHist;
        unsigned int readTrans;

        /** Histogram of number of timing write transactions per time bin */
        Stats::Histogram writeTransHist;
        unsigned int writeTrans;

        /** Disable flag for address distributions. */
        bool disableAddrDists;

        /**
         * Histogram of number of read accesses to addresses over
         * time.
         */
        Stats::SparseHistogram readAddrDist;

        /**
         * Histogram of number of write accesses to addresses over
         * time.
         */
        Stats::SparseHistogram writeAddrDist;

        /**
         * Create the monitor stats and initialise all the members
         * that are not statistics themselves, but used to control the
         * stats or track values during a sample period.
         */
        MonitorStats(const CommMonitorParams* params) :
            disableBurstLengthHists(params->disable_burst_length_hists),
            disableBandwidthHists(params->disable_bandwidth_hists),
            readBytes(0), writtenBytes(0),
            disableLatencyHists(params->disable_latency_hists),
            disableITTDists(params->disable_itt_dists),
            timeOfLastRead(0), timeOfLastWrite(0), timeOfLastReq(0),
            disableOutstandingHists(params->disable_outstanding_hists),
            outstandingReadReqs(0), outstandingWriteReqs(0),
            disableTransactionHists(params->disable_transaction_hists),
            readTrans(0), writeTrans(0),
            disableAddrDists(params->disable_addr_dists)
        { }

    };

    /** This function is called periodically at the end of each time bin */
    void samplePeriodic();

    /** Schedule the first periodic event */
    void startup();

    /** Periodic event called at the end of each simulation time bin */
    EventWrapper<CommMonitor, &CommMonitor::samplePeriodic> samplePeriodicEvent;

    /** Length of simulation time bin*/
    Tick samplePeriodTicks;
    Time samplePeriod;

    /** Address mask for sources of read accesses to be captured */
    Addr readAddrMask;

    /** Address mask for sources of write accesses to be captured */
    Addr writeAddrMask;

    /** Instantiate stats */
    MonitorStats stats;
};

#endif //__MEM_COMM_MONITOR_HH__
