gem5
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
xbar.cc
Go to the documentation of this file.
1 /*
2  * Copyright (c) 2011-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  * Authors: Ali Saidi
41  * Andreas Hansson
42  * William Wang
43  */
44 
50 #include "mem/xbar.hh"
51 
52 #include "base/misc.hh"
53 #include "base/trace.hh"
54 #include "debug/AddrRanges.hh"
55 #include "debug/Drain.hh"
56 #include "debug/XBar.hh"
57 
58 BaseXBar::BaseXBar(const BaseXBarParams *p)
59  : MemObject(p),
60  frontendLatency(p->frontend_latency),
61  forwardLatency(p->forward_latency),
62  responseLatency(p->response_latency),
63  width(p->width),
64  gotAddrRanges(p->port_default_connection_count +
65  p->port_master_connection_count, false),
66  gotAllAddrRanges(false), defaultPortID(InvalidPortID),
67  useDefaultRange(p->use_default_range)
68 {}
69 
71 {
72  for (auto m: masterPorts)
73  delete m;
74 
75  for (auto s: slavePorts)
76  delete s;
77 }
78 
79 void
81 {
82 }
83 
85 BaseXBar::getMasterPort(const std::string &if_name, PortID idx)
86 {
87  if (if_name == "master" && idx < masterPorts.size()) {
88  // the master port index translates directly to the vector position
89  return *masterPorts[idx];
90  } else if (if_name == "default") {
91  return *masterPorts[defaultPortID];
92  } else {
93  return MemObject::getMasterPort(if_name, idx);
94  }
95 }
96 
98 BaseXBar::getSlavePort(const std::string &if_name, PortID idx)
99 {
100  if (if_name == "slave" && idx < slavePorts.size()) {
101  // the slave port index translates directly to the vector position
102  return *slavePorts[idx];
103  } else {
104  return MemObject::getSlavePort(if_name, idx);
105  }
106 }
107 
108 void
110 {
111  // the crossbar will be called at a time that is not necessarily
112  // coinciding with its own clock, so start by determining how long
113  // until the next clock edge (could be zero)
114  Tick offset = clockEdge() - curTick();
115 
116  // the header delay depends on the path through the crossbar, and
117  // we therefore rely on the caller to provide the actual
118  // value
119  pkt->headerDelay += offset + header_delay;
120 
121  // note that we add the header delay to the existing value, and
122  // align it to the crossbar clock
123 
124  // do a quick sanity check to ensure the timings are not being
125  // ignored, note that this specific value may cause problems for
126  // slower interconnects
128  "Encountered header delay exceeding 1 us\n");
129 
130  if (pkt->hasData()) {
131  // the payloadDelay takes into account the relative time to
132  // deliver the payload of the packet, after the header delay,
133  // we take the maximum since the payload delay could already
134  // be longer than what this parcitular crossbar enforces.
135  pkt->payloadDelay = std::max<Tick>(pkt->payloadDelay,
136  divCeil(pkt->getSize(), width) *
137  clockPeriod());
138  }
139 
140  // the payload delay is not paying for the clock offset as that is
141  // already done using the header delay, and the payload delay is
142  // also used to determine how long the crossbar layer is busy and
143  // thus regulates throughput
144 }
145 
146 template <typename SrcType, typename DstType>
148  const std::string& _name) :
149  port(_port), xbar(_xbar), _name(_name), state(IDLE),
150  waitingForPeer(NULL), releaseEvent(this)
151 {
152 }
153 
154 template <typename SrcType, typename DstType>
156 {
157  // ensure the state is busy at this point, as the layer should
158  // transition from idle as soon as it has decided to forward the
159  // packet to prevent any follow-on calls to sendTiming seeing an
160  // unoccupied layer
161  assert(state == BUSY);
162 
163  // until should never be 0 as express snoops never occupy the layer
164  assert(until != 0);
165  xbar.schedule(releaseEvent, until);
166 
167  // account for the occupied ticks
168  occupancy += until - curTick();
169 
170  DPRINTF(BaseXBar, "The crossbar layer is now busy from tick %d to %d\n",
171  curTick(), until);
172 }
173 
174 template <typename SrcType, typename DstType>
175 bool
177 {
178  // if we are in the retry state, we will not see anything but the
179  // retrying port (or in the case of the snoop ports the snoop
180  // response port that mirrors the actual slave port) as we leave
181  // this state again in zero time if the peer does not immediately
182  // call the layer when receiving the retry
183 
184  // first we see if the layer is busy, next we check if the
185  // destination port is already engaged in a transaction waiting
186  // for a retry from the peer
187  if (state == BUSY || waitingForPeer != NULL) {
188  // the port should not be waiting already
189  assert(std::find(waitingForLayer.begin(), waitingForLayer.end(),
190  src_port) == waitingForLayer.end());
191 
192  // put the port at the end of the retry list waiting for the
193  // layer to be freed up (and in the case of a busy peer, for
194  // that transaction to go through, and then the layer to free
195  // up)
196  waitingForLayer.push_back(src_port);
197  return false;
198  }
199 
200  state = BUSY;
201 
202  return true;
203 }
204 
205 template <typename SrcType, typename DstType>
206 void
208 {
209  // we should have gone from idle or retry to busy in the tryTiming
210  // test
211  assert(state == BUSY);
212 
213  // occupy the layer accordingly
214  occupyLayer(busy_time);
215 }
216 
217 template <typename SrcType, typename DstType>
218 void
220  Tick busy_time)
221 {
222  // ensure no one got in between and tried to send something to
223  // this port
224  assert(waitingForPeer == NULL);
225 
226  // if the source port is the current retrying one or not, we have
227  // failed in forwarding and should track that we are now waiting
228  // for the peer to send a retry
229  waitingForPeer = src_port;
230 
231  // we should have gone from idle or retry to busy in the tryTiming
232  // test
233  assert(state == BUSY);
234 
235  // occupy the bus accordingly
236  occupyLayer(busy_time);
237 }
238 
239 template <typename SrcType, typename DstType>
240 void
242 {
243  // releasing the bus means we should now be idle
244  assert(state == BUSY);
245  assert(!releaseEvent.scheduled());
246 
247  // update the state
248  state = IDLE;
249 
250  // bus layer is now idle, so if someone is waiting we can retry
251  if (!waitingForLayer.empty()) {
252  // there is no point in sending a retry if someone is still
253  // waiting for the peer
254  if (waitingForPeer == NULL)
255  retryWaiting();
256  } else if (waitingForPeer == NULL && drainState() == DrainState::Draining) {
257  DPRINTF(Drain, "Crossbar done draining, signaling drain manager\n");
258  //If we weren't able to drain before, do it now.
259  signalDrainDone();
260  }
261 }
262 
263 template <typename SrcType, typename DstType>
264 void
266 {
267  // this should never be called with no one waiting
268  assert(!waitingForLayer.empty());
269 
270  // we always go to retrying from idle
271  assert(state == IDLE);
272 
273  // update the state
274  state = RETRY;
275 
276  // set the retrying port to the front of the retry list and pop it
277  // off the list
278  SrcType* retryingPort = waitingForLayer.front();
279  waitingForLayer.pop_front();
280 
281  // tell the port to retry, which in some cases ends up calling the
282  // layer again
283  sendRetry(retryingPort);
284 
285  // If the layer is still in the retry state, sendTiming wasn't
286  // called in zero time (e.g. the cache does this when a writeback
287  // is squashed)
288  if (state == RETRY) {
289  // update the state to busy and reset the retrying port, we
290  // have done our bit and sent the retry
291  state = BUSY;
292 
293  // occupy the crossbar layer until the next clock edge
294  occupyLayer(xbar.clockEdge());
295  }
296 }
297 
298 template <typename SrcType, typename DstType>
299 void
301 {
302  // we should never get a retry without having failed to forward
303  // something to this port
304  assert(waitingForPeer != NULL);
305 
306  // add the port where the failed packet originated to the front of
307  // the waiting ports for the layer, this allows us to call retry
308  // on the port immediately if the crossbar layer is idle
309  waitingForLayer.push_front(waitingForPeer);
310 
311  // we are no longer waiting for the peer
312  waitingForPeer = NULL;
313 
314  // if the layer is idle, retry this port straight away, if we
315  // are busy, then simply let the port wait for its turn
316  if (state == IDLE) {
317  retryWaiting();
318  } else {
319  assert(state == BUSY);
320  }
321 }
322 
323 PortID
325 {
326  // we should never see any address lookups before we've got the
327  // ranges of all connected slave modules
328  assert(gotAllAddrRanges);
329 
330  // Check the cache
331  PortID dest_id = checkPortCache(addr);
332  if (dest_id != InvalidPortID)
333  return dest_id;
334 
335  // Check the address map interval tree
336  auto i = portMap.find(addr);
337  if (i != portMap.end()) {
338  dest_id = i->second;
339  updatePortCache(dest_id, i->first);
340  return dest_id;
341  }
342 
343  // Check if this matches the default range
344  if (useDefaultRange) {
345  if (defaultRange.contains(addr)) {
346  DPRINTF(AddrRanges, " found addr %#llx on default\n",
347  addr);
348  return defaultPortID;
349  }
350  } else if (defaultPortID != InvalidPortID) {
351  DPRINTF(AddrRanges, "Unable to find destination for addr %#llx, "
352  "will use default port\n", addr);
353  return defaultPortID;
354  }
355 
356  // we should use the range for the default port and it did not
357  // match, or the default port is not set
358  fatal("Unable to find destination for addr %#llx on %s\n", addr,
359  name());
360 }
361 
363 void
365 {
366  DPRINTF(AddrRanges, "Received range change from slave port %s\n",
367  masterPorts[master_port_id]->getSlavePort().name());
368 
369  // remember that we got a range from this master port and thus the
370  // connected slave module
371  gotAddrRanges[master_port_id] = true;
372 
373  // update the global flag
374  if (!gotAllAddrRanges) {
375  // take a logical AND of all the ports and see if we got
376  // ranges from everyone
377  gotAllAddrRanges = true;
379  while (gotAllAddrRanges && r != gotAddrRanges.end()) {
380  gotAllAddrRanges &= *r++;
381  }
382  if (gotAllAddrRanges)
383  DPRINTF(AddrRanges, "Got address ranges from all slaves\n");
384  }
385 
386  // note that we could get the range from the default port at any
387  // point in time, and we cannot assume that the default range is
388  // set before the other ones are, so we do additional checks once
389  // all ranges are provided
390  if (master_port_id == defaultPortID) {
391  // only update if we are indeed checking ranges for the
392  // default port since the port might not have a valid range
393  // otherwise
394  if (useDefaultRange) {
395  AddrRangeList ranges = masterPorts[master_port_id]->getAddrRanges();
396 
397  if (ranges.size() != 1)
398  fatal("Crossbar %s may only have a single default range",
399  name());
400 
401  defaultRange = ranges.front();
402  }
403  } else {
404  // the ports are allowed to update their address ranges
405  // dynamically, so remove any existing entries
406  if (gotAddrRanges[master_port_id]) {
407  for (auto p = portMap.begin(); p != portMap.end(); ) {
408  if (p->second == master_port_id)
409  // erasing invalidates the iterator, so advance it
410  // before the deletion takes place
411  portMap.erase(p++);
412  else
413  p++;
414  }
415  }
416 
417  AddrRangeList ranges = masterPorts[master_port_id]->getAddrRanges();
418 
419  for (const auto& r: ranges) {
420  DPRINTF(AddrRanges, "Adding range %s for id %d\n",
421  r.to_string(), master_port_id);
422  if (portMap.insert(r, master_port_id) == portMap.end()) {
423  PortID conflict_id = portMap.find(r)->second;
424  fatal("%s has two ports responding within range %s:\n\t%s\n\t%s\n",
425  name(),
426  r.to_string(),
427  masterPorts[master_port_id]->getSlavePort().name(),
428  masterPorts[conflict_id]->getSlavePort().name());
429  }
430  }
431  }
432 
433  // if we have received ranges from all our neighbouring slave
434  // modules, go ahead and tell our connected master modules in
435  // turn, this effectively assumes a tree structure of the system
436  if (gotAllAddrRanges) {
437  DPRINTF(AddrRanges, "Aggregating address ranges\n");
438  xbarRanges.clear();
439 
440  // start out with the default range
441  if (useDefaultRange) {
443  fatal("Crossbar %s uses default range, but none provided",
444  name());
445 
446  xbarRanges.push_back(defaultRange);
447  DPRINTF(AddrRanges, "-- Adding default %s\n",
449  }
450 
451  // merge all interleaved ranges and add any range that is not
452  // a subset of the default range
453  std::vector<AddrRange> intlv_ranges;
454  for (const auto& r: portMap) {
455  // if the range is interleaved then save it for now
456  if (r.first.interleaved()) {
457  // if we already got interleaved ranges that are not
458  // part of the same range, then first do a merge
459  // before we add the new one
460  if (!intlv_ranges.empty() &&
461  !intlv_ranges.back().mergesWith(r.first)) {
462  DPRINTF(AddrRanges, "-- Merging range from %d ranges\n",
463  intlv_ranges.size());
464  AddrRange merged_range(intlv_ranges);
465  // next decide if we keep the merged range or not
466  if (!(useDefaultRange &&
467  merged_range.isSubset(defaultRange))) {
468  xbarRanges.push_back(merged_range);
469  DPRINTF(AddrRanges, "-- Adding merged range %s\n",
470  merged_range.to_string());
471  }
472  intlv_ranges.clear();
473  }
474  intlv_ranges.push_back(r.first);
475  } else {
476  // keep the current range if not a subset of the default
477  if (!(useDefaultRange &&
478  r.first.isSubset(defaultRange))) {
479  xbarRanges.push_back(r.first);
480  DPRINTF(AddrRanges, "-- Adding range %s\n",
481  r.first.to_string());
482  }
483  }
484  }
485 
486  // if there is still interleaved ranges waiting to be merged,
487  // go ahead and do it
488  if (!intlv_ranges.empty()) {
489  DPRINTF(AddrRanges, "-- Merging range from %d ranges\n",
490  intlv_ranges.size());
491  AddrRange merged_range(intlv_ranges);
492  if (!(useDefaultRange && merged_range.isSubset(defaultRange))) {
493  xbarRanges.push_back(merged_range);
494  DPRINTF(AddrRanges, "-- Adding merged range %s\n",
495  merged_range.to_string());
496  }
497  }
498 
499  // also check that no range partially overlaps with the
500  // default range, this has to be done after all ranges are set
501  // as there are no guarantees for when the default range is
502  // update with respect to the other ones
503  if (useDefaultRange) {
504  for (const auto& r: xbarRanges) {
505  // see if the new range is partially
506  // overlapping the default range
507  if (r.intersects(defaultRange) &&
508  !r.isSubset(defaultRange))
509  fatal("Range %s intersects the " \
510  "default range of %s but is not a " \
511  "subset\n", r.to_string(), name());
512  }
513  }
514 
515  // tell all our neighbouring master ports that our address
516  // ranges have changed
517  for (const auto& s: slavePorts)
518  s->sendRangeChange();
519  }
520 
521  clearPortCache();
522 }
523 
526 {
527  // we should never be asked without first having sent a range
528  // change, and the latter is only done once we have all the ranges
529  // of the connected devices
530  assert(gotAllAddrRanges);
531 
532  // at the moment, this never happens, as there are no cycles in
533  // the range queries and no devices on the master side of a crossbar
534  // (CPU, cache, bridge etc) actually care about the ranges of the
535  // ports they are connected to
536 
537  DPRINTF(AddrRanges, "Received address range request\n");
538 
539  return xbarRanges;
540 }
541 
542 void
544 {
546 
547  using namespace Stats;
548 
549  transDist
551  .name(name() + ".trans_dist")
552  .desc("Transaction distribution")
553  .flags(nozero);
554 
555  // get the string representation of the commands
556  for (int i = 0; i < MemCmd::NUM_MEM_CMDS; i++) {
557  MemCmd cmd(i);
558  const std::string &cstr = cmd.toString();
559  transDist.subname(i, cstr);
560  }
561 
562  pktCount
563  .init(slavePorts.size(), masterPorts.size())
564  .name(name() + ".pkt_count")
565  .desc("Packet count per connected master and slave (bytes)")
566  .flags(total | nozero | nonan);
567 
568  pktSize
569  .init(slavePorts.size(), masterPorts.size())
570  .name(name() + ".pkt_size")
571  .desc("Cumulative packet size per connected master and slave (bytes)")
572  .flags(total | nozero | nonan);
573 
574  // both the packet count and total size are two-dimensional
575  // vectors, indexed by slave port id and master port id, thus the
576  // neighbouring master and slave, they do not differentiate what
577  // came from the master and was forwarded to the slave (requests
578  // and snoop responses) and what came from the slave and was
579  // forwarded to the master (responses and snoop requests)
580  for (int i = 0; i < slavePorts.size(); i++) {
583  for (int j = 0; j < masterPorts.size(); j++) {
586  }
587  }
588 }
589 
590 template <typename SrcType, typename DstType>
593 {
594  //We should check that we're not "doing" anything, and that noone is
595  //waiting. We might be idle but have someone waiting if the device we
596  //contacted for a retry didn't actually retry.
597  if (state != IDLE) {
598  DPRINTF(Drain, "Crossbar not drained\n");
599  return DrainState::Draining;
600  } else {
601  return DrainState::Drained;
602  }
603 }
604 
605 template <typename SrcType, typename DstType>
606 void
608 {
609  using namespace Stats;
610 
611  occupancy
612  .name(name() + ".occupancy")
613  .desc("Layer occupancy (ticks)")
614  .flags(nozero);
615 
616  utilization
617  .name(name() + ".utilization")
618  .desc("Layer utilization (%)")
619  .precision(1)
620  .flags(nozero);
621 
622  utilization = 100 * occupancy / simTicks;
623 }
624 
const_iterator end() const
#define DPRINTF(x,...)
Definition: trace.hh:212
const_iterator insert(const AddrRange &r, const V &d)
Tick us
microsecond
Definition: core.cc:65
void recvRetry()
Handle a retry from a neighbouring module.
Definition: xbar.cc:300
PortID findPort(Addr addr)
Find which port connected to this crossbar (if any) should be given a packet with this address...
Definition: xbar.cc:324
Derived & init(size_type _x, size_type _y)
Definition: statistics.hh:1253
virtual void regStats()
Register statistics for this object.
Definition: xbar.cc:543
Derived & subname(off_type index, const std::string &name)
Set the subfield name for the given index, and marks this stat to print at the end of simulation...
Definition: statistics.hh:358
Definition: packet.hh:73
void updatePortCache(short id, const AddrRange &range)
Definition: xbar.hh:379
Bitfield< 7 > i
Definition: miscregs.hh:1378
const PortID InvalidPortID
Definition: types.hh:182
DrainState
Object drain/handover states.
Definition: drain.hh:71
Bitfield< 0 > m
Definition: miscregs.hh:1577
Running normally.
const FlagsType nonan
Don't print if this is NAN.
Definition: info.hh:59
bool hasData() const
Definition: packet.hh:521
PortID defaultPortID
Port that handles requests that don't match any of the interfaces.
Definition: xbar.hh:432
ip6_addr_t addr
Definition: inet.hh:335
panic_if(!root,"Invalid expression\n")
Bitfield< 23, 0 > offset
Definition: types.hh:149
bool contains(const Addr &a) const
Determine if the range contains an address.
Definition: addr_range.hh:328
virtual BaseSlavePort & getSlavePort(const std::string &if_name, PortID idx=InvalidPortID)
Get a slave port with a given name and index.
Definition: mem_object.cc:58
std::vector< bool > gotAddrRanges
Remember for each of the master ports of the crossbar if we got an address range from the connected s...
Definition: xbar.hh:424
virtual void init()
init() is called after all C++ SimObjects have been created and all ports are connected.
Definition: xbar.cc:80
Derived & flags(Flags _flags)
Set the flags and marks this stat to print at the end of simulation.
Definition: statistics.hh:311
A BaseSlavePort is a protocol-agnostic slave port, responsible only for the structural connection to ...
Definition: port.hh:139
STL vector class.
Definition: stl.hh:40
Derived & init(size_type size)
Set this vector to have the given size.
Definition: statistics.hh:1118
AddrRangeMap< PortID > portMap
Definition: xbar.hh:322
The base crossbar contains the common elements of the non-coherent and coherent crossbar.
Definition: xbar.hh:73
void succeededTiming(Tick busy_time)
Deal with a destination port accepting a packet by potentially removing the source port from the retr...
Definition: xbar.cc:207
PortID checkPortCache(Addr addr) const
Definition: xbar.hh:364
The AddrRange class encapsulates an address range, and supports a number of tests to check if two ran...
Definition: addr_range.hh:72
AddrRangeList xbarRanges
all contigous ranges seen by this crossbar
Definition: xbar.hh:333
Tick clockEdge(Cycles cycles=Cycles(0)) const
Determine the tick when a cycle begins, by default the current one, but the argument also enables the...
Tick curTick()
The current simulated tick.
Definition: core.hh:47
uint32_t headerDelay
The extra delay from seeing the packet until the header is transmitted.
Definition: packet.hh:340
Bitfield< 4 > s
Definition: miscregs.hh:1738
virtual ~BaseXBar()
Definition: xbar.cc:70
const uint32_t width
the width of the xbar in bytes
Definition: xbar.hh:320
uint64_t Tick
Tick count type.
Definition: types.hh:63
Stats::Vector transDist
Stats for transaction distribution and data passing through the crossbar.
Definition: xbar.hh:451
BaseXBar(const BaseXBarParams *p)
Definition: xbar.cc:58
std::string to_string() const
Get a string representation of the range.
Definition: addr_range.hh:239
#define fatal(...)
Definition: misc.hh:163
const_iterator begin() const
void calcPacketTiming(PacketPtr pkt, Tick header_delay)
Calculate the timing parameters for the packet.
Definition: xbar.cc:109
uint64_t Addr
Address type This will probably be moved somewhere else in the near future.
Definition: types.hh:142
Draining buffers pending serialization/handover.
uint32_t payloadDelay
The extra pipelining delay from seeing the packet until the end of payload is transmitted by the comp...
Definition: packet.hh:358
void failedTiming(SrcType *src_port, Tick busy_time)
Deal with a destination port not accepting a packet by potentially adding the source port to the retr...
Definition: xbar.cc:219
A Packet is used to encapsulate a transfer between two objects in the memory system (e...
Definition: packet.hh:245
bool gotAllAddrRanges
Definition: xbar.hh:425
const FlagsType total
Print the total.
Definition: info.hh:49
Bitfield< 24 > j
Definition: miscregs.hh:1369
const_iterator find(const AddrRange &r) const
BaseSlavePort & getSlavePort(const std::string &if_name, PortID idx=InvalidPortID)
Get a slave port with a given name and index.
Definition: xbar.cc:98
std::vector< MasterPort * > masterPorts
Definition: xbar.hh:429
Derived & name(const std::string &name)
Set the name and marks this stat to print at the end of simulation.
Definition: statistics.hh:254
Tick clockPeriod() const
std::vector< QueuedSlavePort * > slavePorts
The master and slave ports of the crossbar.
Definition: xbar.hh:428
virtual const std::string name() const
Definition: sim_object.hh:117
void occupyLayer(Tick until)
Occupy the layer until until.
Definition: xbar.cc:155
void releaseLayer()
Release the layer after being occupied and return to an idle state where we proceed to send a retry t...
Definition: xbar.cc:241
Derived & ysubname(off_type index, const std::string &subname)
Definition: statistics.hh:440
The MemObject class extends the ClockedObject with accessor functions to get its master and slave por...
Definition: mem_object.hh:60
DrainState drain() override
Drain according to the normal semantics, so that the crossbar can tell the layer to drain...
Definition: xbar.cc:592
A BaseMasterPort is a protocol-agnostic master port, responsible only for the structural connection t...
Definition: port.hh:115
void signalDrainDone() const
Signal that an object is drained.
Definition: drain.hh:267
T divCeil(const T &a, const U &b)
Definition: intmath.hh:198
Layer(DstType &_port, BaseXBar &_xbar, const std::string &_name)
Create a layer and give it a name.
Definition: xbar.cc:147
Bitfield< 4 > width
Definition: miscregs.hh:1383
const std::string & toString() const
Return the string to a cmd given by idx.
Definition: packet.hh:227
void regStats()
Register stats for the layer.
Definition: xbar.cc:607
DrainState drainState() const
Return the current drain state of an object.
Definition: drain.hh:282
bool tryTiming(SrcType *src_port)
Determine if the layer accepts a packet from a specific port.
Definition: xbar.cc:176
Derived & desc(const std::string &_desc)
Set the description and marks this stat to print at the end of simulation.
Definition: statistics.hh:287
int16_t PortID
Port index/ID type, and a symbolic name for an invalid port id.
Definition: types.hh:181
AddrRangeList getAddrRanges() const
Return the address ranges the crossbar is responsible for.
Definition: xbar.cc:525
void clearPortCache()
Definition: xbar.hh:394
unsigned getSize() const
Definition: packet.hh:649
AddrRange defaultRange
Definition: xbar.hh:335
const FlagsType nozero
Don't print if this is zero.
Definition: info.hh:57
Bitfield< 0 > p
Stats::Vector2d pktSize
Definition: xbar.hh:453
void regStats() override
Register statistics for this object.
virtual BaseMasterPort & getMasterPort(const std::string &if_name, PortID idx=InvalidPortID)
Get a master port with a given name and index.
Definition: mem_object.cc:52
const bool useDefaultRange
If true, use address range provided by default device.
Definition: xbar.hh:438
void retryWaiting()
Send a retry to the port at the head of waitingForLayer.
Definition: xbar.cc:265
Declaration of an abstract crossbar base class.
virtual void recvRangeChange(PortID master_port_id)
Function called by the port when the crossbar is recieving a range change.
Definition: xbar.cc:364
Stats::Value simTicks
Definition: stat_control.cc:65
Stats::Vector2d pktCount
Definition: xbar.hh:452
void erase(iterator p)
BaseMasterPort & getMasterPort(const std::string &if_name, PortID idx=InvalidPortID)
A function used to return the port associated with this object.
Definition: xbar.cc:85

Generated on Fri Jun 9 2017 13:03:51 for gem5 by doxygen 1.8.6