gem5 v24.0.0.0
Loading...
Searching...
No Matches
NetworkInterface.cc
Go to the documentation of this file.
1/*
2 * Copyright (c) 2020 Advanced Micro Devices, Inc.
3 * Copyright (c) 2020 Inria
4 * Copyright (c) 2016 Georgia Institute of Technology
5 * Copyright (c) 2008 Princeton University
6 * All rights reserved.
7 *
8 * Redistribution and use in source and binary forms, with or without
9 * modification, are permitted provided that the following conditions are
10 * met: redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer;
12 * redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in the
14 * documentation and/or other materials provided with the distribution;
15 * neither the name of the copyright holders nor the names of its
16 * contributors may be used to endorse or promote products derived from
17 * this software without specific prior written permission.
18 *
19 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
20 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
21 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
22 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
23 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
24 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
25 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
26 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
27 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
28 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
29 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
30 */
31
32
34
35#include <cassert>
36#include <cmath>
37
38#include "base/cast.hh"
39#include "debug/RubyNetwork.hh"
44
45namespace gem5
46{
47
48namespace ruby
49{
50
51namespace garnet
52{
53
55 : ClockedObject(p), Consumer(this), m_id(p.id),
56 m_virtual_networks(p.virt_nets), m_vc_per_vnet(0),
57 m_vc_allocator(m_virtual_networks, 0),
58 m_deadlock_threshold(p.garnet_deadlock_threshold),
59 vc_busy_counter(m_virtual_networks, 0)
60{
62 niOutVcs.resize(0);
63}
64
65void
67 CreditLink *credit_link)
68{
69 InputPort *newInPort = new InputPort(in_link, credit_link);
70 inPorts.push_back(newInPort);
71 DPRINTF(RubyNetwork, "Adding input port:%s with vnets %s\n",
72 in_link->name(), newInPort->printVnets());
73
74 in_link->setLinkConsumer(this);
75 credit_link->setSourceQueue(newInPort->outCreditQueue(), this);
76 if (m_vc_per_vnet != 0) {
78 credit_link->setVcsPerVnet(m_vc_per_vnet);
79 }
80
81}
82
83void
85 CreditLink *credit_link,
86 SwitchID router_id, uint32_t consumerVcs)
87{
88 OutputPort *newOutPort = new OutputPort(out_link, credit_link, router_id);
89 outPorts.push_back(newOutPort);
90
91 assert(consumerVcs > 0);
92 // We are not allowing different physical links to have different vcs
93 // If it is required that the Network Interface support different VCs
94 // for every physical link connected to it. Then they need to change
95 // the logic within outport and inport.
96 if (niOutVcs.size() == 0) {
97 m_vc_per_vnet = consumerVcs;
98 int m_num_vcs = consumerVcs * m_virtual_networks;
99 niOutVcs.resize(m_num_vcs);
100 outVcState.reserve(m_num_vcs);
101 m_ni_out_vcs_enqueue_time.resize(m_num_vcs);
102 // instantiating the NI flit buffers
103 for (int i = 0; i < m_num_vcs; i++) {
105 outVcState.emplace_back(i, m_net_ptr, consumerVcs);
106 }
107
108 // Reset VC Per VNET for input links already instantiated
109 for (auto &iPort: inPorts) {
110 NetworkLink *inNetLink = iPort->inNetLink();
111 inNetLink->setVcsPerVnet(m_vc_per_vnet);
112 credit_link->setVcsPerVnet(m_vc_per_vnet);
113 }
114 } else {
115 fatal_if(consumerVcs != m_vc_per_vnet,
116 "%s: Connected Physical links have different vc requests: %d and %d\n",
117 name(), consumerVcs, m_vc_per_vnet);
118 }
119
120 DPRINTF(RubyNetwork, "OutputPort:%s Vnet: %s\n",
121 out_link->name(), newOutPort->printVnets());
122
123 out_link->setSourceQueue(newOutPort->outFlitQueue(), this);
124 out_link->setVcsPerVnet(m_vc_per_vnet);
125 credit_link->setLinkConsumer(this);
126 credit_link->setVcsPerVnet(m_vc_per_vnet);
127}
128
129void
132{
133 inNode_ptr = in;
134 outNode_ptr = out;
135
136 for (auto& it : in) {
137 if (it != nullptr) {
138 it->setConsumer(this);
139 }
140 }
141}
142
143void
145{
146 // An output MessageBuffer has dequeued something this cycle and there
147 // is now space to enqueue a stalled message. However, we cannot wake
148 // on the same cycle as the dequeue. Schedule a wake at the soonest
149 // possible time (next cycle).
151}
152
153void
155{
156 int vnet = t_flit->get_vnet();
157
158 // Latency
160 Tick network_delay =
161 t_flit->get_dequeue_time() -
162 t_flit->get_enqueue_time() - cyclesToTicks(Cycles(1));
163 Tick src_queueing_delay = t_flit->get_src_delay();
164 Tick dest_queueing_delay = (curTick() - t_flit->get_dequeue_time());
165 Tick queueing_delay = src_queueing_delay + dest_queueing_delay;
166
167 m_net_ptr->increment_flit_network_latency(network_delay, vnet);
168 m_net_ptr->increment_flit_queueing_latency(queueing_delay, vnet);
169
170 if (t_flit->get_type() == TAIL_ || t_flit->get_type() == HEAD_TAIL_) {
172 m_net_ptr->increment_packet_network_latency(network_delay, vnet);
173 m_net_ptr->increment_packet_queueing_latency(queueing_delay, vnet);
174 }
175
176 // Hops
178}
179
180/*
181 * The NI wakeup checks whether there are any ready messages in the protocol
182 * buffer. If yes, it picks that up, flitisizes it into a number of flits and
183 * puts it into an output buffer and schedules the output link. On a wakeup
184 * it also checks whether there are flits in the input link. If yes, it picks
185 * them up and if the flit is a tail, the NI inserts the corresponding message
186 * into the protocol buffer. It also checks for credits being sent by the
187 * downstream router.
188 */
189
190void
192{
193 std::ostringstream oss;
194 for (auto &oPort: outPorts) {
195 oss << oPort->routerID() << "[" << oPort->printVnets() << "] ";
196 }
197 DPRINTF(RubyNetwork, "Network Interface %d connected to router:%s "
198 "woke up. Period: %ld\n", m_id, oss.str(), clockPeriod());
199
200 assert(curTick() == clockEdge());
201 MsgPtr msg_ptr;
202 Tick curTime = clockEdge();
203
204 // Checking for messages coming from the protocol
205 // can pick up a message/cycle for each virtual net
206 for (int vnet = 0; vnet < inNode_ptr.size(); ++vnet) {
207 MessageBuffer *b = inNode_ptr[vnet];
208 if (b == nullptr) {
209 continue;
210 }
211
212 if (b->isReady(curTime)) { // Is there a message waiting
213 msg_ptr = b->peekMsgPtr();
214 if (flitisizeMessage(msg_ptr, vnet)) {
215 b->dequeue(curTime);
216 }
217 }
218 }
219
221
222 // Check if there are flits stalling a virtual channel. Track if a
223 // message is enqueued to restrict ejection to one message per cycle.
225
226 /*********** Check the incoming flit link **********/
227 DPRINTF(RubyNetwork, "Number of input ports: %d\n", inPorts.size());
228 for (auto &iPort: inPorts) {
229 NetworkLink *inNetLink = iPort->inNetLink();
230 if (inNetLink->isReady(curTick())) {
231 flit *t_flit = inNetLink->consumeLink();
232 DPRINTF(RubyNetwork, "Recieved flit:%s\n", *t_flit);
233 assert(t_flit->m_width == iPort->bitWidth());
234
235 int vnet = t_flit->get_vnet();
236 t_flit->set_dequeue_time(curTick());
237
238 // If a tail flit is received, enqueue into the protocol buffers
239 // if space is available. Otherwise, exchange non-tail flits for
240 // credits.
241 if (t_flit->get_type() == TAIL_ ||
242 t_flit->get_type() == HEAD_TAIL_) {
243 if (!iPort->messageEnqueuedThisCycle &&
244 outNode_ptr[vnet]->areNSlotsAvailable(1, curTime)) {
245 // Space is available. Enqueue to protocol buffer.
246 outNode_ptr[vnet]->enqueue(t_flit->get_msg_ptr(), curTime,
248
249 // Simply send a credit back since we are not buffering
250 // this flit in the NI
251 Credit *cFlit = new Credit(t_flit->get_vc(),
252 true, curTick());
253 iPort->sendCredit(cFlit);
254 // Update stats and delete flit pointer
255 incrementStats(t_flit);
256 delete t_flit;
257 } else {
258 // No space available- Place tail flit in stall queue and
259 // set up a callback for when protocol buffer is dequeued.
260 // Stat update and flit pointer deletion will occur upon
261 // unstall.
262 iPort->m_stall_queue.push_back(t_flit);
263 m_stall_count[vnet]++;
264
265 outNode_ptr[vnet]->registerDequeueCallback([this]() {
266 dequeueCallback(); });
267 }
268 } else {
269 // Non-tail flit. Send back a credit but not VC free signal.
270 Credit *cFlit = new Credit(t_flit->get_vc(), false,
271 curTick());
272 // Simply send a credit back since we are not buffering
273 // this flit in the NI
274 iPort->sendCredit(cFlit);
275
276 // Update stats and delete flit pointer.
277 incrementStats(t_flit);
278 delete t_flit;
279 }
280 }
281 }
282
283 /****************** Check the incoming credit link *******/
284
285 for (auto &oPort: outPorts) {
286 CreditLink *inCreditLink = oPort->inCreditLink();
287 if (inCreditLink->isReady(curTick())) {
288 Credit *t_credit = (Credit*) inCreditLink->consumeLink();
289 outVcState[t_credit->get_vc()].increment_credit();
290 if (t_credit->is_free_signal()) {
291 outVcState[t_credit->get_vc()].setState(IDLE_,
292 curTick());
293 }
294 delete t_credit;
295 }
296 }
297
298
299 // It is possible to enqueue multiple outgoing credit flits if a message
300 // was unstalled in the same cycle as a new message arrives. In this
301 // case, we should schedule another wakeup to ensure the credit is sent
302 // back.
303 for (auto &iPort: inPorts) {
304 if (iPort->outCreditQueue()->getSize() > 0) {
305 DPRINTF(RubyNetwork, "Sending a credit %s via %s at %ld\n",
306 *(iPort->outCreditQueue()->peekTopFlit()),
307 iPort->outCreditLink()->name(), clockEdge(Cycles(1)));
308 iPort->outCreditLink()->
310 }
311 }
313}
314
315void
317{
318 // Check all stall queues.
319 // There is one stall queue for each input link
320 for (auto &iPort: inPorts) {
321 iPort->messageEnqueuedThisCycle = false;
322 Tick curTime = clockEdge();
323
324 if (!iPort->m_stall_queue.empty()) {
325 for (auto stallIter = iPort->m_stall_queue.begin();
326 stallIter != iPort->m_stall_queue.end(); ) {
327 flit *stallFlit = *stallIter;
328 int vnet = stallFlit->get_vnet();
329
330 // If we can now eject to the protocol buffer,
331 // send back credits
332 if (outNode_ptr[vnet]->areNSlotsAvailable(1,
333 curTime)) {
334 outNode_ptr[vnet]->enqueue(stallFlit->get_msg_ptr(),
335 curTime, cyclesToTicks(Cycles(1)));
336
337 // Send back a credit with free signal now that the
338 // VC is no longer stalled.
339 Credit *cFlit = new Credit(stallFlit->get_vc(), true,
340 curTick());
341 iPort->sendCredit(cFlit);
342
343 // Update Stats
344 incrementStats(stallFlit);
345
346 // Flit can now safely be deleted and removed from stall
347 // queue
348 delete stallFlit;
349 iPort->m_stall_queue.erase(stallIter);
350 m_stall_count[vnet]--;
351
352 // If there are no more stalled messages for this vnet, the
353 // callback on it's MessageBuffer is not needed.
354 if (m_stall_count[vnet] == 0)
355 outNode_ptr[vnet]->unregisterDequeueCallback();
356
357 iPort->messageEnqueuedThisCycle = true;
358 break;
359 } else {
360 ++stallIter;
361 }
362 }
363 }
364 }
365}
366
367// Embed the protocol message into flits
368bool
370{
371 Message *net_msg_ptr = msg_ptr.get();
372 NetDest net_msg_dest = net_msg_ptr->getDestination();
373
374 // gets all the destinations associated with this message.
375 std::vector<NodeID> dest_nodes = net_msg_dest.getAllDest();
376
377 // Number of flits is dependent on the link bandwidth available.
378 // This is expressed in terms of bytes/cycle or the flit size
379 OutputPort *oPort = getOutportForVnet(vnet);
380 assert(oPort);
381 int num_flits = (int)divCeil((float) m_net_ptr->MessageSizeType_to_int(
382 net_msg_ptr->getMessageSize()), (float)oPort->bitWidth());
383
384 DPRINTF(RubyNetwork, "Message Size:%d vnet:%d bitWidth:%d\n",
386 vnet, oPort->bitWidth());
387
388 // loop to convert all multicast messages into unicast messages
389 for (int ctr = 0; ctr < dest_nodes.size(); ctr++) {
390
391 // this will return a free output virtual channel
392 int vc = calculateVC(vnet);
393
394 if (vc == -1) {
395 return false ;
396 }
397 MsgPtr new_msg_ptr = msg_ptr->clone();
398 NodeID destID = dest_nodes[ctr];
399
400 Message *new_net_msg_ptr = new_msg_ptr.get();
401 if (dest_nodes.size() > 1) {
402 NetDest personal_dest;
403 for (int m = 0; m < (int) MachineType_NUM; m++) {
404 if ((destID >= MachineType_base_number((MachineType) m)) &&
405 destID < MachineType_base_number((MachineType) (m+1))) {
406 // calculating the NetDest associated with this destID
407 personal_dest.clear();
408 personal_dest.add((MachineID) {(MachineType) m, (destID -
409 MachineType_base_number((MachineType) m))});
410 new_net_msg_ptr->getDestination() = personal_dest;
411 break;
412 }
413 }
414 net_msg_dest.removeNetDest(personal_dest);
415 // removing the destination from the original message to reflect
416 // that a message with this particular destination has been
417 // flitisized and an output vc is acquired
418 net_msg_ptr->getDestination().removeNetDest(personal_dest);
419 }
420
421 // Embed Route into the flits
422 // NetDest format is used by the routing table
423 // Custom routing algorithms just need destID
424
425 RouteInfo route;
426 route.vnet = vnet;
427 route.net_dest = new_net_msg_ptr->getDestination();
428 route.src_ni = m_id;
429 route.src_router = oPort->routerID();
430 route.dest_ni = destID;
431 route.dest_router = m_net_ptr->get_router_id(destID, vnet);
432
433 // initialize hops_traversed to -1
434 // so that the first router increments it to 0
435 route.hops_traversed = -1;
436
439 int packet_id = m_net_ptr->getNextPacketID();
440 for (int i = 0; i < num_flits; i++) {
442 flit *fl = new flit(packet_id,
443 i, vc, vnet, route, num_flits, new_msg_ptr,
445 net_msg_ptr->getMessageSize()),
446 oPort->bitWidth(), curTick());
447
448 fl->set_src_delay(curTick() - msg_ptr->getTime());
449 niOutVcs[vc].insert(fl);
450 }
451
453 outVcState[vc].setState(ACTIVE_, curTick());
454 }
455 return true ;
456}
457
458// Looking for a free output vc
459int
461{
462 for (int i = 0; i < m_vc_per_vnet; i++) {
463 int delta = m_vc_allocator[vnet];
464 m_vc_allocator[vnet]++;
465 if (m_vc_allocator[vnet] == m_vc_per_vnet)
466 m_vc_allocator[vnet] = 0;
467
468 if (outVcState[(vnet*m_vc_per_vnet) + delta].isInState(
469 IDLE_, curTick())) {
470 vc_busy_counter[vnet] = 0;
471 return ((vnet*m_vc_per_vnet) + delta);
472 }
473 }
474
475 vc_busy_counter[vnet] += 1;
477 "%s: Possible network deadlock in vnet: %d at time: %llu \n",
478 name(), vnet, curTick());
479
480 return -1;
481}
482
483void
485{
486 int vc = oPort->vcRoundRobin();
487
488 for (int i = 0; i < niOutVcs.size(); i++) {
489 vc++;
490 if (vc == niOutVcs.size())
491 vc = 0;
492
493 int t_vnet = get_vnet(vc);
494 if (oPort->isVnetSupported(t_vnet)) {
495 // model buffer backpressure
496 if (niOutVcs[vc].isReady(curTick()) &&
497 outVcState[vc].has_credit()) {
498
499 bool is_candidate_vc = true;
500 int vc_base = t_vnet * m_vc_per_vnet;
501
502 if (m_net_ptr->isVNetOrdered(t_vnet)) {
503 for (int vc_offset = 0; vc_offset < m_vc_per_vnet;
504 vc_offset++) {
505 int t_vc = vc_base + vc_offset;
506 if (niOutVcs[t_vc].isReady(curTick())) {
507 if (m_ni_out_vcs_enqueue_time[t_vc] <
509 is_candidate_vc = false;
510 break;
511 }
512 }
513 }
514 }
515 if (!is_candidate_vc)
516 continue;
517
518 // Update the round robin arbiter
519 oPort->vcRoundRobin(vc);
520
521 outVcState[vc].decrement_credit();
522
523 // Just removing the top flit
524 flit *t_flit = niOutVcs[vc].getTopFlit();
525 t_flit->set_time(clockEdge(Cycles(1)));
526
527 // Scheduling the flit
528 scheduleFlit(t_flit);
529
530 if (t_flit->get_type() == TAIL_ ||
531 t_flit->get_type() == HEAD_TAIL_) {
533 }
534
535 // Done with this port, continue to schedule
536 // other ports
537 return;
538 }
539 }
540 }
541}
542
543
544
551void
553{
554 // Schedule each output link
555 for (auto &oPort: outPorts) {
556 scheduleOutputPort(oPort);
557 }
558}
559
562{
563 for (auto &iPort : inPorts) {
564 if (iPort->isVnetSupported(vnet)) {
565 return iPort;
566 }
567 }
568
569 return nullptr;
570}
571
572/*
573 * This function returns the outport which supports the given vnet.
574 * Currently, HeteroGarnet does not support multiple outports to
575 * support same vnet. Thus, this function returns the first-and
576 * only outport which supports the vnet.
577 */
580{
581 for (auto &oPort : outPorts) {
582 if (oPort->isVnetSupported(vnet)) {
583 return oPort;
584 }
585 }
586
587 return nullptr;
588}
589void
591{
592 OutputPort *oPort = getOutportForVnet(t_flit->get_vnet());
593
594 if (oPort) {
595 DPRINTF(RubyNetwork, "Scheduling at %s time:%ld flit:%s Message:%s\n",
596 oPort->outNetLink()->name(), clockEdge(Cycles(1)),
597 *t_flit, *(t_flit->get_msg_ptr()));
598 oPort->outFlitQueue()->insert(t_flit);
600 return;
601 }
602
603 panic("No output port found for vnet:%d\n", t_flit->get_vnet());
604 return;
605}
606
607int
609{
610 for (int i = 0; i < m_virtual_networks; i++) {
611 if (vc >= (i*m_vc_per_vnet) && vc < ((i+1)*m_vc_per_vnet)) {
612 return i;
613 }
614 }
615 fatal("Could not determine vc");
616}
617
618
619// Wakeup the NI in the next cycle if there are waiting
620// messages in the protocol buffer, or waiting flits in the
621// output VC buffer.
622// Also check if we have to reschedule because of a clock period
623// difference.
624void
626{
627 for (const auto& it : inNode_ptr) {
628 if (it == nullptr) {
629 continue;
630 }
631
632 while (it->isReady(clockEdge())) { // Is there a message waiting
634 return;
635 }
636 }
637
638 for (auto& ni_out_vc : niOutVcs) {
639 if (ni_out_vc.isReady(clockEdge(Cycles(1)))) {
641 return;
642 }
643 }
644
645 // Check if any input links have flits to be popped.
646 // This can happen if the links are operating at
647 // a higher frequency.
648 for (auto &iPort : inPorts) {
649 NetworkLink *inNetLink = iPort->inNetLink();
650 if (inNetLink->isReady(curTick())) {
652 return;
653 }
654 }
655
656 for (auto &oPort : outPorts) {
657 CreditLink *inCreditLink = oPort->inCreditLink();
658 if (inCreditLink->isReady(curTick())) {
660 return;
661 }
662 }
663}
664
665void
666NetworkInterface::print(std::ostream& out) const
667{
668 out << "[Network Interface]";
669}
670
671bool
673{
674 bool read = false;
675 for (auto& ni_out_vc : niOutVcs) {
676 if (ni_out_vc.functionalRead(pkt, mask))
677 read = true;
678 }
679
680 for (auto &oPort: outPorts) {
681 if (oPort->outFlitQueue()->functionalRead(pkt, mask))
682 read = true;
683 }
684
685 return read;
686}
687
688uint32_t
690{
691 uint32_t num_functional_writes = 0;
692 for (auto& ni_out_vc : niOutVcs) {
693 num_functional_writes += ni_out_vc.functionalWrite(pkt);
694 }
695
696 for (auto &oPort: outPorts) {
697 num_functional_writes += oPort->outFlitQueue()->functionalWrite(pkt);
698 }
699 return num_functional_writes;
700}
701
702} // namespace garnet
703} // namespace ruby
704} // namespace gem5
#define INFINITE_
#define DPRINTF(x,...)
Definition trace.hh:210
The ClockedObject class extends the SimObject with a clock and accessor functions to relate ticks to ...
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 cyclesToTicks(Cycles c) const
Tick clockPeriod() const
Cycles is a wrapper class for representing cycle counts, i.e.
Definition types.hh:79
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
void scheduleEventAbsolute(Tick timeAbs)
Definition Consumer.cc:63
void scheduleEvent(Cycles timeDelta)
Definition Consumer.cc:56
const MsgPtr & peekMsgPtr() const
virtual const NetDest & getDestination() const
Definition Message.hh:114
virtual const MessageSizeType & getMessageSize() const
Definition Message.hh:78
void add(MachineID newElement)
Definition NetDest.cc:45
std::vector< NodeID > getAllDest()
Definition NetDest.cc:112
void removeNetDest(const NetDest &netDest)
Definition NetDest.cc:76
static uint32_t MessageSizeType_to_int(MessageSizeType size_type)
Definition Network.cc:164
bool isVNetOrdered(int vnet) const
int get_router_id(int ni, int vnet)
void increment_flit_queueing_latency(Tick latency, int vnet)
void increment_flit_network_latency(Tick latency, int vnet)
void increment_packet_queueing_latency(Tick latency, int vnet)
void increment_packet_network_latency(Tick latency, int vnet)
void update_traffic_distribution(RouteInfo route)
std::vector< OutputPort * > outPorts
bool functionalRead(Packet *pkt, WriteMask &mask)
void addInPort(NetworkLink *in_link, CreditLink *credit_link)
void addOutPort(NetworkLink *out_link, CreditLink *credit_link, SwitchID router_id, uint32_t consumerVcs)
void print(std::ostream &out) const
GarnetNetworkInterfaceParams Params
std::vector< MessageBuffer * > outNode_ptr
void addNode(std::vector< MessageBuffer * > &inNode, std::vector< MessageBuffer * > &outNode)
void scheduleOutputPort(OutputPort *oPort)
std::vector< MessageBuffer * > inNode_ptr
bool flitisizeMessage(MsgPtr msg_ptr, int vnet)
void scheduleOutputLink()
This function looks at the NI buffers if some buffer has flits which are ready to traverse the link i...
RouteInfo get_route()
Definition flit.hh:68
void set_time(Tick time)
Definition flit.hh:75
void set_src_delay(Tick delay)
Definition flit.hh:78
MsgPtr & get_msg_ptr()
Definition flit.hh:69
void set_dequeue_time(Tick time)
Definition flit.hh:79
flit_type get_type()
Definition flit.hh:70
STL vector class.
Definition stl.hh:37
static constexpr T divCeil(const T &a, const U &b)
Definition intmath.hh:110
#define panic(...)
This implements a cprintf based panic() function.
Definition logging.hh:188
#define fatal_if(cond,...)
Conditional fatal macro that checks the supplied condition and only causes a fatal error if the condi...
Definition logging.hh:236
#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
Bitfield< 3, 0 > mask
Definition pcstate.hh:63
Bitfield< 7 > b
Bitfield< 7 > i
Definition misc_types.hh:67
Bitfield< 33 > id
Bitfield< 0 > m
Bitfield< 0 > p
std::shared_ptr< Message > MsgPtr
Definition Message.hh:60
unsigned int SwitchID
unsigned int NodeID
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
uint64_t Tick
Tick count type.
Definition types.hh:58

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