gem5 v24.0.0.0
Loading...
Searching...
No Matches
bridge.cc
Go to the documentation of this file.
1/*
2 * Copyright (c) 2011-2013, 2015 ARM Limited
3 * All rights reserved
4 *
5 * The license below extends only to copyright in the software and shall
6 * not be construed as granting a license to any other intellectual
7 * property including but not limited to intellectual property relating
8 * to a hardware implementation of the functionality of the software
9 * licensed hereunder. You may use the software subject to the license
10 * terms below provided that you ensure that this notice is replicated
11 * unmodified and in its entirety in all distributions of the software,
12 * modified or unmodified, in source code or in binary form.
13 *
14 * Copyright (c) 2006 The Regents of The University of Michigan
15 * All rights reserved.
16 *
17 * Redistribution and use in source and binary forms, with or without
18 * modification, are permitted provided that the following conditions are
19 * met: redistributions of source code must retain the above copyright
20 * notice, this list of conditions and the following disclaimer;
21 * redistributions in binary form must reproduce the above copyright
22 * notice, this list of conditions and the following disclaimer in the
23 * documentation and/or other materials provided with the distribution;
24 * neither the name of the copyright holders nor the names of its
25 * contributors may be used to endorse or promote products derived from
26 * this software without specific prior written permission.
27 *
28 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
29 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
30 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
31 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
32 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
33 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
34 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
35 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
36 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
37 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
38 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
39 */
40
47#include "mem/bridge.hh"
48
49#include "base/trace.hh"
50#include "debug/Bridge.hh"
51#include "params/Bridge.hh"
52
53namespace gem5
54{
55
57 Bridge& _bridge,
58 BridgeRequestPort& _memSidePort,
59 Cycles _delay, int _resp_limit,
61 : ResponsePort(_name), bridge(_bridge),
62 memSidePort(_memSidePort), delay(_delay),
63 ranges(_ranges.begin(), _ranges.end()),
64 outstandingResponses(0), retryReq(false), respQueueLimit(_resp_limit),
65 sendEvent([this]{ trySendTiming(); }, _name)
66{
67}
68
70 Bridge& _bridge,
71 BridgeResponsePort& _cpuSidePort,
72 Cycles _delay, int _req_limit)
73 : RequestPort(_name), bridge(_bridge),
74 cpuSidePort(_cpuSidePort),
75 delay(_delay), reqQueueLimit(_req_limit),
76 sendEvent([this]{ trySendTiming(); }, _name)
77{
78}
79
82 cpuSidePort(p.name + ".cpu_side_port", *this, memSidePort,
83 ticksToCycles(p.delay), p.resp_size, p.ranges),
84 memSidePort(p.name + ".mem_side_port", *this, cpuSidePort,
85 ticksToCycles(p.delay), p.req_size)
86{
87}
88
89Port &
90Bridge::getPort(const std::string &if_name, PortID idx)
91{
92 if (if_name == "mem_side_port")
93 return memSidePort;
94 else if (if_name == "cpu_side_port")
95 return cpuSidePort;
96 else
97 // pass it along to our super class
98 return ClockedObject::getPort(if_name, idx);
99}
100
101void
103{
104 // make sure both sides are connected and have the same block size
106 fatal("Both ports of a bridge must be connected.\n");
107
108 // notify the request side of our address ranges
110}
111
112bool
117
118bool
120{
121 return transmitList.size() == reqQueueLimit;
122}
123
124bool
126{
127 // all checks are done when the request is accepted on the response
128 // side, so we are guaranteed to have space for the response
129 DPRINTF(Bridge, "recvTimingResp: %s addr 0x%x\n",
130 pkt->cmdString(), pkt->getAddr());
131
132 DPRINTF(Bridge, "Request queue size: %d\n", transmitList.size());
133
134 // technically the packet only reaches us after the header delay,
135 // and typically we also need to deserialise any payload (unless
136 // the two sides of the bridge are synchronous)
137 Tick receive_delay = pkt->headerDelay + pkt->payloadDelay;
138 pkt->headerDelay = pkt->payloadDelay = 0;
139
140 cpuSidePort.schedTimingResp(pkt, bridge.clockEdge(delay) +
141 receive_delay);
142
143 return true;
144}
145
146bool
148{
149 DPRINTF(Bridge, "recvTimingReq: %s addr 0x%x\n",
150 pkt->cmdString(), pkt->getAddr());
151
152 panic_if(pkt->cacheResponding(), "Should not see packets where cache "
153 "is responding");
154
155 // we should not get a new request after committing to retry the
156 // current one, but unfortunately the CPU violates this rule, so
157 // simply ignore it for now
158 if (retryReq)
159 return false;
160
161 DPRINTF(Bridge, "Response queue size: %d outresp: %d\n",
162 transmitList.size(), outstandingResponses);
163
164 // if the request queue is full then there is no hope
166 DPRINTF(Bridge, "Request queue full\n");
167 retryReq = true;
168 } else {
169 // look at the response queue if we expect to see a response
170 bool expects_response = pkt->needsResponse();
171 if (expects_response) {
172 if (respQueueFull()) {
173 DPRINTF(Bridge, "Response queue full\n");
174 retryReq = true;
175 } else {
176 // ok to send the request with space for the response
177 DPRINTF(Bridge, "Reserving space for response\n");
178 assert(outstandingResponses != respQueueLimit);
179 ++outstandingResponses;
180
181 // no need to set retryReq to false as this is already the
182 // case
183 }
184 }
185
186 if (!retryReq) {
187 // technically the packet only reaches us after the header
188 // delay, and typically we also need to deserialise any
189 // payload (unless the two sides of the bridge are
190 // synchronous)
191 Tick receive_delay = pkt->headerDelay + pkt->payloadDelay;
192 pkt->headerDelay = pkt->payloadDelay = 0;
193
194 memSidePort.schedTimingReq(pkt, bridge.clockEdge(delay) +
195 receive_delay);
196 }
197 }
198
199 // remember that we are now stalling a packet and that we have to
200 // tell the sending requestor to retry once space becomes available,
201 // we make no distinction whether the stalling is due to the
202 // request queue or response queue being full
203 return !retryReq;
204}
205
206void
208{
209 if (retryReq) {
210 DPRINTF(Bridge, "Request waiting for retry, now retrying\n");
211 retryReq = false;
212 sendRetryReq();
213 }
214}
215
216void
218{
219 // If we're about to put this packet at the head of the queue, we
220 // need to schedule an event to do the transmit. Otherwise there
221 // should already be an event scheduled for sending the head
222 // packet.
223 if (transmitList.empty()) {
224 bridge.schedule(sendEvent, when);
225 }
226
227 assert(transmitList.size() != reqQueueLimit);
228
229 transmitList.emplace_back(pkt, when);
230}
231
232
233void
235{
236 // If we're about to put this packet at the head of the queue, we
237 // need to schedule an event to do the transmit. Otherwise there
238 // should already be an event scheduled for sending the head
239 // packet.
240 if (transmitList.empty()) {
241 bridge.schedule(sendEvent, when);
242 }
243
244 transmitList.emplace_back(pkt, when);
245}
246
247void
249{
250 assert(!transmitList.empty());
251
252 DeferredPacket req = transmitList.front();
253
254 assert(req.tick <= curTick());
255
256 PacketPtr pkt = req.pkt;
257
258 DPRINTF(Bridge, "trySend request addr 0x%x, queue size %d\n",
259 pkt->getAddr(), transmitList.size());
260
261 if (sendTimingReq(pkt)) {
262 // send successful
263 transmitList.pop_front();
264 DPRINTF(Bridge, "trySend request successful\n");
265
266 // If there are more packets to send, schedule event to try again.
267 if (!transmitList.empty()) {
268 DeferredPacket next_req = transmitList.front();
269 DPRINTF(Bridge, "Scheduling next send\n");
270 bridge.schedule(sendEvent, std::max(next_req.tick,
271 bridge.clockEdge()));
272 }
273
274 // if we have stalled a request due to a full request queue,
275 // then send a retry at this point, also note that if the
276 // request we stalled was waiting for the response queue
277 // rather than the request queue we might stall it again
279 }
280
281 // if the send failed, then we try again once we receive a retry,
282 // and therefore there is no need to take any action
283}
284
285void
287{
288 assert(!transmitList.empty());
289
290 DeferredPacket resp = transmitList.front();
291
292 assert(resp.tick <= curTick());
293
294 PacketPtr pkt = resp.pkt;
295
296 DPRINTF(Bridge, "trySend response addr 0x%x, outstanding %d\n",
297 pkt->getAddr(), outstandingResponses);
298
299 if (sendTimingResp(pkt)) {
300 // send successful
301 transmitList.pop_front();
302 DPRINTF(Bridge, "trySend response successful\n");
303
304 assert(outstandingResponses != 0);
305 --outstandingResponses;
306
307 // If there are more packets to send, schedule event to try again.
308 if (!transmitList.empty()) {
309 DeferredPacket next_resp = transmitList.front();
310 DPRINTF(Bridge, "Scheduling next send\n");
311 bridge.schedule(sendEvent, std::max(next_resp.tick,
312 bridge.clockEdge()));
313 }
314
315 // if there is space in the request queue and we were stalling
316 // a request, it will definitely be possible to accept it now
317 // since there is guaranteed space in the response queue
318 if (!memSidePort.reqQueueFull() && retryReq) {
319 DPRINTF(Bridge, "Request waiting for retry, now retrying\n");
320 retryReq = false;
321 sendRetryReq();
322 }
323 }
324
325 // if the send failed, then we try again once we receive a retry,
326 // and therefore there is no need to take any action
327}
328
329void
331{
332 trySendTiming();
333}
334
335void
337{
338 trySendTiming();
339}
340
341Tick
343{
344 panic_if(pkt->cacheResponding(), "Should not see packets where cache "
345 "is responding");
346
347 return delay * bridge.clockPeriod() + memSidePort.sendAtomic(pkt);
348}
349
350Tick
352 PacketPtr pkt, MemBackdoorPtr &backdoor)
353{
354 return delay * bridge.clockPeriod() + memSidePort.sendAtomicBackdoor(
355 pkt, backdoor);
356}
357
358void
360{
361 pkt->pushLabel(name());
362
363 // check the response queue
364 for (auto i = transmitList.begin(); i != transmitList.end(); ++i) {
365 if (pkt->trySatisfyFunctional((*i).pkt)) {
366 pkt->makeResponse();
367 return;
368 }
369 }
370
371 // also check the request port's request queue
373 return;
374 }
375
376 pkt->popLabel();
377
378 // fall through if pkt still not satisfied
380}
381
382void
388
389bool
391{
392 bool found = false;
393 auto i = transmitList.begin();
394
395 while (i != transmitList.end() && !found) {
396 if (pkt->trySatisfyFunctional((*i).pkt)) {
397 pkt->makeResponse();
398 found = true;
399 }
400 ++i;
401 }
402
403 return found;
404}
405
408{
409 return ranges;
410}
411
412} // namespace gem5
#define DPRINTF(x,...)
Definition trace.hh:210
Declaration of a memory-mapped bridge that connects a requestor and a responder through a request and...
Port on the side that forwards requests and receives responses.
Definition bridge.hh:236
void recvReqRetry() override
When receiving a retry request from the peer port, pass it to the bridge.
Definition bridge.cc:330
BridgeRequestPort(const std::string &_name, Bridge &_bridge, BridgeResponsePort &_cpuSidePort, Cycles _delay, int _req_limit)
Constructor for the BridgeRequestPort.
Definition bridge.cc:69
bool trySatisfyFunctional(PacketPtr pkt)
Check a functional request against the packets in our request queue.
Definition bridge.cc:390
bool reqQueueFull() const
Is this side blocked from accepting new request packets.
Definition bridge.cc:119
bool recvTimingResp(PacketPtr pkt) override
When receiving a timing request from the peer port, pass it to the bridge.
Definition bridge.cc:125
void schedTimingReq(PacketPtr pkt, Tick when)
Queue a request packet to be sent out later and also schedule a send if necessary.
Definition bridge.cc:217
void trySendTiming()
Handle send event, scheduled when the packet at the head of the outbound queue is ready to transmit (...
Definition bridge.cc:248
The port on the side that receives requests and sends responses.
Definition bridge.hh:103
void recvFunctional(PacketPtr pkt) override
When receiving a Functional request from the peer port, pass it to the bridge.
Definition bridge.cc:359
bool respQueueFull() const
Is this side blocked from accepting new response packets.
Definition bridge.cc:113
bool recvTimingReq(PacketPtr pkt) override
When receiving a timing request from the peer port, pass it to the bridge.
Definition bridge.cc:147
unsigned int respQueueLimit
Max queue size for reserved responses.
Definition bridge.hh:136
unsigned int outstandingResponses
Counter to track the outstanding responses.
Definition bridge.hh:130
void recvMemBackdoorReq(const MemBackdoorReq &req, MemBackdoorPtr &backdoor) override
When receiving a Functional backdoor request from the peer port, pass it to the bridge.
Definition bridge.cc:383
BridgeResponsePort(const std::string &_name, Bridge &_bridge, BridgeRequestPort &_memSidePort, Cycles _delay, int _resp_limit, std::vector< AddrRange > _ranges)
Constructor for the BridgeResponsePort.
Definition bridge.cc:56
void recvRespRetry() override
When receiving a retry request from the peer port, pass it to the bridge.
Definition bridge.cc:336
void schedTimingResp(PacketPtr pkt, Tick when)
Queue a response packet to be sent out later and also schedule a send if necessary.
Definition bridge.cc:234
AddrRangeList getAddrRanges() const override
When receiving a address range request the peer port, pass it to the bridge.
Definition bridge.cc:407
Tick recvAtomicBackdoor(PacketPtr pkt, MemBackdoorPtr &backdoor) override
When receiving an Atomic backdoor request from the peer port, pass it to the bridge.
Definition bridge.cc:351
Tick recvAtomic(PacketPtr pkt) override
When receiving an Atomic request from the peer port, pass it to the bridge.
Definition bridge.cc:342
void retryStalledReq()
Retry any stalled request that we have failed to accept at an earlier point in time.
Definition bridge.cc:207
void trySendTiming()
Handle send event, scheduled when the packet at the head of the response queue is ready to transmit (...
Definition bridge.cc:286
A deferred packet stores a packet along with its scheduled transmission time.
Definition bridge.hh:82
const PacketPtr pkt
Definition bridge.hh:87
A bridge is used to interface two different crossbars (or in general a memory-mapped requestor and re...
Definition bridge.hh:74
BridgeRequestPort memSidePort
Request port of the bridge.
Definition bridge.hh:329
Bridge(const Params &p)
Definition bridge.cc:80
Port & getPort(const std::string &if_name, PortID idx=InvalidPortID) override
Get a port with a given name and index.
Definition bridge.cc:90
BridgeParams Params
Definition bridge.hh:338
BridgeResponsePort cpuSidePort
Response port of the bridge.
Definition bridge.hh:326
void init() override
init() is called after all C++ SimObjects have been created and all ports are connected.
Definition bridge.cc:102
The ClockedObject class extends the SimObject with a clock and accessor functions to relate ticks to ...
Cycles ticksToCycles(Tick t) const
Cycles is a wrapper class for representing cycle counts, i.e.
Definition types.hh:79
const std::string _name
Definition named.hh:41
virtual std::string name() const
Definition named.hh:47
A Packet is used to encapsulate a transfer between two objects in the memory system (e....
Definition packet.hh:295
Addr getAddr() const
Definition packet.hh:807
void pushLabel(const std::string &lbl)
Push label for PrintReq (safe to call unconditionally).
Definition packet.hh:1470
const std::string & cmdString() const
Return the string name of the cmd field (for debugging and tracing).
Definition packet.hh:588
bool needsResponse() const
Definition packet.hh:608
uint32_t payloadDelay
The extra pipelining delay from seeing the packet until the end of payload is transmitted by the comp...
Definition packet.hh:449
void makeResponse()
Take a request packet and modify it in place to be suitable for returning as a response to that reque...
Definition packet.hh:1062
uint32_t headerDelay
The extra delay from seeing the packet until the header is transmitted.
Definition packet.hh:431
bool trySatisfyFunctional(PacketPtr other)
Check a functional request against a memory value stored in another packet (i.e.
Definition packet.hh:1399
void popLabel()
Pop label for PrintReq (safe to call unconditionally).
Definition packet.hh:1480
bool cacheResponding() const
Definition packet.hh:659
Ports are used to interface objects to each other.
Definition port.hh:62
bool isConnected() const
Is this port currently connected to a peer?
Definition port.hh:133
A RequestPort is a specialisation of a Port, which implements the default protocol for the three diff...
Definition port.hh:136
void sendMemBackdoorReq(const MemBackdoorReq &req, MemBackdoorPtr &backdoor)
Send a request for a back door to a range of memory.
Definition port.hh:591
Tick sendAtomic(PacketPtr pkt)
Send an atomic request packet, where the data is moved and the state is updated in zero time,...
Definition port.hh:552
void sendFunctional(PacketPtr pkt) const
Send a functional request packet, where the data is instantly updated everywhere in the memory system...
Definition port.hh:579
Tick sendAtomicBackdoor(PacketPtr pkt, MemBackdoorPtr &backdoor)
Send an atomic request packet like above, but also request a backdoor to the data being accessed.
Definition port.hh:565
A ResponsePort is a specialization of a port.
Definition port.hh:349
void sendRangeChange() const
Called by the owner to send a range change.
Definition port.hh:380
STL vector class.
Definition stl.hh:37
#define fatal(...)
This implements a cprintf based fatal() function.
Definition logging.hh:200
#define panic_if(cond,...)
Conditional panic macro that checks the supplied condition and only panics if the condition is true a...
Definition logging.hh:214
virtual Port & getPort(const std::string &if_name, PortID idx=InvalidPortID)
Get a port with a given name and index.
Bitfield< 7 > i
Definition misc_types.hh:67
void sendEvent(ThreadContext *tc)
Send an event (SEV) to a specific PE if there isn't already a pending event.
Definition utility.cc:65
Bitfield< 0 > p
Copyright (c) 2024 - Pranith Kumar Copyright (c) 2020 Inria All rights reserved.
Definition binary32.hh:36
Tick curTick()
The universal simulation clock.
Definition cur_tick.hh:46
int16_t PortID
Port index/ID type, and a symbolic name for an invalid port id.
Definition types.hh:245
uint64_t Tick
Tick count type.
Definition types.hh:58

Generated on Tue Jun 18 2024 16:24:04 for gem5 by doxygen 1.11.0