comm_monitor.cc revision 8981
15081Sgblack@eecs.umich.edu/*
25081Sgblack@eecs.umich.edu * Copyright (c) 2012 ARM Limited
35081Sgblack@eecs.umich.edu * All rights reserved
47087Snate@binkert.org *
57087Snate@binkert.org * The license below extends only to copyright in the software and shall
67087Snate@binkert.org * not be construed as granting a license to any other intellectual
77087Snate@binkert.org * property including but not limited to intellectual property relating
87087Snate@binkert.org * to a hardware implementation of the functionality of the software
97087Snate@binkert.org * licensed hereunder.  You may use the software subject to the license
107087Snate@binkert.org * terms below provided that you ensure that this notice is replicated
117087Snate@binkert.org * unmodified and in its entirety in all distributions of the software,
125081Sgblack@eecs.umich.edu * modified or unmodified, in source code or in binary form.
137087Snate@binkert.org *
147087Snate@binkert.org * Redistribution and use in source and binary forms, with or without
157087Snate@binkert.org * modification, are permitted provided that the following conditions are
167087Snate@binkert.org * met: redistributions of source code must retain the above copyright
177087Snate@binkert.org * notice, this list of conditions and the following disclaimer;
187087Snate@binkert.org * redistributions in binary form must reproduce the above copyright
197087Snate@binkert.org * notice, this list of conditions and the following disclaimer in the
207087Snate@binkert.org * documentation and/or other materials provided with the distribution;
215081Sgblack@eecs.umich.edu * neither the name of the copyright holders nor the names of its
227087Snate@binkert.org * contributors may be used to endorse or promote products derived from
235081Sgblack@eecs.umich.edu * this software without specific prior written permission.
245081Sgblack@eecs.umich.edu *
255081Sgblack@eecs.umich.edu * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
265081Sgblack@eecs.umich.edu * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
275081Sgblack@eecs.umich.edu * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
285081Sgblack@eecs.umich.edu * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
295081Sgblack@eecs.umich.edu * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
305081Sgblack@eecs.umich.edu * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
315081Sgblack@eecs.umich.edu * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
325081Sgblack@eecs.umich.edu * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
335081Sgblack@eecs.umich.edu * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
345081Sgblack@eecs.umich.edu * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
355081Sgblack@eecs.umich.edu * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
365081Sgblack@eecs.umich.edu *
375081Sgblack@eecs.umich.edu * Authors: Thomas Grass
385081Sgblack@eecs.umich.edu *          Andreas Hansson
395081Sgblack@eecs.umich.edu */
405081Sgblack@eecs.umich.edu
415961Sgblack@eecs.umich.edu#include "debug/CommMonitor.hh"
425081Sgblack@eecs.umich.edu#include "mem/comm_monitor.hh"
435081Sgblack@eecs.umich.edu#include "sim/stats.hh"
445081Sgblack@eecs.umich.edu
455081Sgblack@eecs.umich.eduCommMonitor::CommMonitor(Params* params)
465119Sgblack@eecs.umich.edu    : MemObject(params),
475961Sgblack@eecs.umich.edu      masterPort(name() + "-master", *this),
485081Sgblack@eecs.umich.edu      slavePort(name() + "-slave", *this),
495081Sgblack@eecs.umich.edu      samplePeriodicEvent(this),
505081Sgblack@eecs.umich.edu      samplePeriodTicks(params->sample_period),
515081Sgblack@eecs.umich.edu      readAddrMask(params->read_addr_mask),
525081Sgblack@eecs.umich.edu      writeAddrMask(params->write_addr_mask),
535081Sgblack@eecs.umich.edu      stats(params)
545119Sgblack@eecs.umich.edu{
555961Sgblack@eecs.umich.edu    // keep track of the sample period both in ticks and absolute time
565081Sgblack@eecs.umich.edu    samplePeriod.setTick(params->sample_period);
575081Sgblack@eecs.umich.edu
585081Sgblack@eecs.umich.edu    DPRINTF(CommMonitor,
595081Sgblack@eecs.umich.edu            "Created monitor %s with sample period %d ticks (%f s)\n",
605081Sgblack@eecs.umich.edu            name(), samplePeriodTicks, samplePeriod);
615961Sgblack@eecs.umich.edu}
625081Sgblack@eecs.umich.edu
635081Sgblack@eecs.umich.eduCommMonitor*
645081Sgblack@eecs.umich.eduCommMonitorParams::create()
655081Sgblack@eecs.umich.edu{
665119Sgblack@eecs.umich.edu    return new CommMonitor(this);
675961Sgblack@eecs.umich.edu}
685081Sgblack@eecs.umich.edu
695081Sgblack@eecs.umich.eduvoid
705081Sgblack@eecs.umich.eduCommMonitor::init()
715081Sgblack@eecs.umich.edu{
725081Sgblack@eecs.umich.edu    // make sure both sides of the monitor are connected
735081Sgblack@eecs.umich.edu    if (!slavePort.isConnected() || !masterPort.isConnected())
745119Sgblack@eecs.umich.edu        fatal("Communication monitor is not connected on both sides.\n");
755961Sgblack@eecs.umich.edu}
765081Sgblack@eecs.umich.edu
775081Sgblack@eecs.umich.eduMasterPort&
785081Sgblack@eecs.umich.eduCommMonitor::getMasterPort(const std::string& if_name, int idx)
795081Sgblack@eecs.umich.edu{
805081Sgblack@eecs.umich.edu    if (if_name == "master") {
815961Sgblack@eecs.umich.edu        return masterPort;
825081Sgblack@eecs.umich.edu    } else {
835081Sgblack@eecs.umich.edu        return MemObject::getMasterPort(if_name, idx);
845081Sgblack@eecs.umich.edu    }
855081Sgblack@eecs.umich.edu}
865119Sgblack@eecs.umich.edu
875961Sgblack@eecs.umich.eduSlavePort&
885081Sgblack@eecs.umich.eduCommMonitor::getSlavePort(const std::string& if_name, int idx)
895081Sgblack@eecs.umich.edu{
905081Sgblack@eecs.umich.edu    if (if_name == "slave") {
915081Sgblack@eecs.umich.edu        return slavePort;
925081Sgblack@eecs.umich.edu    } else {
935081Sgblack@eecs.umich.edu        return MemObject::getSlavePort(if_name, idx);
945119Sgblack@eecs.umich.edu    }
955961Sgblack@eecs.umich.edu}
965081Sgblack@eecs.umich.edu
975081Sgblack@eecs.umich.eduvoid
985081Sgblack@eecs.umich.eduCommMonitor::recvFunctional(PacketPtr pkt)
996480Sgblack@eecs.umich.edu{
1006480Sgblack@eecs.umich.edu    masterPort.sendFunctional(pkt);
1016480Sgblack@eecs.umich.edu}
1026480Sgblack@eecs.umich.edu
1036480Sgblack@eecs.umich.eduvoid
1046480Sgblack@eecs.umich.eduCommMonitor::recvFunctionalSnoop(PacketPtr pkt)
1056480Sgblack@eecs.umich.edu{
1066480Sgblack@eecs.umich.edu    slavePort.sendFunctionalSnoop(pkt);
1076480Sgblack@eecs.umich.edu}
1086480Sgblack@eecs.umich.edu
1096480Sgblack@eecs.umich.eduTick
1106480Sgblack@eecs.umich.eduCommMonitor::recvAtomic(PacketPtr pkt)
1116480Sgblack@eecs.umich.edu{
1126480Sgblack@eecs.umich.edu    return masterPort.sendAtomic(pkt);
1136480Sgblack@eecs.umich.edu}
1146480Sgblack@eecs.umich.edu
1156480Sgblack@eecs.umich.eduTick
1166480Sgblack@eecs.umich.eduCommMonitor::recvAtomicSnoop(PacketPtr pkt)
1176480Sgblack@eecs.umich.edu{
1186480Sgblack@eecs.umich.edu    return slavePort.sendAtomicSnoop(pkt);
1196480Sgblack@eecs.umich.edu}
1206480Sgblack@eecs.umich.edu
1216480Sgblack@eecs.umich.edubool
1226480Sgblack@eecs.umich.eduCommMonitor::recvTimingReq(PacketPtr pkt)
1236480Sgblack@eecs.umich.edu{
1246480Sgblack@eecs.umich.edu    // should always see a request
1256480Sgblack@eecs.umich.edu    assert(pkt->isRequest());
1266480Sgblack@eecs.umich.edu
1276480Sgblack@eecs.umich.edu    // Store relevant fields of packet, because packet may be modified
1286480Sgblack@eecs.umich.edu    // or even deleted when sendTiming() is called.
1296480Sgblack@eecs.umich.edu    bool isRead = pkt->isRead();
1306480Sgblack@eecs.umich.edu    bool isWrite = pkt->isWrite();
1316480Sgblack@eecs.umich.edu    unsigned size = pkt->getSize();
1326480Sgblack@eecs.umich.edu    Addr addr = pkt->getAddr();
1336480Sgblack@eecs.umich.edu    bool needsResponse = pkt->needsResponse();
1346480Sgblack@eecs.umich.edu    bool memInhibitAsserted = pkt->memInhibitAsserted();
1356480Sgblack@eecs.umich.edu    Packet::SenderState* senderState = pkt->senderState;
1366480Sgblack@eecs.umich.edu
1376480Sgblack@eecs.umich.edu    // If a cache miss is served by a cache, a monitor near the memory
1386480Sgblack@eecs.umich.edu    // would see a request which needs a response, but this response
1396480Sgblack@eecs.umich.edu    // would be inhibited and not come back from the memory. Therefore
1406480Sgblack@eecs.umich.edu    // we additionally have to check the inhibit flag.
1416480Sgblack@eecs.umich.edu    if (needsResponse && !memInhibitAsserted && !stats.disableLatencyHists) {
1426480Sgblack@eecs.umich.edu        pkt->senderState = new CommMonitorSenderState(senderState,
1436480Sgblack@eecs.umich.edu                                                      curTick());
1446480Sgblack@eecs.umich.edu    }
1455081Sgblack@eecs.umich.edu
1465081Sgblack@eecs.umich.edu    // Attempt to send the packet (always succeeds for inhibited
1475961Sgblack@eecs.umich.edu    // packets)
1485081Sgblack@eecs.umich.edu    bool successful = masterPort.sendTimingReq(pkt);
1495081Sgblack@eecs.umich.edu
1505081Sgblack@eecs.umich.edu    // If not successful, restore the sender state
1515081Sgblack@eecs.umich.edu    if (!successful && needsResponse && !stats.disableLatencyHists) {
1525119Sgblack@eecs.umich.edu        delete pkt->senderState;
1535961Sgblack@eecs.umich.edu        pkt->senderState = senderState;
1545081Sgblack@eecs.umich.edu    }
1555081Sgblack@eecs.umich.edu
1565081Sgblack@eecs.umich.edu    if (successful && isRead) {
1575081Sgblack@eecs.umich.edu        DPRINTF(CommMonitor, "Forwarded read request\n");
1585081Sgblack@eecs.umich.edu
1595081Sgblack@eecs.umich.edu        // Increment number of observed read transactions
1605119Sgblack@eecs.umich.edu        if (!stats.disableTransactionHists) {
1615961Sgblack@eecs.umich.edu            ++stats.readTrans;
1625081Sgblack@eecs.umich.edu        }
1635081Sgblack@eecs.umich.edu
1645081Sgblack@eecs.umich.edu        // Get sample of burst length
1655081Sgblack@eecs.umich.edu        if (!stats.disableBurstLengthHists) {
1665081Sgblack@eecs.umich.edu            stats.readBurstLengthHist.sample(size);
1675961Sgblack@eecs.umich.edu        }
1685081Sgblack@eecs.umich.edu
1695081Sgblack@eecs.umich.edu        // Sample the masked address
1705081Sgblack@eecs.umich.edu        if (!stats.disableAddrDists) {
1715081Sgblack@eecs.umich.edu            stats.readAddrDist.sample(addr & readAddrMask);
1725119Sgblack@eecs.umich.edu        }
1735961Sgblack@eecs.umich.edu
1745081Sgblack@eecs.umich.edu        // If it needs a response increment number of outstanding read
1755081Sgblack@eecs.umich.edu        // requests
1765081Sgblack@eecs.umich.edu        if (!stats.disableOutstandingHists && needsResponse) {
1775081Sgblack@eecs.umich.edu            ++stats.outstandingReadReqs;
1785081Sgblack@eecs.umich.edu        }
1795081Sgblack@eecs.umich.edu
1805119Sgblack@eecs.umich.edu        if (!stats.disableITTDists) {
1815961Sgblack@eecs.umich.edu            // Sample value of read-read inter transaction time
1825081Sgblack@eecs.umich.edu            if (stats.timeOfLastRead != 0) {
1835081Sgblack@eecs.umich.edu                stats.ittReadRead.sample(curTick() - stats.timeOfLastRead);
1845081Sgblack@eecs.umich.edu            }
1855081Sgblack@eecs.umich.edu            stats.timeOfLastRead = curTick();
1865081Sgblack@eecs.umich.edu
1875961Sgblack@eecs.umich.edu            // Sample value of req-req inter transaction time
1885081Sgblack@eecs.umich.edu            if (stats.timeOfLastReq != 0) {
1895081Sgblack@eecs.umich.edu                stats.ittReqReq.sample(curTick() - stats.timeOfLastReq);
1905081Sgblack@eecs.umich.edu            }
1915081Sgblack@eecs.umich.edu            stats.timeOfLastReq = curTick();
1925119Sgblack@eecs.umich.edu        }
1935961Sgblack@eecs.umich.edu    } else if (successful && isWrite) {
1945081Sgblack@eecs.umich.edu        DPRINTF(CommMonitor, "Forwarded write request\n");
1955081Sgblack@eecs.umich.edu
1965081Sgblack@eecs.umich.edu        // Same as for reads
1975081Sgblack@eecs.umich.edu        if (!stats.disableTransactionHists) {
1985081Sgblack@eecs.umich.edu            ++stats.writeTrans;
1995081Sgblack@eecs.umich.edu        }
2005119Sgblack@eecs.umich.edu
2015961Sgblack@eecs.umich.edu        if (!stats.disableBurstLengthHists) {
2025081Sgblack@eecs.umich.edu            stats.writeBurstLengthHist.sample(size);
2035081Sgblack@eecs.umich.edu        }
2045081Sgblack@eecs.umich.edu
2056481Sgblack@eecs.umich.edu        // Update the bandwidth stats on the request
2066481Sgblack@eecs.umich.edu        if (!stats.disableBandwidthHists) {
2076481Sgblack@eecs.umich.edu            stats.writtenBytes += size;
2086481Sgblack@eecs.umich.edu            stats.totalWrittenBytes += size;
2096481Sgblack@eecs.umich.edu        }
2106481Sgblack@eecs.umich.edu
2116481Sgblack@eecs.umich.edu        // Sample the masked write address
2126481Sgblack@eecs.umich.edu        if (!stats.disableAddrDists) {
2136481Sgblack@eecs.umich.edu            stats.writeAddrDist.sample(addr & writeAddrMask);
2146481Sgblack@eecs.umich.edu        }
2156481Sgblack@eecs.umich.edu
2166481Sgblack@eecs.umich.edu        if (!stats.disableOutstandingHists && needsResponse) {
2176481Sgblack@eecs.umich.edu            ++stats.outstandingWriteReqs;
2186481Sgblack@eecs.umich.edu        }
2196481Sgblack@eecs.umich.edu
2206481Sgblack@eecs.umich.edu        if (!stats.disableITTDists) {
2216481Sgblack@eecs.umich.edu            // Sample value of write-to-write inter transaction time
2226481Sgblack@eecs.umich.edu            if (stats.timeOfLastWrite != 0) {
2236481Sgblack@eecs.umich.edu                stats.ittWriteWrite.sample(curTick() - stats.timeOfLastWrite);
2246481Sgblack@eecs.umich.edu            }
2256481Sgblack@eecs.umich.edu            stats.timeOfLastWrite = curTick();
2266481Sgblack@eecs.umich.edu
2276481Sgblack@eecs.umich.edu            // Sample value of req-to-req inter transaction time
2285977Sgblack@eecs.umich.edu            if (stats.timeOfLastReq != 0) {
2295977Sgblack@eecs.umich.edu                stats.ittReqReq.sample(curTick() - stats.timeOfLastReq);
2306481Sgblack@eecs.umich.edu            }
2316481Sgblack@eecs.umich.edu            stats.timeOfLastReq = curTick();
2325977Sgblack@eecs.umich.edu        }
2335977Sgblack@eecs.umich.edu    } else if (successful) {
2345977Sgblack@eecs.umich.edu        DPRINTF(CommMonitor, "Forwarded non read/write request\n");
2355977Sgblack@eecs.umich.edu    }
2365977Sgblack@eecs.umich.edu
2376481Sgblack@eecs.umich.edu    return successful;
2386481Sgblack@eecs.umich.edu}
2395977Sgblack@eecs.umich.edu
2405977Sgblack@eecs.umich.edubool
2415977Sgblack@eecs.umich.eduCommMonitor::recvTimingResp(PacketPtr pkt)
2425977Sgblack@eecs.umich.edu{
2435977Sgblack@eecs.umich.edu    // should always see responses
2445977Sgblack@eecs.umich.edu    assert(pkt->isResponse());
2455977Sgblack@eecs.umich.edu
2466481Sgblack@eecs.umich.edu    // Store relevant fields of packet, because packet may be modified
2476481Sgblack@eecs.umich.edu    // or even deleted when sendTiming() is called.
2485977Sgblack@eecs.umich.edu    bool isRead = pkt->isRead();
2495977Sgblack@eecs.umich.edu    bool isWrite = pkt->isWrite();
2505977Sgblack@eecs.umich.edu    unsigned size = pkt->getSize();
2515081Sgblack@eecs.umich.edu    Tick latency = 0;
2525081Sgblack@eecs.umich.edu    CommMonitorSenderState* commReceivedState =
2535961Sgblack@eecs.umich.edu        dynamic_cast<CommMonitorSenderState*>(pkt->senderState);
2545081Sgblack@eecs.umich.edu
2555081Sgblack@eecs.umich.edu    if (!stats.disableLatencyHists) {
2565081Sgblack@eecs.umich.edu        // Restore initial sender state
2575081Sgblack@eecs.umich.edu        if (commReceivedState == NULL)
2585119Sgblack@eecs.umich.edu            panic("Monitor got a response without monitor sender state\n");
2595961Sgblack@eecs.umich.edu
2605081Sgblack@eecs.umich.edu        // Restore the sate
2615081Sgblack@eecs.umich.edu        pkt->senderState = commReceivedState->origSenderState;
2625081Sgblack@eecs.umich.edu    }
2635081Sgblack@eecs.umich.edu
2645081Sgblack@eecs.umich.edu    // Attempt to send the packet
2655081Sgblack@eecs.umich.edu    bool successful = slavePort.sendTimingResp(pkt);
2665119Sgblack@eecs.umich.edu
2675961Sgblack@eecs.umich.edu    if (!stats.disableLatencyHists) {
2685081Sgblack@eecs.umich.edu        // If packet successfully send, sample value of latency,
2695081Sgblack@eecs.umich.edu        // afterwards delete sender state, otherwise restore state
2705081Sgblack@eecs.umich.edu        if (successful) {
2715081Sgblack@eecs.umich.edu            latency = curTick() - commReceivedState->transmitTime;
2725081Sgblack@eecs.umich.edu            DPRINTF(CommMonitor, "Latency: %d\n", latency);
2735961Sgblack@eecs.umich.edu            delete commReceivedState;
2745081Sgblack@eecs.umich.edu        } else {
2755081Sgblack@eecs.umich.edu            // Don't delete anything and let the packet look like we
2765081Sgblack@eecs.umich.edu            // did not touch it
2775081Sgblack@eecs.umich.edu            pkt->senderState = commReceivedState;
2785119Sgblack@eecs.umich.edu        }
2795961Sgblack@eecs.umich.edu    }
2805081Sgblack@eecs.umich.edu
2815081Sgblack@eecs.umich.edu    if (successful && isRead) {
2825081Sgblack@eecs.umich.edu        // Decrement number of outstanding read requests
2835081Sgblack@eecs.umich.edu        DPRINTF(CommMonitor, "Received read response\n");
2845081Sgblack@eecs.umich.edu        if (!stats.disableOutstandingHists) {
2855081Sgblack@eecs.umich.edu            assert(stats.outstandingReadReqs != 0);
2865119Sgblack@eecs.umich.edu            --stats.outstandingReadReqs;
2875961Sgblack@eecs.umich.edu        }
2885081Sgblack@eecs.umich.edu
2895081Sgblack@eecs.umich.edu        if (!stats.disableLatencyHists) {
2905081Sgblack@eecs.umich.edu            stats.readLatencyHist.sample(latency);
2915081Sgblack@eecs.umich.edu        }
2925081Sgblack@eecs.umich.edu
2935961Sgblack@eecs.umich.edu        // Update the bandwidth stats based on responses for reads
2945081Sgblack@eecs.umich.edu        if (!stats.disableBandwidthHists) {
2955081Sgblack@eecs.umich.edu            stats.readBytes += size;
2965081Sgblack@eecs.umich.edu            stats.totalReadBytes += size;
2975081Sgblack@eecs.umich.edu        }
2985119Sgblack@eecs.umich.edu
2995961Sgblack@eecs.umich.edu    } else if (successful && isWrite) {
3005081Sgblack@eecs.umich.edu        // Decrement number of outstanding write requests
3015081Sgblack@eecs.umich.edu        DPRINTF(CommMonitor, "Received write response\n");
3025081Sgblack@eecs.umich.edu        if (!stats.disableOutstandingHists) {
3035081Sgblack@eecs.umich.edu            assert(stats.outstandingWriteReqs != 0);
3045081Sgblack@eecs.umich.edu            --stats.outstandingWriteReqs;
3055081Sgblack@eecs.umich.edu        }
3065119Sgblack@eecs.umich.edu
3075961Sgblack@eecs.umich.edu        if (!stats.disableLatencyHists) {
3085081Sgblack@eecs.umich.edu            stats.writeLatencyHist.sample(latency);
3095081Sgblack@eecs.umich.edu        }
3105081Sgblack@eecs.umich.edu    } else if (successful) {
311        DPRINTF(CommMonitor, "Received non read/write response\n");
312    }
313    return successful;
314}
315
316void
317CommMonitor::recvTimingSnoopReq(PacketPtr pkt)
318{
319    slavePort.sendTimingSnoopReq(pkt);
320}
321
322bool
323CommMonitor::recvTimingSnoopResp(PacketPtr pkt)
324{
325    return masterPort.sendTimingSnoopResp(pkt);
326}
327
328bool
329CommMonitor::isSnooping() const
330{
331    return slavePort.getMasterPort().isSnooping();
332}
333
334unsigned
335CommMonitor::deviceBlockSizeMaster()
336{
337    return slavePort.peerBlockSize();
338}
339
340unsigned
341CommMonitor::deviceBlockSizeSlave()
342{
343    return masterPort.peerBlockSize();
344}
345
346AddrRangeList
347CommMonitor::getAddrRanges()
348{
349    return masterPort.getSlavePort().getAddrRanges();
350}
351
352void
353CommMonitor::recvRetryMaster()
354{
355    slavePort.sendRetry();
356}
357
358void
359CommMonitor::recvRetrySlave()
360{
361    masterPort.sendRetry();
362}
363
364void
365CommMonitor::recvRangeChange()
366{
367    slavePort.sendRangeChange();
368}
369
370void
371CommMonitor::regStats()
372{
373    // Initialise all the monitor stats
374    using namespace Stats;
375
376    stats.readBurstLengthHist
377        .init(params()->burst_length_bins)
378        .name(name() + ".readBurstLengthHist")
379        .desc("Histogram of burst lengths of transmitted packets")
380        .flags(stats.disableBurstLengthHists ? nozero : pdf);
381
382    stats.writeBurstLengthHist
383        .init(params()->burst_length_bins)
384        .name(name() + ".writeBurstLengthHist")
385        .desc("Histogram of burst lengths of transmitted packets")
386        .flags(stats.disableBurstLengthHists ? nozero : pdf);
387
388    // Stats based on received responses
389    stats.readBandwidthHist
390        .init(params()->bandwidth_bins)
391        .name(name() + ".readBandwidthHist")
392        .desc("Histogram of read bandwidth per sample period (bytes/s)")
393        .flags(stats.disableBandwidthHists ? nozero : pdf);
394
395    stats.averageReadBW
396        .name(name() + ".averageReadBandwidth")
397        .desc("Average read bandwidth (bytes/s)")
398        .flags(stats.disableBandwidthHists ? nozero : pdf);
399
400    stats.totalReadBytes
401        .name(name() + ".totalReadBytes")
402        .desc("Number of bytes read")
403        .flags(stats.disableBandwidthHists ? nozero : pdf);
404
405    stats.averageReadBW = stats.totalReadBytes / simSeconds;
406
407    // Stats based on successfully sent requests
408    stats.writeBandwidthHist
409        .init(params()->bandwidth_bins)
410        .name(name() + ".writeBandwidthHist")
411        .desc("Histogram of write bandwidth (bytes/s)")
412        .flags(stats.disableBandwidthHists ? (pdf | nozero) : pdf);
413
414    stats.averageWriteBW
415        .name(name() + ".averageWriteBandwidth")
416        .desc("Average write bandwidth (bytes/s)")
417        .flags(stats.disableBandwidthHists ? nozero : pdf);
418
419    stats.totalWrittenBytes
420        .name(name() + ".totalWrittenBytes")
421        .desc("Number of bytes written")
422        .flags(stats.disableBandwidthHists ? nozero : pdf);
423
424    stats.averageWriteBW = stats.totalWrittenBytes / simSeconds;
425
426    stats.readLatencyHist
427        .init(params()->latency_bins)
428        .name(name() + ".readLatencyHist")
429        .desc("Read request-response latency")
430        .flags(stats.disableLatencyHists ? nozero : pdf);
431
432    stats.writeLatencyHist
433        .init(params()->latency_bins)
434        .name(name() + ".writeLatencyHist")
435        .desc("Write request-response latency")
436        .flags(stats.disableLatencyHists ? nozero : pdf);
437
438    stats.ittReadRead
439        .init(1, params()->itt_max_bin, params()->itt_max_bin /
440              params()->itt_bins)
441        .name(name() + ".ittReadRead")
442        .desc("Read-to-read inter transaction time")
443        .flags(stats.disableITTDists ? nozero : pdf);
444
445    stats.ittWriteWrite
446        .init(1, params()->itt_max_bin, params()->itt_max_bin /
447              params()->itt_bins)
448        .name(name() + ".ittWriteWrite")
449        .desc("Write-to-write inter transaction time")
450        .flags(stats.disableITTDists ? nozero : pdf);
451
452    stats.ittReqReq
453        .init(1, params()->itt_max_bin, params()->itt_max_bin /
454              params()->itt_bins)
455        .name(name() + ".ittReqReq")
456        .desc("Request-to-request inter transaction time")
457        .flags(stats.disableITTDists ? nozero : pdf);
458
459    stats.outstandingReadsHist
460        .init(params()->outstanding_bins)
461        .name(name() + ".outstandingReadsHist")
462        .desc("Outstanding read transactions")
463        .flags(stats.disableOutstandingHists ? nozero : pdf);
464
465    stats.outstandingWritesHist
466        .init(params()->outstanding_bins)
467        .name(name() + ".outstandingWritesHist")
468        .desc("Outstanding write transactions")
469        .flags(stats.disableOutstandingHists ? nozero : pdf);
470
471    stats.readTransHist
472        .init(params()->transaction_bins)
473        .name(name() + ".readTransHist")
474        .desc("Histogram of read transactions per sample period")
475        .flags(stats.disableTransactionHists ? nozero : pdf);
476
477    stats.writeTransHist
478        .init(params()->transaction_bins)
479        .name(name() + ".writeTransHist")
480        .desc("Histogram of read transactions per sample period")
481        .flags(stats.disableTransactionHists ? nozero : pdf);
482
483    stats.readAddrDist
484        .init(0)
485        .name(name() + ".readAddrDist")
486        .desc("Read address distribution")
487        .flags(stats.disableAddrDists ? nozero : pdf);
488
489    stats.writeAddrDist
490        .init(0)
491        .name(name() + ".writeAddrDist")
492        .desc("Write address distribution")
493        .flags(stats.disableAddrDists ? nozero : pdf);
494}
495
496void
497CommMonitor::samplePeriodic()
498{
499    // the periodic stats update runs on the granularity of sample
500    // periods, but in combination with this there may also be a
501    // external resets and dumps of the stats (through schedStatEvent)
502    // causing the stats themselves to capture less than a sample
503    // period
504
505    // only capture if we have not reset the stats during the last
506    // sample period
507    if (simTicks.value() >= samplePeriodTicks) {
508        if (!stats.disableTransactionHists) {
509            stats.readTransHist.sample(stats.readTrans);
510            stats.writeTransHist.sample(stats.writeTrans);
511        }
512
513        if (!stats.disableBandwidthHists) {
514            stats.readBandwidthHist.sample(stats.readBytes / samplePeriod);
515            stats.writeBandwidthHist.sample(stats.writtenBytes / samplePeriod);
516        }
517
518        if (!stats.disableOutstandingHists) {
519            stats.outstandingReadsHist.sample(stats.outstandingReadReqs);
520            stats.outstandingWritesHist.sample(stats.outstandingWriteReqs);
521        }
522    }
523
524    // reset the sampled values
525    stats.readTrans = 0;
526    stats.writeTrans = 0;
527
528    stats.readBytes = 0;
529    stats.writtenBytes = 0;
530
531    schedule(samplePeriodicEvent, curTick() + samplePeriodTicks);
532}
533
534void
535CommMonitor::startup()
536{
537    schedule(samplePeriodicEvent, curTick() + samplePeriodTicks);
538}
539