summaryrefslogtreecommitdiff
path: root/src/mem/bridge.hh
diff options
context:
space:
mode:
Diffstat (limited to 'src/mem/bridge.hh')
-rw-r--r--src/mem/bridge.hh214
1 files changed, 92 insertions, 122 deletions
diff --git a/src/mem/bridge.hh b/src/mem/bridge.hh
index 2672a6e8c..8a5cbf92a 100644
--- a/src/mem/bridge.hh
+++ b/src/mem/bridge.hh
@@ -46,132 +46,127 @@
class Bridge : public MemObject
{
- public:
- enum Side
+ protected:
+ /** Decleration of the buses port type, one will be instantiated for each
+ of the interfaces connecting to the bus. */
+ class BridgePort : public Port
{
- SideA,
- SideB
- };
+ /** A pointer to the bridge to which this port belongs. */
+ Bridge *bridge;
- protected:
- /** Function called by the port when the bus is recieving a Timing
- transaction.*/
- bool recvTiming(Packet *pkt, Side id);
+ /**
+ * Pointer to the port on the other side of the bridge
+ * (connected to the other bus).
+ */
+ BridgePort *otherPort;
- /** Function called by the port when the bus is recieving a Atomic
- transaction.*/
- Tick recvAtomic(Packet *pkt, Side id);
+ /** Minimum delay though this bridge. */
+ Tick delay;
- /** Function called by the port when the bus is recieving a Functional
- transaction.*/
- void recvFunctional(Packet *pkt, Side id);
+ class PacketBuffer : public Packet::SenderState {
- /** Function called by the port when the bus is recieving a status change.*/
- void recvStatusChange(Port::Status status, Side id);
+ public:
+ Tick ready;
+ Packet *pkt;
+ Packet::SenderState *origSenderState;
+ short origSrc;
+ bool expectResponse;
- /** Process address range request.
- * @param resp addresses that we can respond to
- * @param snoop addresses that we would like to snoop
- * @param id ide of the busport that made the request.
- */
- void addressRanges(AddrRangeList &resp, AddrRangeList &snoop, Side id);
+ PacketBuffer(Packet *_pkt, Tick t)
+ : ready(t), pkt(_pkt),
+ origSenderState(_pkt->senderState), origSrc(_pkt->getSrc()),
+ expectResponse(_pkt->needsResponse())
+ {
+ pkt->senderState = this;
+ }
+ void fixResponse(Packet *pkt)
+ {
+ assert(pkt->senderState == this);
+ pkt->setDest(origSrc);
+ pkt->senderState = origSenderState;
+ }
+ };
- /** Event that the SendEvent calls when it fires. This code must reschedule
- * the send event as required. */
- void timerEvent();
+ /**
+ * Outbound packet queue. Packets are held in this queue for a
+ * specified delay to model the processing delay of the
+ * bridge.
+ */
+ std::list<PacketBuffer*> sendQueue;
- /** Decleration of the buses port type, one will be instantiated for each
- of the interfaces connecting to the bus. */
- class BridgePort : public Port
- {
- /** A pointer to the bus to which this port belongs. */
- Bridge *bridge;
+ int outstandingResponses;
+
+ /** Max queue size for outbound packets */
+ int queueLimit;
+
+ /**
+ * Is this side blocked from accepting outbound packets?
+ */
+ bool queueFull() { return (sendQueue.size() == queueLimit); }
+
+ bool queueForSendTiming(Packet *pkt);
+
+ void finishSend(PacketBuffer *buf);
+
+ /**
+ * Handle send event, scheduled when the packet at the head of
+ * the outbound queue is ready to transmit (for timing
+ * accesses only).
+ */
+ void trySend();
+
+ class SendEvent : public Event
+ {
+ BridgePort *port;
+
+ public:
+ SendEvent(BridgePort *p)
+ : Event(&mainEventQueue), port(p) {}
+
+ virtual void process() { port->trySend(); }
- /** A id to keep track of the intercafe ID this port is connected to. */
- Bridge::Side side;
+ virtual const char *description() { return "bridge send event"; }
+ };
+
+ SendEvent sendEvent;
public:
/** Constructor for the BusPort.*/
- BridgePort(Bridge *_bridge, Side _side)
- : Port(""), bridge(_bridge), side(_side)
- { }
-
- int numQueued() { return outbound.size(); }
+ BridgePort(const std::string &_name,
+ Bridge *_bridge, BridgePort *_otherPort,
+ int _delay, int _queueLimit);
protected:
- /** Data this is waiting to be transmitted. */
- std::list<std::pair<Packet*, Tick> > outbound;
-
- void sendPkt(Packet *pkt);
- void sendPkt(std::pair<Packet*, Tick> p);
- /** When reciving a timing request from the peer port,
+ /** When receiving a timing request from the peer port,
pass it to the bridge. */
- virtual bool recvTiming(Packet *pkt)
- { return bridge->recvTiming(pkt, side); }
+ virtual bool recvTiming(Packet *pkt);
- /** When reciving a retry request from the peer port,
+ /** When receiving a retry request from the peer port,
pass it to the bridge. */
virtual Packet* recvRetry();
- /** When reciving a Atomic requestfrom the peer port,
+ /** When receiving a Atomic requestfrom the peer port,
pass it to the bridge. */
- virtual Tick recvAtomic(Packet *pkt)
- { return bridge->recvAtomic(pkt, side); }
+ virtual Tick recvAtomic(Packet *pkt);
- /** When reciving a Functional request from the peer port,
+ /** When receiving a Functional request from the peer port,
pass it to the bridge. */
- virtual void recvFunctional(Packet *pkt)
- { bridge->recvFunctional(pkt, side); }
+ virtual void recvFunctional(Packet *pkt);
- /** When reciving a status changefrom the peer port,
+ /** When receiving a status changefrom the peer port,
pass it to the bridge. */
- virtual void recvStatusChange(Status status)
- { bridge->recvStatusChange(status, side); }
+ virtual void recvStatusChange(Status status);
- /** When reciving a address range request the peer port,
+ /** When receiving a address range request the peer port,
pass it to the bridge. */
- virtual void getDeviceAddressRanges(AddrRangeList &resp, AddrRangeList &snoop)
- { bridge->addressRanges(resp, snoop, side); }
-
- friend class Bridge;
- };
-
- class SendEvent : public Event
- {
- Bridge *bridge;
-
- SendEvent(Bridge *b)
- : Event(&mainEventQueue), bridge(b) {}
-
- virtual void process() { bridge->timerEvent(); }
-
- virtual const char *description() { return "bridge delay event"; }
- friend class Bridge;
+ virtual void getDeviceAddressRanges(AddrRangeList &resp,
+ AddrRangeList &snoop);
};
- SendEvent sendEvent;
-
- /** Sides of the bus bridges. */
- BridgePort* sideA;
- BridgePort* sideB;
-
- /** inbound queues on both sides. */
- std::list<std::pair<Packet*, Tick> > inboundA;
- std::list<std::pair<Packet*, Tick> > inboundB;
-
- /** The size of the queue for data coming into side a */
- int queueSizeA;
- int queueSizeB;
-
- /* if the side is blocked or not. */
- bool blockedA;
- bool blockedB;
-
- /** Miminum delay though this bridge. */
- Tick delay;
+ BridgePort portA, portB;
/** If this bridge should acknowledge writes. */
bool ackWrites;
@@ -179,36 +174,11 @@ class Bridge : public MemObject
public:
/** A function used to return the port associated with this bus object. */
- virtual Port *getPort(const std::string &if_name)
- {
- if (if_name == "side_a") {
- if (sideA != NULL)
- panic("bridge side a already connected to.");
- sideA = new BridgePort(this, SideA);
- return sideA;
- } else if (if_name == "side_b") {
- if (sideB != NULL)
- panic("bridge side b already connected to.");
- sideB = new BridgePort(this, SideB);
- return sideB;
- } else
- return NULL;
- }
+ virtual Port *getPort(const std::string &if_name);
virtual void init();
- Bridge(const std::string &n, int qsa, int qsb, Tick _delay, int write_ack)
- : MemObject(n), sendEvent(this), sideA(NULL), sideB(NULL),
- queueSizeA(qsa), queueSizeB(qsb), blockedA(false), blockedB(false),
- delay(_delay), ackWrites(write_ack)
- {}
-
- /** Check if the port should block/unblock after recieving/sending a packet.
- * */
- void blockCheck(Side id);
-
- friend class Bridge::SendEvent;
-
+ Bridge(const std::string &n, int qsa, int qsb, Tick _delay, int write_ack);
};
#endif //__MEM_BUS_HH__