/*
- * Copyright (c) 2012-2013 ARM Limited
+ * Copyright (c) 2012-2013, 2015 ARM Limited
* All rights reserved
*
* The license below extends only to copyright in the software and shall
* Andreas Hansson
*/
-#include "base/callback.hh"
-#include "base/output.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)
slavePort(name() + "-slave", *this),
samplePeriodicEvent(this),
samplePeriodTicks(params->sample_period),
+ samplePeriod(params->sample_period / SimClock::Float::s),
readAddrMask(params->read_addr_mask),
writeAddrMask(params->write_addr_mask),
- stats(params),
- traceStream(NULL)
+ stats(params)
{
- // If we are using a trace file, then open the file,
- if (params->trace_file != "") {
- // If the trace file is not specified as an absolute path,
- // append the current simulation output directory
- std::string filename = simout.resolve(params->trace_file);
- traceStream = new ProtoOutputStream(filename);
-
- // Create a protobuf message for the header and write it to
- // the stream
- Message::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 s)\n",
- name(), samplePeriodTicks, samplePeriod);
-}
-
-void
-CommMonitor::closeStreams()
-{
- if (traceStream != NULL)
- delete traceStream;
+ "Created monitor %s with sample period %d ticks (%f ms)\n",
+ name(), samplePeriodTicks, samplePeriod * 1E3);
}
CommMonitor*
fatal("Communication monitor is not connected on both sides.\n");
}
+void
+CommMonitor::regProbePoints()
+{
+ ppPktReq.reset(new ProbePoints::Packet(getProbeManager(), "PktRequest"));
+ ppPktResp.reset(new ProbePoints::Packet(getProbeManager(), "PktResponse"));
+}
+
BaseMasterPort&
CommMonitor::getMasterPort(const std::string& if_name, PortID idx)
{
Tick
CommMonitor::recvAtomic(PacketPtr pkt)
{
- return masterPort.sendAtomic(pkt);
+ ppPktReq->notify(pkt);
+
+ const Tick delay(masterPort.sendAtomic(pkt));
+ assert(pkt->isResponse());
+ ppPktResp->notify(pkt);
+ return delay;
}
Tick
// 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 bool is_read = pkt->isRead();
+ const bool is_write = pkt->isWrite();
+ const MemCmd cmd = pkt->cmd;
+ const unsigned size = pkt->getSize();
+ const Addr addr = pkt->getAddr();
+ const bool expects_response(
+ pkt->needsResponse() && !pkt->memInhibitAsserted());
// 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
delete pkt->popSenderState();
}
- if (successful && traceStream != NULL) {
- // Create a protobuf message representing the
- // packet. Currently we do not preserve the flags in the
- // trace.
- Message::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) {
+ // The receiver might already have modified the packet. We
+ // want to give the probe access to the original packet, which
+ // means we need to fake the original packet by temporarily
+ // restoring the command.
+ const MemCmd response_cmd(pkt->cmd);
+ pkt->cmd = cmd;
+ ppPktReq->notify(pkt);
+ pkt->cmd = response_cmd;
}
if (successful && is_read) {
}
}
+ if (successful) {
+ assert(pkt->isResponse());
+ ppPktResp->notify(pkt);
+ }
+
if (successful && is_read) {
// Decrement number of outstanding read requests
DPRINTF(CommMonitor, "Received read response\n");
}
void
-CommMonitor::recvRetryMaster()
+CommMonitor::recvReqRetry()
{
- slavePort.sendRetry();
+ slavePort.sendRetryReq();
}
void
-CommMonitor::recvRetrySlave()
+CommMonitor::recvRespRetry()
{
- masterPort.sendRetry();
+ masterPort.sendRetryResp();
}
void