#include "mem/coherent_bus.hh"
CoherentBus::CoherentBus(const CoherentBusParams *p)
- : BaseBus(p)
+ : BaseBus(p), reqLayer(*this, ".reqLayer", p->clock),
+ respLayer(*this, ".respLayer", p->clock),
+ snoopRespLayer(*this, ".snoopRespLayer", p->clock)
{
// create the ports based on the size of the master and slave
// vector ports, and the presence of the default port, the ports
// are enumerated starting from zero
for (int i = 0; i < p->port_master_connection_count; ++i) {
- std::string portName = csprintf("%s-p%d", name(), i);
+ std::string portName = csprintf("%s.master[%d]", name(), i);
MasterPort* bp = new CoherentBusMasterPort(portName, *this, i);
masterPorts.push_back(bp);
}
// our corresponding master port
if (p->port_default_connection_count) {
defaultPortID = masterPorts.size();
- std::string portName = csprintf("%s-default", name());
+ std::string portName = name() + ".default";
MasterPort* bp = new CoherentBusMasterPort(portName, *this,
defaultPortID);
masterPorts.push_back(bp);
// create the slave ports, once again starting at zero
for (int i = 0; i < p->port_slave_connection_count; ++i) {
- std::string portName = csprintf("%s-p%d", name(), i);
+ std::string portName = csprintf("%s.slave[%d]", name(), i);
SlavePort* bp = new CoherentBusSlavePort(portName, *this, i);
slavePorts.push_back(bp);
}
void
CoherentBus::init()
{
+ // the base class is responsible for determining the block size
+ BaseBus::init();
+
// iterate over our slave ports and determine which of our
// neighbouring master ports are snooping and add them as snoopers
for (SlavePortConstIter p = slavePorts.begin(); p != slavePorts.end();
// test if the bus should be considered occupied for the current
// port, and exclude express snoops from the check
- if (!is_express_snoop && !tryTiming(src_port)) {
+ if (!is_express_snoop && !reqLayer.tryTiming(src_port)) {
DPRINTF(CoherentBus, "recvTimingReq: src %s %s 0x%x BUSY\n",
src_port->name(), pkt->cmdString(), pkt->getAddr());
return false;
src_port->name(), pkt->cmdString(), pkt->getAddr());
// update the bus state and schedule an idle event
- failedTiming(src_port, headerFinishTime);
+ reqLayer.failedTiming(src_port, headerFinishTime);
} else {
// update the bus state and schedule an idle event
- succeededTiming(packetFinishTime);
+ reqLayer.succeededTiming(packetFinishTime);
}
}
// test if the bus should be considered occupied for the current
// port
- if (!tryTiming(src_port)) {
+ if (!respLayer.tryTiming(src_port)) {
DPRINTF(CoherentBus, "recvTimingResp: src %s %s 0x%x BUSY\n",
src_port->name(), pkt->cmdString(), pkt->getAddr());
return false;
// deadlock
assert(success);
- succeededTiming(packetFinishTime);
+ respLayer.succeededTiming(packetFinishTime);
return true;
}
// test if the bus should be considered occupied for the current
// port
- if (!tryTiming(src_port)) {
+ if (!snoopRespLayer.tryTiming(src_port)) {
DPRINTF(CoherentBus, "recvTimingSnoopResp: src %s %s 0x%x BUSY\n",
src_port->name(), pkt->cmdString(), pkt->getAddr());
return false;
assert(success);
}
- succeededTiming(packetFinishTime);
+ snoopRespLayer.succeededTiming(packetFinishTime);
return true;
}
}
}
+void
+CoherentBus::recvRetry()
+{
+ // responses and snoop responses never block on forwarding them,
+ // so the retry will always be coming from a port to which we
+ // tried to forward a request
+ reqLayer.recvRetry();
+}
+
Tick
CoherentBus::recvAtomic(PacketPtr pkt, PortID slave_port_id)
{
}
}
+unsigned int
+CoherentBus::drain(DrainManager *dm)
+{
+ // sum up the individual layers
+ return reqLayer.drain(dm) + respLayer.drain(dm) + snoopRespLayer.drain(dm);
+}
+
CoherentBus *
CoherentBusParams::create()
{