comm_monitor.cc revision 10309
111784Sarthur.perais@inria.fr/*
211784Sarthur.perais@inria.fr * Copyright (c) 2012-2013 ARM Limited
311784Sarthur.perais@inria.fr * All rights reserved
411784Sarthur.perais@inria.fr *
511784Sarthur.perais@inria.fr * The license below extends only to copyright in the software and shall
611784Sarthur.perais@inria.fr * not be construed as granting a license to any other intellectual
711784Sarthur.perais@inria.fr * property including but not limited to intellectual property relating
811784Sarthur.perais@inria.fr * to a hardware implementation of the functionality of the software
911784Sarthur.perais@inria.fr * licensed hereunder.  You may use the software subject to the license
1011784Sarthur.perais@inria.fr * terms below provided that you ensure that this notice is replicated
1111784Sarthur.perais@inria.fr * unmodified and in its entirety in all distributions of the software,
1211784Sarthur.perais@inria.fr * modified or unmodified, in source code or in binary form.
1311784Sarthur.perais@inria.fr *
1411784Sarthur.perais@inria.fr * Redistribution and use in source and binary forms, with or without
1511784Sarthur.perais@inria.fr * modification, are permitted provided that the following conditions are
1611784Sarthur.perais@inria.fr * met: redistributions of source code must retain the above copyright
1711784Sarthur.perais@inria.fr * notice, this list of conditions and the following disclaimer;
1811784Sarthur.perais@inria.fr * redistributions in binary form must reproduce the above copyright
1911784Sarthur.perais@inria.fr * notice, this list of conditions and the following disclaimer in the
2011784Sarthur.perais@inria.fr * documentation and/or other materials provided with the distribution;
2111784Sarthur.perais@inria.fr * neither the name of the copyright holders nor the names of its
2211784Sarthur.perais@inria.fr * contributors may be used to endorse or promote products derived from
2311784Sarthur.perais@inria.fr * this software without specific prior written permission.
2411784Sarthur.perais@inria.fr *
2511784Sarthur.perais@inria.fr * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
2611784Sarthur.perais@inria.fr * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
2711784Sarthur.perais@inria.fr * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
2811784Sarthur.perais@inria.fr * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
2911784Sarthur.perais@inria.fr * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
3011784Sarthur.perais@inria.fr * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
3111784Sarthur.perais@inria.fr * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
3211784Sarthur.perais@inria.fr * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
3311784Sarthur.perais@inria.fr * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
3411784Sarthur.perais@inria.fr * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
3511784Sarthur.perais@inria.fr * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
3611784Sarthur.perais@inria.fr *
3711784Sarthur.perais@inria.fr * Authors: Thomas Grass
3811784Sarthur.perais@inria.fr *          Andreas Hansson
3911784Sarthur.perais@inria.fr */
4011784Sarthur.perais@inria.fr
4111784Sarthur.perais@inria.fr#include "base/callback.hh"
4211784Sarthur.perais@inria.fr#include "base/output.hh"
4311784Sarthur.perais@inria.fr#include "base/trace.hh"
4412334Sgabeblack@google.com#include "debug/CommMonitor.hh"
4511784Sarthur.perais@inria.fr#include "mem/comm_monitor.hh"
4611784Sarthur.perais@inria.fr#include "proto/packet.pb.h"
4711784Sarthur.perais@inria.fr#include "sim/stats.hh"
4811784Sarthur.perais@inria.fr
4911784Sarthur.perais@inria.frCommMonitor::CommMonitor(Params* params)
5011784Sarthur.perais@inria.fr    : MemObject(params),
5111784Sarthur.perais@inria.fr      masterPort(name() + "-master", *this),
5211784Sarthur.perais@inria.fr      slavePort(name() + "-slave", *this),
5313420Spau.cabre@metempsy.com      samplePeriodicEvent(this),
5411784Sarthur.perais@inria.fr      samplePeriodTicks(params->sample_period),
5511784Sarthur.perais@inria.fr      readAddrMask(params->read_addr_mask),
5611784Sarthur.perais@inria.fr      writeAddrMask(params->write_addr_mask),
5711784Sarthur.perais@inria.fr      stats(params),
5811784Sarthur.perais@inria.fr      traceStream(NULL),
5911784Sarthur.perais@inria.fr      system(params->system)
6011784Sarthur.perais@inria.fr{
6111784Sarthur.perais@inria.fr    // If we are using a trace file, then open the file
6213442Spau.cabre@metempsy.com    if (params->trace_enable) {
6313442Spau.cabre@metempsy.com        std::string filename;
6413442Spau.cabre@metempsy.com        if (params->trace_file != "") {
6513442Spau.cabre@metempsy.com            // If the trace file is not specified as an absolute path,
6613442Spau.cabre@metempsy.com            // append the current simulation output directory
6713442Spau.cabre@metempsy.com            filename = simout.resolve(params->trace_file);
6813442Spau.cabre@metempsy.com
6911784Sarthur.perais@inria.fr            std::string suffix = ".gz";
7011784Sarthur.perais@inria.fr            // If trace_compress has been set, check the suffix. Append
7113442Spau.cabre@metempsy.com            // accordingly.
7213442Spau.cabre@metempsy.com            if (params->trace_compress &&
7313442Spau.cabre@metempsy.com                filename.compare(filename.size() - suffix.size(), suffix.size(),
7413442Spau.cabre@metempsy.com                                 suffix) != 0)
7513442Spau.cabre@metempsy.com                    filename = filename + suffix;
7611784Sarthur.perais@inria.fr        } else {
7711784Sarthur.perais@inria.fr            // Generate a filename from the name of the SimObject. Append .trc
7811784Sarthur.perais@inria.fr            // and .gz if we want compression enabled.
7911784Sarthur.perais@inria.fr            filename = simout.resolve(name() + ".trc" +
8011784Sarthur.perais@inria.fr                                      (params->trace_compress ? ".gz" : ""));
8111784Sarthur.perais@inria.fr        }
8211784Sarthur.perais@inria.fr
8311784Sarthur.perais@inria.fr        traceStream = new ProtoOutputStream(filename);
8411784Sarthur.perais@inria.fr
8511784Sarthur.perais@inria.fr        // Create a protobuf message for the header and write it to
8611784Sarthur.perais@inria.fr        // the stream
8711784Sarthur.perais@inria.fr        ProtoMessage::PacketHeader header_msg;
8811784Sarthur.perais@inria.fr        header_msg.set_obj_id(name());
8911784Sarthur.perais@inria.fr        header_msg.set_tick_freq(SimClock::Frequency);
9011784Sarthur.perais@inria.fr        traceStream->write(header_msg);
9111784Sarthur.perais@inria.fr
9211784Sarthur.perais@inria.fr        // Register a callback to compensate for the destructor not
9311784Sarthur.perais@inria.fr        // being called. The callback forces the stream to flush and
9411784Sarthur.perais@inria.fr        // closes the output file.
9511784Sarthur.perais@inria.fr        Callback* cb = new MakeCallback<CommMonitor,
9611784Sarthur.perais@inria.fr            &CommMonitor::closeStreams>(this);
9711784Sarthur.perais@inria.fr        registerExitCallback(cb);
9811784Sarthur.perais@inria.fr    }
9911784Sarthur.perais@inria.fr
10011784Sarthur.perais@inria.fr    // keep track of the sample period both in ticks and absolute time
10111784Sarthur.perais@inria.fr    samplePeriod.setTick(params->sample_period);
10211784Sarthur.perais@inria.fr
10311784Sarthur.perais@inria.fr    DPRINTF(CommMonitor,
10411784Sarthur.perais@inria.fr            "Created monitor %s with sample period %d ticks (%f ms)\n",
10511784Sarthur.perais@inria.fr            name(), samplePeriodTicks, samplePeriod.msec());
10611784Sarthur.perais@inria.fr}
10711784Sarthur.perais@inria.fr
10811784Sarthur.perais@inria.frvoid
10911784Sarthur.perais@inria.frCommMonitor::closeStreams()
11011784Sarthur.perais@inria.fr{
11111784Sarthur.perais@inria.fr    if (traceStream != NULL)
11211784Sarthur.perais@inria.fr        delete traceStream;
11311784Sarthur.perais@inria.fr}
11411784Sarthur.perais@inria.fr
11511784Sarthur.perais@inria.frCommMonitor*
11611784Sarthur.perais@inria.frCommMonitorParams::create()
11711784Sarthur.perais@inria.fr{
11811784Sarthur.perais@inria.fr    return new CommMonitor(this);
11911784Sarthur.perais@inria.fr}
12011784Sarthur.perais@inria.fr
12111784Sarthur.perais@inria.frvoid
12211784Sarthur.perais@inria.frCommMonitor::init()
12311784Sarthur.perais@inria.fr{
12411784Sarthur.perais@inria.fr    // make sure both sides of the monitor are connected
12511784Sarthur.perais@inria.fr    if (!slavePort.isConnected() || !masterPort.isConnected())
12611784Sarthur.perais@inria.fr        fatal("Communication monitor is not connected on both sides.\n");
12711784Sarthur.perais@inria.fr
12811784Sarthur.perais@inria.fr    if (traceStream != NULL) {
12911784Sarthur.perais@inria.fr        // Check the memory mode. We only record something when in
13011784Sarthur.perais@inria.fr        // timing mode. Warn accordingly.
13111784Sarthur.perais@inria.fr        if (!system->isTimingMode())
13211784Sarthur.perais@inria.fr            warn("%s: Not in timing mode. No trace will be recorded.", name());
13311784Sarthur.perais@inria.fr    }
13411784Sarthur.perais@inria.fr}
13511784Sarthur.perais@inria.fr
13611784Sarthur.perais@inria.frBaseMasterPort&
13711784Sarthur.perais@inria.frCommMonitor::getMasterPort(const std::string& if_name, PortID idx)
13813420Spau.cabre@metempsy.com{
13913420Spau.cabre@metempsy.com    if (if_name == "master") {
14013420Spau.cabre@metempsy.com        return masterPort;
14113420Spau.cabre@metempsy.com    } else {
14213420Spau.cabre@metempsy.com        return MemObject::getMasterPort(if_name, idx);
14311784Sarthur.perais@inria.fr    }
14411784Sarthur.perais@inria.fr}
14511784Sarthur.perais@inria.fr
14611784Sarthur.perais@inria.frBaseSlavePort&
14711784Sarthur.perais@inria.frCommMonitor::getSlavePort(const std::string& if_name, PortID idx)
14811784Sarthur.perais@inria.fr{
14911784Sarthur.perais@inria.fr    if (if_name == "slave") {
15011784Sarthur.perais@inria.fr        return slavePort;
15111784Sarthur.perais@inria.fr    } else {
15211784Sarthur.perais@inria.fr        return MemObject::getSlavePort(if_name, idx);
15311784Sarthur.perais@inria.fr    }
15411784Sarthur.perais@inria.fr}
15511784Sarthur.perais@inria.fr
15611784Sarthur.perais@inria.frvoid
15711784Sarthur.perais@inria.frCommMonitor::recvFunctional(PacketPtr pkt)
15813413Spau.cabre@metempsy.com{
15911784Sarthur.perais@inria.fr    masterPort.sendFunctional(pkt);
16011784Sarthur.perais@inria.fr}
16111784Sarthur.perais@inria.fr
16211784Sarthur.perais@inria.frvoid
16311784Sarthur.perais@inria.frCommMonitor::recvFunctionalSnoop(PacketPtr pkt)
16413413Spau.cabre@metempsy.com{
16513413Spau.cabre@metempsy.com    slavePort.sendFunctionalSnoop(pkt);
16611784Sarthur.perais@inria.fr}
16711784Sarthur.perais@inria.fr
16811784Sarthur.perais@inria.frTick
16911784Sarthur.perais@inria.frCommMonitor::recvAtomic(PacketPtr pkt)
17011784Sarthur.perais@inria.fr{
17111784Sarthur.perais@inria.fr    return masterPort.sendAtomic(pkt);
17211784Sarthur.perais@inria.fr}
17311784Sarthur.perais@inria.fr
17411784Sarthur.perais@inria.frTick
17511784Sarthur.perais@inria.frCommMonitor::recvAtomicSnoop(PacketPtr pkt)
17611784Sarthur.perais@inria.fr{
17711784Sarthur.perais@inria.fr    return slavePort.sendAtomicSnoop(pkt);
17811784Sarthur.perais@inria.fr}
17911784Sarthur.perais@inria.fr
18011784Sarthur.perais@inria.frbool
18111784Sarthur.perais@inria.frCommMonitor::recvTimingReq(PacketPtr pkt)
18211784Sarthur.perais@inria.fr{
18311784Sarthur.perais@inria.fr    // should always see a request
18411784Sarthur.perais@inria.fr    assert(pkt->isRequest());
18511784Sarthur.perais@inria.fr
18611784Sarthur.perais@inria.fr    // Store relevant fields of packet, because packet may be modified
18711784Sarthur.perais@inria.fr    // or even deleted when sendTiming() is called.
18811784Sarthur.perais@inria.fr    bool is_read = pkt->isRead();
18911784Sarthur.perais@inria.fr    bool is_write = pkt->isWrite();
19011784Sarthur.perais@inria.fr    int cmd = pkt->cmdToIndex();
19111784Sarthur.perais@inria.fr    Request::FlagsType req_flags = pkt->req->getFlags();
19213413Spau.cabre@metempsy.com    unsigned size = pkt->getSize();
19313413Spau.cabre@metempsy.com    Addr addr = pkt->getAddr();
19411784Sarthur.perais@inria.fr    bool expects_response = pkt->needsResponse() && !pkt->memInhibitAsserted();
19511784Sarthur.perais@inria.fr
19611784Sarthur.perais@inria.fr    // If a cache miss is served by a cache, a monitor near the memory
19711784Sarthur.perais@inria.fr    // would see a request which needs a response, but this response
19811784Sarthur.perais@inria.fr    // would be inhibited and not come back from the memory. Therefore
19911784Sarthur.perais@inria.fr    // we additionally have to check the inhibit flag.
20011784Sarthur.perais@inria.fr    if (expects_response && !stats.disableLatencyHists) {
20111784Sarthur.perais@inria.fr        pkt->pushSenderState(new CommMonitorSenderState(curTick()));
20211784Sarthur.perais@inria.fr    }
20311784Sarthur.perais@inria.fr
20411784Sarthur.perais@inria.fr    // Attempt to send the packet (always succeeds for inhibited
20513413Spau.cabre@metempsy.com    // packets)
20613413Spau.cabre@metempsy.com    bool successful = masterPort.sendTimingReq(pkt);
20713413Spau.cabre@metempsy.com
20811784Sarthur.perais@inria.fr    // If not successful, restore the sender state
20911784Sarthur.perais@inria.fr    if (!successful && expects_response && !stats.disableLatencyHists) {
21011784Sarthur.perais@inria.fr        delete pkt->popSenderState();
21111784Sarthur.perais@inria.fr    }
21211784Sarthur.perais@inria.fr
21311784Sarthur.perais@inria.fr    if (successful && traceStream != NULL) {
21411784Sarthur.perais@inria.fr        // Create a protobuf message representing the
21511784Sarthur.perais@inria.fr        // packet. Currently we do not preserve the flags in the
21611784Sarthur.perais@inria.fr        // trace.
21711784Sarthur.perais@inria.fr        ProtoMessage::Packet pkt_msg;
21811784Sarthur.perais@inria.fr        pkt_msg.set_tick(curTick());
21911784Sarthur.perais@inria.fr        pkt_msg.set_cmd(cmd);
22011784Sarthur.perais@inria.fr        pkt_msg.set_flags(req_flags);
22111784Sarthur.perais@inria.fr        pkt_msg.set_addr(addr);
22211784Sarthur.perais@inria.fr        pkt_msg.set_size(size);
22311784Sarthur.perais@inria.fr
22411784Sarthur.perais@inria.fr        traceStream->write(pkt_msg);
22511784Sarthur.perais@inria.fr    }
22611784Sarthur.perais@inria.fr
22713442Spau.cabre@metempsy.com    if (successful && is_read) {
22813442Spau.cabre@metempsy.com        DPRINTF(CommMonitor, "Forwarded read request\n");
22913442Spau.cabre@metempsy.com
23013442Spau.cabre@metempsy.com        // Increment number of observed read transactions
23113442Spau.cabre@metempsy.com        if (!stats.disableTransactionHists) {
23213442Spau.cabre@metempsy.com            ++stats.readTrans;
23313442Spau.cabre@metempsy.com        }
23413442Spau.cabre@metempsy.com
23513442Spau.cabre@metempsy.com        // Get sample of burst length
23613442Spau.cabre@metempsy.com        if (!stats.disableBurstLengthHists) {
23713442Spau.cabre@metempsy.com            stats.readBurstLengthHist.sample(size);
23813442Spau.cabre@metempsy.com        }
23913442Spau.cabre@metempsy.com
24013442Spau.cabre@metempsy.com        // Sample the masked address
24111784Sarthur.perais@inria.fr        if (!stats.disableAddrDists) {
24211784Sarthur.perais@inria.fr            stats.readAddrDist.sample(addr & readAddrMask);
24311784Sarthur.perais@inria.fr        }
24411784Sarthur.perais@inria.fr
24513420Spau.cabre@metempsy.com        // If it needs a response increment number of outstanding read
24611784Sarthur.perais@inria.fr        // requests
24711784Sarthur.perais@inria.fr        if (!stats.disableOutstandingHists && expects_response) {
24811784Sarthur.perais@inria.fr            ++stats.outstandingReadReqs;
24913420Spau.cabre@metempsy.com        }
25013420Spau.cabre@metempsy.com
25111784Sarthur.perais@inria.fr        if (!stats.disableITTDists) {
25211784Sarthur.perais@inria.fr            // Sample value of read-read inter transaction time
25311784Sarthur.perais@inria.fr            if (stats.timeOfLastRead != 0) {
25413420Spau.cabre@metempsy.com                stats.ittReadRead.sample(curTick() - stats.timeOfLastRead);
25513420Spau.cabre@metempsy.com            }
25611784Sarthur.perais@inria.fr            stats.timeOfLastRead = curTick();
25711784Sarthur.perais@inria.fr
25811784Sarthur.perais@inria.fr            // Sample value of req-req inter transaction time
25911784Sarthur.perais@inria.fr            if (stats.timeOfLastReq != 0) {
26011784Sarthur.perais@inria.fr                stats.ittReqReq.sample(curTick() - stats.timeOfLastReq);
26111784Sarthur.perais@inria.fr            }
26213420Spau.cabre@metempsy.com            stats.timeOfLastReq = curTick();
26313420Spau.cabre@metempsy.com        }
26413420Spau.cabre@metempsy.com    } else if (successful && is_write) {
26513420Spau.cabre@metempsy.com        DPRINTF(CommMonitor, "Forwarded write request\n");
26613420Spau.cabre@metempsy.com
26711784Sarthur.perais@inria.fr        // Same as for reads
26811784Sarthur.perais@inria.fr        if (!stats.disableTransactionHists) {
26911784Sarthur.perais@inria.fr            ++stats.writeTrans;
27011784Sarthur.perais@inria.fr        }
27111784Sarthur.perais@inria.fr
27211784Sarthur.perais@inria.fr        if (!stats.disableBurstLengthHists) {
27311784Sarthur.perais@inria.fr            stats.writeBurstLengthHist.sample(size);
27411784Sarthur.perais@inria.fr        }
27511784Sarthur.perais@inria.fr
27611784Sarthur.perais@inria.fr        // Update the bandwidth stats on the request
27713442Spau.cabre@metempsy.com        if (!stats.disableBandwidthHists) {
27811784Sarthur.perais@inria.fr            stats.writtenBytes += size;
27911784Sarthur.perais@inria.fr            stats.totalWrittenBytes += size;
28011784Sarthur.perais@inria.fr        }
28111784Sarthur.perais@inria.fr
28213442Spau.cabre@metempsy.com        // Sample the masked write address
28313442Spau.cabre@metempsy.com        if (!stats.disableAddrDists) {
28411784Sarthur.perais@inria.fr            stats.writeAddrDist.sample(addr & writeAddrMask);
28511784Sarthur.perais@inria.fr        }
28611784Sarthur.perais@inria.fr
28711784Sarthur.perais@inria.fr        if (!stats.disableOutstandingHists && expects_response) {
28811784Sarthur.perais@inria.fr            ++stats.outstandingWriteReqs;
28911784Sarthur.perais@inria.fr        }
29011784Sarthur.perais@inria.fr
29111784Sarthur.perais@inria.fr        if (!stats.disableITTDists) {
29211784Sarthur.perais@inria.fr            // Sample value of write-to-write inter transaction time
29311784Sarthur.perais@inria.fr            if (stats.timeOfLastWrite != 0) {
29411784Sarthur.perais@inria.fr                stats.ittWriteWrite.sample(curTick() - stats.timeOfLastWrite);
29511784Sarthur.perais@inria.fr            }
29611784Sarthur.perais@inria.fr            stats.timeOfLastWrite = curTick();
29711784Sarthur.perais@inria.fr
29811784Sarthur.perais@inria.fr            // Sample value of req-to-req inter transaction time
29911784Sarthur.perais@inria.fr            if (stats.timeOfLastReq != 0) {
30011784Sarthur.perais@inria.fr                stats.ittReqReq.sample(curTick() - stats.timeOfLastReq);
30111784Sarthur.perais@inria.fr            }
30211784Sarthur.perais@inria.fr            stats.timeOfLastReq = curTick();
30311784Sarthur.perais@inria.fr        }
30413442Spau.cabre@metempsy.com    } else if (successful) {
30513442Spau.cabre@metempsy.com        DPRINTF(CommMonitor, "Forwarded non read/write request\n");
30611784Sarthur.perais@inria.fr    }
30711784Sarthur.perais@inria.fr
30811784Sarthur.perais@inria.fr    return successful;
30911784Sarthur.perais@inria.fr}
31011784Sarthur.perais@inria.fr
31111784Sarthur.perais@inria.frbool
31211784Sarthur.perais@inria.frCommMonitor::recvTimingResp(PacketPtr pkt)
31311784Sarthur.perais@inria.fr{
31411784Sarthur.perais@inria.fr    // should always see responses
31511784Sarthur.perais@inria.fr    assert(pkt->isResponse());
31611784Sarthur.perais@inria.fr
31711784Sarthur.perais@inria.fr    // Store relevant fields of packet, because packet may be modified
31811784Sarthur.perais@inria.fr    // or even deleted when sendTiming() is called.
31911784Sarthur.perais@inria.fr    bool is_read = pkt->isRead();
32011784Sarthur.perais@inria.fr    bool is_write = pkt->isWrite();
32111784Sarthur.perais@inria.fr    unsigned size = pkt->getSize();
32211784Sarthur.perais@inria.fr    Tick latency = 0;
32311784Sarthur.perais@inria.fr    CommMonitorSenderState* received_state =
32411784Sarthur.perais@inria.fr        dynamic_cast<CommMonitorSenderState*>(pkt->senderState);
32511784Sarthur.perais@inria.fr
32613442Spau.cabre@metempsy.com    if (!stats.disableLatencyHists) {
32711784Sarthur.perais@inria.fr        // Restore initial sender state
32811784Sarthur.perais@inria.fr        if (received_state == NULL)
32911784Sarthur.perais@inria.fr            panic("Monitor got a response without monitor sender state\n");
33013442Spau.cabre@metempsy.com
33113442Spau.cabre@metempsy.com        // Restore the sate
33211784Sarthur.perais@inria.fr        pkt->senderState = received_state->predecessor;
33311784Sarthur.perais@inria.fr    }
33411784Sarthur.perais@inria.fr
33511784Sarthur.perais@inria.fr    // Attempt to send the packet
33611784Sarthur.perais@inria.fr    bool successful = slavePort.sendTimingResp(pkt);
33711784Sarthur.perais@inria.fr
33811784Sarthur.perais@inria.fr    if (!stats.disableLatencyHists) {
33911784Sarthur.perais@inria.fr        // If packet successfully send, sample value of latency,
34011784Sarthur.perais@inria.fr        // afterwards delete sender state, otherwise restore state
34111784Sarthur.perais@inria.fr        if (successful) {
34211784Sarthur.perais@inria.fr            latency = curTick() - received_state->transmitTime;
34311784Sarthur.perais@inria.fr            DPRINTF(CommMonitor, "Latency: %d\n", latency);
34411784Sarthur.perais@inria.fr            delete received_state;
34511784Sarthur.perais@inria.fr        } else {
34613442Spau.cabre@metempsy.com            // Don't delete anything and let the packet look like we
34713442Spau.cabre@metempsy.com            // did not touch it
34811784Sarthur.perais@inria.fr            pkt->senderState = received_state;
34911784Sarthur.perais@inria.fr        }
35011784Sarthur.perais@inria.fr    }
35111784Sarthur.perais@inria.fr
35211784Sarthur.perais@inria.fr    if (successful && is_read) {
35311784Sarthur.perais@inria.fr        // Decrement number of outstanding read requests
35411784Sarthur.perais@inria.fr        DPRINTF(CommMonitor, "Received read response\n");
35511784Sarthur.perais@inria.fr        if (!stats.disableOutstandingHists) {
35611784Sarthur.perais@inria.fr            assert(stats.outstandingReadReqs != 0);
35711784Sarthur.perais@inria.fr            --stats.outstandingReadReqs;
35811784Sarthur.perais@inria.fr        }
35911784Sarthur.perais@inria.fr
36011784Sarthur.perais@inria.fr        if (!stats.disableLatencyHists) {
36111784Sarthur.perais@inria.fr            stats.readLatencyHist.sample(latency);
36211784Sarthur.perais@inria.fr        }
36311784Sarthur.perais@inria.fr
36411784Sarthur.perais@inria.fr        // Update the bandwidth stats based on responses for reads
36511784Sarthur.perais@inria.fr        if (!stats.disableBandwidthHists) {
36611784Sarthur.perais@inria.fr            stats.readBytes += size;
36711784Sarthur.perais@inria.fr            stats.totalReadBytes += size;
36811784Sarthur.perais@inria.fr        }
36911784Sarthur.perais@inria.fr
37011784Sarthur.perais@inria.fr    } else if (successful && is_write) {
37111784Sarthur.perais@inria.fr        // Decrement number of outstanding write requests
37211784Sarthur.perais@inria.fr        DPRINTF(CommMonitor, "Received write response\n");
37311784Sarthur.perais@inria.fr        if (!stats.disableOutstandingHists) {
37411784Sarthur.perais@inria.fr            assert(stats.outstandingWriteReqs != 0);
37511784Sarthur.perais@inria.fr            --stats.outstandingWriteReqs;
37611784Sarthur.perais@inria.fr        }
37711784Sarthur.perais@inria.fr
37811784Sarthur.perais@inria.fr        if (!stats.disableLatencyHists) {
37911784Sarthur.perais@inria.fr            stats.writeLatencyHist.sample(latency);
38011784Sarthur.perais@inria.fr        }
38111784Sarthur.perais@inria.fr    } else if (successful) {
38211784Sarthur.perais@inria.fr        DPRINTF(CommMonitor, "Received non read/write response\n");
38311784Sarthur.perais@inria.fr    }
38411784Sarthur.perais@inria.fr    return successful;
38513442Spau.cabre@metempsy.com}
38611784Sarthur.perais@inria.fr
38711784Sarthur.perais@inria.frvoid
38811784Sarthur.perais@inria.frCommMonitor::recvTimingSnoopReq(PacketPtr pkt)
38911784Sarthur.perais@inria.fr{
39011784Sarthur.perais@inria.fr    slavePort.sendTimingSnoopReq(pkt);
39111784Sarthur.perais@inria.fr}
39211784Sarthur.perais@inria.fr
39311784Sarthur.perais@inria.frbool
39411784Sarthur.perais@inria.frCommMonitor::recvTimingSnoopResp(PacketPtr pkt)
39511784Sarthur.perais@inria.fr{
39611784Sarthur.perais@inria.fr    return masterPort.sendTimingSnoopResp(pkt);
39711784Sarthur.perais@inria.fr}
39811784Sarthur.perais@inria.fr
39911784Sarthur.perais@inria.frbool
40011784Sarthur.perais@inria.frCommMonitor::isSnooping() const
40111784Sarthur.perais@inria.fr{
40211784Sarthur.perais@inria.fr    // check if the connected master port is snooping
40311784Sarthur.perais@inria.fr    return slavePort.isSnooping();
40411784Sarthur.perais@inria.fr}
40511784Sarthur.perais@inria.fr
40611784Sarthur.perais@inria.frAddrRangeList
40711784Sarthur.perais@inria.frCommMonitor::getAddrRanges() const
40811784Sarthur.perais@inria.fr{
40911784Sarthur.perais@inria.fr    // get the address ranges of the connected slave port
41011784Sarthur.perais@inria.fr    return masterPort.getAddrRanges();
41111784Sarthur.perais@inria.fr}
41211784Sarthur.perais@inria.fr
41311784Sarthur.perais@inria.frvoid
41411784Sarthur.perais@inria.frCommMonitor::recvRetryMaster()
41511784Sarthur.perais@inria.fr{
41611784Sarthur.perais@inria.fr    slavePort.sendRetry();
41711784Sarthur.perais@inria.fr}
41811784Sarthur.perais@inria.fr
41911784Sarthur.perais@inria.frvoid
42011784Sarthur.perais@inria.frCommMonitor::recvRetrySlave()
42111784Sarthur.perais@inria.fr{
42211784Sarthur.perais@inria.fr    masterPort.sendRetry();
42311784Sarthur.perais@inria.fr}
42411784Sarthur.perais@inria.fr
42511784Sarthur.perais@inria.frvoid
42611784Sarthur.perais@inria.frCommMonitor::recvRangeChange()
42711784Sarthur.perais@inria.fr{
42811784Sarthur.perais@inria.fr    slavePort.sendRangeChange();
42911784Sarthur.perais@inria.fr}
43011784Sarthur.perais@inria.fr
43111784Sarthur.perais@inria.frvoid
43211784Sarthur.perais@inria.frCommMonitor::regStats()
43311784Sarthur.perais@inria.fr{
43411784Sarthur.perais@inria.fr    // Initialise all the monitor stats
43511784Sarthur.perais@inria.fr    using namespace Stats;
43611784Sarthur.perais@inria.fr
43711784Sarthur.perais@inria.fr    stats.readBurstLengthHist
43811784Sarthur.perais@inria.fr        .init(params()->burst_length_bins)
43911784Sarthur.perais@inria.fr        .name(name() + ".readBurstLengthHist")
44011784Sarthur.perais@inria.fr        .desc("Histogram of burst lengths of transmitted packets")
44111784Sarthur.perais@inria.fr        .flags(stats.disableBurstLengthHists ? nozero : pdf);
44211784Sarthur.perais@inria.fr
44311784Sarthur.perais@inria.fr    stats.writeBurstLengthHist
44411784Sarthur.perais@inria.fr        .init(params()->burst_length_bins)
44511784Sarthur.perais@inria.fr        .name(name() + ".writeBurstLengthHist")
44611784Sarthur.perais@inria.fr        .desc("Histogram of burst lengths of transmitted packets")
44711784Sarthur.perais@inria.fr        .flags(stats.disableBurstLengthHists ? nozero : pdf);
44811784Sarthur.perais@inria.fr
44911784Sarthur.perais@inria.fr    // Stats based on received responses
45011784Sarthur.perais@inria.fr    stats.readBandwidthHist
45111784Sarthur.perais@inria.fr        .init(params()->bandwidth_bins)
45211784Sarthur.perais@inria.fr        .name(name() + ".readBandwidthHist")
45311784Sarthur.perais@inria.fr        .desc("Histogram of read bandwidth per sample period (bytes/s)")
45411784Sarthur.perais@inria.fr        .flags(stats.disableBandwidthHists ? nozero : pdf);
45511784Sarthur.perais@inria.fr
45611784Sarthur.perais@inria.fr    stats.averageReadBW
45711784Sarthur.perais@inria.fr        .name(name() + ".averageReadBandwidth")
45811784Sarthur.perais@inria.fr        .desc("Average read bandwidth (bytes/s)")
45911784Sarthur.perais@inria.fr        .flags(stats.disableBandwidthHists ? nozero : pdf);
46011784Sarthur.perais@inria.fr
46111784Sarthur.perais@inria.fr    stats.totalReadBytes
46211784Sarthur.perais@inria.fr        .name(name() + ".totalReadBytes")
46311784Sarthur.perais@inria.fr        .desc("Number of bytes read")
46411784Sarthur.perais@inria.fr        .flags(stats.disableBandwidthHists ? nozero : pdf);
46511784Sarthur.perais@inria.fr
46611784Sarthur.perais@inria.fr    stats.averageReadBW = stats.totalReadBytes / simSeconds;
46711784Sarthur.perais@inria.fr
46811784Sarthur.perais@inria.fr    // Stats based on successfully sent requests
46911784Sarthur.perais@inria.fr    stats.writeBandwidthHist
47011784Sarthur.perais@inria.fr        .init(params()->bandwidth_bins)
47111784Sarthur.perais@inria.fr        .name(name() + ".writeBandwidthHist")
47211784Sarthur.perais@inria.fr        .desc("Histogram of write bandwidth (bytes/s)")
47311784Sarthur.perais@inria.fr        .flags(stats.disableBandwidthHists ? (pdf | nozero) : pdf);
47411784Sarthur.perais@inria.fr
47511784Sarthur.perais@inria.fr    stats.averageWriteBW
47611784Sarthur.perais@inria.fr        .name(name() + ".averageWriteBandwidth")
47711784Sarthur.perais@inria.fr        .desc("Average write bandwidth (bytes/s)")
47811784Sarthur.perais@inria.fr        .flags(stats.disableBandwidthHists ? nozero : pdf);
47911784Sarthur.perais@inria.fr
48011784Sarthur.perais@inria.fr    stats.totalWrittenBytes
48111784Sarthur.perais@inria.fr        .name(name() + ".totalWrittenBytes")
48211784Sarthur.perais@inria.fr        .desc("Number of bytes written")
48311784Sarthur.perais@inria.fr        .flags(stats.disableBandwidthHists ? nozero : pdf);
48411784Sarthur.perais@inria.fr
48511784Sarthur.perais@inria.fr    stats.averageWriteBW = stats.totalWrittenBytes / simSeconds;
48611784Sarthur.perais@inria.fr
48711784Sarthur.perais@inria.fr    stats.readLatencyHist
48811784Sarthur.perais@inria.fr        .init(params()->latency_bins)
48911784Sarthur.perais@inria.fr        .name(name() + ".readLatencyHist")
49011784Sarthur.perais@inria.fr        .desc("Read request-response latency")
49111784Sarthur.perais@inria.fr        .flags(stats.disableLatencyHists ? nozero : pdf);
49211784Sarthur.perais@inria.fr
49311784Sarthur.perais@inria.fr    stats.writeLatencyHist
49411784Sarthur.perais@inria.fr        .init(params()->latency_bins)
49511784Sarthur.perais@inria.fr        .name(name() + ".writeLatencyHist")
49611784Sarthur.perais@inria.fr        .desc("Write request-response latency")
49711784Sarthur.perais@inria.fr        .flags(stats.disableLatencyHists ? nozero : pdf);
49811784Sarthur.perais@inria.fr
49911784Sarthur.perais@inria.fr    stats.ittReadRead
50011784Sarthur.perais@inria.fr        .init(1, params()->itt_max_bin, params()->itt_max_bin /
50111784Sarthur.perais@inria.fr              params()->itt_bins)
50211784Sarthur.perais@inria.fr        .name(name() + ".ittReadRead")
50311784Sarthur.perais@inria.fr        .desc("Read-to-read inter transaction time")
50411784Sarthur.perais@inria.fr        .flags(stats.disableITTDists ? nozero : pdf);
50511784Sarthur.perais@inria.fr
50611784Sarthur.perais@inria.fr    stats.ittWriteWrite
50711784Sarthur.perais@inria.fr        .init(1, params()->itt_max_bin, params()->itt_max_bin /
50811784Sarthur.perais@inria.fr              params()->itt_bins)
50911784Sarthur.perais@inria.fr        .name(name() + ".ittWriteWrite")
51011784Sarthur.perais@inria.fr        .desc("Write-to-write inter transaction time")
51111784Sarthur.perais@inria.fr        .flags(stats.disableITTDists ? nozero : pdf);
51211784Sarthur.perais@inria.fr
51311784Sarthur.perais@inria.fr    stats.ittReqReq
51411784Sarthur.perais@inria.fr        .init(1, params()->itt_max_bin, params()->itt_max_bin /
51511784Sarthur.perais@inria.fr              params()->itt_bins)
51611784Sarthur.perais@inria.fr        .name(name() + ".ittReqReq")
51711784Sarthur.perais@inria.fr        .desc("Request-to-request inter transaction time")
51811784Sarthur.perais@inria.fr        .flags(stats.disableITTDists ? nozero : pdf);
51911784Sarthur.perais@inria.fr
52011784Sarthur.perais@inria.fr    stats.outstandingReadsHist
52111784Sarthur.perais@inria.fr        .init(params()->outstanding_bins)
52211784Sarthur.perais@inria.fr        .name(name() + ".outstandingReadsHist")
52311784Sarthur.perais@inria.fr        .desc("Outstanding read transactions")
52411784Sarthur.perais@inria.fr        .flags(stats.disableOutstandingHists ? nozero : pdf);
52511784Sarthur.perais@inria.fr
52611784Sarthur.perais@inria.fr    stats.outstandingWritesHist
52711784Sarthur.perais@inria.fr        .init(params()->outstanding_bins)
52811784Sarthur.perais@inria.fr        .name(name() + ".outstandingWritesHist")
52911784Sarthur.perais@inria.fr        .desc("Outstanding write transactions")
53011784Sarthur.perais@inria.fr        .flags(stats.disableOutstandingHists ? nozero : pdf);
53111784Sarthur.perais@inria.fr
53211784Sarthur.perais@inria.fr    stats.readTransHist
53311784Sarthur.perais@inria.fr        .init(params()->transaction_bins)
53411784Sarthur.perais@inria.fr        .name(name() + ".readTransHist")
53511784Sarthur.perais@inria.fr        .desc("Histogram of read transactions per sample period")
53611784Sarthur.perais@inria.fr        .flags(stats.disableTransactionHists ? nozero : pdf);
53711784Sarthur.perais@inria.fr
53811784Sarthur.perais@inria.fr    stats.writeTransHist
53911784Sarthur.perais@inria.fr        .init(params()->transaction_bins)
54011784Sarthur.perais@inria.fr        .name(name() + ".writeTransHist")
54111784Sarthur.perais@inria.fr        .desc("Histogram of read transactions per sample period")
54211784Sarthur.perais@inria.fr        .flags(stats.disableTransactionHists ? nozero : pdf);
54311784Sarthur.perais@inria.fr
54411784Sarthur.perais@inria.fr    stats.readAddrDist
54511784Sarthur.perais@inria.fr        .init(0)
54611784Sarthur.perais@inria.fr        .name(name() + ".readAddrDist")
54711784Sarthur.perais@inria.fr        .desc("Read address distribution")
54811784Sarthur.perais@inria.fr        .flags(stats.disableAddrDists ? nozero : pdf);
54911784Sarthur.perais@inria.fr
55011784Sarthur.perais@inria.fr    stats.writeAddrDist
55111784Sarthur.perais@inria.fr        .init(0)
55211784Sarthur.perais@inria.fr        .name(name() + ".writeAddrDist")
55311784Sarthur.perais@inria.fr        .desc("Write address distribution")
55411784Sarthur.perais@inria.fr        .flags(stats.disableAddrDists ? nozero : pdf);
55511784Sarthur.perais@inria.fr}
55611784Sarthur.perais@inria.fr
55711784Sarthur.perais@inria.frvoid
55811784Sarthur.perais@inria.frCommMonitor::samplePeriodic()
55911784Sarthur.perais@inria.fr{
56011784Sarthur.perais@inria.fr    // the periodic stats update runs on the granularity of sample
56111784Sarthur.perais@inria.fr    // periods, but in combination with this there may also be a
56211784Sarthur.perais@inria.fr    // external resets and dumps of the stats (through schedStatEvent)
56311784Sarthur.perais@inria.fr    // causing the stats themselves to capture less than a sample
56411784Sarthur.perais@inria.fr    // period
56511784Sarthur.perais@inria.fr
56611784Sarthur.perais@inria.fr    // only capture if we have not reset the stats during the last
56711784Sarthur.perais@inria.fr    // sample period
56811784Sarthur.perais@inria.fr    if (simTicks.value() >= samplePeriodTicks) {
56911784Sarthur.perais@inria.fr        if (!stats.disableTransactionHists) {
57011784Sarthur.perais@inria.fr            stats.readTransHist.sample(stats.readTrans);
57111784Sarthur.perais@inria.fr            stats.writeTransHist.sample(stats.writeTrans);
57211784Sarthur.perais@inria.fr        }
57311784Sarthur.perais@inria.fr
57411784Sarthur.perais@inria.fr        if (!stats.disableBandwidthHists) {
57511784Sarthur.perais@inria.fr            stats.readBandwidthHist.sample(stats.readBytes / samplePeriod);
57611784Sarthur.perais@inria.fr            stats.writeBandwidthHist.sample(stats.writtenBytes / samplePeriod);
57711784Sarthur.perais@inria.fr        }
57811784Sarthur.perais@inria.fr
57911784Sarthur.perais@inria.fr        if (!stats.disableOutstandingHists) {
58011784Sarthur.perais@inria.fr            stats.outstandingReadsHist.sample(stats.outstandingReadReqs);
58111784Sarthur.perais@inria.fr            stats.outstandingWritesHist.sample(stats.outstandingWriteReqs);
58211784Sarthur.perais@inria.fr        }
58311784Sarthur.perais@inria.fr    }
58411784Sarthur.perais@inria.fr
58511784Sarthur.perais@inria.fr    // reset the sampled values
58611784Sarthur.perais@inria.fr    stats.readTrans = 0;
58711784Sarthur.perais@inria.fr    stats.writeTrans = 0;
58811784Sarthur.perais@inria.fr
58911784Sarthur.perais@inria.fr    stats.readBytes = 0;
59011784Sarthur.perais@inria.fr    stats.writtenBytes = 0;
59111784Sarthur.perais@inria.fr
59211784Sarthur.perais@inria.fr    schedule(samplePeriodicEvent, curTick() + samplePeriodTicks);
59311784Sarthur.perais@inria.fr}
59411784Sarthur.perais@inria.fr
59511784Sarthur.perais@inria.frvoid
59611784Sarthur.perais@inria.frCommMonitor::startup()
59711784Sarthur.perais@inria.fr{
59811784Sarthur.perais@inria.fr    schedule(samplePeriodicEvent, curTick() + samplePeriodTicks);
59911784Sarthur.perais@inria.fr}
60011784Sarthur.perais@inria.fr