diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/arch/x86/pagetable_walker.cc | 2 | ||||
-rw-r--r-- | src/cpu/BaseCPU.py | 8 | ||||
-rw-r--r-- | src/dev/io_device.cc | 6 | ||||
-rw-r--r-- | src/dev/pcidev.cc | 2 | ||||
-rw-r--r-- | src/dev/x86/intdev.hh | 2 | ||||
-rw-r--r-- | src/mem/SConscript | 24 | ||||
-rw-r--r-- | src/mem/XBar.py (renamed from src/mem/Bus.py) | 28 | ||||
-rw-r--r-- | src/mem/bridge.cc | 12 | ||||
-rw-r--r-- | src/mem/bridge.hh | 12 | ||||
-rw-r--r-- | src/mem/cache/cache_impl.hh | 30 | ||||
-rw-r--r-- | src/mem/coherent_xbar.cc (renamed from src/mem/coherent_bus.cc) | 281 | ||||
-rw-r--r-- | src/mem/coherent_xbar.hh (renamed from src/mem/coherent_bus.hh) | 150 | ||||
-rw-r--r-- | src/mem/dram_ctrl.cc | 2 | ||||
-rw-r--r-- | src/mem/dramsim2.cc | 2 | ||||
-rw-r--r-- | src/mem/noncoherent_xbar.cc (renamed from src/mem/noncoherent_bus.cc) | 142 | ||||
-rw-r--r-- | src/mem/noncoherent_xbar.hh (renamed from src/mem/noncoherent_bus.hh) | 116 | ||||
-rw-r--r-- | src/mem/packet.hh | 57 | ||||
-rw-r--r-- | src/mem/physical.cc | 8 | ||||
-rw-r--r-- | src/mem/simple_mem.cc | 2 | ||||
-rw-r--r-- | src/mem/xbar.cc (renamed from src/mem/bus.cc) | 218 | ||||
-rw-r--r-- | src/mem/xbar.hh (renamed from src/mem/bus.hh) | 147 | ||||
-rw-r--r-- | src/python/m5/params.py | 2 | ||||
-rw-r--r-- | src/python/m5/util/dot_writer.py | 8 |
23 files changed, 607 insertions, 654 deletions
diff --git a/src/arch/x86/pagetable_walker.cc b/src/arch/x86/pagetable_walker.cc index 3d8cc9292..db3b4b933 100644 --- a/src/arch/x86/pagetable_walker.cc +++ b/src/arch/x86/pagetable_walker.cc @@ -597,7 +597,7 @@ Walker::WalkerState::recvPacket(PacketPtr pkt) assert(!read); // @todo someone should pay for this - pkt->busFirstWordDelay = pkt->busLastWordDelay = 0; + pkt->firstWordDelay = pkt->lastWordDelay = 0; state = nextState; nextState = Ready; diff --git a/src/cpu/BaseCPU.py b/src/cpu/BaseCPU.py index b7f0b2089..8ba90209a 100644 --- a/src/cpu/BaseCPU.py +++ b/src/cpu/BaseCPU.py @@ -47,7 +47,7 @@ from m5.defines import buildEnv from m5.params import * from m5.proxy import * -from Bus import CoherentBus +from XBar import CoherentXBar from InstTracer import InstTracer from ExeTracer import ExeTracer from MemObject import MemObject @@ -274,8 +274,8 @@ class BaseCPU(MemObject): self.itb_walker_cache = iwc self.dtb_walker_cache = dwc if buildEnv['TARGET_ISA'] in ['arm']: - self.itb_walker_cache_bus = CoherentBus() - self.dtb_walker_cache_bus = CoherentBus() + self.itb_walker_cache_bus = CoherentXBar() + self.dtb_walker_cache_bus = CoherentXBar() self.itb_walker_cache_bus.master = iwc.cpu_side self.dtb_walker_cache_bus.master = dwc.cpu_side self.itb.walker.port = self.itb_walker_cache_bus.slave @@ -308,7 +308,7 @@ class BaseCPU(MemObject): # Set a width of 32 bytes (256-bits), which is four times that # of the default bus. The clock of the CPU is inherited by # default. - self.toL2Bus = CoherentBus(width = 32) + self.toL2Bus = CoherentXBar(width = 32) self.connectCachedPorts(self.toL2Bus) self.l2cache = l2c self.toL2Bus.master = self.l2cache.cpu_side diff --git a/src/dev/io_device.cc b/src/dev/io_device.cc index 0c927651d..b118294f7 100644 --- a/src/dev/io_device.cc +++ b/src/dev/io_device.cc @@ -42,7 +42,7 @@ */ #include "base/trace.hh" -#include "debug/BusAddrRanges.hh" +#include "debug/AddrRanges.hh" #include "dev/io_device.hh" #include "sim/system.hh" @@ -55,7 +55,7 @@ Tick PioPort::recvAtomic(PacketPtr pkt) { // @todo: We need to pay for this and not just zero it out - pkt->busFirstWordDelay = pkt->busLastWordDelay = 0; + pkt->firstWordDelay = pkt->lastWordDelay = 0; return pkt->isRead() ? device->read(pkt) : device->write(pkt); } @@ -113,7 +113,7 @@ BasicPioDevice::getAddrRanges() const { assert(pioSize != 0); AddrRangeList ranges; - DPRINTF(BusAddrRanges, "registering range: %#x-%#x\n", pioAddr, pioSize); + DPRINTF(AddrRanges, "registering range: %#x-%#x\n", pioAddr, pioSize); ranges.push_back(RangeSize(pioAddr, pioSize)); return ranges; } diff --git a/src/dev/pcidev.cc b/src/dev/pcidev.cc index adc12bb55..b27547519 100644 --- a/src/dev/pcidev.cc +++ b/src/dev/pcidev.cc @@ -80,7 +80,7 @@ PciDevice::PciConfigPort::recvAtomic(PacketPtr pkt) assert(pkt->getAddr() >= configAddr && pkt->getAddr() < configAddr + PCI_CONFIG_SIZE); // @todo someone should pay for this - pkt->busFirstWordDelay = pkt->busLastWordDelay = 0; + pkt->firstWordDelay = pkt->lastWordDelay = 0; return pkt->isRead() ? device->readConfig(pkt) : device->writeConfig(pkt); } diff --git a/src/dev/x86/intdev.hh b/src/dev/x86/intdev.hh index 078ea2b6f..294a2b887 100644 --- a/src/dev/x86/intdev.hh +++ b/src/dev/x86/intdev.hh @@ -82,7 +82,7 @@ class IntDevice Tick recvMessage(PacketPtr pkt) { // @todo someone should pay for this - pkt->busFirstWordDelay = pkt->busLastWordDelay = 0; + pkt->firstWordDelay = pkt->lastWordDelay = 0; return device->recvMessage(pkt); } }; diff --git a/src/mem/SConscript b/src/mem/SConscript index c351661b8..35f2e9ce4 100644 --- a/src/mem/SConscript +++ b/src/mem/SConscript @@ -39,28 +39,28 @@ if env['HAVE_PROTOBUF']: SimObject('AbstractMemory.py') SimObject('AddrMapper.py') SimObject('Bridge.py') -SimObject('Bus.py') SimObject('DRAMCtrl.py') SimObject('MemObject.py') SimObject('SimpleMemory.py') +SimObject('XBar.py') Source('abstract_mem.cc') Source('addr_mapper.cc') Source('bridge.cc') -Source('bus.cc') -Source('coherent_bus.cc') +Source('coherent_xbar.cc') Source('dram_ctrl.cc') Source('mem_object.cc') Source('mport.cc') -Source('noncoherent_bus.cc') +Source('noncoherent_xbar.cc') Source('packet.cc') Source('port.cc') Source('packet_queue.cc') -Source('tport.cc') Source('port_proxy.cc') -Source('simple_mem.cc') Source('physical.cc') +Source('simple_mem.cc') Source('snoop_filter.cc') +Source('tport.cc') +Source('xbar.cc') if env['TARGET_ISA'] != 'null': Source('fs_translating_port_proxy.cc') @@ -74,13 +74,13 @@ if env['HAVE_DRAMSIM']: Source('dramsim2_wrapper.cc') Source('dramsim2.cc') -DebugFlag('BaseBus') -DebugFlag('BusAddrRanges') -DebugFlag('CoherentBus') -DebugFlag('NoncoherentBus') +DebugFlag('AddrRanges') +DebugFlag('BaseXBar') +DebugFlag('CoherentXBar') +DebugFlag('NoncoherentXBar') DebugFlag('SnoopFilter') -CompoundFlag('Bus', ['BaseBus', 'BusAddrRanges', 'CoherentBus', - 'NoncoherentBus', 'SnoopFilter']) +CompoundFlag('XBar', ['BaseXBar', 'CoherentXBar', 'NoncoherentXBar', + 'SnoopFilter']) DebugFlag('Bridge') DebugFlag('CommMonitor') diff --git a/src/mem/Bus.py b/src/mem/XBar.py index 06fff93b5..2aeefe132 100644 --- a/src/mem/Bus.py +++ b/src/mem/XBar.py @@ -45,14 +45,14 @@ from m5.params import * from m5.proxy import * from m5.SimObject import SimObject -class BaseBus(MemObject): - type = 'BaseBus' +class BaseXBar(MemObject): + type = 'BaseXBar' abstract = True - cxx_header = "mem/bus.hh" + cxx_header = "mem/xbar.hh" slave = VectorSlavePort("vector port for connecting masters") master = VectorMasterPort("vector port for connecting slaves") header_cycles = Param.Cycles(1, "cycles of overhead per transaction") - width = Param.Unsigned(8, "bus width (bytes)") + width = Param.Unsigned(8, "xbar width (bytes)") # The default port can be left unconnected, or be used to connect # a default slave port @@ -62,24 +62,24 @@ class BaseBus(MemObject): # address range, in which case it may overlap with other # ports. The default range is always checked first, thus creating # a two-level hierarchical lookup. This is useful e.g. for the PCI - # bus configuration. + # xbar configuration. use_default_range = Param.Bool(False, "Perform address mapping for " \ "the default port") -class NoncoherentBus(BaseBus): - type = 'NoncoherentBus' - cxx_header = "mem/noncoherent_bus.hh" +class NoncoherentXBar(BaseXBar): + type = 'NoncoherentXBar' + cxx_header = "mem/noncoherent_xbar.hh" -class CoherentBus(BaseBus): - type = 'CoherentBus' - cxx_header = "mem/coherent_bus.hh" +class CoherentXBar(BaseXBar): + type = 'CoherentXBar' + cxx_header = "mem/coherent_xbar.hh" - system = Param.System(Parent.any, "System that the bus belongs to.") - snoop_filter = Param.SnoopFilter(NULL, "Selected snoop filter for the bus.") + system = Param.System(Parent.any, "System that the crossbar belongs to.") + snoop_filter = Param.SnoopFilter(NULL, "Selected snoop filter.") class SnoopFilter(SimObject): type = 'SnoopFilter' cxx_header = "mem/snoop_filter.hh" lookup_latency = Param.Cycles(3, "lookup latency (cycles)") - system = Param.System(Parent.any, "System that the bus belongs to.") + system = Param.System(Parent.any, "System that the crossbar belongs to.") diff --git a/src/mem/bridge.cc b/src/mem/bridge.cc index 3b101ceab..085c97b53 100644 --- a/src/mem/bridge.cc +++ b/src/mem/bridge.cc @@ -44,7 +44,7 @@ /** * @file - * Implementation of a memory-mapped bus bridge that connects a master + * Implementation of a memory-mapped bridge that connects a master * and a slave through a request and response queue. */ @@ -108,7 +108,7 @@ Bridge::init() { // make sure both sides are connected and have the same block size if (!slavePort.isConnected() || !masterPort.isConnected()) - fatal("Both ports of bus bridge are not connected to a bus.\n"); + fatal("Both ports of a bridge must be connected.\n"); // notify the master side of our address ranges slavePort.sendRangeChange(); @@ -137,7 +137,7 @@ Bridge::BridgeMasterPort::recvTimingResp(PacketPtr pkt) DPRINTF(Bridge, "Request queue size: %d\n", transmitList.size()); // @todo: We need to pay for this and not just zero it out - pkt->busFirstWordDelay = pkt->busLastWordDelay = 0; + pkt->firstWordDelay = pkt->lastWordDelay = 0; slavePort.schedTimingResp(pkt, bridge.clockEdge(delay)); @@ -181,7 +181,7 @@ Bridge::BridgeSlavePort::recvTimingReq(PacketPtr pkt) if (!retryReq) { // @todo: We need to pay for this and not just zero it out - pkt->busFirstWordDelay = pkt->busLastWordDelay = 0; + pkt->firstWordDelay = pkt->lastWordDelay = 0; masterPort.schedTimingReq(pkt, bridge.clockEdge(delay)); } @@ -209,7 +209,7 @@ Bridge::BridgeMasterPort::schedTimingReq(PacketPtr pkt, Tick when) { // If we expect to see a response, we need to restore the source // and destination field that is potentially changed by a second - // bus + // crossbar if (!pkt->memInhibitAsserted() && pkt->needsResponse()) { // Update the sender state so we can deal with the response // appropriately @@ -242,7 +242,7 @@ Bridge::BridgeSlavePort::schedTimingResp(PacketPtr pkt, Tick when) pkt->setDest(req_state->origSrc); delete req_state; - // the bridge assumes that at least one bus has set the + // the bridge assumes that at least one crossbar has set the // destination field of the packet assert(pkt->isDestValid()); DPRINTF(Bridge, "response, new dest %d\n", pkt->getDest()); diff --git a/src/mem/bridge.hh b/src/mem/bridge.hh index e672c1f7a..a79d67484 100644 --- a/src/mem/bridge.hh +++ b/src/mem/bridge.hh @@ -44,7 +44,7 @@ /** * @file - * Declaration of a memory-mapped bus bridge that connects a master + * Declaration of a memory-mapped bridge that connects a master * and a slave through a request and response queue. */ @@ -58,7 +58,7 @@ #include "params/Bridge.hh" /** - * A bridge is used to interface two different busses (or in general a + * A bridge is used to interface two different crossbars (or in general a * memory-mapped master and slave), with buffering for requests and * responses. The bridge has a fixed delay for packets passing through * it and responds to a fixed set of address ranges. @@ -125,8 +125,7 @@ class Bridge : public MemObject Bridge& bridge; /** - * Master port on the other side of the bridge (connected to - * the other bus). + * Master port on the other side of the bridge. */ BridgeMasterPort& masterPort; @@ -241,8 +240,7 @@ class Bridge : public MemObject Bridge& bridge; /** - * The slave port on the other side of the bridge (connected - * to the other bus). + * The slave port on the other side of the bridge. */ BridgeSlavePort& slavePort; @@ -343,4 +341,4 @@ class Bridge : public MemObject Bridge(Params *p); }; -#endif //__MEM_BUS_HH__ +#endif //__MEM_BRIDGE_HH__ diff --git a/src/mem/cache/cache_impl.hh b/src/mem/cache/cache_impl.hh index 8c091fa39..e4a6f3c24 100644 --- a/src/mem/cache/cache_impl.hh +++ b/src/mem/cache/cache_impl.hh @@ -423,7 +423,7 @@ Cache<TagStore>::recvTimingSnoopResp(PacketPtr pkt) pkt->setDest(rec->prevSrc); delete rec; // @todo someone should pay for this - pkt->busFirstWordDelay = pkt->busLastWordDelay = 0; + pkt->firstWordDelay = pkt->lastWordDelay = 0; memSidePort->schedTimingSnoopResp(pkt, time); } @@ -482,7 +482,7 @@ Cache<TagStore>::recvTimingReq(PacketPtr pkt) Packet *snoopPkt = new Packet(pkt, true); // clear flags // also reset the bus time that the original packet has // not yet paid for - snoopPkt->busFirstWordDelay = snoopPkt->busLastWordDelay = 0; + snoopPkt->firstWordDelay = snoopPkt->lastWordDelay = 0; snoopPkt->setExpressSnoop(); snoopPkt->assertMemInhibit(); bool M5_VAR_USED success = memSidePort->sendTimingReq(snoopPkt); @@ -505,7 +505,7 @@ Cache<TagStore>::recvTimingReq(PacketPtr pkt) uncacheableFlush(pkt); // @todo: someone should pay for this - pkt->busFirstWordDelay = pkt->busLastWordDelay = 0; + pkt->firstWordDelay = pkt->lastWordDelay = 0; // writes go in write buffer, reads use MSHR, // prefetches are acknowledged (responded to) and dropped @@ -562,7 +562,7 @@ Cache<TagStore>::recvTimingReq(PacketPtr pkt) if (needsResponse) { pkt->makeTimingResponse(); // @todo: Make someone pay for this - pkt->busFirstWordDelay = pkt->busLastWordDelay = 0; + pkt->firstWordDelay = pkt->lastWordDelay = 0; cpuSidePort->schedTimingResp(pkt, clockEdge(lat)); } else { /// @todo nominally we should just delete the packet here, @@ -574,7 +574,7 @@ Cache<TagStore>::recvTimingReq(PacketPtr pkt) // miss // @todo: Make someone pay for this - pkt->busFirstWordDelay = pkt->busLastWordDelay = 0; + pkt->firstWordDelay = pkt->lastWordDelay = 0; if (blk && blk->isValid() && (blk->status & BlkCanGoExclusive) && pkt->isWrite() && (pkt->cmd != MemCmd::WriteInvalidateReq)) { @@ -1115,8 +1115,8 @@ Cache<TagStore>::recvTimingResp(PacketPtr pkt) // from lower level caches/memory to an upper level cache or // the core. completion_time = clockEdge(responseLatency) + - (transfer_offset ? pkt->busLastWordDelay : - pkt->busFirstWordDelay); + (transfer_offset ? pkt->lastWordDelay : + pkt->firstWordDelay); assert(!target->pkt->req->isUncacheable()); @@ -1132,7 +1132,7 @@ Cache<TagStore>::recvTimingResp(PacketPtr pkt) // from lower level caches/memory to an upper level cache or // the core. completion_time = clockEdge(responseLatency) + - pkt->busLastWordDelay; + pkt->lastWordDelay; target->pkt->req->setExtraData(0); } else if (pkt->cmd == MemCmd::WriteInvalidateResp) { if (blk) { @@ -1165,13 +1165,13 @@ Cache<TagStore>::recvTimingResp(PacketPtr pkt) // will occur for its impatience (since it will think it // has dirty data), but it really can't be helped. completion_time = clockEdge(responseLatency) + - pkt->busLastWordDelay; + pkt->lastWordDelay; } else { // not a cache fill, just forwarding response // responseLatency is the latency of the return path // from lower level cahces/memory to the core. completion_time = clockEdge(responseLatency) + - pkt->busLastWordDelay; + pkt->lastWordDelay; if (pkt->isRead() && !is_error) { target->pkt->setData(pkt->getPtr<uint8_t>()); } @@ -1191,7 +1191,7 @@ Cache<TagStore>::recvTimingResp(PacketPtr pkt) target->pkt->getAddr()); } // reset the bus additional time as it is now accounted for - target->pkt->busFirstWordDelay = target->pkt->busLastWordDelay = 0; + target->pkt->firstWordDelay = target->pkt->lastWordDelay = 0; cpuSidePort->schedTimingResp(target->pkt, completion_time); break; @@ -1239,7 +1239,7 @@ Cache<TagStore>::recvTimingResp(PacketPtr pkt) mq = mshr->queue; mq->markPending(mshr); requestMemSideBus((RequestCause)mq->index, clockEdge() + - pkt->busLastWordDelay); + pkt->lastWordDelay); } else { mq->deallocate(mshr); if (wasFull && !mq->isFull()) { @@ -1495,7 +1495,7 @@ Cache<TagStore>::handleFill(PacketPtr pkt, BlkType *blk, } blk->whenReady = clockEdge() + responseLatency * clockPeriod() + - pkt->busLastWordDelay; + pkt->lastWordDelay; return blk; } @@ -1522,7 +1522,7 @@ doTimingSupplyResponse(PacketPtr req_pkt, uint8_t *blk_data, pkt->allocate(); pkt->makeTimingResponse(); // @todo Make someone pay for this - pkt->busFirstWordDelay = pkt->busLastWordDelay = 0; + pkt->firstWordDelay = pkt->lastWordDelay = 0; if (pkt->isRead()) { pkt->setDataFromBlock(blk_data, blkSize); } @@ -1572,7 +1572,7 @@ Cache<TagStore>::handleSnoop(PacketPtr pkt, BlkType *blk, snoopPkt.pushSenderState(new ForwardResponseRecord(pkt->getSrc())); // the snoop packet does not need to wait any additional // time - snoopPkt.busFirstWordDelay = snoopPkt.busLastWordDelay = 0; + snoopPkt.firstWordDelay = snoopPkt.lastWordDelay = 0; cpuSidePort->sendTimingSnoopReq(&snoopPkt); if (snoopPkt.memInhibitAsserted()) { // cache-to-cache response from some upper cache diff --git a/src/mem/coherent_bus.cc b/src/mem/coherent_xbar.cc index 9529e9e7d..ce5116de9 100644 --- a/src/mem/coherent_bus.cc +++ b/src/mem/coherent_xbar.cc @@ -1,5 +1,5 @@ /* - * Copyright (c) 2011-2013 ARM Limited + * Copyright (c) 2011-2014 ARM Limited * All rights reserved * * The license below extends only to copyright in the software and shall @@ -44,25 +44,25 @@ /** * @file - * Definition of a bus object. + * Definition of a crossbar object. */ #include "base/misc.hh" #include "base/trace.hh" -#include "debug/BusAddrRanges.hh" -#include "debug/CoherentBus.hh" -#include "mem/coherent_bus.hh" +#include "debug/AddrRanges.hh" +#include "debug/CoherentXBar.hh" +#include "mem/coherent_xbar.hh" #include "sim/system.hh" -CoherentBus::CoherentBus(const CoherentBusParams *p) - : BaseBus(p), system(p->system), snoopFilter(p->snoop_filter) +CoherentXBar::CoherentXBar(const CoherentXBarParams *p) + : BaseXBar(p), system(p->system), snoopFilter(p->snoop_filter) { // 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.master[%d]", name(), i); - MasterPort* bp = new CoherentBusMasterPort(portName, *this, i); + MasterPort* bp = new CoherentXBarMasterPort(portName, *this, i); masterPorts.push_back(bp); reqLayers.push_back(new ReqLayer(*bp, *this, csprintf(".reqLayer%d", i))); @@ -75,7 +75,7 @@ CoherentBus::CoherentBus(const CoherentBusParams *p) if (p->port_default_connection_count) { defaultPortID = masterPorts.size(); std::string portName = name() + ".default"; - MasterPort* bp = new CoherentBusMasterPort(portName, *this, + MasterPort* bp = new CoherentXBarMasterPort(portName, *this, defaultPortID); masterPorts.push_back(bp); reqLayers.push_back(new ReqLayer(*bp, *this, csprintf(".reqLayer%d", @@ -88,7 +88,7 @@ CoherentBus::CoherentBus(const CoherentBusParams *p) // 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.slave[%d]", name(), i); - SlavePort* bp = new CoherentBusSlavePort(portName, *this, i); + SlavePort* bp = new CoherentXBarSlavePort(portName, *this, i); slavePorts.push_back(bp); respLayers.push_back(new RespLayer(*bp, *this, csprintf(".respLayer%d", i))); @@ -101,42 +101,41 @@ CoherentBus::CoherentBus(const CoherentBusParams *p) clearPortCache(); } -CoherentBus::~CoherentBus() +CoherentXBar::~CoherentXBar() { - 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; - for (auto p = snoopRespPorts.begin(); p != snoopRespPorts.end(); ++p) - delete *p; + for (auto l: reqLayers) + delete l; + for (auto l: respLayers) + delete l; + for (auto l: snoopLayers) + delete l; + for (auto p: snoopRespPorts) + delete p; } void -CoherentBus::init() +CoherentXBar::init() { // the base class is responsible for determining the block size - BaseBus::init(); + BaseXBar::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(); - ++p) { + for (const auto& p: slavePorts) { // check if the connected master port is snooping - if ((*p)->isSnooping()) { - DPRINTF(BusAddrRanges, "Adding snooping master %s\n", - (*p)->getMasterPort().name()); - snoopPorts.push_back(*p); + if (p->isSnooping()) { + DPRINTF(AddrRanges, "Adding snooping master %s\n", + p->getMasterPort().name()); + snoopPorts.push_back(p); } } if (snoopPorts.empty()) - warn("CoherentBus %s has no snooping ports attached!\n", name()); + warn("CoherentXBar %s has no snooping ports attached!\n", name()); } bool -CoherentBus::recvTimingReq(PacketPtr pkt, PortID slave_port_id) +CoherentXBar::recvTimingReq(PacketPtr pkt, PortID slave_port_id) { // determine the source port based on the id SlavePort *src_port = slavePorts[slave_port_id]; @@ -147,15 +146,15 @@ CoherentBus::recvTimingReq(PacketPtr pkt, PortID slave_port_id) // determine the destination based on the address PortID master_port_id = findPort(pkt->getAddr()); - // test if the bus should be considered occupied for the current + // test if the crossbar should be considered occupied for the current // port, and exclude express snoops from the check if (!is_express_snoop && !reqLayers[master_port_id]->tryTiming(src_port)) { - DPRINTF(CoherentBus, "recvTimingReq: src %s %s 0x%x BUS BUSY\n", + DPRINTF(CoherentXBar, "recvTimingReq: src %s %s 0x%x BUSY\n", src_port->name(), pkt->cmdString(), pkt->getAddr()); return false; } - DPRINTF(CoherentBus, "recvTimingReq: src %s %s expr %d 0x%x\n", + DPRINTF(CoherentXBar, "recvTimingReq: src %s %s expr %d 0x%x\n", src_port->name(), pkt->cmdString(), is_express_snoop, pkt->getAddr()); @@ -168,7 +167,7 @@ CoherentBus::recvTimingReq(PacketPtr pkt, PortID slave_port_id) pkt->setSrc(slave_port_id); calcPacketTiming(pkt); - Tick packetFinishTime = pkt->busLastWordDelay + curTick(); + Tick packetFinishTime = pkt->lastWordDelay + curTick(); // uncacheable requests need never be snooped if (!pkt->req->isUncacheable() && !system->bypassCaches()) { @@ -178,7 +177,7 @@ CoherentBus::recvTimingReq(PacketPtr pkt, PortID slave_port_id) // check with the snoop filter where to forward this packet auto sf_res = snoopFilter->lookupRequest(pkt, *src_port); packetFinishTime += sf_res.second * clockPeriod(); - DPRINTF(CoherentBus, "recvTimingReq: src %s %s 0x%x"\ + DPRINTF(CoherentXBar, "recvTimingReq: src %s %s 0x%x"\ " SF size: %i lat: %i\n", src_port->name(), pkt->cmdString(), pkt->getAddr(), sf_res.first.size(), sf_res.second); @@ -228,8 +227,7 @@ CoherentBus::recvTimingReq(PacketPtr pkt, PortID slave_port_id) // if this is an express snoop, we are done at this point if (is_express_snoop) { assert(success); - snoopDataThroughBus += pkt_size; - snoopsThroughBus++; + snoops++; } else { // for normal requests, check if successful if (!success) { @@ -242,25 +240,24 @@ CoherentBus::recvTimingReq(PacketPtr pkt, PortID slave_port_id) outstandingReq.erase(pkt->req); // undo the calculation so we can check for 0 again - pkt->busFirstWordDelay = pkt->busLastWordDelay = 0; + pkt->firstWordDelay = pkt->lastWordDelay = 0; - DPRINTF(CoherentBus, "recvTimingReq: src %s %s 0x%x RETRY\n", + DPRINTF(CoherentXBar, "recvTimingReq: src %s %s 0x%x RETRY\n", src_port->name(), pkt->cmdString(), pkt->getAddr()); - // update the bus state and schedule an idle event + // update the layer state and schedule an idle event reqLayers[master_port_id]->failedTiming(src_port, clockEdge(headerCycles)); } else { - // update the bus state and schedule an idle event + // update the layer state and schedule an idle event reqLayers[master_port_id]->succeededTiming(packetFinishTime); - dataThroughBus += pkt_size; } } // stats updates only consider packets that were successfully sent if (success) { pktCount[slave_port_id][master_port_id]++; - totPktSize[slave_port_id][master_port_id] += pkt_size; + pktSize[slave_port_id][master_port_id] += pkt_size; transDist[pkt_cmd]++; } @@ -268,7 +265,7 @@ CoherentBus::recvTimingReq(PacketPtr pkt, PortID slave_port_id) } bool -CoherentBus::recvTimingResp(PacketPtr pkt, PortID master_port_id) +CoherentXBar::recvTimingResp(PacketPtr pkt, PortID master_port_id) { // determine the source port based on the id MasterPort *src_port = masterPorts[master_port_id]; @@ -276,15 +273,15 @@ CoherentBus::recvTimingResp(PacketPtr pkt, PortID master_port_id) // determine the destination based on what is stored in the packet PortID slave_port_id = pkt->getDest(); - // test if the bus should be considered occupied for the current - // port + // test if the crossbar should be considered occupied for the + // current port if (!respLayers[slave_port_id]->tryTiming(src_port)) { - DPRINTF(CoherentBus, "recvTimingResp: src %s %s 0x%x BUSY\n", + DPRINTF(CoherentXBar, "recvTimingResp: src %s %s 0x%x BUSY\n", src_port->name(), pkt->cmdString(), pkt->getAddr()); return false; } - DPRINTF(CoherentBus, "recvTimingResp: src %s %s 0x%x\n", + DPRINTF(CoherentXBar, "recvTimingResp: src %s %s 0x%x\n", src_port->name(), pkt->cmdString(), pkt->getAddr()); // store size and command as they might be modified when @@ -293,10 +290,10 @@ CoherentBus::recvTimingResp(PacketPtr pkt, PortID master_port_id) unsigned int pkt_cmd = pkt->cmdToIndex(); calcPacketTiming(pkt); - Tick packetFinishTime = pkt->busLastWordDelay + curTick(); + Tick packetFinishTime = pkt->lastWordDelay + curTick(); // the packet is a normal response to a request that we should - // have seen passing through the bus + // have seen passing through the crossbar assert(outstandingReq.find(pkt->req) != outstandingReq.end()); if (snoopFilter && !pkt->req->isUncacheable() && !system->bypassCaches()) { @@ -317,25 +314,23 @@ CoherentBus::recvTimingResp(PacketPtr pkt, PortID master_port_id) respLayers[slave_port_id]->succeededTiming(packetFinishTime); // stats updates - dataThroughBus += pkt_size; pktCount[slave_port_id][master_port_id]++; - totPktSize[slave_port_id][master_port_id] += pkt_size; + pktSize[slave_port_id][master_port_id] += pkt_size; transDist[pkt_cmd]++; return true; } void -CoherentBus::recvTimingSnoopReq(PacketPtr pkt, PortID master_port_id) +CoherentXBar::recvTimingSnoopReq(PacketPtr pkt, PortID master_port_id) { - DPRINTF(CoherentBus, "recvTimingSnoopReq: src %s %s 0x%x\n", + DPRINTF(CoherentXBar, "recvTimingSnoopReq: src %s %s 0x%x\n", masterPorts[master_port_id]->name(), pkt->cmdString(), pkt->getAddr()); // update stats here as we know the forwarding will succeed transDist[pkt->cmdToIndex()]++; - snoopDataThroughBus += pkt->hasData() ? pkt->getSize() : 0; - snoopsThroughBus++; + snoops++; // we should only see express snoops from caches assert(pkt->isExpressSnoop()); @@ -347,7 +342,7 @@ CoherentBus::recvTimingSnoopReq(PacketPtr pkt, PortID master_port_id) // let the Snoop Filter work its magic and guide probing auto sf_res = snoopFilter->lookupSnoop(pkt); // No timing here: packetFinishTime += sf_res.second * clockPeriod(); - DPRINTF(CoherentBus, "recvTimingSnoopReq: src %s %s 0x%x"\ + DPRINTF(CoherentXBar, "recvTimingSnoopReq: src %s %s 0x%x"\ " SF size: %i lat: %i\n", masterPorts[master_port_id]->name(), pkt->cmdString(), pkt->getAddr(), sf_res.first.size(), sf_res.second); @@ -367,7 +362,7 @@ CoherentBus::recvTimingSnoopReq(PacketPtr pkt, PortID master_port_id) } bool -CoherentBus::recvTimingSnoopResp(PacketPtr pkt, PortID slave_port_id) +CoherentXBar::recvTimingSnoopResp(PacketPtr pkt, PortID slave_port_id) { // determine the source port based on the id SlavePort* src_port = slavePorts[slave_port_id]; @@ -382,13 +377,13 @@ CoherentBus::recvTimingSnoopResp(PacketPtr pkt, PortID slave_port_id) bool forwardAsSnoop = outstandingReq.find(pkt->req) == outstandingReq.end(); - // test if the bus should be considered occupied for the current - // 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 + // test if the crossbar should be considered occupied for the + // current 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) { if (!snoopLayers[dest_port_id]->tryTiming(src_port)) { - DPRINTF(CoherentBus, "recvTimingSnoopResp: src %s %s 0x%x BUSY\n", + DPRINTF(CoherentXBar, "recvTimingSnoopResp: src %s %s 0x%x BUSY\n", src_port->name(), pkt->cmdString(), pkt->getAddr()); return false; } @@ -396,13 +391,13 @@ CoherentBus::recvTimingSnoopResp(PacketPtr pkt, PortID slave_port_id) // get the master port that mirrors this slave port internally MasterPort* snoop_port = snoopRespPorts[slave_port_id]; if (!respLayers[dest_port_id]->tryTiming(snoop_port)) { - DPRINTF(CoherentBus, "recvTimingSnoopResp: src %s %s 0x%x BUSY\n", + DPRINTF(CoherentXBar, "recvTimingSnoopResp: src %s %s 0x%x BUSY\n", snoop_port->name(), pkt->cmdString(), pkt->getAddr()); return false; } } - DPRINTF(CoherentBus, "recvTimingSnoopResp: src %s %s 0x%x\n", + DPRINTF(CoherentXBar, "recvTimingSnoopResp: src %s %s 0x%x\n", src_port->name(), pkt->cmdString(), pkt->getAddr()); // store size and command as they might be modified when @@ -414,7 +409,7 @@ CoherentBus::recvTimingSnoopResp(PacketPtr pkt, PortID slave_port_id) assert(!pkt->isExpressSnoop()); calcPacketTiming(pkt); - Tick packetFinishTime = pkt->busLastWordDelay + curTick(); + Tick packetFinishTime = pkt->lastWordDelay + curTick(); // forward it either as a snoop response or a normal response if (forwardAsSnoop) { @@ -431,22 +426,22 @@ CoherentBus::recvTimingSnoopResp(PacketPtr pkt, PortID slave_port_id) bool success M5_VAR_USED = masterPorts[dest_port_id]->sendTimingSnoopResp(pkt); pktCount[slave_port_id][dest_port_id]++; - totPktSize[slave_port_id][dest_port_id] += pkt_size; + pktSize[slave_port_id][dest_port_id] += pkt_size; assert(success); 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 - // since we created the snoop request as part of - // recvTiming, this should now be a normal response again + // i.e. from a coherent master connected to the crossbar, and + // since we created the snoop request as part of recvTiming, + // this should now be a normal response again outstandingReq.erase(pkt->req); // this is a snoop response from a coherent master, with a - // destination field set on its way through the bus as - // request, hence it should never go back to where the - // snoop response came from, but instead to where the - // original request came from + // destination field set on its way through the crossbar as + // request, hence it should never go back to where the snoop + // response came from, but instead to where the original + // request came from assert(slave_port_id != dest_port_id); if (snoopFilter) { @@ -455,7 +450,7 @@ CoherentBus::recvTimingSnoopResp(PacketPtr pkt, PortID slave_port_id) *slavePorts[dest_port_id]); } - DPRINTF(CoherentBus, "recvTimingSnoopResp: src %s %s 0x%x"\ + DPRINTF(CoherentXBar, "recvTimingSnoopResp: src %s %s 0x%x"\ " FWD RESP\n", src_port->name(), pkt->cmdString(), pkt->getAddr()); @@ -478,18 +473,17 @@ CoherentBus::recvTimingSnoopResp(PacketPtr pkt, PortID slave_port_id) // stats updates transDist[pkt_cmd]++; - snoopDataThroughBus += pkt_size; - snoopsThroughBus++; + snoops++; return true; } void -CoherentBus::forwardTiming(PacketPtr pkt, PortID exclude_slave_port_id, +CoherentXBar::forwardTiming(PacketPtr pkt, PortID exclude_slave_port_id, const std::vector<SlavePort*>& dests) { - DPRINTF(CoherentBus, "%s for %s address %x size %d\n", __func__, + DPRINTF(CoherentXBar, "%s for %s address %x size %d\n", __func__, pkt->cmdString(), pkt->getAddr(), pkt->getSize()); // snoops should only happen if the system isn't bypassing caches @@ -497,8 +491,7 @@ CoherentBus::forwardTiming(PacketPtr pkt, PortID exclude_slave_port_id, unsigned fanout = 0; - for (SlavePortConstIter s = dests.begin(); s != dests.end(); ++s) { - SlavePort *p = *s; + for (const auto& p: dests) { // we could have gotten this request from a snooping master // (corresponding to our own slave port that is also in // snoopPorts) and should not send it back to where it came @@ -516,7 +509,7 @@ CoherentBus::forwardTiming(PacketPtr pkt, PortID exclude_slave_port_id, } void -CoherentBus::recvRetry(PortID master_port_id) +CoherentXBar::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 @@ -525,14 +518,14 @@ CoherentBus::recvRetry(PortID master_port_id) } Tick -CoherentBus::recvAtomic(PacketPtr pkt, PortID slave_port_id) +CoherentXBar::recvAtomic(PacketPtr pkt, PortID slave_port_id) { - DPRINTF(CoherentBus, "recvAtomic: packet src %s addr 0x%x cmd %s\n", + DPRINTF(CoherentXBar, "recvAtomic: packet src %s addr 0x%x cmd %s\n", slavePorts[slave_port_id]->name(), pkt->getAddr(), pkt->cmdString()); - // add the request data - dataThroughBus += pkt->hasData() ? pkt->getSize() : 0; + unsigned int pkt_size = pkt->hasData() ? pkt->getSize() : 0; + unsigned int pkt_cmd = pkt->cmdToIndex(); MemCmd snoop_response_cmd = MemCmd::InvalidCmd; Tick snoop_response_latency = 0; @@ -546,7 +539,7 @@ CoherentBus::recvAtomic(PacketPtr pkt, PortID slave_port_id) auto sf_res = snoopFilter->lookupRequest(pkt, *slavePorts[slave_port_id]); snoop_response_latency += sf_res.second * clockPeriod(); - DPRINTF(CoherentBus, "%s: src %s %s 0x%x"\ + DPRINTF(CoherentXBar, "%s: src %s %s 0x%x"\ " SF size: %i lat: %i\n", __func__, slavePorts[slave_port_id]->name(), pkt->cmdString(), pkt->getAddr(), sf_res.first.size(), sf_res.second); @@ -561,10 +554,15 @@ CoherentBus::recvAtomic(PacketPtr pkt, PortID slave_port_id) // even if we had a snoop response, we must continue and also // perform the actual request at the destination - PortID dest_id = findPort(pkt->getAddr()); + PortID master_port_id = findPort(pkt->getAddr()); + + // stats updates for the request + pktCount[slave_port_id][master_port_id]++; + pktSize[slave_port_id][master_port_id] += pkt_size; + transDist[pkt_cmd]++; // forward the request to the appropriate destination - Tick response_latency = masterPorts[dest_id]->sendAtomic(pkt); + Tick response_latency = masterPorts[master_port_id]->sendAtomic(pkt); // Lower levels have replied, tell the snoop filter if (snoopFilter && !pkt->req->isUncacheable() && !system->bypassCaches() && @@ -581,24 +579,30 @@ CoherentBus::recvAtomic(PacketPtr pkt, PortID slave_port_id) } // add the response data - if (pkt->isResponse()) - dataThroughBus += pkt->hasData() ? pkt->getSize() : 0; + if (pkt->isResponse()) { + pkt_size = pkt->hasData() ? pkt->getSize() : 0; + pkt_cmd = pkt->cmdToIndex(); + + // stats updates + pktCount[slave_port_id][master_port_id]++; + pktSize[slave_port_id][master_port_id] += pkt_size; + transDist[pkt_cmd]++; + } // @todo: Not setting first-word time - pkt->busLastWordDelay = response_latency; + pkt->lastWordDelay = response_latency; return response_latency; } Tick -CoherentBus::recvAtomicSnoop(PacketPtr pkt, PortID master_port_id) +CoherentXBar::recvAtomicSnoop(PacketPtr pkt, PortID master_port_id) { - DPRINTF(CoherentBus, "recvAtomicSnoop: packet src %s addr 0x%x cmd %s\n", + DPRINTF(CoherentXBar, "recvAtomicSnoop: packet src %s addr 0x%x cmd %s\n", masterPorts[master_port_id]->name(), pkt->getAddr(), pkt->cmdString()); // add the request snoop data - snoopDataThroughBus += pkt->hasData() ? pkt->getSize() : 0; - snoopsThroughBus++; + snoops++; // forward to all snoopers std::pair<MemCmd, Tick> snoop_result; @@ -606,7 +610,7 @@ CoherentBus::recvAtomicSnoop(PacketPtr pkt, PortID master_port_id) if (snoopFilter) { auto sf_res = snoopFilter->lookupSnoop(pkt); snoop_response_latency += sf_res.second * clockPeriod(); - DPRINTF(CoherentBus, "%s: src %s %s 0x%x SF size: %i lat: %i\n", + DPRINTF(CoherentXBar, "%s: src %s %s 0x%x SF size: %i lat: %i\n", __func__, masterPorts[master_port_id]->name(), pkt->cmdString(), pkt->getAddr(), sf_res.first.size(), sf_res.second); snoop_result = forwardAtomic(pkt, InvalidPortID, master_port_id, @@ -622,17 +626,16 @@ CoherentBus::recvAtomicSnoop(PacketPtr pkt, PortID master_port_id) // add the response snoop data if (pkt->isResponse()) { - snoopDataThroughBus += pkt->hasData() ? pkt->getSize() : 0; - snoopsThroughBus++; + snoops++; } // @todo: Not setting first-word time - pkt->busLastWordDelay = snoop_response_latency; + pkt->lastWordDelay = snoop_response_latency; return snoop_response_latency; } std::pair<MemCmd, Tick> -CoherentBus::forwardAtomic(PacketPtr pkt, PortID exclude_slave_port_id, +CoherentXBar::forwardAtomic(PacketPtr pkt, PortID exclude_slave_port_id, PortID source_master_port_id, const std::vector<SlavePort*>& dests) { @@ -648,8 +651,7 @@ CoherentBus::forwardAtomic(PacketPtr pkt, PortID exclude_slave_port_id, unsigned fanout = 0; - for (SlavePortConstIter s = dests.begin(); s != dests.end(); ++s) { - SlavePort *p = *s; + for (const auto& p: dests) { // we could have gotten this request from a snooping master // (corresponding to our own slave port that is also in // snoopPorts) and should not send it back to where it came @@ -704,11 +706,11 @@ CoherentBus::forwardAtomic(PacketPtr pkt, PortID exclude_slave_port_id, } void -CoherentBus::recvFunctional(PacketPtr pkt, PortID slave_port_id) +CoherentXBar::recvFunctional(PacketPtr pkt, PortID slave_port_id) { if (!pkt->isPrint()) { // don't do DPRINTFs on PrintReq as it clutters up the output - DPRINTF(CoherentBus, + DPRINTF(CoherentXBar, "recvFunctional: packet src %s addr 0x%x cmd %s\n", slavePorts[slave_port_id]->name(), pkt->getAddr(), pkt->cmdString()); @@ -730,11 +732,11 @@ CoherentBus::recvFunctional(PacketPtr pkt, PortID slave_port_id) } void -CoherentBus::recvFunctionalSnoop(PacketPtr pkt, PortID master_port_id) +CoherentXBar::recvFunctionalSnoop(PacketPtr pkt, PortID master_port_id) { if (!pkt->isPrint()) { // don't do DPRINTFs on PrintReq as it clutters up the output - DPRINTF(CoherentBus, + DPRINTF(CoherentXBar, "recvFunctionalSnoop: packet src %s addr 0x%x cmd %s\n", masterPorts[master_port_id]->name(), pkt->getAddr(), pkt->cmdString()); @@ -745,13 +747,12 @@ CoherentBus::recvFunctionalSnoop(PacketPtr pkt, PortID master_port_id) } void -CoherentBus::forwardFunctional(PacketPtr pkt, PortID exclude_slave_port_id) +CoherentXBar::forwardFunctional(PacketPtr pkt, PortID exclude_slave_port_id) { // snoops should only happen if the system isn't bypassing caches assert(!system->bypassCaches()); - for (SlavePortIter s = snoopPorts.begin(); s != snoopPorts.end(); ++s) { - SlavePort *p = *s; + for (const auto& p: snoopPorts) { // we could have gotten this request from a snooping master // (corresponding to our own slave port that is also in // snoopPorts) and should not send it back to where it came @@ -768,43 +769,33 @@ CoherentBus::forwardFunctional(PacketPtr pkt, PortID exclude_slave_port_id) } unsigned int -CoherentBus::drain(DrainManager *dm) +CoherentXBar::drain(DrainManager *dm) { // sum up the individual layers 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); + for (auto l: reqLayers) + total += l->drain(dm); + for (auto l: respLayers) + total += l->drain(dm); + for (auto l: snoopLayers) + total += l->drain(dm); return total; } void -CoherentBus::regStats() +CoherentXBar::regStats() { - // register the stats of the base class and our three bus layers - BaseBus::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") - .desc("Total data (bytes)") - ; - - snoopDataThroughBus - .name(name() + ".snoop_data_through_bus") - .desc("Total snoop data (bytes)") - ; - - snoopsThroughBus - .name(name() + ".snoops_through_bus") + // register the stats of the base class and our layers + BaseXBar::regStats(); + for (auto l: reqLayers) + l->regStats(); + for (auto l: respLayers) + l->regStats(); + for (auto l: snoopLayers) + l->regStats(); + + snoops + .name(name() + ".snoops") .desc("Total snoops (count)") ; @@ -813,18 +804,10 @@ CoherentBus::regStats() .name(name() + ".snoop_fanout") .desc("Request fanout histogram") ; - - throughput - .name(name() + ".throughput") - .desc("Throughput (bytes/s)") - .precision(0) - ; - - throughput = (dataThroughBus + snoopDataThroughBus) / simSeconds; } -CoherentBus * -CoherentBusParams::create() +CoherentXBar * +CoherentXBarParams::create() { - return new CoherentBus(this); + return new CoherentXBar(this); } diff --git a/src/mem/coherent_bus.hh b/src/mem/coherent_xbar.hh index 26ad92791..fd4dd1cca 100644 --- a/src/mem/coherent_bus.hh +++ b/src/mem/coherent_xbar.hh @@ -1,5 +1,5 @@ /* - * Copyright (c) 2011-2013 ARM Limited + * Copyright (c) 2011-2014 ARM Limited * All rights reserved * * The license below extends only to copyright in the software and shall @@ -45,36 +45,36 @@ /** * @file - * Declaration of a coherent bus. + * Declaration of a coherent crossbar. */ -#ifndef __MEM_COHERENT_BUS_HH__ -#define __MEM_COHERENT_BUS_HH__ +#ifndef __MEM_COHERENT_XBAR_HH__ +#define __MEM_COHERENT_XBAR_HH__ #include "base/hashmap.hh" -#include "mem/bus.hh" #include "mem/snoop_filter.hh" -#include "params/CoherentBus.hh" +#include "mem/xbar.hh" +#include "params/CoherentXBar.hh" /** - * A coherent bus connects a number of (potentially) snooping masters - * and slaves, and routes the request and response packets based on - * the address, and also forwards all requests to the snoopers and - * deals with the snoop responses. + * A coherent crossbar connects a number of (potentially) snooping + * masters and slaves, and routes the request and response packets + * based on the address, and also forwards all requests to the + * snoopers and deals with the snoop responses. * - * The coherent bus can be used as a template for modelling QPI, -* HyperTransport, ACE and coherent OCP buses, and is typically used - * for the L1-to-L2 buses and as the main system interconnect. - * @sa \ref gem5MemorySystem "gem5 Memory System" + * The coherent crossbar can be used as a template for modelling QPI, + * HyperTransport, ACE and coherent OCP buses, and is typically used + * for the L1-to-L2 buses and as the main system interconnect. @sa + * \ref gem5MemorySystem "gem5 Memory System" */ -class CoherentBus : public BaseBus +class CoherentXBar : public BaseXBar { protected: /** - * Declare the layers of this bus, one vector for requests, one - * for responses, and one for snoop responses + * Declare the layers of this crossbar, one vector for requests, + * one for responses, and one for snoop responses */ typedef Layer<SlavePort,MasterPort> ReqLayer; typedef Layer<MasterPort,SlavePort> RespLayer; @@ -84,88 +84,88 @@ class CoherentBus : public BaseBus std::vector<SnoopLayer*> snoopLayers; /** - * Declaration of the coherent bus slave port type, one will be - * instantiated for each of the master ports connecting to the - * bus. + * Declaration of the coherent crossbar slave port type, one will + * be instantiated for each of the master ports connecting to the + * crossbar. */ - class CoherentBusSlavePort : public SlavePort + class CoherentXBarSlavePort : public SlavePort { private: - /** A reference to the bus to which this port belongs. */ - CoherentBus &bus; + /** A reference to the crossbar to which this port belongs. */ + CoherentXBar &xbar; public: - CoherentBusSlavePort(const std::string &_name, - CoherentBus &_bus, PortID _id) - : SlavePort(_name, &_bus, _id), bus(_bus) + CoherentXBarSlavePort(const std::string &_name, + CoherentXBar &_xbar, PortID _id) + : SlavePort(_name, &_xbar, _id), xbar(_xbar) { } protected: /** - * When receiving a timing request, pass it to the bus. + * When receiving a timing request, pass it to the crossbar. */ virtual bool recvTimingReq(PacketPtr pkt) - { return bus.recvTimingReq(pkt, id); } + { return xbar.recvTimingReq(pkt, id); } /** - * When receiving a timing snoop response, pass it to the bus. + * When receiving a timing snoop response, pass it to the crossbar. */ virtual bool recvTimingSnoopResp(PacketPtr pkt) - { return bus.recvTimingSnoopResp(pkt, id); } + { return xbar.recvTimingSnoopResp(pkt, id); } /** - * When receiving an atomic request, pass it to the bus. + * When receiving an atomic request, pass it to the crossbar. */ virtual Tick recvAtomic(PacketPtr pkt) - { return bus.recvAtomic(pkt, id); } + { return xbar.recvAtomic(pkt, id); } /** - * When receiving a functional request, pass it to the bus. + * When receiving a functional request, pass it to the crossbar. */ virtual void recvFunctional(PacketPtr pkt) - { bus.recvFunctional(pkt, id); } + { xbar.recvFunctional(pkt, id); } /** - * When receiving a retry, pass it to the bus. + * When receiving a retry, pass it to the crossbar. */ virtual void recvRetry() - { panic("Bus slave ports always succeed and should never retry.\n"); } + { panic("Crossbar slave ports should never retry.\n"); } /** - * Return the union of all adress ranges seen by this bus. + * Return the union of all adress ranges seen by this crossbar. */ virtual AddrRangeList getAddrRanges() const - { return bus.getAddrRanges(); } + { return xbar.getAddrRanges(); } }; /** - * Declaration of the coherent bus master port type, one will be + * Declaration of the coherent crossbar master port type, one will be * instantiated for each of the slave interfaces connecting to the - * bus. + * crossbar. */ - class CoherentBusMasterPort : public MasterPort + class CoherentXBarMasterPort : public MasterPort { private: - /** A reference to the bus to which this port belongs. */ - CoherentBus &bus; + /** A reference to the crossbar to which this port belongs. */ + CoherentXBar &xbar; public: - CoherentBusMasterPort(const std::string &_name, - CoherentBus &_bus, PortID _id) - : MasterPort(_name, &_bus, _id), bus(_bus) + CoherentXBarMasterPort(const std::string &_name, + CoherentXBar &_xbar, PortID _id) + : MasterPort(_name, &_xbar, _id), xbar(_xbar) { } protected: /** * Determine if this port should be considered a snooper. For - * a coherent bus master port this is always true. + * a coherent crossbar master port this is always true. * * @return a boolean that is true if this port is snooping */ @@ -173,38 +173,38 @@ class CoherentBus : public BaseBus { return true; } /** - * When receiving a timing response, pass it to the bus. + * When receiving a timing response, pass it to the crossbar. */ virtual bool recvTimingResp(PacketPtr pkt) - { return bus.recvTimingResp(pkt, id); } + { return xbar.recvTimingResp(pkt, id); } /** - * When receiving a timing snoop request, pass it to the bus. + * When receiving a timing snoop request, pass it to the crossbar. */ virtual void recvTimingSnoopReq(PacketPtr pkt) - { return bus.recvTimingSnoopReq(pkt, id); } + { return xbar.recvTimingSnoopReq(pkt, id); } /** - * When receiving an atomic snoop request, pass it to the bus. + * When receiving an atomic snoop request, pass it to the crossbar. */ virtual Tick recvAtomicSnoop(PacketPtr pkt) - { return bus.recvAtomicSnoop(pkt, id); } + { return xbar.recvAtomicSnoop(pkt, id); } /** - * When receiving a functional snoop request, pass it to the bus. + * When receiving a functional snoop request, pass it to the crossbar. */ virtual void recvFunctionalSnoop(PacketPtr pkt) - { bus.recvFunctionalSnoop(pkt, id); } + { xbar.recvFunctionalSnoop(pkt, id); } /** When reciving a range change from the peer port (at id), - pass it to the bus. */ + pass it to the crossbar. */ virtual void recvRangeChange() - { bus.recvRangeChange(id); } + { xbar.recvRangeChange(id); } /** When reciving a retry from the peer port (at id), - pass it to the bus. */ + pass it to the crossbar. */ virtual void recvRetry() - { bus.recvRetry(id); } + { xbar.recvRetry(id); } }; @@ -226,8 +226,8 @@ class CoherentBus : public BaseBus /** * Create a snoop response port that mirrors a given slave port. */ - SnoopRespPort(SlavePort& slave_port, CoherentBus& _bus) : - MasterPort(slave_port.name() + ".snoopRespPort", &_bus), + SnoopRespPort(SlavePort& slave_port, CoherentXBar& _xbar) : + MasterPort(slave_port.name() + ".snoopRespPort", &_xbar), slavePort(slave_port) { } /** @@ -261,7 +261,7 @@ class CoherentBus : public BaseBus /** * Store the outstanding requests so we can determine which ones * we generated and which ones were merely forwarded. This is used - * in the coherent bus when coherency responses come back. + * in the coherent crossbar when coherency responses come back. */ m5::hash_set<RequestPtr> outstandingReq; @@ -275,19 +275,19 @@ class CoherentBus : public BaseBus * broadcast needed for probes. NULL denotes an absent filter. */ SnoopFilter *snoopFilter; - /** Function called by the port when the bus is recieving a Timing + /** Function called by the port when the crossbar is recieving a Timing request packet.*/ bool recvTimingReq(PacketPtr pkt, PortID slave_port_id); - /** Function called by the port when the bus is recieving a Timing + /** Function called by the port when the crossbar is recieving a Timing response packet.*/ bool recvTimingResp(PacketPtr pkt, PortID master_port_id); - /** Function called by the port when the bus is recieving a timing + /** Function called by the port when the crossbar is recieving a timing snoop request.*/ void recvTimingSnoopReq(PacketPtr pkt, PortID master_port_id); - /** Function called by the port when the bus is recieving a timing + /** Function called by the port when the crossbar is recieving a timing snoop response.*/ bool recvTimingSnoopResp(PacketPtr pkt, PortID slave_port_id); @@ -319,11 +319,11 @@ class CoherentBus : public BaseBus void forwardTiming(PacketPtr pkt, PortID exclude_slave_port_id, const std::vector<SlavePort*>& dests); - /** Function called by the port when the bus is recieving a Atomic + /** Function called by the port when the crossbar is recieving a Atomic transaction.*/ Tick recvAtomic(PacketPtr pkt, PortID slave_port_id); - /** Function called by the port when the bus is recieving an + /** Function called by the port when the crossbar is recieving an atomic snoop transaction.*/ Tick recvAtomicSnoop(PacketPtr pkt, PortID master_port_id); @@ -360,11 +360,11 @@ class CoherentBus : public BaseBus PortID source_master_port_id, const std::vector<SlavePort*>& dests); - /** Function called by the port when the bus is recieving a Functional + /** Function called by the port when the crossbar is recieving a Functional transaction.*/ void recvFunctional(PacketPtr pkt, PortID slave_port_id); - /** Function called by the port when the bus is recieving a functional + /** Function called by the port when the crossbar is recieving a functional snoop transaction.*/ void recvFunctionalSnoop(PacketPtr pkt, PortID master_port_id); @@ -378,22 +378,20 @@ class CoherentBus : public BaseBus */ void forwardFunctional(PacketPtr pkt, PortID exclude_slave_port_id); - Stats::Scalar dataThroughBus; - Stats::Scalar snoopDataThroughBus; - Stats::Scalar snoopsThroughBus; + Stats::Scalar snoops; Stats::Distribution snoopFanout; public: virtual void init(); - CoherentBus(const CoherentBusParams *p); + CoherentXBar(const CoherentXBarParams *p); - virtual ~CoherentBus(); + virtual ~CoherentXBar(); unsigned int drain(DrainManager *dm); virtual void regStats(); }; -#endif //__MEM_COHERENT_BUS_HH__ +#endif //__MEM_COHERENT_XBAR_HH__ diff --git a/src/mem/dram_ctrl.cc b/src/mem/dram_ctrl.cc index 38c240fcf..198cb52a4 100644 --- a/src/mem/dram_ctrl.cc +++ b/src/mem/dram_ctrl.cc @@ -819,7 +819,7 @@ DRAMCtrl::accessAndRespond(PacketPtr pkt, Tick static_latency) assert(pkt->isResponse()); // @todo someone should pay for this - pkt->busFirstWordDelay = pkt->busLastWordDelay = 0; + pkt->firstWordDelay = pkt->lastWordDelay = 0; // queue the packet in the response queue to be sent out after // the static latency has passed diff --git a/src/mem/dramsim2.cc b/src/mem/dramsim2.cc index 27dc36976..3356fd7d2 100644 --- a/src/mem/dramsim2.cc +++ b/src/mem/dramsim2.cc @@ -268,7 +268,7 @@ DRAMSim2::accessAndRespond(PacketPtr pkt) assert(pkt->isResponse()); // @todo someone should pay for this - pkt->busFirstWordDelay = pkt->busLastWordDelay = 0; + pkt->firstWordDelay = pkt->lastWordDelay = 0; DPRINTF(DRAMSim2, "Queuing response for address %lld\n", pkt->getAddr()); diff --git a/src/mem/noncoherent_bus.cc b/src/mem/noncoherent_xbar.cc index d34ae6d20..bc51be5a2 100644 --- a/src/mem/noncoherent_bus.cc +++ b/src/mem/noncoherent_xbar.cc @@ -1,5 +1,5 @@ /* - * Copyright (c) 2011-2013 ARM Limited + * Copyright (c) 2011-2014 ARM Limited * All rights reserved * * The license below extends only to copyright in the software and shall @@ -44,25 +44,24 @@ /** * @file - * Definition of a bus object. + * Definition of a non-coherent crossbar object. */ #include "base/misc.hh" #include "base/trace.hh" -#include "debug/Bus.hh" -#include "debug/BusAddrRanges.hh" -#include "debug/NoncoherentBus.hh" -#include "mem/noncoherent_bus.hh" +#include "debug/NoncoherentXBar.hh" +#include "debug/XBar.hh" +#include "mem/noncoherent_xbar.hh" -NoncoherentBus::NoncoherentBus(const NoncoherentBusParams *p) - : BaseBus(p) +NoncoherentXBar::NoncoherentXBar(const NoncoherentXBarParams *p) + : BaseXBar(p) { // 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.master[%d]", name(), i); - MasterPort* bp = new NoncoherentBusMasterPort(portName, *this, i); + MasterPort* bp = new NoncoherentXBarMasterPort(portName, *this, i); masterPorts.push_back(bp); reqLayers.push_back(new ReqLayer(*bp, *this, csprintf(".reqLayer%d", i))); @@ -73,7 +72,7 @@ NoncoherentBus::NoncoherentBus(const NoncoherentBusParams *p) if (p->port_default_connection_count) { defaultPortID = masterPorts.size(); std::string portName = name() + ".default"; - MasterPort* bp = new NoncoherentBusMasterPort(portName, *this, + MasterPort* bp = new NoncoherentXBarMasterPort(portName, *this, defaultPortID); masterPorts.push_back(bp); reqLayers.push_back(new ReqLayer(*bp, *this, csprintf(".reqLayer%d", @@ -83,7 +82,7 @@ NoncoherentBus::NoncoherentBus(const NoncoherentBusParams *p) // 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.slave[%d]", name(), i); - SlavePort* bp = new NoncoherentBusSlavePort(portName, *this, i); + SlavePort* bp = new NoncoherentXBarSlavePort(portName, *this, i); slavePorts.push_back(bp); respLayers.push_back(new RespLayer(*bp, *this, csprintf(".respLayer%d", i))); @@ -92,35 +91,35 @@ NoncoherentBus::NoncoherentBus(const NoncoherentBusParams *p) clearPortCache(); } -NoncoherentBus::~NoncoherentBus() +NoncoherentXBar::~NoncoherentXBar() { - 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: reqLayers) + delete l; + for (auto l: respLayers) + delete l; } bool -NoncoherentBus::recvTimingReq(PacketPtr pkt, PortID slave_port_id) +NoncoherentXBar::recvTimingReq(PacketPtr pkt, PortID slave_port_id) { // determine the source port based on the id SlavePort *src_port = slavePorts[slave_port_id]; - // we should never see express snoops on a non-coherent bus + // we should never see express snoops on a non-coherent crossbar assert(!pkt->isExpressSnoop()); // determine the destination based on the address PortID master_port_id = findPort(pkt->getAddr()); - // test if the bus should be considered occupied for the current + // test if the layer should be considered occupied for the current // port if (!reqLayers[master_port_id]->tryTiming(src_port)) { - DPRINTF(NoncoherentBus, "recvTimingReq: src %s %s 0x%x BUSY\n", + DPRINTF(NoncoherentXBar, "recvTimingReq: src %s %s 0x%x BUSY\n", src_port->name(), pkt->cmdString(), pkt->getAddr()); return false; } - DPRINTF(NoncoherentBus, "recvTimingReq: src %s %s 0x%x\n", + DPRINTF(NoncoherentXBar, "recvTimingReq: src %s %s 0x%x\n", src_port->name(), pkt->cmdString(), pkt->getAddr()); // store size and command as they might be modified when @@ -132,7 +131,7 @@ NoncoherentBus::recvTimingReq(PacketPtr pkt, PortID slave_port_id) pkt->setSrc(slave_port_id); calcPacketTiming(pkt); - Tick packetFinishTime = pkt->busLastWordDelay + curTick(); + Tick packetFinishTime = pkt->lastWordDelay + curTick(); // since it is a normal request, attempt to send the packet bool success = masterPorts[master_port_id]->sendTimingReq(pkt); @@ -141,11 +140,11 @@ NoncoherentBus::recvTimingReq(PacketPtr pkt, PortID slave_port_id) // inhibited packets should never be forced to retry assert(!pkt->memInhibitAsserted()); - DPRINTF(NoncoherentBus, "recvTimingReq: src %s %s 0x%x RETRY\n", + DPRINTF(NoncoherentXBar, "recvTimingReq: src %s %s 0x%x RETRY\n", src_port->name(), pkt->cmdString(), pkt->getAddr()); // undo the calculation so we can check for 0 again - pkt->busFirstWordDelay = pkt->busLastWordDelay = 0; + pkt->firstWordDelay = pkt->lastWordDelay = 0; // occupy until the header is sent reqLayers[master_port_id]->failedTiming(src_port, @@ -157,16 +156,15 @@ NoncoherentBus::recvTimingReq(PacketPtr pkt, PortID slave_port_id) reqLayers[master_port_id]->succeededTiming(packetFinishTime); // stats updates - dataThroughBus += pkt_size; pktCount[slave_port_id][master_port_id]++; - totPktSize[slave_port_id][master_port_id] += pkt_size; + pktSize[slave_port_id][master_port_id] += pkt_size; transDist[pkt_cmd]++; return true; } bool -NoncoherentBus::recvTimingResp(PacketPtr pkt, PortID master_port_id) +NoncoherentXBar::recvTimingResp(PacketPtr pkt, PortID master_port_id) { // determine the source port based on the id MasterPort *src_port = masterPorts[master_port_id]; @@ -174,15 +172,15 @@ NoncoherentBus::recvTimingResp(PacketPtr pkt, PortID master_port_id) // determine the destination based on what is stored in the packet PortID slave_port_id = pkt->getDest(); - // test if the bus should be considered occupied for the current + // test if the layer should be considered occupied for the current // port if (!respLayers[slave_port_id]->tryTiming(src_port)) { - DPRINTF(NoncoherentBus, "recvTimingResp: src %s %s 0x%x BUSY\n", + DPRINTF(NoncoherentXBar, "recvTimingResp: src %s %s 0x%x BUSY\n", src_port->name(), pkt->cmdString(), pkt->getAddr()); return false; } - DPRINTF(NoncoherentBus, "recvTimingResp: src %s %s 0x%x\n", + DPRINTF(NoncoherentXBar, "recvTimingResp: src %s %s 0x%x\n", src_port->name(), pkt->cmdString(), pkt->getAddr()); // store size and command as they might be modified when @@ -191,7 +189,7 @@ NoncoherentBus::recvTimingResp(PacketPtr pkt, PortID master_port_id) unsigned int pkt_cmd = pkt->cmdToIndex(); calcPacketTiming(pkt); - Tick packetFinishTime = pkt->busLastWordDelay + curTick(); + Tick packetFinishTime = pkt->lastWordDelay + curTick(); // send the packet through the destination slave port bool success M5_VAR_USED = slavePorts[slave_port_id]->sendTimingResp(pkt); @@ -203,16 +201,15 @@ NoncoherentBus::recvTimingResp(PacketPtr pkt, PortID master_port_id) respLayers[slave_port_id]->succeededTiming(packetFinishTime); // stats updates - dataThroughBus += pkt_size; pktCount[slave_port_id][master_port_id]++; - totPktSize[slave_port_id][master_port_id] += pkt_size; + pktSize[slave_port_id][master_port_id] += pkt_size; transDist[pkt_cmd]++; return true; } void -NoncoherentBus::recvRetry(PortID master_port_id) +NoncoherentXBar::recvRetry(PortID master_port_id) { // responses never block on forwarding them, so the retry will // always be coming from a port to which we tried to forward a @@ -221,36 +218,48 @@ NoncoherentBus::recvRetry(PortID master_port_id) } Tick -NoncoherentBus::recvAtomic(PacketPtr pkt, PortID slave_port_id) +NoncoherentXBar::recvAtomic(PacketPtr pkt, PortID slave_port_id) { - DPRINTF(NoncoherentBus, "recvAtomic: packet src %s addr 0x%x cmd %s\n", + DPRINTF(NoncoherentXBar, "recvAtomic: packet src %s addr 0x%x cmd %s\n", slavePorts[slave_port_id]->name(), pkt->getAddr(), pkt->cmdString()); - // add the request data - dataThroughBus += pkt->hasData() ? pkt->getSize() : 0; + unsigned int pkt_size = pkt->hasData() ? pkt->getSize() : 0; + unsigned int pkt_cmd = pkt->cmdToIndex(); // determine the destination port - PortID dest_id = findPort(pkt->getAddr()); + PortID master_port_id = findPort(pkt->getAddr()); + + // stats updates for the request + pktCount[slave_port_id][master_port_id]++; + pktSize[slave_port_id][master_port_id] += pkt_size; + transDist[pkt_cmd]++; // forward the request to the appropriate destination - Tick response_latency = masterPorts[dest_id]->sendAtomic(pkt); + Tick response_latency = masterPorts[master_port_id]->sendAtomic(pkt); // add the response data - if (pkt->isResponse()) - dataThroughBus += pkt->hasData() ? pkt->getSize() : 0; + if (pkt->isResponse()) { + pkt_size = pkt->hasData() ? pkt->getSize() : 0; + pkt_cmd = pkt->cmdToIndex(); + + // stats updates + pktCount[slave_port_id][master_port_id]++; + pktSize[slave_port_id][master_port_id] += pkt_size; + transDist[pkt_cmd]++; + } // @todo: Not setting first-word time - pkt->busLastWordDelay = response_latency; + pkt->lastWordDelay = response_latency; return response_latency; } void -NoncoherentBus::recvFunctional(PacketPtr pkt, PortID slave_port_id) +NoncoherentXBar::recvFunctional(PacketPtr pkt, PortID slave_port_id) { if (!pkt->isPrint()) { // don't do DPRINTFs on PrintReq as it clutters up the output - DPRINTF(NoncoherentBus, + DPRINTF(NoncoherentXBar, "recvFunctional: packet src %s addr 0x%x cmd %s\n", slavePorts[slave_port_id]->name(), pkt->getAddr(), pkt->cmdString()); @@ -264,43 +273,30 @@ NoncoherentBus::recvFunctional(PacketPtr pkt, PortID slave_port_id) } unsigned int -NoncoherentBus::drain(DrainManager *dm) +NoncoherentXBar::drain(DrainManager *dm) { // sum up the individual layers 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: reqLayers) + total += l->drain(dm); + for (auto l: respLayers) + total += l->drain(dm); return total; } -NoncoherentBus* -NoncoherentBusParams::create() +NoncoherentXBar* +NoncoherentXBarParams::create() { - return new NoncoherentBus(this); + return new NoncoherentXBar(this); } void -NoncoherentBus::regStats() +NoncoherentXBar::regStats() { - // register the stats of the base class and our two bus layers - BaseBus::regStats(); - for (auto l = reqLayers.begin(); l != reqLayers.end(); ++l) - (*l)->regStats(); - for (auto l = respLayers.begin(); l != respLayers.end(); ++l) - (*l)->regStats(); - - dataThroughBus - .name(name() + ".data_through_bus") - .desc("Total data (bytes)") - ; - - throughput - .name(name() + ".throughput") - .desc("Throughput (bytes/s)") - .precision(0) - ; - - throughput = dataThroughBus / simSeconds; + // register the stats of the base class and our layers + BaseXBar::regStats(); + for (auto l: reqLayers) + l->regStats(); + for (auto l: respLayers) + l->regStats(); } diff --git a/src/mem/noncoherent_bus.hh b/src/mem/noncoherent_xbar.hh index a1b9da6e3..122fc6b27 100644 --- a/src/mem/noncoherent_bus.hh +++ b/src/mem/noncoherent_xbar.hh @@ -1,5 +1,5 @@ /* - * Copyright (c) 2011-2013 ARM Limited + * Copyright (c) 2011-2014 ARM Limited * All rights reserved * * The license below extends only to copyright in the software and shall @@ -45,36 +45,36 @@ /** * @file - * Declaration of a non-coherent bus. + * Declaration of a non-coherent crossbar. */ -#ifndef __MEM_NONCOHERENT_BUS_HH__ -#define __MEM_NONCOHERENT_BUS_HH__ +#ifndef __MEM_NONCOHERENT_XBAR_HH__ +#define __MEM_NONCOHERENT_XBAR_HH__ -#include "mem/bus.hh" -#include "params/NoncoherentBus.hh" +#include "mem/xbar.hh" +#include "params/NoncoherentXBar.hh" /** - * A non-coherent bus connects a number of non-snooping masters and - * slaves, and routes the request and response packets based on the - * address. The request packets issued by the master connected to a - * non-coherent bus could still snoop in caches attached to a coherent - * bus, as is the case with the I/O bus and memory bus in most system - * configurations. No snoops will, however, reach any master on the - * non-coherent bus itself. + * A non-coherent crossbar connects a number of non-snooping masters + * and slaves, and routes the request and response packets based on + * the address. The request packets issued by the master connected to + * a non-coherent crossbar could still snoop in caches attached to a + * coherent crossbar, as is the case with the I/O bus and memory bus + * in most system configurations. No snoops will, however, reach any + * master on the non-coherent crossbar itself. * - * The non-coherent bus can be used as a template for modelling PCI, + * The non-coherent crossbar can be used as a template for modelling * PCIe, and non-coherent AMBA and OCP buses, and is typically used * for the I/O buses. */ -class NoncoherentBus : public BaseBus +class NoncoherentXBar : public BaseXBar { protected: /** - * Declare the layers of this bus, one vector for requests and one - * for responses. + * Declare the layers of this crossbar, one vector for requests + * and one for responses. */ typedef Layer<SlavePort,MasterPort> ReqLayer; typedef Layer<MasterPort,SlavePort> RespLayer; @@ -82,102 +82,102 @@ class NoncoherentBus : public BaseBus std::vector<RespLayer*> respLayers; /** - * Declaration of the non-coherent bus slave port type, one will - * be instantiated for each of the master ports connecting to the - * bus. + * Declaration of the non-coherent crossbar slave port type, one + * will be instantiated for each of the master ports connecting to + * the crossbar. */ - class NoncoherentBusSlavePort : public SlavePort + class NoncoherentXBarSlavePort : public SlavePort { private: - /** A reference to the bus to which this port belongs. */ - NoncoherentBus &bus; + /** A reference to the crossbar to which this port belongs. */ + NoncoherentXBar &xbar; public: - NoncoherentBusSlavePort(const std::string &_name, - NoncoherentBus &_bus, PortID _id) - : SlavePort(_name, &_bus, _id), bus(_bus) + NoncoherentXBarSlavePort(const std::string &_name, + NoncoherentXBar &_xbar, PortID _id) + : SlavePort(_name, &_xbar, _id), xbar(_xbar) { } protected: /** - * When receiving a timing request, pass it to the bus. + * When receiving a timing request, pass it to the crossbar. */ virtual bool recvTimingReq(PacketPtr pkt) - { return bus.recvTimingReq(pkt, id); } + { return xbar.recvTimingReq(pkt, id); } /** - * When receiving an atomic request, pass it to the bus. + * When receiving an atomic request, pass it to the crossbar. */ virtual Tick recvAtomic(PacketPtr pkt) - { return bus.recvAtomic(pkt, id); } + { return xbar.recvAtomic(pkt, id); } /** - * When receiving a functional request, pass it to the bus. + * When receiving a functional request, pass it to the crossbar. */ virtual void recvFunctional(PacketPtr pkt) - { bus.recvFunctional(pkt, id); } + { xbar.recvFunctional(pkt, id); } /** - * When receiving a retry, pass it to the bus. + * When receiving a retry, pass it to the crossbar. */ virtual void recvRetry() - { panic("Bus slave ports always succeed and should never retry.\n"); } + { panic("Crossbar slave ports should never retry.\n"); } /** - * Return the union of all adress ranges seen by this bus. + * Return the union of all adress ranges seen by this crossbar. */ virtual AddrRangeList getAddrRanges() const - { return bus.getAddrRanges(); } + { return xbar.getAddrRanges(); } }; /** - * Declaration of the bus master port type, one will be + * Declaration of the crossbar master port type, one will be * instantiated for each of the slave ports connecting to the - * bus. + * crossbar. */ - class NoncoherentBusMasterPort : public MasterPort + class NoncoherentXBarMasterPort : public MasterPort { private: - /** A reference to the bus to which this port belongs. */ - NoncoherentBus &bus; + /** A reference to the crossbar to which this port belongs. */ + NoncoherentXBar &xbar; public: - NoncoherentBusMasterPort(const std::string &_name, - NoncoherentBus &_bus, PortID _id) - : MasterPort(_name, &_bus, _id), bus(_bus) + NoncoherentXBarMasterPort(const std::string &_name, + NoncoherentXBar &_xbar, PortID _id) + : MasterPort(_name, &_xbar, _id), xbar(_xbar) { } protected: /** - * When receiving a timing response, pass it to the bus. + * When receiving a timing response, pass it to the crossbar. */ virtual bool recvTimingResp(PacketPtr pkt) - { return bus.recvTimingResp(pkt, id); } + { return xbar.recvTimingResp(pkt, id); } /** When reciving a range change from the peer port (at id), - pass it to the bus. */ + pass it to the crossbar. */ virtual void recvRangeChange() - { bus.recvRangeChange(id); } + { xbar.recvRangeChange(id); } /** When reciving a retry from the peer port (at id), - pass it to the bus. */ + pass it to the crossbar. */ virtual void recvRetry() - { bus.recvRetry(id); } + { xbar.recvRetry(id); } }; - /** Function called by the port when the bus is recieving a Timing + /** Function called by the port when the crossbar is recieving a Timing request packet.*/ virtual bool recvTimingReq(PacketPtr pkt, PortID slave_port_id); - /** Function called by the port when the bus is recieving a Timing + /** Function called by the port when the crossbar is recieving a Timing response packet.*/ virtual bool recvTimingResp(PacketPtr pkt, PortID master_port_id); @@ -185,19 +185,19 @@ class NoncoherentBus : public BaseBus * requests. */ void recvRetry(PortID master_port_id); - /** Function called by the port when the bus is recieving a Atomic + /** Function called by the port when the crossbar is recieving a Atomic transaction.*/ Tick recvAtomic(PacketPtr pkt, PortID slave_port_id); - /** Function called by the port when the bus is recieving a Functional + /** Function called by the port when the crossbar is recieving a Functional transaction.*/ void recvFunctional(PacketPtr pkt, PortID slave_port_id); public: - NoncoherentBus(const NoncoherentBusParams *p); + NoncoherentXBar(const NoncoherentXBarParams *p); - virtual ~NoncoherentBus(); + virtual ~NoncoherentXBar(); unsigned int drain(DrainManager *dm); @@ -205,7 +205,7 @@ class NoncoherentBus : public BaseBus * stats */ virtual void regStats(); - Stats::Scalar dataThroughBus; + Stats::Scalar totPktSize; }; -#endif //__MEM_NONCOHERENT_BUS_HH__ +#endif //__MEM_NONCOHERENT_XBAR_HH__ diff --git a/src/mem/packet.hh b/src/mem/packet.hh index c070eaea7..4ed307f66 100644 --- a/src/mem/packet.hh +++ b/src/mem/packet.hh @@ -293,14 +293,14 @@ class Packet : public Printable /** * Source port identifier set on a request packet to enable * appropriate routing of the responses. The source port - * identifier is set by any multiplexing component, e.g. a bus, as - * the timing responses need this information to be routed back to - * the appropriate port at a later point in time. The field can be - * updated (over-written) as the request packet passes through - * additional multiplexing components, and it is their - * responsibility to remember the original source port identifier, - * for example by using an appropriate sender state. The latter is - * done in the cache and bridge. + * identifier is set by any multiplexing component, e.g. a + * crossbar, as the timing responses need this information to be + * routed back to the appropriate port at a later point in + * time. The field can be updated (over-written) as the request + * packet passes through additional multiplexing components, and + * it is their responsibility to remember the original source port + * identifier, for example by using an appropriate sender + * state. The latter is done in the cache and bridge. */ PortID src; @@ -309,7 +309,7 @@ class Packet : public Printable * packets that passed through a multiplexing component as a * request packet. The source port identifier is turned into a * destination port identifier when the packet is turned into a - * response, and the destination is used, e.g. by the bus, to + * response, and the destination is used, e.g. by the crossbar, to * select the appropriate path through the interconnect. */ PortID dest; @@ -333,21 +333,22 @@ class Packet : public Printable /** * The extra delay from seeing the packet until the first word is - * transmitted by the bus that provided it (if any). This delay is - * used to communicate the bus waiting time to the neighbouring - * object (e.g. a cache) that actually makes the packet wait. As - * the delay is relative, a 32-bit unsigned should be sufficient. + * transmitted. This delay is used to communicate the crossbar + * forwarding latency to the neighbouring object (e.g. a cache) + * that actually makes the packet wait. As the delay is relative, + * a 32-bit unsigned should be sufficient. */ - uint32_t busFirstWordDelay; + uint32_t firstWordDelay; /** - * The extra delay from seeing the packet until the last word is - * transmitted by the bus that provided it (if any). Similar to - * the first word time, this is used to make up for the fact that - * the bus does not make the packet wait. As the delay is relative, - * a 32-bit unsigned should be sufficient. + * The extra pipelining delay from seeing the packet until the + * last word is transmitted by the component that provided it (if + * any). This includes the first word delay. Similar to the first + * word delay, this is used to make up for the fact that the + * crossbar does not make the packet wait. As the delay is + * relative, a 32-bit unsigned should be sufficient. */ - uint32_t busLastWordDelay; + uint32_t lastWordDelay; /** * A virtual base opaque structure used to hold state associated @@ -541,8 +542,6 @@ class Packet : public Printable PortID getSrc() const { assert(isSrcValid()); return src; } /// Accessor function to set the source index of the packet. void setSrc(PortID _src) { src = _src; } - /// Reset source field, e.g. to retransmit packet on different bus. - void clearSrc() { src = InvalidPortID; } bool isDestValid() const { return dest != InvalidPortID; } /// Accessor function for the destination index of the packet. @@ -604,7 +603,7 @@ class Packet : public Printable : cmd(_cmd), req(_req), data(nullptr), addr(0), _isSecure(false), src(InvalidPortID), dest(InvalidPortID), bytesValidStart(0), bytesValidEnd(0), - busFirstWordDelay(0), busLastWordDelay(0), + firstWordDelay(0), lastWordDelay(0), senderState(NULL) { if (req->hasPaddr()) { @@ -627,7 +626,7 @@ class Packet : public Printable : cmd(_cmd), req(_req), data(nullptr), addr(0), _isSecure(false), src(InvalidPortID), dest(InvalidPortID), bytesValidStart(0), bytesValidEnd(0), - busFirstWordDelay(0), busLastWordDelay(0), + firstWordDelay(0), lastWordDelay(0), senderState(NULL) { if (req->hasPaddr()) { @@ -653,8 +652,8 @@ class Packet : public Printable src(pkt->src), dest(pkt->dest), bytesValidStart(pkt->bytesValidStart), bytesValidEnd(pkt->bytesValidEnd), - busFirstWordDelay(pkt->busFirstWordDelay), - busLastWordDelay(pkt->busLastWordDelay), + firstWordDelay(pkt->firstWordDelay), + lastWordDelay(pkt->lastWordDelay), senderState(pkt->senderState) { if (!clearFlags) @@ -739,8 +738,8 @@ class Packet : public Printable dest = InvalidPortID; bytesValidStart = 0; bytesValidEnd = 0; - busFirstWordDelay = 0; - busLastWordDelay = 0; + firstWordDelay = 0; + lastWordDelay = 0; flags.set(VALID_ADDR|VALID_SIZE); deleteData(); @@ -766,7 +765,7 @@ class Packet : public Printable flags.clear(EXPRESS_SNOOP); dest = src; - clearSrc(); + src = InvalidPortID; } void diff --git a/src/mem/physical.cc b/src/mem/physical.cc index 1b76b52e8..08ec83410 100644 --- a/src/mem/physical.cc +++ b/src/mem/physical.cc @@ -51,7 +51,7 @@ #include <string> #include "base/trace.hh" -#include "debug/BusAddrRanges.hh" +#include "debug/AddrRanges.hh" #include "debug/Checkpoint.hh" #include "mem/abstract_mem.hh" #include "mem/physical.hh" @@ -79,7 +79,7 @@ PhysicalMemory::PhysicalMemory(const string& _name, fatal("Memory address range for %s is overlapping\n", (*m)->name()); } else { - DPRINTF(BusAddrRanges, + DPRINTF(AddrRanges, "Skipping memory %s that is not in global address map\n", (*m)->name()); // this type of memory is used e.g. as reference memory by @@ -144,7 +144,7 @@ PhysicalMemory::createBackingStore(AddrRange range, range.to_string()); // perform the actual mmap - DPRINTF(BusAddrRanges, "Creating backing store for range %s with size %d\n", + DPRINTF(AddrRanges, "Creating backing store for range %s with size %d\n", range.to_string(), range.size()); int map_flags = MAP_ANON | MAP_PRIVATE; uint8_t* pmem = (uint8_t*) mmap(NULL, range.size(), @@ -164,7 +164,7 @@ PhysicalMemory::createBackingStore(AddrRange range, // point the memories to their backing store for (vector<AbstractMemory*>::const_iterator m = _memories.begin(); m != _memories.end(); ++m) { - DPRINTF(BusAddrRanges, "Mapping memory %s to backing store\n", + DPRINTF(AddrRanges, "Mapping memory %s to backing store\n", (*m)->name()); (*m)->setBackingStore(pmem); } diff --git a/src/mem/simple_mem.cc b/src/mem/simple_mem.cc index b2d518dc7..11ed74b3b 100644 --- a/src/mem/simple_mem.cc +++ b/src/mem/simple_mem.cc @@ -122,7 +122,7 @@ SimpleMemory::recvTimingReq(PacketPtr pkt) } // @todo someone should pay for this - pkt->busFirstWordDelay = pkt->busLastWordDelay = 0; + pkt->firstWordDelay = pkt->lastWordDelay = 0; // update the release time according to the bandwidth limit, and // do so with respect to the time it takes to finish this request diff --git a/src/mem/bus.cc b/src/mem/xbar.cc index 730c612ca..6e4630fb6 100644 --- a/src/mem/bus.cc +++ b/src/mem/xbar.cc @@ -1,5 +1,5 @@ /* - * Copyright (c) 2011-2013 ARM Limited + * Copyright (c) 2011-2014 ARM Limited * All rights reserved * * The license below extends only to copyright in the software and shall @@ -44,17 +44,17 @@ /** * @file - * Definition of a bus object. + * Definition of a crossbar object. */ #include "base/misc.hh" #include "base/trace.hh" -#include "debug/Bus.hh" -#include "debug/BusAddrRanges.hh" +#include "debug/AddrRanges.hh" #include "debug/Drain.hh" -#include "mem/bus.hh" +#include "debug/XBar.hh" +#include "mem/xbar.hh" -BaseBus::BaseBus(const BaseBusParams *p) +BaseXBar::BaseXBar(const BaseXBarParams *p) : MemObject(p), headerCycles(p->header_cycles), width(p->width), gotAddrRanges(p->port_default_connection_count + @@ -63,26 +63,22 @@ BaseBus::BaseBus(const BaseBusParams *p) useDefaultRange(p->use_default_range) {} -BaseBus::~BaseBus() +BaseXBar::~BaseXBar() { - for (MasterPortIter m = masterPorts.begin(); m != masterPorts.end(); - ++m) { - delete *m; - } + for (auto m: masterPorts) + delete m; - for (SlavePortIter s = slavePorts.begin(); s != slavePorts.end(); - ++s) { - delete *s; - } + for (auto s: slavePorts) + delete s; } void -BaseBus::init() +BaseXBar::init() { } BaseMasterPort & -BaseBus::getMasterPort(const std::string &if_name, PortID idx) +BaseXBar::getMasterPort(const std::string &if_name, PortID idx) { if (if_name == "master" && idx < masterPorts.size()) { // the master port index translates directly to the vector position @@ -95,7 +91,7 @@ BaseBus::getMasterPort(const std::string &if_name, PortID idx) } BaseSlavePort & -BaseBus::getSlavePort(const std::string &if_name, PortID idx) +BaseXBar::getSlavePort(const std::string &if_name, PortID idx) { if (if_name == "slave" && idx < slavePorts.size()) { // the slave port index translates directly to the vector position @@ -106,9 +102,9 @@ BaseBus::getSlavePort(const std::string &if_name, PortID idx) } void -BaseBus::calcPacketTiming(PacketPtr pkt) +BaseXBar::calcPacketTiming(PacketPtr pkt) { - // the bus will be called at a time that is not necessarily + // the crossbar will be called at a time that is not necessarily // coinciding with its own clock, so start by determining how long // until the next clock edge (could be zero) Tick offset = clockEdge() - curTick(); @@ -117,58 +113,58 @@ BaseBus::calcPacketTiming(PacketPtr pkt) unsigned dataCycles = pkt->hasData() ? divCeil(pkt->getSize(), width) : 0; // before setting the bus delay fields of the packet, ensure that - // the delay from any previous bus has been accounted for - if (pkt->busFirstWordDelay != 0 || pkt->busLastWordDelay != 0) - panic("Packet %s already has bus delay (%d, %d) that should be " - "accounted for.\n", pkt->cmdString(), pkt->busFirstWordDelay, - pkt->busLastWordDelay); + // the delay from any previous crossbar has been accounted for + if (pkt->firstWordDelay != 0 || pkt->lastWordDelay != 0) + panic("Packet %s already has delay (%d, %d) that should be " + "accounted for.\n", pkt->cmdString(), pkt->firstWordDelay, + pkt->lastWordDelay); // The first word will be delivered on the cycle after the header. - pkt->busFirstWordDelay = (headerCycles + 1) * clockPeriod() + offset; + pkt->firstWordDelay = (headerCycles + 1) * clockPeriod() + offset; - // Note that currently busLastWordDelay can be smaller than - // busFirstWordDelay if the packet has no data - pkt->busLastWordDelay = (headerCycles + dataCycles) * clockPeriod() + + // Note that currently lastWordDelay can be smaller than + // firstWordDelay if the packet has no data + pkt->lastWordDelay = (headerCycles + dataCycles) * clockPeriod() + offset; } template <typename SrcType, typename DstType> -BaseBus::Layer<SrcType,DstType>::Layer(DstType& _port, BaseBus& _bus, +BaseXBar::Layer<SrcType,DstType>::Layer(DstType& _port, BaseXBar& _xbar, const std::string& _name) : - port(_port), bus(_bus), _name(_name), state(IDLE), drainManager(NULL), + port(_port), xbar(_xbar), _name(_name), state(IDLE), drainManager(NULL), waitingForPeer(NULL), releaseEvent(this) { } template <typename SrcType, typename DstType> -void BaseBus::Layer<SrcType,DstType>::occupyLayer(Tick until) +void BaseXBar::Layer<SrcType,DstType>::occupyLayer(Tick until) { - // ensure the state is busy at this point, as the bus should + // ensure the state is busy at this point, as the layer should // transition from idle as soon as it has decided to forward the // packet to prevent any follow-on calls to sendTiming seeing an - // unoccupied bus + // unoccupied layer assert(state == BUSY); - // until should never be 0 as express snoops never occupy the bus + // until should never be 0 as express snoops never occupy the layer assert(until != 0); - bus.schedule(releaseEvent, until); + xbar.schedule(releaseEvent, until); // account for the occupied ticks occupancy += until - curTick(); - DPRINTF(BaseBus, "The bus is now busy from tick %d to %d\n", + DPRINTF(BaseXBar, "The crossbar layer is now busy from tick %d to %d\n", curTick(), until); } template <typename SrcType, typename DstType> bool -BaseBus::Layer<SrcType,DstType>::tryTiming(SrcType* src_port) +BaseXBar::Layer<SrcType,DstType>::tryTiming(SrcType* src_port) { // if we are in the retry state, we will not see anything but the // retrying port (or in the case of the snoop ports the snoop // response port that mirrors the actual slave port) as we leave // this state again in zero time if the peer does not immediately - // call the bus when receiving the retry + // call the layer when receiving the retry // first we see if the layer is busy, next we check if the // destination port is already engaged in a transaction waiting @@ -180,13 +176,12 @@ BaseBus::Layer<SrcType,DstType>::tryTiming(SrcType* src_port) // put the port at the end of the retry list waiting for the // layer to be freed up (and in the case of a busy peer, for - // that transaction to go through, and then the bus to free + // that transaction to go through, and then the layer to free // up) waitingForLayer.push_back(src_port); return false; } - // update the state to busy state = BUSY; return true; @@ -194,19 +189,19 @@ BaseBus::Layer<SrcType,DstType>::tryTiming(SrcType* src_port) template <typename SrcType, typename DstType> void -BaseBus::Layer<SrcType,DstType>::succeededTiming(Tick busy_time) +BaseXBar::Layer<SrcType,DstType>::succeededTiming(Tick busy_time) { // we should have gone from idle or retry to busy in the tryTiming // test assert(state == BUSY); - // occupy the bus accordingly + // occupy the layer accordingly occupyLayer(busy_time); } template <typename SrcType, typename DstType> void -BaseBus::Layer<SrcType,DstType>::failedTiming(SrcType* src_port, +BaseXBar::Layer<SrcType,DstType>::failedTiming(SrcType* src_port, Tick busy_time) { // ensure no one got in between and tried to send something to @@ -228,7 +223,7 @@ BaseBus::Layer<SrcType,DstType>::failedTiming(SrcType* src_port, template <typename SrcType, typename DstType> void -BaseBus::Layer<SrcType,DstType>::releaseLayer() +BaseXBar::Layer<SrcType,DstType>::releaseLayer() { // releasing the bus means we should now be idle assert(state == BUSY); @@ -244,7 +239,7 @@ BaseBus::Layer<SrcType,DstType>::releaseLayer() if (waitingForPeer == NULL) retryWaiting(); } else if (waitingForPeer == NULL && drainManager) { - DPRINTF(Drain, "Bus done draining, signaling drain manager\n"); + DPRINTF(Drain, "Crossbar done draining, signaling drain manager\n"); //If we weren't able to drain before, do it now. drainManager->signalDrainDone(); // Clear the drain event once we're done with it. @@ -254,7 +249,7 @@ BaseBus::Layer<SrcType,DstType>::releaseLayer() template <typename SrcType, typename DstType> void -BaseBus::Layer<SrcType,DstType>::retryWaiting() +BaseXBar::Layer<SrcType,DstType>::retryWaiting() { // this should never be called with no one waiting assert(!waitingForLayer.empty()); @@ -271,24 +266,24 @@ BaseBus::Layer<SrcType,DstType>::retryWaiting() waitingForLayer.pop_front(); // tell the port to retry, which in some cases ends up calling the - // bus + // layer again retryingPort->sendRetry(); - // If the bus is still in the retry state, sendTiming wasn't + // If the layer is still in the retry state, sendTiming wasn't // called in zero time (e.g. the cache does this), burn a cycle if (state == RETRY) { // update the state to busy and reset the retrying port, we // have done our bit and sent the retry state = BUSY; - // occupy the bus layer until the next cycle ends - occupyLayer(bus.clockEdge(Cycles(1))); + // occupy the crossbar layer until the next cycle ends + occupyLayer(xbar.clockEdge(Cycles(1))); } } template <typename SrcType, typename DstType> void -BaseBus::Layer<SrcType,DstType>::recvRetry() +BaseXBar::Layer<SrcType,DstType>::recvRetry() { // we should never get a retry without having failed to forward // something to this port @@ -296,13 +291,13 @@ BaseBus::Layer<SrcType,DstType>::recvRetry() // add the port where the failed packet originated to the front of // the waiting ports for the layer, this allows us to call retry - // on the port immediately if the bus layer is idle + // on the port immediately if the crossbar layer is idle waitingForLayer.push_front(waitingForPeer); // we are no longer waiting for the peer waitingForPeer = NULL; - // if the bus layer is idle, retry this port straight away, if we + // if the layer is idle, retry this port straight away, if we // are busy, then simply let the port wait for its turn if (state == IDLE) { retryWaiting(); @@ -312,7 +307,7 @@ BaseBus::Layer<SrcType,DstType>::recvRetry() } PortID -BaseBus::findPort(Addr addr) +BaseXBar::findPort(Addr addr) { // we should never see any address lookups before we've got the // ranges of all connected slave modules @@ -324,7 +319,7 @@ BaseBus::findPort(Addr addr) return dest_id; // Check the address map interval tree - PortMapConstIter i = portMap.find(addr); + auto i = portMap.find(addr); if (i != portMap.end()) { dest_id = i->second; updatePortCache(dest_id, i->first); @@ -334,27 +329,27 @@ BaseBus::findPort(Addr addr) // Check if this matches the default range if (useDefaultRange) { if (defaultRange.contains(addr)) { - DPRINTF(BusAddrRanges, " found addr %#llx on default\n", + DPRINTF(AddrRanges, " found addr %#llx on default\n", addr); return defaultPortID; } } else if (defaultPortID != InvalidPortID) { - DPRINTF(BusAddrRanges, "Unable to find destination for addr %#llx, " + DPRINTF(AddrRanges, "Unable to find destination for addr %#llx, " "will use default port\n", addr); return defaultPortID; } // we should use the range for the default port and it did not // match, or the default port is not set - fatal("Unable to find destination for addr %#llx on bus %s\n", addr, + fatal("Unable to find destination for addr %#llx on %s\n", addr, name()); } -/** Function called by the port when the bus is receiving a range change.*/ +/** Function called by the port when the crossbar is receiving a range change.*/ void -BaseBus::recvRangeChange(PortID master_port_id) +BaseXBar::recvRangeChange(PortID master_port_id) { - DPRINTF(BusAddrRanges, "Received range change from slave port %s\n", + DPRINTF(AddrRanges, "Received range change from slave port %s\n", masterPorts[master_port_id]->getSlavePort().name()); // remember that we got a range from this master port and thus the @@ -371,7 +366,7 @@ BaseBus::recvRangeChange(PortID master_port_id) gotAllAddrRanges &= *r++; } if (gotAllAddrRanges) - DPRINTF(BusAddrRanges, "Got address ranges from all slaves\n"); + DPRINTF(AddrRanges, "Got address ranges from all slaves\n"); } // note that we could get the range from the default port at any @@ -386,7 +381,7 @@ BaseBus::recvRangeChange(PortID master_port_id) AddrRangeList ranges = masterPorts[master_port_id]->getAddrRanges(); if (ranges.size() != 1) - fatal("Bus %s may only have a single default range", + fatal("Crossbar %s may only have a single default range", name()); defaultRange = ranges.front(); @@ -395,7 +390,7 @@ BaseBus::recvRangeChange(PortID master_port_id) // the ports are allowed to update their address ranges // dynamically, so remove any existing entries if (gotAddrRanges[master_port_id]) { - for (PortMapIter p = portMap.begin(); p != portMap.end(); ) { + for (auto p = portMap.begin(); p != portMap.end(); ) { if (p->second == master_port_id) // erasing invalidates the iterator, so advance it // before the deletion takes place @@ -407,11 +402,11 @@ BaseBus::recvRangeChange(PortID master_port_id) AddrRangeList ranges = masterPorts[master_port_id]->getAddrRanges(); - for (AddrRangeConstIter r = ranges.begin(); r != ranges.end(); ++r) { - DPRINTF(BusAddrRanges, "Adding range %s for id %d\n", - r->to_string(), master_port_id); - if (portMap.insert(*r, master_port_id) == portMap.end()) { - PortID conflict_id = portMap.find(*r)->second; + for (const auto& r: ranges) { + DPRINTF(AddrRanges, "Adding range %s for id %d\n", + r.to_string(), master_port_id); + if (portMap.insert(r, master_port_id) == portMap.end()) { + PortID conflict_id = portMap.find(r)->second; fatal("%s has two ports with same range:\n\t%s\n\t%s\n", name(), masterPorts[master_port_id]->getSlavePort().name(), @@ -424,52 +419,51 @@ BaseBus::recvRangeChange(PortID master_port_id) // modules, go ahead and tell our connected master modules in // turn, this effectively assumes a tree structure of the system if (gotAllAddrRanges) { - DPRINTF(BusAddrRanges, "Aggregating bus ranges\n"); - busRanges.clear(); + DPRINTF(AddrRanges, "Aggregating address ranges\n"); + xbarRanges.clear(); // start out with the default range if (useDefaultRange) { if (!gotAddrRanges[defaultPortID]) - fatal("Bus %s uses default range, but none provided", + fatal("Crossbar %s uses default range, but none provided", name()); - busRanges.push_back(defaultRange); - DPRINTF(BusAddrRanges, "-- Adding default %s\n", + xbarRanges.push_back(defaultRange); + DPRINTF(AddrRanges, "-- Adding default %s\n", defaultRange.to_string()); } // merge all interleaved ranges and add any range that is not // a subset of the default range std::vector<AddrRange> intlv_ranges; - for (AddrRangeMap<PortID>::const_iterator r = portMap.begin(); - r != portMap.end(); ++r) { + for (const auto& r: portMap) { // if the range is interleaved then save it for now - if (r->first.interleaved()) { + if (r.first.interleaved()) { // if we already got interleaved ranges that are not // part of the same range, then first do a merge // before we add the new one if (!intlv_ranges.empty() && - !intlv_ranges.back().mergesWith(r->first)) { - DPRINTF(BusAddrRanges, "-- Merging range from %d ranges\n", + !intlv_ranges.back().mergesWith(r.first)) { + DPRINTF(AddrRanges, "-- Merging range from %d ranges\n", intlv_ranges.size()); AddrRange merged_range(intlv_ranges); // next decide if we keep the merged range or not if (!(useDefaultRange && merged_range.isSubset(defaultRange))) { - busRanges.push_back(merged_range); - DPRINTF(BusAddrRanges, "-- Adding merged range %s\n", + xbarRanges.push_back(merged_range); + DPRINTF(AddrRanges, "-- Adding merged range %s\n", merged_range.to_string()); } intlv_ranges.clear(); } - intlv_ranges.push_back(r->first); + intlv_ranges.push_back(r.first); } else { // keep the current range if not a subset of the default if (!(useDefaultRange && - r->first.isSubset(defaultRange))) { - busRanges.push_back(r->first); - DPRINTF(BusAddrRanges, "-- Adding range %s\n", - r->first.to_string()); + r.first.isSubset(defaultRange))) { + xbarRanges.push_back(r.first); + DPRINTF(AddrRanges, "-- Adding range %s\n", + r.first.to_string()); } } } @@ -477,12 +471,12 @@ BaseBus::recvRangeChange(PortID master_port_id) // if there is still interleaved ranges waiting to be merged, // go ahead and do it if (!intlv_ranges.empty()) { - DPRINTF(BusAddrRanges, "-- Merging range from %d ranges\n", + DPRINTF(AddrRanges, "-- Merging range from %d ranges\n", intlv_ranges.size()); AddrRange merged_range(intlv_ranges); if (!(useDefaultRange && merged_range.isSubset(defaultRange))) { - busRanges.push_back(merged_range); - DPRINTF(BusAddrRanges, "-- Adding merged range %s\n", + xbarRanges.push_back(merged_range); + DPRINTF(AddrRanges, "-- Adding merged range %s\n", merged_range.to_string()); } } @@ -492,30 +486,28 @@ BaseBus::recvRangeChange(PortID master_port_id) // as there are no guarantees for when the default range is // update with respect to the other ones if (useDefaultRange) { - for (AddrRangeConstIter r = busRanges.begin(); - r != busRanges.end(); ++r) { + for (const auto& r: xbarRanges) { // see if the new range is partially // overlapping the default range - if (r->intersects(defaultRange) && - !r->isSubset(defaultRange)) + if (r.intersects(defaultRange) && + !r.isSubset(defaultRange)) fatal("Range %s intersects the " \ "default range of %s but is not a " \ - "subset\n", r->to_string(), name()); + "subset\n", r.to_string(), name()); } } // tell all our neighbouring master ports that our address // ranges have changed - for (SlavePortConstIter s = slavePorts.begin(); s != slavePorts.end(); - ++s) - (*s)->sendRangeChange(); + for (const auto& s: slavePorts) + s->sendRangeChange(); } clearPortCache(); } AddrRangeList -BaseBus::getAddrRanges() const +BaseXBar::getAddrRanges() const { // we should never be asked without first having sent a range // change, and the latter is only done once we have all the ranges @@ -523,17 +515,17 @@ BaseBus::getAddrRanges() const assert(gotAllAddrRanges); // at the moment, this never happens, as there are no cycles in - // the range queries and no devices on the master side of a bus + // the range queries and no devices on the master side of a crossbar // (CPU, cache, bridge etc) actually care about the ranges of the // ports they are connected to - DPRINTF(BusAddrRanges, "Received address range request\n"); + DPRINTF(AddrRanges, "Received address range request\n"); - return busRanges; + return xbarRanges; } void -BaseBus::regStats() +BaseXBar::regStats() { using namespace Stats; @@ -556,9 +548,9 @@ BaseBus::regStats() .desc("Packet count per connected master and slave (bytes)") .flags(total | nozero | nonan); - totPktSize + pktSize .init(slavePorts.size(), masterPorts.size()) - .name(name() + ".tot_pkt_size") + .name(name() + ".pkt_size") .desc("Cumulative packet size per connected master and slave (bytes)") .flags(total | nozero | nonan); @@ -570,23 +562,23 @@ BaseBus::regStats() // forwarded to the master (responses and snoop requests) for (int i = 0; i < slavePorts.size(); i++) { pktCount.subname(i, slavePorts[i]->getMasterPort().name()); - totPktSize.subname(i, slavePorts[i]->getMasterPort().name()); + pktSize.subname(i, slavePorts[i]->getMasterPort().name()); for (int j = 0; j < masterPorts.size(); j++) { pktCount.ysubname(j, masterPorts[j]->getSlavePort().name()); - totPktSize.ysubname(j, masterPorts[j]->getSlavePort().name()); + pktSize.ysubname(j, masterPorts[j]->getSlavePort().name()); } } } template <typename SrcType, typename DstType> unsigned int -BaseBus::Layer<SrcType,DstType>::drain(DrainManager *dm) +BaseXBar::Layer<SrcType,DstType>::drain(DrainManager *dm) { //We should check that we're not "doing" anything, and that noone is //waiting. We might be idle but have someone waiting if the device we //contacted for a retry didn't actually retry. if (state != IDLE) { - DPRINTF(Drain, "Bus not drained\n"); + DPRINTF(Drain, "Crossbar not drained\n"); drainManager = dm; return 1; } @@ -595,7 +587,7 @@ BaseBus::Layer<SrcType,DstType>::drain(DrainManager *dm) template <typename SrcType, typename DstType> void -BaseBus::Layer<SrcType,DstType>::regStats() +BaseXBar::Layer<SrcType,DstType>::regStats() { using namespace Stats; @@ -614,9 +606,9 @@ BaseBus::Layer<SrcType,DstType>::regStats() } /** - * Bus layer template instantiations. Could be removed with _impl.hh + * Crossbar layer template instantiations. Could be removed with _impl.hh * file, but since there are only two given options (MasterPort and * SlavePort) it seems a bit excessive at this point. */ -template class BaseBus::Layer<SlavePort,MasterPort>; -template class BaseBus::Layer<MasterPort,SlavePort>; +template class BaseXBar::Layer<SlavePort,MasterPort>; +template class BaseXBar::Layer<MasterPort,SlavePort>; diff --git a/src/mem/bus.hh b/src/mem/xbar.hh index f01a3ae7f..7f3c17677 100644 --- a/src/mem/bus.hh +++ b/src/mem/xbar.hh @@ -1,5 +1,5 @@ /* - * Copyright (c) 2011-2013 ARM Limited + * Copyright (c) 2011-2014 ARM Limited * All rights reserved * * The license below extends only to copyright in the software and shall @@ -45,53 +45,47 @@ /** * @file - * Declaration of an abstract bus base class. + * Declaration of an abstract crossbar base class. */ -#ifndef __MEM_BUS_HH__ -#define __MEM_BUS_HH__ +#ifndef __MEM_XBAR_HH__ +#define __MEM_XBAR_HH__ #include <deque> #include "base/addr_range_map.hh" #include "base/types.hh" #include "mem/mem_object.hh" -#include "params/BaseBus.hh" +#include "params/BaseXBar.hh" #include "sim/stats.hh" /** - * The base bus contains the common elements of the non-coherent and - * coherent bus. It is an abstract class that does not have any of the - * functionality relating to the actual reception and transmission of - * packets, as this is left for the subclasses. + * The base crossbar contains the common elements of the non-coherent + * and coherent crossbar. It is an abstract class that does not have + * any of the functionality relating to the actual reception and + * transmission of packets, as this is left for the subclasses. * - * The BaseBus is responsible for the basic flow control (busy or + * The BaseXBar is responsible for the basic flow control (busy or * not), the administration of retries, and the address decoding. */ -class BaseBus : public MemObject +class BaseXBar : public MemObject { protected: /** - * A bus layer is an internal bus structure with its own flow - * control and arbitration. Hence, a single-layer bus mimics a - * traditional off-chip tri-state bus (like PCI), where only one - * set of wires are shared. For on-chip buses, a good starting - * point is to have three layers, for requests, responses, and - * snoop responses respectively (snoop requests are instantaneous - * and do not need any flow control or arbitration). This case is - * similar to AHB and some OCP configurations. - * - * As a further extensions beyond the three-layer bus, a future - * multi-layer bus has with one layer per connected slave port - * provides a full or partial crossbar, like AXI, OCP, PCIe etc. + * A layer is an internal crossbar arbitration point with its own + * flow control. Each layer is a converging multiplexer tree. By + * instantiating one layer per destination port (and per packet + * type, i.e. request, response, snoop request and snoop + * response), we model full crossbar structures like AXI, ACE, + * PCIe, etc. * * The template parameter, PortClass, indicates the destination - * port type for the bus. The retry list holds either master ports - * or slave ports, depending on the direction of the layer. Thus, - * a request layer has a retry list containing slave ports, - * whereas a response layer holds master ports. + * port type for the layer. The retry list holds either master + * ports or slave ports, depending on the direction of the + * layer. Thus, a request layer has a retry list containing slave + * ports, whereas a response layer holds master ports. */ template <typename SrcType, typename DstType> class Layer : public Drainable @@ -100,17 +94,17 @@ class BaseBus : public MemObject public: /** - * Create a bus layer and give it a name. The bus layer uses - * the bus an event manager. + * Create a layer and give it a name. The layer uses + * the crossbar an event manager. * * @param _port destination port the layer converges at - * @param _bus the bus this layer belongs to + * @param _xbar the crossbar this layer belongs to * @param _name the layer's name */ - Layer(DstType& _port, BaseBus& _bus, const std::string& _name); + Layer(DstType& _port, BaseXBar& _xbar, const std::string& _name); /** - * Drain according to the normal semantics, so that the bus + * Drain according to the normal semantics, so that the crossbar * can tell the layer to drain, and pass an event to signal * back when drained. * @@ -121,27 +115,27 @@ class BaseBus : public MemObject unsigned int drain(DrainManager *dm); /** - * Get the bus layer's name + * Get the crossbar layer's name */ - const std::string name() const { return bus.name() + _name; } + const std::string name() const { return xbar.name() + _name; } /** - * Determine if the bus layer accepts a packet from a specific + * Determine if the layer accepts a packet from a specific * port. If not, the port in question is also added to the * retry list. In either case the state of the layer is * updated accordingly. * * @param port Source port presenting the packet * - * @return True if the bus layer accepts the packet + * @return True if the layer accepts the packet */ bool tryTiming(SrcType* src_port); /** * Deal with a destination port accepting a packet by potentially * removing the source port from the retry list (if retrying) and - * occupying the bus layer accordingly. + * occupying the layer accordingly. * * @param busy_time Time to spend as a result of a successful send */ @@ -150,7 +144,7 @@ class BaseBus : public MemObject /** * Deal with a destination port not accepting a packet by * potentially adding the source port to the retry list (if - * not already at the front) and occupying the bus layer + * not already at the front) and occupying the layer * accordingly. * * @param src_port Source port @@ -158,7 +152,7 @@ class BaseBus : public MemObject */ void failedTiming(SrcType* src_port, Tick busy_time); - /** Occupy the bus layer until until */ + /** Occupy the layer until until */ void occupyLayer(Tick until); /** @@ -184,31 +178,31 @@ class BaseBus : public MemObject /** The destination port this layer converges at. */ DstType& port; - /** The bus this layer is a part of. */ - BaseBus& bus; + /** The crossbar this layer is a part of. */ + BaseXBar& xbar; /** A name for this layer. */ std::string _name; /** - * We declare an enum to track the state of the bus layer. The - * starting point is an idle state where the bus layer is - * waiting for a packet to arrive. Upon arrival, the bus layer + * We declare an enum to track the state of the layer. The + * starting point is an idle state where the layer is waiting + * for a packet to arrive. Upon arrival, the layer * transitions to the busy state, where it remains either * until the packet transfer is done, or the header time is - * spent. Once the bus layer leaves the busy state, it can + * spent. Once the layer leaves the busy state, it can * either go back to idle, if no packets have arrived while it - * was busy, or the bus layer goes on to retry the first port + * was busy, or the layer goes on to retry the first port * in waitingForLayer. A similar transition takes place from - * idle to retry if the bus layer receives a retry from one of + * idle to retry if the layer receives a retry from one of * its connected ports. The retry state lasts until the port * in questions calls sendTiming and returns control to the - * bus layer, or goes to a busy state if the port does not + * layer, or goes to a busy state if the port does not * immediately react to the retry by calling sendTiming. */ enum State { IDLE, BUSY, RETRY }; - /** track the state of the bus layer */ + /** track the state of the layer */ State state; /** manager to signal when drained */ @@ -227,7 +221,7 @@ class BaseBus : public MemObject SrcType* waitingForPeer; /** - * Release the bus layer after being occupied and return to an + * Release the layer after being occupied and return to an * idle state where we proceed to send a retry to any * potential waiting port, or drain if asked to do so. */ @@ -238,7 +232,7 @@ class BaseBus : public MemObject /** * Stats for occupancy and utilization. These stats capture - * the time the bus spends in the busy state and are thus only + * the time the layer spends in the busy state and are thus only * relevant when the memory system is in timing mode. */ Stats::Scalar occupancy; @@ -248,27 +242,27 @@ class BaseBus : public MemObject /** cycles of overhead per transaction */ const Cycles headerCycles; - /** the width of the bus in bytes */ + /** the width of the xbar in bytes */ const uint32_t width; - typedef AddrRangeMap<PortID>::iterator PortMapIter; - typedef AddrRangeMap<PortID>::const_iterator PortMapConstIter; AddrRangeMap<PortID> portMap; - /** all contigous ranges seen by this bus */ - AddrRangeList busRanges; + /** all contigous ranges seen by this crossbar */ + AddrRangeList xbarRanges; AddrRange defaultRange; /** - * Function called by the port when the bus is recieving a range change. + * Function called by the port when the crossbar is recieving a + * range change. * * @param master_port_id id of the port that received the change */ void recvRangeChange(PortID master_port_id); - /** Find which port connected to this bus (if any) should be given a packet - * with this address. + /** Find which port connected to this crossbar (if any) should be + * given a packet with this address. + * * @param addr Address to find port for. * @return id of port that the packet should be sent out of. */ @@ -322,7 +316,7 @@ class BaseBus : public MemObject } /** - * Return the address ranges the bus is responsible for. + * Return the address ranges the crossbar is responsible for. * * @return a list of non-overlapping address ranges */ @@ -330,31 +324,25 @@ class BaseBus : public MemObject /** * Calculate the timing parameters for the packet. Updates the - * busFirstWordDelay and busLastWordDelay fields of the packet + * firstWordDelay and lastWordDelay fields of the packet * object with the relative number of ticks required to transmit * the header and the first word, and the last word, respectively. */ void calcPacketTiming(PacketPtr pkt); /** - * Remember for each of the master ports of the bus if we got an - * address range from the connected slave. For convenience, also - * keep track of if we got ranges from all the slave modules or - * not. + * Remember for each of the master ports of the crossbar if we got + * an address range from the connected slave. For convenience, + * also keep track of if we got ranges from all the slave modules + * or not. */ std::vector<bool> gotAddrRanges; bool gotAllAddrRanges; - /** The master and slave ports of the bus */ + /** The master and slave ports of the crossbar */ std::vector<SlavePort*> slavePorts; std::vector<MasterPort*> masterPorts; - /** Convenience typedefs. */ - typedef std::vector<SlavePort*>::iterator SlavePortIter; - typedef std::vector<MasterPort*>::iterator MasterPortIter; - typedef std::vector<SlavePort*>::const_iterator SlavePortConstIter; - typedef std::vector<MasterPort*>::const_iterator MasterPortConstIter; - /** Port that handles requests that don't match any of the interfaces.*/ PortID defaultPortID; @@ -364,29 +352,28 @@ class BaseBus : public MemObject addresses not handled by another port to default device. */ const bool useDefaultRange; - BaseBus(const BaseBusParams *p); + BaseXBar(const BaseXBarParams *p); - virtual ~BaseBus(); + virtual ~BaseXBar(); /** * Stats for transaction distribution and data passing through the - * bus. The transaction distribution is globally counting + * crossbar. The transaction distribution is globally counting * different types of commands. The packet count and total packet - * size are two-dimensional vectors that are indexed by the bus + * size are two-dimensional vectors that are indexed by the * slave port and master port id (thus the neighbouring master and * neighbouring slave), summing up both directions (request and * response). */ - Stats::Formula throughput; Stats::Vector transDist; Stats::Vector2d pktCount; - Stats::Vector2d totPktSize; + Stats::Vector2d pktSize; public: virtual void init(); - /** A function used to return the port associated with this bus object. */ + /** A function used to return the port associated with this object. */ BaseMasterPort& getMasterPort(const std::string& if_name, PortID idx = InvalidPortID); BaseSlavePort& getSlavePort(const std::string& if_name, @@ -398,4 +385,4 @@ class BaseBus : public MemObject }; -#endif //__MEM_BUS_HH__ +#endif //__MEM_XBAR_HH__ diff --git a/src/python/m5/params.py b/src/python/m5/params.py index cf5764530..6c4a61d6a 100644 --- a/src/python/m5/params.py +++ b/src/python/m5/params.py @@ -1870,7 +1870,7 @@ class SlavePort(Port): raise TypeError, 'wrong number of arguments' # VectorPort description object. Like Port, but represents a vector -# of connections (e.g., as on a Bus). +# of connections (e.g., as on a XBar). class VectorPort(Port): def __init__(self, *args): self.isVec = True diff --git a/src/python/m5/util/dot_writer.py b/src/python/m5/util/dot_writer.py index ab4687f7f..f54d6a1ab 100644 --- a/src/python/m5/util/dot_writer.py +++ b/src/python/m5/util/dot_writer.py @@ -173,7 +173,7 @@ def dot_create_node(simNode, full_path, label): class NodeType: SYS = 0 CPU = 1 - BUS = 2 + XBAR = 2 MEM = 3 DEV = 4 OTHER = 5 @@ -190,8 +190,8 @@ def get_node_type(simNode): elif 'PioDevice' in dir(m5.objects) and \ isinstance(simNode, m5.objects.PioDevice): return NodeType.DEV - elif isinstance(simNode, m5.objects.BaseBus): - return NodeType.BUS + elif isinstance(simNode, m5.objects.BaseXBar): + return NodeType.XBAR elif isinstance(simNode, m5.objects.AbstractMemory): return NodeType.MEM else: @@ -205,7 +205,7 @@ def get_type_colour(nodeType): return (228, 231, 235) elif nodeType == NodeType.CPU: return (187, 198, 217) - elif nodeType == NodeType.BUS: + elif nodeType == NodeType.XBAR: return (111, 121, 140) elif nodeType == NodeType.MEM: return (94, 89, 88) |