39#include "debug/RubyNetwork.hh"
57 m_virtual_networks(
p.virt_nets), m_vc_per_vnet(0),
58 m_vc_allocator(m_virtual_networks, 0),
59 m_deadlock_threshold(
p.garnet_deadlock_threshold),
60 vc_busy_counter(m_virtual_networks, 0)
72 DPRINTF(RubyNetwork,
"Adding input port:%s with vnets %s\n",
87 SwitchID router_id, uint32_t consumerVcs)
92 assert(consumerVcs > 0);
104 for (
int i = 0;
i < m_num_vcs;
i++) {
117 "%s: Connected Physical links have different vc requests: %d and %d\n",
121 DPRINTF(RubyNetwork,
"OutputPort:%s Vnet: %s\n",
137 for (
auto& it : in) {
139 it->setConsumer(
this);
166 Tick queueing_delay = src_queueing_delay + dest_queueing_delay;
194 std::ostringstream oss;
196 oss << oPort->routerID() <<
"[" << oPort->printVnets() <<
"] ";
198 DPRINTF(RubyNetwork,
"Network Interface %d connected to router:%s "
207 for (
int vnet = 0; vnet <
inNode_ptr.size(); ++vnet) {
213 if (
b->isReady(curTime)) {
228 DPRINTF(RubyNetwork,
"Number of input ports: %d\n",
inPorts.size());
233 DPRINTF(RubyNetwork,
"Recieved flit:%s\n", *t_flit);
234 assert(t_flit->
m_width == iPort->bitWidth());
244 if (!iPort->messageEnqueuedThisCycle &&
245 outNode_ptr[vnet]->areNSlotsAvailable(1, curTime)) {
256 iPort->sendCredit(cFlit);
265 iPort->m_stall_queue.push_back(t_flit);
268 outNode_ptr[vnet]->registerDequeueCallback([
this]() {
277 iPort->sendCredit(cFlit);
289 CreditLink *inCreditLink = oPort->inCreditLink();
307 if (iPort->outCreditQueue()->getSize() > 0) {
308 DPRINTF(RubyNetwork,
"Sending a credit %s via %s at %ld\n",
309 *(iPort->outCreditQueue()->peekTopFlit()),
311 iPort->outCreditLink()->
324 iPort->messageEnqueuedThisCycle =
false;
327 if (!iPort->m_stall_queue.empty()) {
328 for (
auto stallIter = iPort->m_stall_queue.begin();
329 stallIter != iPort->m_stall_queue.end(); ) {
330 flit *stallFlit = *stallIter;
346 iPort->sendCredit(cFlit);
354 iPort->m_stall_queue.erase(stallIter);
362 iPort->messageEnqueuedThisCycle =
true;
376 Message *net_msg_ptr = msg_ptr.get();
389 DPRINTF(RubyNetwork,
"Message Size:%d vnet:%d bitWidth:%d\n",
394 for (
int ctr = 0; ctr < dest_nodes.size(); ctr++) {
402 MsgPtr new_msg_ptr = msg_ptr->clone();
403 NodeID destID = dest_nodes[ctr];
405 Message *new_net_msg_ptr = new_msg_ptr.get();
406 if (dest_nodes.size() > 1) {
408 for (
int m = 0;
m < (int) MachineType_NUM;
m++) {
412 personal_dest.
clear();
445 for (
int i = 0;
i < num_flits;
i++) {
448 i, vc, vnet, route, num_flits, new_msg_ptr,
482 "%s: Possible network deadlock in vnet: %d at time: %llu \n",
504 bool is_candidate_vc =
true;
510 int t_vc = vc_base + vc_offset;
514 is_candidate_vc =
false;
520 if (!is_candidate_vc)
569 if (iPort->isVnetSupported(vnet)) {
587 if (oPort->isVnetSupported(vnet)) {
600 DPRINTF(RubyNetwork,
"Scheduling at %s time:%ld flit:%s Message:%s\n",
608 panic(
"No output port found for vnet:%d\n", t_flit->
get_vnet());
620 fatal(
"Could not determine vc");
662 CreditLink *inCreditLink = oPort->inCreditLink();
673 out <<
"[Network Interface]";
681 if (ni_out_vc.functionalRead(pkt,
mask))
686 if (oPort->outFlitQueue()->functionalRead(pkt,
mask))
696 uint32_t num_functional_writes = 0;
698 num_functional_writes += ni_out_vc.functionalWrite(pkt);
702 num_functional_writes += oPort->outFlitQueue()->functionalWrite(pkt);
704 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)
RubySystem * getRubySystem() const
bool getRandomization() const
bool getWarmupEnabled() const
int MachineType_base_number(const MachineType &obj)
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)
int MachineType_base_number(const MachineType &obj)
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 Arm Limited All rights reserved.
Tick curTick()
The universal simulation clock.
uint64_t Tick
Tick count type.