/*
- * Copyright (c) 2012-2013 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
*/
-#include "base/callback.hh"
-#include "base/output.hh"
+#include "mem/comm_monitor.hh"
+
#include "base/trace.hh"
#include "debug/CommMonitor.hh"
-#include "mem/comm_monitor.hh"
-#include "proto/packet.pb.h"
#include "sim/stats.hh"
-CommMonitor::CommMonitor(Params* params)
- : MemObject(params),
- masterPort(name() + "-master", *this),
- slavePort(name() + "-slave", *this),
- samplePeriodicEvent(this),
- samplePeriodTicks(params->sample_period),
- readAddrMask(params->read_addr_mask),
- writeAddrMask(params->write_addr_mask),
- stats(params),
- traceStream(NULL),
- system(params->system)
+CommMonitor::CommMonitor(const Params ¶ms)
+ : SimObject(params),
+ memSidePort(name() + "-mem_side_port", *this),
+ cpuSidePort(name() + "-cpu_side_port", *this),
+ samplePeriodicEvent([this]{ samplePeriodic(); }, name()),
+ samplePeriodTicks(params.sample_period),
+ samplePeriod(params.sample_period / SimClock::Float::s),
+ stats(this, params)
{
- // If we are using a trace file, then open the file
- if (params->trace_enable) {
- std::string filename;
- if (params->trace_file != "") {
- // If the trace file is not specified as an absolute path,
- // append the current simulation output directory
- filename = simout.resolve(params->trace_file);
-
- std::string suffix = ".gz";
- // If trace_compress has been set, check the suffix. Append
- // accordingly.
- if (params->trace_compress &&
- filename.compare(filename.size() - suffix.size(), suffix.size(),
- suffix) != 0)
- filename = filename + suffix;
- } else {
- // Generate a filename from the name of the SimObject. Append .trc
- // and .gz if we want compression enabled.
- filename = simout.resolve(name() + ".trc" +
- (params->trace_compress ? ".gz" : ""));
- }
-
- traceStream = new ProtoOutputStream(filename);
-
- // Create a protobuf message for the header and write it to
- // the stream
- ProtoMessage::PacketHeader header_msg;
- header_msg.set_obj_id(name());
- header_msg.set_tick_freq(SimClock::Frequency);
- traceStream->write(header_msg);
-
- // Register a callback to compensate for the destructor not
- // being called. The callback forces the stream to flush and
- // closes the output file.
- Callback* cb = new MakeCallback<CommMonitor,
- &CommMonitor::closeStreams>(this);
- registerExitCallback(cb);
- }
-
- // keep track of the sample period both in ticks and absolute time
- samplePeriod.setTick(params->sample_period);
-
DPRINTF(CommMonitor,
"Created monitor %s with sample period %d ticks (%f ms)\n",
- name(), samplePeriodTicks, samplePeriod.msec());
+ name(), samplePeriodTicks, samplePeriod * 1E3);
}
-CommMonitor::~CommMonitor()
+void
+CommMonitor::init()
{
- // if not already done, close the stream
- closeStreams();
+ // make sure both sides of the monitor are connected
+ if (!cpuSidePort.isConnected() || !memSidePort.isConnected())
+ fatal("Communication monitor is not connected on both sides.\n");
}
void
-CommMonitor::closeStreams()
+CommMonitor::regProbePoints()
{
- if (traceStream != NULL)
- delete traceStream;
+ ppPktReq.reset(new ProbePoints::Packet(getProbeManager(), "PktRequest"));
+ ppPktResp.reset(new ProbePoints::Packet(getProbeManager(), "PktResponse"));
}
-CommMonitor*
-CommMonitorParams::create()
+Port &
+CommMonitor::getPort(const std::string &if_name, PortID idx)
{
- return new CommMonitor(this);
+ if (if_name == "mem_side_port") {
+ return memSidePort;
+ } else if (if_name == "cpu_side_port") {
+ return cpuSidePort;
+ } else {
+ return SimObject::getPort(if_name, idx);
+ }
}
void
-CommMonitor::init()
+CommMonitor::recvFunctional(PacketPtr pkt)
{
- // make sure both sides of the monitor are connected
- if (!slavePort.isConnected() || !masterPort.isConnected())
- fatal("Communication monitor is not connected on both sides.\n");
-
- if (traceStream != NULL) {
- // Check the memory mode. We only record something when in
- // timing mode. Warn accordingly.
- if (!system->isTimingMode())
- warn("%s: Not in timing mode. No trace will be recorded.", name());
- }
+ memSidePort.sendFunctional(pkt);
}
-BaseMasterPort&
-CommMonitor::getMasterPort(const std::string& if_name, PortID idx)
+void
+CommMonitor::recvFunctionalSnoop(PacketPtr pkt)
{
- if (if_name == "master") {
- return masterPort;
- } else {
- return MemObject::getMasterPort(if_name, idx);
- }
+ cpuSidePort.sendFunctionalSnoop(pkt);
}
-BaseSlavePort&
-CommMonitor::getSlavePort(const std::string& if_name, PortID idx)
+CommMonitor::MonitorStats::MonitorStats(Stats::Group *parent,
+ const CommMonitorParams ¶ms)
+ : Stats::Group(parent),
+
+ disableBurstLengthHists(params.disable_burst_length_hists),
+ ADD_STAT(readBurstLengthHist,
+ "Histogram of burst lengths of transmitted packets"),
+ ADD_STAT(writeBurstLengthHist,
+ "Histogram of burst lengths of transmitted packets"),
+
+ disableBandwidthHists(params.disable_bandwidth_hists),
+ readBytes(0),
+ ADD_STAT(readBandwidthHist,
+ "Histogram of read bandwidth per sample period (bytes/s)"),
+ ADD_STAT(totalReadBytes, "Number of bytes read"),
+ ADD_STAT(averageReadBandwidth, "Average read bandwidth (bytes/s)",
+ totalReadBytes / simSeconds),
+
+ writtenBytes(0),
+ ADD_STAT(writeBandwidthHist, "Histogram of write bandwidth (bytes/s)"),
+ ADD_STAT(totalWrittenBytes, "Number of bytes written"),
+ ADD_STAT(averageWriteBandwidth, "Average write bandwidth (bytes/s)",
+ totalWrittenBytes / simSeconds),
+
+ disableLatencyHists(params.disable_latency_hists),
+ ADD_STAT(readLatencyHist, "Read request-response latency"),
+ ADD_STAT(writeLatencyHist, "Write request-response latency"),
+
+ disableITTDists(params.disable_itt_dists),
+ ADD_STAT(ittReadRead, "Read-to-read inter transaction time"),
+ ADD_STAT(ittWriteWrite , "Write-to-write inter transaction time"),
+ ADD_STAT(ittReqReq, "Request-to-request inter transaction time"),
+ timeOfLastRead(0), timeOfLastWrite(0), timeOfLastReq(0),
+
+ disableOutstandingHists(params.disable_outstanding_hists),
+ ADD_STAT(outstandingReadsHist, "Outstanding read transactions"),
+ outstandingReadReqs(0),
+ ADD_STAT(outstandingWritesHist, "Outstanding write transactions"),
+ outstandingWriteReqs(0),
+
+ disableTransactionHists(params.disable_transaction_hists),
+ ADD_STAT(readTransHist,
+ "Histogram of read transactions per sample period"),
+ readTrans(0),
+ ADD_STAT(writeTransHist,
+ "Histogram of write transactions per sample period"),
+ writeTrans(0),
+
+ disableAddrDists(params.disable_addr_dists),
+ readAddrMask(params.read_addr_mask),
+ writeAddrMask(params.write_addr_mask),
+ ADD_STAT(readAddrDist, "Read address distribution"),
+ ADD_STAT(writeAddrDist, "Write address distribution")
{
- if (if_name == "slave") {
- return slavePort;
- } else {
- return MemObject::getSlavePort(if_name, idx);
- }
+ using namespace Stats;
+
+ readBurstLengthHist
+ .init(params.burst_length_bins)
+ .flags(disableBurstLengthHists ? nozero : pdf);
+
+ writeBurstLengthHist
+ .init(params.burst_length_bins)
+ .flags(disableBurstLengthHists ? nozero : pdf);
+
+ // Stats based on received responses
+ readBandwidthHist
+ .init(params.bandwidth_bins)
+ .flags(disableBandwidthHists ? nozero : pdf);
+
+ averageReadBandwidth
+ .flags(disableBandwidthHists ? nozero : pdf);
+
+ totalReadBytes
+ .flags(disableBandwidthHists ? nozero : pdf);
+
+ // Stats based on successfully sent requests
+ writeBandwidthHist
+ .init(params.bandwidth_bins)
+ .flags(disableBandwidthHists ? (pdf | nozero) : pdf);
+
+ averageWriteBandwidth
+ .flags(disableBandwidthHists ? nozero : pdf);
+
+ totalWrittenBytes
+ .flags(disableBandwidthHists ? nozero : pdf);
+
+
+ readLatencyHist
+ .init(params.latency_bins)
+ .flags(disableLatencyHists ? nozero : pdf);
+
+ writeLatencyHist
+ .init(params.latency_bins)
+ .flags(disableLatencyHists ? nozero : pdf);
+
+ ittReadRead
+ .init(1, params.itt_max_bin, params.itt_max_bin /
+ params.itt_bins)
+ .flags(disableITTDists ? nozero : pdf);
+
+ ittWriteWrite
+ .init(1, params.itt_max_bin, params.itt_max_bin /
+ params.itt_bins)
+ .flags(disableITTDists ? nozero : pdf);
+
+ ittReqReq
+ .init(1, params.itt_max_bin, params.itt_max_bin /
+ params.itt_bins)
+ .flags(disableITTDists ? nozero : pdf);
+
+ outstandingReadsHist
+ .init(params.outstanding_bins)
+ .flags(disableOutstandingHists ? nozero : pdf);
+
+ outstandingWritesHist
+ .init(params.outstanding_bins)
+ .flags(disableOutstandingHists ? nozero : pdf);
+
+ readTransHist
+ .init(params.transaction_bins)
+ .flags(disableTransactionHists ? nozero : pdf);
+
+ writeTransHist
+ .init(params.transaction_bins)
+ .flags(disableTransactionHists ? nozero : pdf);
+
+ readAddrDist
+ .init(0)
+ .flags(disableAddrDists ? nozero : pdf);
+
+ writeAddrDist
+ .init(0)
+ .flags(disableAddrDists ? nozero : pdf);
}
void
-CommMonitor::recvFunctional(PacketPtr pkt)
+CommMonitor::MonitorStats::updateReqStats(
+ const ProbePoints::PacketInfo& pkt_info, bool is_atomic,
+ bool expects_response)
{
- masterPort.sendFunctional(pkt);
+ if (pkt_info.cmd.isRead()) {
+ // Increment number of observed read transactions
+ if (!disableTransactionHists)
+ ++readTrans;
+
+ // Get sample of burst length
+ if (!disableBurstLengthHists)
+ readBurstLengthHist.sample(pkt_info.size);
+
+ // Sample the masked address
+ if (!disableAddrDists)
+ readAddrDist.sample(pkt_info.addr & readAddrMask);
+
+ if (!disableITTDists) {
+ // Sample value of read-read inter transaction time
+ if (timeOfLastRead != 0)
+ ittReadRead.sample(curTick() - timeOfLastRead);
+ timeOfLastRead = curTick();
+
+ // Sample value of req-req inter transaction time
+ if (timeOfLastReq != 0)
+ ittReqReq.sample(curTick() - timeOfLastReq);
+ timeOfLastReq = curTick();
+ }
+ if (!is_atomic && !disableOutstandingHists && expects_response)
+ ++outstandingReadReqs;
+
+ } else if (pkt_info.cmd.isWrite()) {
+ // Same as for reads
+ if (!disableTransactionHists)
+ ++writeTrans;
+
+ if (!disableBurstLengthHists)
+ writeBurstLengthHist.sample(pkt_info.size);
+
+ // Update the bandwidth stats on the request
+ if (!disableBandwidthHists) {
+ writtenBytes += pkt_info.size;
+ totalWrittenBytes += pkt_info.size;
+ }
+
+ // Sample the masked write address
+ if (!disableAddrDists)
+ writeAddrDist.sample(pkt_info.addr & writeAddrMask);
+
+ if (!disableITTDists) {
+ // Sample value of write-to-write inter transaction time
+ if (timeOfLastWrite != 0)
+ ittWriteWrite.sample(curTick() - timeOfLastWrite);
+ timeOfLastWrite = curTick();
+
+ // Sample value of req-to-req inter transaction time
+ if (timeOfLastReq != 0)
+ ittReqReq.sample(curTick() - timeOfLastReq);
+ timeOfLastReq = curTick();
+ }
+
+ if (!is_atomic && !disableOutstandingHists && expects_response)
+ ++outstandingWriteReqs;
+ }
}
void
-CommMonitor::recvFunctionalSnoop(PacketPtr pkt)
+CommMonitor::MonitorStats::updateRespStats(
+ const ProbePoints::PacketInfo& pkt_info, Tick latency, bool is_atomic)
{
- slavePort.sendFunctionalSnoop(pkt);
+ if (pkt_info.cmd.isRead()) {
+ // Decrement number of outstanding read requests
+ if (!is_atomic && !disableOutstandingHists) {
+ assert(outstandingReadReqs != 0);
+ --outstandingReadReqs;
+ }
+
+ if (!disableLatencyHists)
+ readLatencyHist.sample(latency);
+
+ // Update the bandwidth stats based on responses for reads
+ if (!disableBandwidthHists) {
+ readBytes += pkt_info.size;
+ totalReadBytes += pkt_info.size;
+ }
+
+ } else if (pkt_info.cmd.isWrite()) {
+ // Decrement number of outstanding write requests
+ if (!is_atomic && !disableOutstandingHists) {
+ assert(outstandingWriteReqs != 0);
+ --outstandingWriteReqs;
+ }
+
+ if (!disableLatencyHists)
+ writeLatencyHist.sample(latency);
+ }
}
Tick
CommMonitor::recvAtomic(PacketPtr pkt)
{
- return masterPort.sendAtomic(pkt);
+ const bool expects_response(pkt->needsResponse() &&
+ !pkt->cacheResponding());
+ ProbePoints::PacketInfo req_pkt_info(pkt);
+ ppPktReq->notify(req_pkt_info);
+
+ const Tick delay(memSidePort.sendAtomic(pkt));
+
+ stats.updateReqStats(req_pkt_info, true, expects_response);
+ if (expects_response)
+ stats.updateRespStats(req_pkt_info, delay, true);
+
+ // Some packets, such as WritebackDirty, don't need response.
+ assert(pkt->isResponse() || !expects_response);
+ ProbePoints::PacketInfo resp_pkt_info(pkt);
+ ppPktResp->notify(resp_pkt_info);
+ return delay;
}
Tick
CommMonitor::recvAtomicSnoop(PacketPtr pkt)
{
- return slavePort.sendAtomicSnoop(pkt);
+ return cpuSidePort.sendAtomicSnoop(pkt);
}
bool
// Store relevant fields of packet, because packet may be modified
// or even deleted when sendTiming() is called.
- bool is_read = pkt->isRead();
- bool is_write = pkt->isWrite();
- int cmd = pkt->cmdToIndex();
- Request::FlagsType req_flags = pkt->req->getFlags();
- unsigned size = pkt->getSize();
- Addr addr = pkt->getAddr();
- bool expects_response = pkt->needsResponse() && !pkt->memInhibitAsserted();
+ const ProbePoints::PacketInfo pkt_info(pkt);
+
+ const bool expects_response(pkt->needsResponse() &&
+ !pkt->cacheResponding());
// If a cache miss is served by a cache, a monitor near the memory
// would see a request which needs a response, but this response
- // would be inhibited and not come back from the memory. Therefore
- // we additionally have to check the inhibit flag.
+ // would not come back from the memory. Therefore we additionally
+ // have to check the cacheResponding flag
if (expects_response && !stats.disableLatencyHists) {
pkt->pushSenderState(new CommMonitorSenderState(curTick()));
}
- // Attempt to send the packet (always succeeds for inhibited
- // packets)
- bool successful = masterPort.sendTimingReq(pkt);
+ // Attempt to send the packet
+ bool successful = memSidePort.sendTimingReq(pkt);
// If not successful, restore the sender state
if (!successful && expects_response && !stats.disableLatencyHists) {
delete pkt->popSenderState();
}
- if (successful && traceStream != NULL) {
- // Create a protobuf message representing the
- // packet. Currently we do not preserve the flags in the
- // trace.
- ProtoMessage::Packet pkt_msg;
- pkt_msg.set_tick(curTick());
- pkt_msg.set_cmd(cmd);
- pkt_msg.set_flags(req_flags);
- pkt_msg.set_addr(addr);
- pkt_msg.set_size(size);
-
- traceStream->write(pkt_msg);
+ if (successful) {
+ ppPktReq->notify(pkt_info);
}
- if (successful && is_read) {
- DPRINTF(CommMonitor, "Forwarded read request\n");
-
- // Increment number of observed read transactions
- if (!stats.disableTransactionHists) {
- ++stats.readTrans;
- }
-
- // Get sample of burst length
- if (!stats.disableBurstLengthHists) {
- stats.readBurstLengthHist.sample(size);
- }
-
- // Sample the masked address
- if (!stats.disableAddrDists) {
- stats.readAddrDist.sample(addr & readAddrMask);
- }
-
- // If it needs a response increment number of outstanding read
- // requests
- if (!stats.disableOutstandingHists && expects_response) {
- ++stats.outstandingReadReqs;
- }
-
- if (!stats.disableITTDists) {
- // Sample value of read-read inter transaction time
- if (stats.timeOfLastRead != 0) {
- stats.ittReadRead.sample(curTick() - stats.timeOfLastRead);
- }
- stats.timeOfLastRead = curTick();
-
- // Sample value of req-req inter transaction time
- if (stats.timeOfLastReq != 0) {
- stats.ittReqReq.sample(curTick() - stats.timeOfLastReq);
- }
- stats.timeOfLastReq = curTick();
- }
- } else if (successful && is_write) {
- DPRINTF(CommMonitor, "Forwarded write request\n");
-
- // Same as for reads
- if (!stats.disableTransactionHists) {
- ++stats.writeTrans;
- }
-
- if (!stats.disableBurstLengthHists) {
- stats.writeBurstLengthHist.sample(size);
- }
-
- // Update the bandwidth stats on the request
- if (!stats.disableBandwidthHists) {
- stats.writtenBytes += size;
- stats.totalWrittenBytes += size;
- }
-
- // Sample the masked write address
- if (!stats.disableAddrDists) {
- stats.writeAddrDist.sample(addr & writeAddrMask);
- }
-
- if (!stats.disableOutstandingHists && expects_response) {
- ++stats.outstandingWriteReqs;
- }
-
- if (!stats.disableITTDists) {
- // Sample value of write-to-write inter transaction time
- if (stats.timeOfLastWrite != 0) {
- stats.ittWriteWrite.sample(curTick() - stats.timeOfLastWrite);
- }
- stats.timeOfLastWrite = curTick();
-
- // Sample value of req-to-req inter transaction time
- if (stats.timeOfLastReq != 0) {
- stats.ittReqReq.sample(curTick() - stats.timeOfLastReq);
- }
- stats.timeOfLastReq = curTick();
- }
- } else if (successful) {
- DPRINTF(CommMonitor, "Forwarded non read/write request\n");
+ if (successful) {
+ DPRINTF(CommMonitor, "Forwarded %s request\n", pkt->isRead() ? "read" :
+ pkt->isWrite() ? "write" : "non read/write");
+ stats.updateReqStats(pkt_info, false, expects_response);
}
-
return successful;
}
// Store relevant fields of packet, because packet may be modified
// or even deleted when sendTiming() is called.
- bool is_read = pkt->isRead();
- bool is_write = pkt->isWrite();
- unsigned size = pkt->getSize();
+ const ProbePoints::PacketInfo pkt_info(pkt);
+
Tick latency = 0;
CommMonitorSenderState* received_state =
dynamic_cast<CommMonitorSenderState*>(pkt->senderState);
}
// Attempt to send the packet
- bool successful = slavePort.sendTimingResp(pkt);
+ bool successful = cpuSidePort.sendTimingResp(pkt);
if (!stats.disableLatencyHists) {
// If packet successfully send, sample value of latency,
}
}
- if (successful && is_read) {
- // Decrement number of outstanding read requests
- DPRINTF(CommMonitor, "Received read response\n");
- if (!stats.disableOutstandingHists) {
- assert(stats.outstandingReadReqs != 0);
- --stats.outstandingReadReqs;
- }
-
- if (!stats.disableLatencyHists) {
- stats.readLatencyHist.sample(latency);
- }
-
- // Update the bandwidth stats based on responses for reads
- if (!stats.disableBandwidthHists) {
- stats.readBytes += size;
- stats.totalReadBytes += size;
- }
-
- } else if (successful && is_write) {
- // Decrement number of outstanding write requests
- DPRINTF(CommMonitor, "Received write response\n");
- if (!stats.disableOutstandingHists) {
- assert(stats.outstandingWriteReqs != 0);
- --stats.outstandingWriteReqs;
- }
-
- if (!stats.disableLatencyHists) {
- stats.writeLatencyHist.sample(latency);
- }
- } else if (successful) {
- DPRINTF(CommMonitor, "Received non read/write response\n");
+ if (successful) {
+ ppPktResp->notify(pkt_info);
+ DPRINTF(CommMonitor, "Received %s response\n", pkt->isRead() ? "read" :
+ pkt->isWrite() ? "write" : "non read/write");
+ stats.updateRespStats(pkt_info, latency, false);
}
return successful;
}
void
CommMonitor::recvTimingSnoopReq(PacketPtr pkt)
{
- slavePort.sendTimingSnoopReq(pkt);
+ cpuSidePort.sendTimingSnoopReq(pkt);
}
bool
CommMonitor::recvTimingSnoopResp(PacketPtr pkt)
{
- return masterPort.sendTimingSnoopResp(pkt);
+ return memSidePort.sendTimingSnoopResp(pkt);
+}
+
+void
+CommMonitor::recvRetrySnoopResp()
+{
+ cpuSidePort.sendRetrySnoopResp();
}
bool
CommMonitor::isSnooping() const
{
- // check if the connected master port is snooping
- return slavePort.isSnooping();
+ // check if the connected request port is snooping
+ return cpuSidePort.isSnooping();
}
AddrRangeList
CommMonitor::getAddrRanges() const
{
- // get the address ranges of the connected slave port
- return masterPort.getAddrRanges();
+ // get the address ranges of the connected CPU-side port
+ return memSidePort.getAddrRanges();
}
void
-CommMonitor::recvRetryMaster()
+CommMonitor::recvReqRetry()
{
- slavePort.sendRetry();
+ cpuSidePort.sendRetryReq();
}
void
-CommMonitor::recvRetrySlave()
+CommMonitor::recvRespRetry()
{
- masterPort.sendRetry();
+ memSidePort.sendRetryResp();
}
-void
-CommMonitor::recvRangeChange()
+bool
+CommMonitor::tryTiming(PacketPtr pkt)
{
- slavePort.sendRangeChange();
+ return memSidePort.tryTiming(pkt);
}
void
-CommMonitor::regStats()
+CommMonitor::recvRangeChange()
{
- // Initialise all the monitor stats
- using namespace Stats;
-
- stats.readBurstLengthHist
- .init(params()->burst_length_bins)
- .name(name() + ".readBurstLengthHist")
- .desc("Histogram of burst lengths of transmitted packets")
- .flags(stats.disableBurstLengthHists ? nozero : pdf);
-
- stats.writeBurstLengthHist
- .init(params()->burst_length_bins)
- .name(name() + ".writeBurstLengthHist")
- .desc("Histogram of burst lengths of transmitted packets")
- .flags(stats.disableBurstLengthHists ? nozero : pdf);
-
- // Stats based on received responses
- stats.readBandwidthHist
- .init(params()->bandwidth_bins)
- .name(name() + ".readBandwidthHist")
- .desc("Histogram of read bandwidth per sample period (bytes/s)")
- .flags(stats.disableBandwidthHists ? nozero : pdf);
-
- stats.averageReadBW
- .name(name() + ".averageReadBandwidth")
- .desc("Average read bandwidth (bytes/s)")
- .flags(stats.disableBandwidthHists ? nozero : pdf);
-
- stats.totalReadBytes
- .name(name() + ".totalReadBytes")
- .desc("Number of bytes read")
- .flags(stats.disableBandwidthHists ? nozero : pdf);
-
- stats.averageReadBW = stats.totalReadBytes / simSeconds;
-
- // Stats based on successfully sent requests
- stats.writeBandwidthHist
- .init(params()->bandwidth_bins)
- .name(name() + ".writeBandwidthHist")
- .desc("Histogram of write bandwidth (bytes/s)")
- .flags(stats.disableBandwidthHists ? (pdf | nozero) : pdf);
-
- stats.averageWriteBW
- .name(name() + ".averageWriteBandwidth")
- .desc("Average write bandwidth (bytes/s)")
- .flags(stats.disableBandwidthHists ? nozero : pdf);
-
- stats.totalWrittenBytes
- .name(name() + ".totalWrittenBytes")
- .desc("Number of bytes written")
- .flags(stats.disableBandwidthHists ? nozero : pdf);
-
- stats.averageWriteBW = stats.totalWrittenBytes / simSeconds;
-
- stats.readLatencyHist
- .init(params()->latency_bins)
- .name(name() + ".readLatencyHist")
- .desc("Read request-response latency")
- .flags(stats.disableLatencyHists ? nozero : pdf);
-
- stats.writeLatencyHist
- .init(params()->latency_bins)
- .name(name() + ".writeLatencyHist")
- .desc("Write request-response latency")
- .flags(stats.disableLatencyHists ? nozero : pdf);
-
- stats.ittReadRead
- .init(1, params()->itt_max_bin, params()->itt_max_bin /
- params()->itt_bins)
- .name(name() + ".ittReadRead")
- .desc("Read-to-read inter transaction time")
- .flags(stats.disableITTDists ? nozero : pdf);
-
- stats.ittWriteWrite
- .init(1, params()->itt_max_bin, params()->itt_max_bin /
- params()->itt_bins)
- .name(name() + ".ittWriteWrite")
- .desc("Write-to-write inter transaction time")
- .flags(stats.disableITTDists ? nozero : pdf);
-
- stats.ittReqReq
- .init(1, params()->itt_max_bin, params()->itt_max_bin /
- params()->itt_bins)
- .name(name() + ".ittReqReq")
- .desc("Request-to-request inter transaction time")
- .flags(stats.disableITTDists ? nozero : pdf);
-
- stats.outstandingReadsHist
- .init(params()->outstanding_bins)
- .name(name() + ".outstandingReadsHist")
- .desc("Outstanding read transactions")
- .flags(stats.disableOutstandingHists ? nozero : pdf);
-
- stats.outstandingWritesHist
- .init(params()->outstanding_bins)
- .name(name() + ".outstandingWritesHist")
- .desc("Outstanding write transactions")
- .flags(stats.disableOutstandingHists ? nozero : pdf);
-
- stats.readTransHist
- .init(params()->transaction_bins)
- .name(name() + ".readTransHist")
- .desc("Histogram of read transactions per sample period")
- .flags(stats.disableTransactionHists ? nozero : pdf);
-
- stats.writeTransHist
- .init(params()->transaction_bins)
- .name(name() + ".writeTransHist")
- .desc("Histogram of read transactions per sample period")
- .flags(stats.disableTransactionHists ? nozero : pdf);
-
- stats.readAddrDist
- .init(0)
- .name(name() + ".readAddrDist")
- .desc("Read address distribution")
- .flags(stats.disableAddrDists ? nozero : pdf);
-
- stats.writeAddrDist
- .init(0)
- .name(name() + ".writeAddrDist")
- .desc("Write address distribution")
- .flags(stats.disableAddrDists ? nozero : pdf);
+ cpuSidePort.sendRangeChange();
}
void