1/* 2 * Copyright (c) 2011-2015, 2018 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 --- 62 unchanged lines hidden (view full) --- 71{ 72 for (auto m: masterPorts) 73 delete m; 74 75 for (auto s: slavePorts) 76 delete s; 77} 78 |
79Port & 80BaseXBar::getPort(const std::string &if_name, PortID idx) 81{ 82 if (if_name == "master" && idx < masterPorts.size()) { 83 // the master port index translates directly to the vector position 84 return *masterPorts[idx]; 85 } else if (if_name == "default") { 86 return *masterPorts[defaultPortID]; --- 39 unchanged lines hidden (view full) --- 126 127 // the payload delay is not paying for the clock offset as that is 128 // already done using the header delay, and the payload delay is 129 // also used to determine how long the crossbar layer is busy and 130 // thus regulates throughput 131} 132 133template <typename SrcType, typename DstType> |
134BaseXBar::Layer<SrcType, DstType>::Layer(DstType& _port, BaseXBar& _xbar, |
135 const std::string& _name) : 136 port(_port), xbar(_xbar), _name(_name), state(IDLE), 137 waitingForPeer(NULL), releaseEvent([this]{ releaseLayer(); }, name()) 138{ 139} 140 141template <typename SrcType, typename DstType> |
142void BaseXBar::Layer<SrcType, DstType>::occupyLayer(Tick until) |
143{ 144 // ensure the state is busy at this point, as the layer should 145 // transition from idle as soon as it has decided to forward the 146 // packet to prevent any follow-on calls to sendTiming seeing an 147 // unoccupied layer 148 assert(state == BUSY); 149 150 // until should never be 0 as express snoops never occupy the layer --- 4 unchanged lines hidden (view full) --- 155 occupancy += until - curTick(); 156 157 DPRINTF(BaseXBar, "The crossbar layer is now busy from tick %d to %d\n", 158 curTick(), until); 159} 160 161template <typename SrcType, typename DstType> 162bool |
163BaseXBar::Layer<SrcType, DstType>::tryTiming(SrcType* src_port) |
164{ 165 // if we are in the retry state, we will not see anything but the 166 // retrying port (or in the case of the snoop ports the snoop 167 // response port that mirrors the actual slave port) as we leave 168 // this state again in zero time if the peer does not immediately 169 // call the layer when receiving the retry 170 171 // first we see if the layer is busy, next we check if the --- 14 unchanged lines hidden (view full) --- 186 187 state = BUSY; 188 189 return true; 190} 191 192template <typename SrcType, typename DstType> 193void |
194BaseXBar::Layer<SrcType, DstType>::succeededTiming(Tick busy_time) |
195{ 196 // we should have gone from idle or retry to busy in the tryTiming 197 // test 198 assert(state == BUSY); 199 200 // occupy the layer accordingly 201 occupyLayer(busy_time); 202} 203 204template <typename SrcType, typename DstType> 205void |
206BaseXBar::Layer<SrcType, DstType>::failedTiming(SrcType* src_port, |
207 Tick busy_time) 208{ 209 // ensure no one got in between and tried to send something to 210 // this port 211 assert(waitingForPeer == NULL); 212 213 // if the source port is the current retrying one or not, we have 214 // failed in forwarding and should track that we are now waiting --- 5 unchanged lines hidden (view full) --- 220 assert(state == BUSY); 221 222 // occupy the bus accordingly 223 occupyLayer(busy_time); 224} 225 226template <typename SrcType, typename DstType> 227void |
228BaseXBar::Layer<SrcType, DstType>::releaseLayer() |
229{ 230 // releasing the bus means we should now be idle 231 assert(state == BUSY); 232 assert(!releaseEvent.scheduled()); 233 234 // update the state 235 state = IDLE; 236 --- 7 unchanged lines hidden (view full) --- 244 DPRINTF(Drain, "Crossbar done draining, signaling drain manager\n"); 245 //If we weren't able to drain before, do it now. 246 signalDrainDone(); 247 } 248} 249 250template <typename SrcType, typename DstType> 251void |
252BaseXBar::Layer<SrcType, DstType>::retryWaiting() |
253{ 254 // this should never be called with no one waiting 255 assert(!waitingForLayer.empty()); 256 257 // we always go to retrying from idle 258 assert(state == IDLE); 259 260 // update the state --- 18 unchanged lines hidden (view full) --- 279 280 // occupy the crossbar layer until the next clock edge 281 occupyLayer(xbar.clockEdge()); 282 } 283} 284 285template <typename SrcType, typename DstType> 286void |
287BaseXBar::Layer<SrcType, DstType>::recvRetry() |
288{ 289 // we should never get a retry without having failed to forward 290 // something to this port 291 assert(waitingForPeer != NULL); 292 293 // add the port where the failed packet originated to the front of 294 // the waiting ports for the layer, this allows us to call retry 295 // on the port immediately if the crossbar layer is idle --- 267 unchanged lines hidden (view full) --- 563 pktCount.ysubname(j, masterPorts[j]->getSlavePort().name()); 564 pktSize.ysubname(j, masterPorts[j]->getSlavePort().name()); 565 } 566 } 567} 568 569template <typename SrcType, typename DstType> 570DrainState |
571BaseXBar::Layer<SrcType, DstType>::drain() |
572{ 573 //We should check that we're not "doing" anything, and that noone is 574 //waiting. We might be idle but have someone waiting if the device we 575 //contacted for a retry didn't actually retry. 576 if (state != IDLE) { 577 DPRINTF(Drain, "Crossbar not drained\n"); 578 return DrainState::Draining; 579 } else { 580 return DrainState::Drained; 581 } 582} 583 584template <typename SrcType, typename DstType> 585void |
586BaseXBar::Layer<SrcType, DstType>::regStats() |
587{ 588 using namespace Stats; 589 590 occupancy 591 .name(name() + ".occupancy") 592 .desc("Layer occupancy (ticks)") 593 .flags(nozero); 594 --- 6 unchanged lines hidden (view full) --- 601 utilization = 100 * occupancy / simTicks; 602} 603 604/** 605 * Crossbar layer template instantiations. Could be removed with _impl.hh 606 * file, but since there are only two given options (MasterPort and 607 * SlavePort) it seems a bit excessive at this point. 608 */ |
609template class BaseXBar::Layer<SlavePort, MasterPort>; 610template class BaseXBar::Layer<MasterPort, SlavePort>; |