bridge.hh (2640:266b80dd5eca) bridge.hh (2643:67ac7b611c56)
1/*
2 * Copyright (c) 2006 The Regents of The University of Michigan
3 * All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions are
7 * met: redistributions of source code must retain the above copyright
8 * notice, this list of conditions and the following disclaimer;

--- 32 unchanged lines hidden (view full) ---

41
42#include "mem/mem_object.hh"
43#include "mem/packet.hh"
44#include "mem/port.hh"
45#include "sim/eventq.hh"
46
47class Bridge : public MemObject
48{
1/*
2 * Copyright (c) 2006 The Regents of The University of Michigan
3 * All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions are
7 * met: redistributions of source code must retain the above copyright
8 * notice, this list of conditions and the following disclaimer;

--- 32 unchanged lines hidden (view full) ---

41
42#include "mem/mem_object.hh"
43#include "mem/packet.hh"
44#include "mem/port.hh"
45#include "sim/eventq.hh"
46
47class Bridge : public MemObject
48{
49 public:
50 enum Side
49 protected:
50 /** Decleration of the buses port type, one will be instantiated for each
51 of the interfaces connecting to the bus. */
52 class BridgePort : public Port
51 {
53 {
52 SideA,
53 SideB
54 };
54 /** A pointer to the bridge to which this port belongs. */
55 Bridge *bridge;
55
56
56 protected:
57 /** Function called by the port when the bus is recieving a Timing
58 transaction.*/
59 bool recvTiming(Packet *pkt, Side id);
57 /**
58 * Pointer to the port on the other side of the bridge
59 * (connected to the other bus).
60 */
61 BridgePort *otherPort;
60
62
61 /** Function called by the port when the bus is recieving a Atomic
62 transaction.*/
63 Tick recvAtomic(Packet *pkt, Side id);
63 /** Minimum delay though this bridge. */
64 Tick delay;
64
65
65 /** Function called by the port when the bus is recieving a Functional
66 transaction.*/
67 void recvFunctional(Packet *pkt, Side id);
66 class PacketBuffer : public Packet::SenderState {
68
67
69 /** Function called by the port when the bus is recieving a status change.*/
70 void recvStatusChange(Port::Status status, Side id);
68 public:
69 Tick ready;
70 Packet *pkt;
71 Packet::SenderState *origSenderState;
72 short origSrc;
73 bool expectResponse;
71
74
72 /** Process address range request.
73 * @param resp addresses that we can respond to
74 * @param snoop addresses that we would like to snoop
75 * @param id ide of the busport that made the request.
76 */
77 void addressRanges(AddrRangeList &resp, AddrRangeList &snoop, Side id);
75 PacketBuffer(Packet *_pkt, Tick t)
76 : ready(t), pkt(_pkt),
77 origSenderState(_pkt->senderState), origSrc(_pkt->getSrc()),
78 expectResponse(_pkt->needsResponse())
79 {
80 pkt->senderState = this;
81 }
78
82
83 void fixResponse(Packet *pkt)
84 {
85 assert(pkt->senderState == this);
86 pkt->setDest(origSrc);
87 pkt->senderState = origSenderState;
88 }
89 };
79
90
80 /** Event that the SendEvent calls when it fires. This code must reschedule
81 * the send event as required. */
82 void timerEvent();
91 /**
92 * Outbound packet queue. Packets are held in this queue for a
93 * specified delay to model the processing delay of the
94 * bridge.
95 */
96 std::list<PacketBuffer*> sendQueue;
83
97
84 /** Decleration of the buses port type, one will be instantiated for each
85 of the interfaces connecting to the bus. */
86 class BridgePort : public Port
87 {
88 /** A pointer to the bus to which this port belongs. */
89 Bridge *bridge;
98 int outstandingResponses;
90
99
91 /** A id to keep track of the intercafe ID this port is connected to. */
92 Bridge::Side side;
100 /** Max queue size for outbound packets */
101 int queueLimit;
93
102
103 /**
104 * Is this side blocked from accepting outbound packets?
105 */
106 bool queueFull() { return (sendQueue.size() == queueLimit); }
107
108 bool queueForSendTiming(Packet *pkt);
109
110 void finishSend(PacketBuffer *buf);
111
112 /**
113 * Handle send event, scheduled when the packet at the head of
114 * the outbound queue is ready to transmit (for timing
115 * accesses only).
116 */
117 void trySend();
118
119 class SendEvent : public Event
120 {
121 BridgePort *port;
122
123 public:
124 SendEvent(BridgePort *p)
125 : Event(&mainEventQueue), port(p) {}
126
127 virtual void process() { port->trySend(); }
128
129 virtual const char *description() { return "bridge send event"; }
130 };
131
132 SendEvent sendEvent;
133
94 public:
95
96 /** Constructor for the BusPort.*/
134 public:
135
136 /** Constructor for the BusPort.*/
97 BridgePort(Bridge *_bridge, Side _side)
98 : Port(""), bridge(_bridge), side(_side)
99 { }
137 BridgePort(const std::string &_name,
138 Bridge *_bridge, BridgePort *_otherPort,
139 int _delay, int _queueLimit);
100
140
101 int numQueued() { return outbound.size(); }
102
103 protected:
141 protected:
104 /** Data this is waiting to be transmitted. */
105 std::list<std::pair<Packet*, Tick> > outbound;
106
142
107 void sendPkt(Packet *pkt);
108 void sendPkt(std::pair<Packet*, Tick> p);
109
110 /** When reciving a timing request from the peer port,
143 /** When receiving a timing request from the peer port,
111 pass it to the bridge. */
144 pass it to the bridge. */
112 virtual bool recvTiming(Packet *pkt)
113 { return bridge->recvTiming(pkt, side); }
145 virtual bool recvTiming(Packet *pkt);
114
146
115 /** When reciving a retry request from the peer port,
147 /** When receiving a retry request from the peer port,
116 pass it to the bridge. */
117 virtual Packet* recvRetry();
118
148 pass it to the bridge. */
149 virtual Packet* recvRetry();
150
119 /** When reciving a Atomic requestfrom the peer port,
151 /** When receiving a Atomic requestfrom the peer port,
120 pass it to the bridge. */
152 pass it to the bridge. */
121 virtual Tick recvAtomic(Packet *pkt)
122 { return bridge->recvAtomic(pkt, side); }
153 virtual Tick recvAtomic(Packet *pkt);
123
154
124 /** When reciving a Functional request from the peer port,
155 /** When receiving a Functional request from the peer port,
125 pass it to the bridge. */
156 pass it to the bridge. */
126 virtual void recvFunctional(Packet *pkt)
127 { bridge->recvFunctional(pkt, side); }
157 virtual void recvFunctional(Packet *pkt);
128
158
129 /** When reciving a status changefrom the peer port,
159 /** When receiving a status changefrom the peer port,
130 pass it to the bridge. */
160 pass it to the bridge. */
131 virtual void recvStatusChange(Status status)
132 { bridge->recvStatusChange(status, side); }
161 virtual void recvStatusChange(Status status);
133
162
134 /** When reciving a address range request the peer port,
163 /** When receiving a address range request the peer port,
135 pass it to the bridge. */
164 pass it to the bridge. */
136 virtual void getDeviceAddressRanges(AddrRangeList &resp, AddrRangeList &snoop)
137 { bridge->addressRanges(resp, snoop, side); }
138
139 friend class Bridge;
165 virtual void getDeviceAddressRanges(AddrRangeList &resp,
166 AddrRangeList &snoop);
140 };
141
167 };
168
142 class SendEvent : public Event
143 {
144 Bridge *bridge;
169 BridgePort portA, portB;
145
170
146 SendEvent(Bridge *b)
147 : Event(&mainEventQueue), bridge(b) {}
148
149 virtual void process() { bridge->timerEvent(); }
150
151 virtual const char *description() { return "bridge delay event"; }
152 friend class Bridge;
153 };
154
155 SendEvent sendEvent;
156
157 /** Sides of the bus bridges. */
158 BridgePort* sideA;
159 BridgePort* sideB;
160
161 /** inbound queues on both sides. */
162 std::list<std::pair<Packet*, Tick> > inboundA;
163 std::list<std::pair<Packet*, Tick> > inboundB;
164
165 /** The size of the queue for data coming into side a */
166 int queueSizeA;
167 int queueSizeB;
168
169 /* if the side is blocked or not. */
170 bool blockedA;
171 bool blockedB;
172
173 /** Miminum delay though this bridge. */
174 Tick delay;
175
176 /** If this bridge should acknowledge writes. */
177 bool ackWrites;
178
179 public:
180
181 /** A function used to return the port associated with this bus object. */
171 /** If this bridge should acknowledge writes. */
172 bool ackWrites;
173
174 public:
175
176 /** A function used to return the port associated with this bus object. */
182 virtual Port *getPort(const std::string &if_name)
183 {
184 if (if_name == "side_a") {
185 if (sideA != NULL)
186 panic("bridge side a already connected to.");
187 sideA = new BridgePort(this, SideA);
188 return sideA;
189 } else if (if_name == "side_b") {
190 if (sideB != NULL)
191 panic("bridge side b already connected to.");
192 sideB = new BridgePort(this, SideB);
193 return sideB;
194 } else
195 return NULL;
196 }
177 virtual Port *getPort(const std::string &if_name);
197
198 virtual void init();
199
178
179 virtual void init();
180
200 Bridge(const std::string &n, int qsa, int qsb, Tick _delay, int write_ack)
201 : MemObject(n), sendEvent(this), sideA(NULL), sideB(NULL),
202 queueSizeA(qsa), queueSizeB(qsb), blockedA(false), blockedB(false),
203 delay(_delay), ackWrites(write_ack)
204 {}
205
206 /** Check if the port should block/unblock after recieving/sending a packet.
207 * */
208 void blockCheck(Side id);
209
210 friend class Bridge::SendEvent;
211
181 Bridge(const std::string &n, int qsa, int qsb, Tick _delay, int write_ack);
212};
213
214#endif //__MEM_BUS_HH__
182};
183
184#endif //__MEM_BUS_HH__