xbar.cc (13784:1941dc118243) xbar.cc (13808:0a44fbc3a853)
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
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
79void
80BaseXBar::init()
81{
82}
83
84Port &
85BaseXBar::getPort(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];

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

131
132 // the payload delay is not paying for the clock offset as that is
133 // already done using the header delay, and the payload delay is
134 // also used to determine how long the crossbar layer is busy and
135 // thus regulates throughput
136}
137
138template <typename SrcType, typename DstType>
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>
139BaseXBar::Layer::Layer(DstType& _port, BaseXBar& _xbar,
134BaseXBar::Layer<SrcType, DstType>::Layer(DstType& _port, BaseXBar& _xbar,
140 const std::string& _name) :
141 port(_port), xbar(_xbar), _name(_name), state(IDLE),
142 waitingForPeer(NULL), releaseEvent([this]{ releaseLayer(); }, name())
143{
144}
145
146template <typename SrcType, typename DstType>
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>
147void BaseXBar::Layer::occupyLayer(Tick until)
142void BaseXBar::Layer<SrcType, DstType>::occupyLayer(Tick until)
148{
149 // ensure the state is busy at this point, as the layer should
150 // transition from idle as soon as it has decided to forward the
151 // packet to prevent any follow-on calls to sendTiming seeing an
152 // unoccupied layer
153 assert(state == BUSY);
154
155 // until should never be 0 as express snoops never occupy the layer

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

160 occupancy += until - curTick();
161
162 DPRINTF(BaseXBar, "The crossbar layer is now busy from tick %d to %d\n",
163 curTick(), until);
164}
165
166template <typename SrcType, typename DstType>
167bool
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
168BaseXBar::Layer::tryTiming(SrcType* src_port)
163BaseXBar::Layer<SrcType, DstType>::tryTiming(SrcType* src_port)
169{
170 // if we are in the retry state, we will not see anything but the
171 // retrying port (or in the case of the snoop ports the snoop
172 // response port that mirrors the actual slave port) as we leave
173 // this state again in zero time if the peer does not immediately
174 // call the layer when receiving the retry
175
176 // first we see if the layer is busy, next we check if the

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

191
192 state = BUSY;
193
194 return true;
195}
196
197template <typename SrcType, typename DstType>
198void
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
199BaseXBar::Layer::succeededTiming(Tick busy_time)
194BaseXBar::Layer<SrcType, DstType>::succeededTiming(Tick busy_time)
200{
201 // we should have gone from idle or retry to busy in the tryTiming
202 // test
203 assert(state == BUSY);
204
205 // occupy the layer accordingly
206 occupyLayer(busy_time);
207}
208
209template <typename SrcType, typename DstType>
210void
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
211BaseXBar::Layer::failedTiming(SrcType* src_port,
206BaseXBar::Layer<SrcType, DstType>::failedTiming(SrcType* src_port,
212 Tick busy_time)
213{
214 // ensure no one got in between and tried to send something to
215 // this port
216 assert(waitingForPeer == NULL);
217
218 // if the source port is the current retrying one or not, we have
219 // failed in forwarding and should track that we are now waiting

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

225 assert(state == BUSY);
226
227 // occupy the bus accordingly
228 occupyLayer(busy_time);
229}
230
231template <typename SrcType, typename DstType>
232void
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
233BaseXBar::Layer::releaseLayer()
228BaseXBar::Layer<SrcType, DstType>::releaseLayer()
234{
235 // releasing the bus means we should now be idle
236 assert(state == BUSY);
237 assert(!releaseEvent.scheduled());
238
239 // update the state
240 state = IDLE;
241

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

249 DPRINTF(Drain, "Crossbar done draining, signaling drain manager\n");
250 //If we weren't able to drain before, do it now.
251 signalDrainDone();
252 }
253}
254
255template <typename SrcType, typename DstType>
256void
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
257BaseXBar::Layer::retryWaiting()
252BaseXBar::Layer<SrcType, DstType>::retryWaiting()
258{
259 // this should never be called with no one waiting
260 assert(!waitingForLayer.empty());
261
262 // we always go to retrying from idle
263 assert(state == IDLE);
264
265 // update the state

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

284
285 // occupy the crossbar layer until the next clock edge
286 occupyLayer(xbar.clockEdge());
287 }
288}
289
290template <typename SrcType, typename DstType>
291void
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
292BaseXBar::Layer::recvRetry()
287BaseXBar::Layer<SrcType, DstType>::recvRetry()
293{
294 // we should never get a retry without having failed to forward
295 // something to this port
296 assert(waitingForPeer != NULL);
297
298 // add the port where the failed packet originated to the front of
299 // the waiting ports for the layer, this allows us to call retry
300 // on the port immediately if the crossbar layer is idle

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

568 pktCount.ysubname(j, masterPorts[j]->getSlavePort().name());
569 pktSize.ysubname(j, masterPorts[j]->getSlavePort().name());
570 }
571 }
572}
573
574template <typename SrcType, typename DstType>
575DrainState
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
576BaseXBar::Layer::drain()
571BaseXBar::Layer<SrcType, DstType>::drain()
577{
578 //We should check that we're not "doing" anything, and that noone is
579 //waiting. We might be idle but have someone waiting if the device we
580 //contacted for a retry didn't actually retry.
581 if (state != IDLE) {
582 DPRINTF(Drain, "Crossbar not drained\n");
583 return DrainState::Draining;
584 } else {
585 return DrainState::Drained;
586 }
587}
588
589template <typename SrcType, typename DstType>
590void
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
591BaseXBar::Layer::regStats()
586BaseXBar::Layer<SrcType, DstType>::regStats()
592{
593 using namespace Stats;
594
595 occupancy
596 .name(name() + ".occupancy")
597 .desc("Layer occupancy (ticks)")
598 .flags(nozero);
599

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

606 utilization = 100 * occupancy / simTicks;
607}
608
609/**
610 * Crossbar layer template instantiations. Could be removed with _impl.hh
611 * file, but since there are only two given options (MasterPort and
612 * SlavePort) it seems a bit excessive at this point.
613 */
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 */
614template class BaseXBar::Layer;
615template class BaseXBar::Layer;
609template class BaseXBar::Layer<SlavePort, MasterPort>;
610template class BaseXBar::Layer<MasterPort, SlavePort>;