diff options
Diffstat (limited to 'src/mem/coherent_bus.cc')
-rw-r--r-- | src/mem/coherent_bus.cc | 74 |
1 files changed, 50 insertions, 24 deletions
diff --git a/src/mem/coherent_bus.cc b/src/mem/coherent_bus.cc index 923fa08d6..20597bc3a 100644 --- a/src/mem/coherent_bus.cc +++ b/src/mem/coherent_bus.cc @@ -55,14 +55,7 @@ #include "sim/system.hh" CoherentBus::CoherentBus(const CoherentBusParams *p) - : BaseBus(p), - reqLayer(*this, ".reqLayer", p->port_master_connection_count + - p->port_default_connection_count), - respLayer(*this, ".respLayer", p->port_slave_connection_count), - snoopRespLayer(*this, ".snoopRespLayer", - p->port_master_connection_count + - p->port_default_connection_count), - system(p->system) + : BaseBus(p), system(p->system) { // create the ports based on the size of the master and slave // vector ports, and the presence of the default port, the ports @@ -71,6 +64,10 @@ CoherentBus::CoherentBus(const CoherentBusParams *p) std::string portName = csprintf("%s.master[%d]", name(), i); MasterPort* bp = new CoherentBusMasterPort(portName, *this, i); masterPorts.push_back(bp); + reqLayers.push_back(new ReqLayer(*bp, *this, + csprintf(".reqLayer%d", i))); + snoopLayers.push_back(new SnoopLayer(*bp, *this, + csprintf(".snoopLayer%d", i))); } // see if we have a default slave device connected and if so add @@ -81,6 +78,11 @@ CoherentBus::CoherentBus(const CoherentBusParams *p) MasterPort* bp = new CoherentBusMasterPort(portName, *this, defaultPortID); masterPorts.push_back(bp); + reqLayers.push_back(new ReqLayer(*bp, *this, csprintf(".reqLayer%d", + defaultPortID))); + snoopLayers.push_back(new SnoopLayer(*bp, *this, + csprintf(".snoopLayer%d", + defaultPortID))); } // create the slave ports, once again starting at zero @@ -88,11 +90,23 @@ CoherentBus::CoherentBus(const CoherentBusParams *p) std::string portName = csprintf("%s.slave[%d]", name(), i); SlavePort* bp = new CoherentBusSlavePort(portName, *this, i); slavePorts.push_back(bp); + respLayers.push_back(new RespLayer(*bp, *this, + csprintf(".respLayer%d", i))); } clearPortCache(); } +CoherentBus::~CoherentBus() +{ + for (auto l = reqLayers.begin(); l != reqLayers.end(); ++l) + delete *l; + for (auto l = respLayers.begin(); l != respLayers.end(); ++l) + delete *l; + for (auto l = snoopLayers.begin(); l != snoopLayers.end(); ++l) + delete *l; +} + void CoherentBus::init() { @@ -129,7 +143,7 @@ CoherentBus::recvTimingReq(PacketPtr pkt, PortID slave_port_id) // test if the bus should be considered occupied for the current // port, and exclude express snoops from the check - if (!is_express_snoop && !reqLayer.tryTiming(src_port, master_port_id)) { + if (!is_express_snoop && !reqLayers[master_port_id]->tryTiming(src_port)) { DPRINTF(CoherentBus, "recvTimingReq: src %s %s 0x%x BUS BUSY\n", src_port->name(), pkt->cmdString(), pkt->getAddr()); return false; @@ -198,11 +212,11 @@ CoherentBus::recvTimingReq(PacketPtr pkt, PortID slave_port_id) src_port->name(), pkt->cmdString(), pkt->getAddr()); // update the bus state and schedule an idle event - reqLayer.failedTiming(src_port, master_port_id, - clockEdge(headerCycles)); + reqLayers[master_port_id]->failedTiming(src_port, + clockEdge(headerCycles)); } else { // update the bus state and schedule an idle event - reqLayer.succeededTiming(packetFinishTime); + reqLayers[master_port_id]->succeededTiming(packetFinishTime); dataThroughBus += pkt_size; } } @@ -228,7 +242,7 @@ CoherentBus::recvTimingResp(PacketPtr pkt, PortID master_port_id) // test if the bus should be considered occupied for the current // port - if (!respLayer.tryTiming(src_port, slave_port_id)) { + if (!respLayers[slave_port_id]->tryTiming(src_port)) { DPRINTF(CoherentBus, "recvTimingResp: src %s %s 0x%x BUSY\n", src_port->name(), pkt->cmdString(), pkt->getAddr()); return false; @@ -259,7 +273,7 @@ CoherentBus::recvTimingResp(PacketPtr pkt, PortID master_port_id) // deadlock assert(success); - respLayer.succeededTiming(packetFinishTime); + respLayers[slave_port_id]->succeededTiming(packetFinishTime); // stats updates dataThroughBus += pkt_size; @@ -318,10 +332,12 @@ CoherentBus::recvTimingSnoopResp(PacketPtr pkt, PortID slave_port_id) // port, note that the check is bypassed if the response is being // passed on as a normal response since this is occupying the // response layer rather than the snoop response layer - if (forwardAsSnoop && !snoopRespLayer.tryTiming(src_port, dest_port_id)) { - DPRINTF(CoherentBus, "recvTimingSnoopResp: src %s %s 0x%x BUSY\n", - src_port->name(), pkt->cmdString(), pkt->getAddr()); - return false; + if (forwardAsSnoop) { + if (!snoopLayers[dest_port_id]->tryTiming(src_port)) { + DPRINTF(CoherentBus, "recvTimingSnoopResp: src %s %s 0x%x BUSY\n", + src_port->name(), pkt->cmdString(), pkt->getAddr()); + return false; + } } DPRINTF(CoherentBus, "recvTimingSnoopResp: src %s %s 0x%x\n", @@ -349,7 +365,7 @@ CoherentBus::recvTimingSnoopResp(PacketPtr pkt, PortID slave_port_id) totPktSize[slave_port_id][dest_port_id] += pkt_size; assert(success); - snoopRespLayer.succeededTiming(packetFinishTime); + snoopLayers[dest_port_id]->succeededTiming(packetFinishTime); } else { // we got a snoop response on one of our slave ports, // i.e. from a coherent master connected to the bus, and @@ -416,7 +432,7 @@ CoherentBus::recvRetry(PortID master_port_id) // 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(master_port_id); + reqLayers[master_port_id]->recvRetry(); } Tick @@ -606,7 +622,14 @@ unsigned int CoherentBus::drain(DrainManager *dm) { // sum up the individual layers - return reqLayer.drain(dm) + respLayer.drain(dm) + snoopRespLayer.drain(dm); + unsigned int total = 0; + for (auto l = reqLayers.begin(); l != reqLayers.end(); ++l) + total += (*l)->drain(dm); + for (auto l = respLayers.begin(); l != respLayers.end(); ++l) + total += (*l)->drain(dm); + for (auto l = snoopLayers.begin(); l != snoopLayers.end(); ++l) + total += (*l)->drain(dm); + return total; } void @@ -614,9 +637,12 @@ CoherentBus::regStats() { // register the stats of the base class and our three bus layers BaseBus::regStats(); - reqLayer.regStats(); - respLayer.regStats(); - snoopRespLayer.regStats(); + for (auto l = reqLayers.begin(); l != reqLayers.end(); ++l) + (*l)->regStats(); + for (auto l = respLayers.begin(); l != respLayers.end(); ++l) + (*l)->regStats(); + for (auto l = snoopLayers.begin(); l != snoopLayers.end(); ++l) + (*l)->regStats(); dataThroughBus .name(name() + ".data_through_bus") |