diff options
Diffstat (limited to 'src/mem/bus.hh')
-rw-r--r-- | src/mem/bus.hh | 94 |
1 files changed, 75 insertions, 19 deletions
diff --git a/src/mem/bus.hh b/src/mem/bus.hh index 941389296..509b8cf9b 100644 --- a/src/mem/bus.hh +++ b/src/mem/bus.hh @@ -46,13 +46,20 @@ #include "mem/packet.hh" #include "mem/port.hh" #include "mem/request.hh" +#include "sim/eventq.hh" class Bus : public MemObject { /** a globally unique id for this bus. */ int busId; + /** the clock speed for the bus */ + int clock; + /** the width of the bus in bytes */ + int width; + /** the next tick at which the bus will be idle */ + Tick tickNextIdle; - static const int defaultId = -1; + static const int defaultId = -3; //Make it unique from Broadcast struct DevMap { int portId; @@ -62,9 +69,6 @@ class Bus : public MemObject AddrRangeList defaultRange; std::vector<DevMap> portSnoopList; - std::vector<int> snoopCallbacks; - - /** Function called by the port when the bus is recieving a Timing transaction.*/ bool recvTiming(Packet *pkt); @@ -103,18 +107,16 @@ class Bus : public MemObject std::vector<int> findSnoopPorts(Addr addr, int id); /** Snoop all relevant ports atomicly. */ - void atomicSnoop(Packet *pkt); + Tick atomicSnoop(Packet *pkt); - /** Snoop for NACK and Blocked in phase 1 - * @return True if succeds. - */ - bool timingSnoopPhase1(Packet *pkt); + /** Snoop all relevant ports functionally. */ + void functionalSnoop(Packet *pkt); - /** @todo Don't need to commit all snoops just those that need it - *(register somehow). */ - /** Commit all snoops now that we know if any of them would have blocked. + /** Call snoop on caches, be sure to set SNOOP_COMMIT bit if you want + * the snoop to happen + * @return True if succeds. */ - void timingSnoopPhase2(Packet *pkt); + bool timingSnoop(Packet *pkt); /** Process address range request. * @param resp addresses that we can respond to @@ -123,11 +125,15 @@ class Bus : public MemObject */ void addressRanges(AddrRangeList &resp, AddrRangeList &snoop, int id); + /** Occupy the bus with transmitting the packet pkt */ + void occupyBus(PacketPtr pkt); /** Declaration of the buses port type, one will be instantiated for each of the interfaces connecting to the bus. */ class BusPort : public Port { + bool _onRetryList; + /** A pointer to the bus to which this port belongs. */ Bus *bus; @@ -138,9 +144,15 @@ class Bus : public MemObject /** Constructor for the BusPort.*/ BusPort(const std::string &_name, Bus *_bus, int _id) - : Port(_name), bus(_bus), id(_id) + : Port(_name), _onRetryList(false), bus(_bus), id(_id) { } + bool onRetryList() + { return _onRetryList; } + + void onRetryList(bool newVal) + { _onRetryList = newVal; } + protected: /** When reciving a timing request from the peer port (at id), @@ -181,16 +193,52 @@ class Bus : public MemObject }; + class BusFreeEvent : public Event + { + Bus * bus; + + public: + BusFreeEvent(Bus * _bus); + void process(); + const char *description(); + }; + + BusFreeEvent busIdle; + + bool inRetry; + /** An array of pointers to the peer port interfaces connected to this bus.*/ - std::vector<Port*> interfaces; + std::vector<BusPort*> interfaces; /** An array of pointers to ports that retry should be called on because the * original send failed for whatever reason.*/ - std::list<Port*> retryList; + std::list<BusPort*> retryList; + + void addToRetryList(BusPort * port) + { + if (!inRetry) { + // The device wasn't retrying a packet, or wasn't at an appropriate + // time. + assert(!port->onRetryList()); + port->onRetryList(true); + retryList.push_back(port); + } else { + if (port->onRetryList()) { + // The device was retrying a packet. It didn't work, so we'll leave + // it at the head of the retry list. + assert(port == retryList.front()); + inRetry = false; + } + else { + port->onRetryList(true); + retryList.push_back(port); + } + } + } /** Port that handles requests that don't match any of the interfaces.*/ - Port *defaultPort; + BusPort *defaultPort; public: @@ -199,8 +247,16 @@ class Bus : public MemObject virtual void init(); - Bus(const std::string &n, int bus_id) - : MemObject(n), busId(bus_id), defaultPort(NULL) {} + Bus(const std::string &n, int bus_id, int _clock, int _width) + : MemObject(n), busId(bus_id), clock(_clock), width(_width), + tickNextIdle(0), busIdle(this), inRetry(false), defaultPort(NULL) + { + //Both the width and clock period must be positive + if (width <= 0) + fatal("Bus width must be positive\n"); + if (clock <= 0) + fatal("Bus clock period must be positive\n"); + } }; |