/*
- * Copyright (c) 2012-2013, 2015 ARM Limited
- * All rights reserved
+ * Copyright (c) 2012-2013, 2015, 2018-2019 ARM Limited
+ * Copyright (c) 2016 Google Inc.
+ * Copyright (c) 2017, Centre National de la Recherche Scientifique
+ * 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
* 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 "mem/mem_object.hh"
-#include "mem/stack_dist_calc.hh"
+#include "mem/port.hh"
#include "params/CommMonitor.hh"
-#include "proto/protoio.hh"
#include "sim/probe/mem.hh"
-#include "sim/system.hh"
+#include "sim/sim_object.hh"
/**
- * The communication monitor is a MemObject which can monitor statistics of
+ * The communication monitor is a SimObject 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
* to capture the number of accesses to an address over time ("heat map").
* All stats can be disabled from Python.
*/
-class CommMonitor : public MemObject
+class CommMonitor : public SimObject
{
public: // Construction & SimObject interfaces
/** Parameters of communication monitor */
typedef CommMonitorParams Params;
- const Params* params() const
- { return reinterpret_cast<const Params*>(_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();
+ CommMonitor(const Params ¶ms);
- void init() M5_ATTR_OVERRIDE;
- void regStats() M5_ATTR_OVERRIDE;
- void startup() M5_ATTR_OVERRIDE;
- void regProbePoints() M5_ATTR_OVERRIDE;
+ void init() override;
+ void startup() override;
+ void regProbePoints() override;
- public: // MemObject interfaces
- BaseMasterPort& getMasterPort(const std::string& if_name,
- PortID idx = InvalidPortID) M5_ATTR_OVERRIDE;
-
- BaseSlavePort& getSlavePort(const std::string& if_name,
- PortID idx = InvalidPortID) M5_ATTR_OVERRIDE;
+ public: // SimObject interfaces
+ Port &getPort(const std::string &if_name,
+ PortID idx=InvalidPortID) override;
private:
};
/**
- * This is the master port of the communication monitor. All recv
+ * This is the request 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
+ * send function of the CPU-side port is called. Besides this, these
* functions can also perform actions for capturing statistics.
*/
- class MonitorMasterPort : public MasterPort
+ class MonitorRequestPort : public RequestPort
{
public:
- MonitorMasterPort(const std::string& _name, CommMonitor& _mon)
- : MasterPort(_name, &_mon), mon(_mon)
+ MonitorRequestPort(const std::string& _name, CommMonitor& _mon)
+ : RequestPort(_name, &_mon), mon(_mon)
{ }
protected:
mon.recvReqRetry();
}
+ void recvRetrySnoopResp()
+ {
+ mon.recvRetrySnoopResp();
+ }
+
private:
CommMonitor& mon;
};
- /** Instance of master port, facing the memory side */
- MonitorMasterPort masterPort;
+ /** Instance of request port, facing the memory side */
+ MonitorRequestPort memSidePort;
/**
- * This is the slave port of the communication monitor. All recv
+ * This is the CPU-side 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
+ * send function of the request port is called. Besides this, these
* functions can also perform actions for capturing statistics.
*/
- class MonitorSlavePort : public SlavePort
+ class MonitorResponsePort : public ResponsePort
{
public:
- MonitorSlavePort(const std::string& _name, CommMonitor& _mon)
- : SlavePort(_name, &_mon), mon(_mon)
+ MonitorResponsePort(const std::string& _name, CommMonitor& _mon)
+ : ResponsePort(_name, &_mon), mon(_mon)
{ }
protected:
mon.recvRespRetry();
}
+ bool tryTiming(PacketPtr pkt)
+ {
+ return mon.tryTiming(pkt);
+ }
+
private:
CommMonitor& mon;
};
- /** Instance of slave port, i.e. on the CPU side */
- MonitorSlavePort slavePort;
+ /** Instance of response port, i.e. on the CPU side */
+ MonitorResponsePort cpuSidePort;
void recvFunctional(PacketPtr pkt);
bool recvTimingSnoopResp(PacketPtr pkt);
+ void recvRetrySnoopResp();
+
AddrRangeList getAddrRanges() const;
bool isSnooping() const;
void recvRangeChange();
+ bool tryTiming(PacketPtr pkt);
+
/** Stats declarations, all in a struct for convenience. */
- struct MonitorStats
+ struct MonitorStats : public Stats::Group
{
-
- /** Disable flag for burst length historgrams **/
+ /** Disable flag for burst length histograms **/
bool disableBurstLengthHists;
/** Histogram of read burst lengths */
*/
unsigned int readBytes;
Stats::Histogram readBandwidthHist;
- Stats::Formula averageReadBW;
Stats::Scalar totalReadBytes;
+ Stats::Formula averageReadBandwidth;
/**
* Histogram for write bandwidth per sample window. The
*/
unsigned int writtenBytes;
Stats::Histogram writeBandwidthHist;
- Stats::Formula averageWriteBW;
Stats::Scalar totalWrittenBytes;
+ Stats::Formula averageWriteBandwidth;
/** Disable flag for latency histograms. */
bool disableLatencyHists;
/** Disable flag for address distributions. */
bool disableAddrDists;
+ /** Address mask for sources of read accesses to be captured */
+ const Addr readAddrMask;
+
+ /** Address mask for sources of write accesses to be captured */
+ const Addr writeAddrMask;
+
/**
* Histogram of number of read accesses to addresses over
* time.
* 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)
- { }
+ MonitorStats(Stats::Group *parent, const CommMonitorParams ¶ms);
+ void updateReqStats(const ProbePoints::PacketInfo& pkt, bool is_atomic,
+ bool expects_response);
+ void updateRespStats(const ProbePoints::PacketInfo& pkt, Tick latency,
+ bool is_atomic);
};
/** This function is called periodically at the end of each time bin */
void samplePeriodic();
- /**
- * Callback to flush and close all open output streams on exit. If
- * we were calling the destructor it could be done there.
- */
- void closeStreams();
-
/** Periodic event called at the end of each simulation time bin */
- EventWrapper<CommMonitor, &CommMonitor::samplePeriodic> samplePeriodicEvent;
+ EventFunctionWrapper samplePeriodicEvent;
/**
*@{
/** Sample period in seconds */
const double samplePeriod;
- /** Address mask for sources of read accesses to be captured */
- const Addr readAddrMask;
-
- /** Address mask for sources of write accesses to be captured */
- const Addr writeAddrMask;
-
- /** Optional stack distance calculator */
- StackDistCalc *const stackDistCalc;
-
- /** The system in which the monitor lives */
- System *const system;
-
/** @} */
- /** Output stream for a potential trace. */
- ProtoOutputStream *traceStream;
-
/** Instantiate stats */
MonitorStats stats;