#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;
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);
/** Snoop all relevant ports atomicly. */
void 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
};
+ class BusFreeEvent : public Event
+ {
+ Bus * bus;
+
+ public:
+ BusFreeEvent(Bus * _bus);
+ void process();
+ const char *description();
+ };
+
+ BusFreeEvent busIdle;
+
+ void occupyBus(int numCycles);
+
+ Port * retryingPort;
+
/** An array of pointers to the peer port interfaces
connected to this bus.*/
std::vector<Port*> interfaces;
* original send failed for whatever reason.*/
std::list<Port*> retryList;
+ void addToRetryList(Port * port)
+ {
+ if (!retryingPort) {
+ // The device wasn't retrying a packet, or wasn't at an appropriate
+ // time.
+ retryList.push_back(port);
+ } else {
+ // The device was retrying a packet. It didn't work, so we'll leave
+ // it at the head of the retry list.
+ retryingPort = NULL;
+
+ // We shouldn't be receiving a packet from one port when a different
+ // one is retrying.
+ assert(port == retryingPort);
+ }
+ }
+
/** Port that handles requests that don't match any of the interfaces.*/
Port *defaultPort;
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), retryingPort(NULL), defaultPort(NULL)
+ {
+ //Both the width and clock period must be positive
+ assert(width);
+ assert(clock);
+ }
};