39#include "debug/RubyNetwork.hh"
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)
71 DPRINTF(RubyNetwork,
"Adding input port:%s with vnets %s\n",
86 SwitchID router_id, uint32_t consumerVcs)
91 assert(consumerVcs > 0);
103 for (
int i = 0;
i < m_num_vcs;
i++) {
116 "%s: Connected Physical links have different vc requests: %d and %d\n",
120 DPRINTF(RubyNetwork,
"OutputPort:%s Vnet: %s\n",
136 for (
auto& it : in) {
138 it->setConsumer(
this);
165 Tick queueing_delay = src_queueing_delay + dest_queueing_delay;
193 std::ostringstream oss;
195 oss << oPort->routerID() <<
"[" << oPort->printVnets() <<
"] ";
197 DPRINTF(RubyNetwork,
"Network Interface %d connected to router:%s "
206 for (
int vnet = 0; vnet <
inNode_ptr.size(); ++vnet) {
212 if (
b->isReady(curTime)) {
227 DPRINTF(RubyNetwork,
"Number of input ports: %d\n",
inPorts.size());
232 DPRINTF(RubyNetwork,
"Recieved flit:%s\n", *t_flit);
233 assert(t_flit->
m_width == iPort->bitWidth());
243 if (!iPort->messageEnqueuedThisCycle &&
244 outNode_ptr[vnet]->areNSlotsAvailable(1, curTime)) {
253 iPort->sendCredit(cFlit);
262 iPort->m_stall_queue.push_back(t_flit);
265 outNode_ptr[vnet]->registerDequeueCallback([
this]() {
274 iPort->sendCredit(cFlit);
286 CreditLink *inCreditLink = oPort->inCreditLink();
304 if (iPort->outCreditQueue()->getSize() > 0) {
305 DPRINTF(RubyNetwork,
"Sending a credit %s via %s at %ld\n",
306 *(iPort->outCreditQueue()->peekTopFlit()),
308 iPort->outCreditLink()->
321 iPort->messageEnqueuedThisCycle =
false;
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;
341 iPort->sendCredit(cFlit);
349 iPort->m_stall_queue.erase(stallIter);
357 iPort->messageEnqueuedThisCycle =
true;
371 Message *net_msg_ptr = msg_ptr.get();
384 DPRINTF(RubyNetwork,
"Message Size:%d vnet:%d bitWidth:%d\n",
389 for (
int ctr = 0; ctr < dest_nodes.size(); ctr++) {
397 MsgPtr new_msg_ptr = msg_ptr->clone();
398 NodeID destID = dest_nodes[ctr];
400 Message *new_net_msg_ptr = new_msg_ptr.get();
401 if (dest_nodes.size() > 1) {
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))) {
407 personal_dest.
clear();
409 MachineType_base_number((MachineType)
m))});
440 for (
int i = 0;
i < num_flits;
i++) {
443 i, vc, vnet, route, num_flits, new_msg_ptr,
477 "%s: Possible network deadlock in vnet: %d at time: %llu \n",
499 bool is_candidate_vc =
true;
505 int t_vc = vc_base + vc_offset;
509 is_candidate_vc =
false;
515 if (!is_candidate_vc)
564 if (iPort->isVnetSupported(vnet)) {
582 if (oPort->isVnetSupported(vnet)) {
595 DPRINTF(RubyNetwork,
"Scheduling at %s time:%ld flit:%s Message:%s\n",
603 panic(
"No output port found for vnet:%d\n", t_flit->
get_vnet());
615 fatal(
"Could not determine vc");
657 CreditLink *inCreditLink = oPort->inCreditLink();
668 out <<
"[Network Interface]";
676 if (ni_out_vc.functionalRead(pkt,
mask))
681 if (oPort->outFlitQueue()->functionalRead(pkt,
mask))
691 uint32_t num_functional_writes = 0;
693 num_functional_writes += ni_out_vc.functionalWrite(pkt);
697 num_functional_writes += oPort->outFlitQueue()->functionalWrite(pkt);
699 return num_functional_writes;
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
Cycles is a wrapper class for representing cycle counts, i.e.
virtual std::string name() const
A Packet is used to encapsulate a transfer between two objects in the memory system (e....
void scheduleEventAbsolute(Tick timeAbs)
void scheduleEvent(Cycles timeDelta)
const MsgPtr & peekMsgPtr() const
virtual const NetDest & getDestination() const
virtual const MessageSizeType & getMessageSize() const
void add(MachineID newElement)
std::vector< NodeID > getAllDest()
void removeNetDest(const NetDest &netDest)
static uint32_t MessageSizeType_to_int(MessageSizeType size_type)
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_received_packets(int vnet)
void increment_injected_flits(int vnet)
void increment_packet_queueing_latency(Tick latency, int vnet)
void increment_total_hops(int hops)
void increment_packet_network_latency(Tick latency, int vnet)
void update_traffic_distribution(RouteInfo route)
void increment_injected_packets(int vnet)
void increment_received_flits(int vnet)
bool isVnetSupported(int pVnet)
NetworkLink * outNetLink()
flitBuffer * outFlitQueue()
std::vector< OutputPort * > outPorts
bool functionalRead(Packet *pkt, WriteMask &mask)
std::vector< int > m_vc_allocator
std::vector< InputPort * > inPorts
void addInPort(NetworkLink *in_link, CreditLink *credit_link)
GarnetNetwork * m_net_ptr
void scheduleFlit(flit *t_flit)
int calculateVC(int vnet)
const int m_virtual_networks
void addOutPort(NetworkLink *out_link, CreditLink *credit_link, SwitchID router_id, uint32_t consumerVcs)
std::vector< int > m_stall_count
std::vector< int > vc_busy_counter
void incrementStats(flit *t_flit)
void print(std::ostream &out) const
GarnetNetworkInterfaceParams Params
std::vector< MessageBuffer * > outNode_ptr
void addNode(std::vector< MessageBuffer * > &inNode, std::vector< MessageBuffer * > &outNode)
InputPort * getInportForVnet(int vnet)
void scheduleOutputPort(OutputPort *oPort)
NetworkInterface(const Params &p)
OutputPort * getOutportForVnet(int vnet)
std::vector< MessageBuffer * > inNode_ptr
uint32_t functionalWrite(Packet *)
bool flitisizeMessage(MsgPtr msg_ptr, int vnet)
std::vector< Tick > m_ni_out_vcs_enqueue_time
std::vector< OutVcState > outVcState
std::vector< flitBuffer > niOutVcs
void scheduleOutputLink()
This function looks at the NI buffers if some buffer has flits which are ready to traverse the link i...
bool isReady(Tick curTime)
void setLinkConsumer(Consumer *consumer)
void setSourceQueue(flitBuffer *src_queue, ClockedObject *srcClockObject)
virtual void setVcsPerVnet(uint32_t consumerVcs)
void set_src_delay(Tick delay)
void set_dequeue_time(Tick time)
static constexpr T divCeil(const T &a, const U &b)
#define panic(...)
This implements a cprintf based panic() function.
#define fatal_if(cond,...)
Conditional fatal macro that checks the supplied condition and only causes a fatal error if the condi...
#define fatal(...)
This implements a cprintf based fatal() function.
#define panic_if(cond,...)
Conditional panic macro that checks the supplied condition and only panics if the condition is true a...
std::shared_ptr< Message > MsgPtr
Copyright (c) 2024 - Pranith Kumar Copyright (c) 2020 Inria All rights reserved.
Tick curTick()
The universal simulation clock.
uint64_t Tick
Tick count type.