NetworkInterface.cc revision 11666
111666Stushar@ece.gatech.edu/* 211666Stushar@ece.gatech.edu * Copyright (c) 2008 Princeton University 311666Stushar@ece.gatech.edu * Copyright (c) 2016 Georgia Institute of Technology 411666Stushar@ece.gatech.edu * All rights reserved. 511666Stushar@ece.gatech.edu * 611666Stushar@ece.gatech.edu * Redistribution and use in source and binary forms, with or without 711666Stushar@ece.gatech.edu * modification, are permitted provided that the following conditions are 811666Stushar@ece.gatech.edu * met: redistributions of source code must retain the above copyright 911666Stushar@ece.gatech.edu * notice, this list of conditions and the following disclaimer; 1011666Stushar@ece.gatech.edu * redistributions in binary form must reproduce the above copyright 1111666Stushar@ece.gatech.edu * notice, this list of conditions and the following disclaimer in the 1211666Stushar@ece.gatech.edu * documentation and/or other materials provided with the distribution; 1311666Stushar@ece.gatech.edu * neither the name of the copyright holders nor the names of its 1411666Stushar@ece.gatech.edu * contributors may be used to endorse or promote products derived from 1511666Stushar@ece.gatech.edu * this software without specific prior written permission. 1611666Stushar@ece.gatech.edu * 1711666Stushar@ece.gatech.edu * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 1811666Stushar@ece.gatech.edu * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 1911666Stushar@ece.gatech.edu * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 2011666Stushar@ece.gatech.edu * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 2111666Stushar@ece.gatech.edu * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 2211666Stushar@ece.gatech.edu * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 2311666Stushar@ece.gatech.edu * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 2411666Stushar@ece.gatech.edu * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 2511666Stushar@ece.gatech.edu * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 2611666Stushar@ece.gatech.edu * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 2711666Stushar@ece.gatech.edu * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 2811666Stushar@ece.gatech.edu * 2911666Stushar@ece.gatech.edu * Authors: Niket Agarwal 3011666Stushar@ece.gatech.edu * Tushar Krishna 3111666Stushar@ece.gatech.edu */ 3211666Stushar@ece.gatech.edu 3311666Stushar@ece.gatech.edu 3411666Stushar@ece.gatech.edu#include "mem/ruby/network/garnet2.0/NetworkInterface.hh" 3511666Stushar@ece.gatech.edu 3611666Stushar@ece.gatech.edu#include <cassert> 3711666Stushar@ece.gatech.edu#include <cmath> 3811666Stushar@ece.gatech.edu 3911666Stushar@ece.gatech.edu#include "base/cast.hh" 4011666Stushar@ece.gatech.edu#include "base/stl_helpers.hh" 4111666Stushar@ece.gatech.edu#include "debug/RubyNetwork.hh" 4211666Stushar@ece.gatech.edu#include "mem/ruby/network/MessageBuffer.hh" 4311666Stushar@ece.gatech.edu#include "mem/ruby/network/garnet2.0/Credit.hh" 4411666Stushar@ece.gatech.edu#include "mem/ruby/network/garnet2.0/flitBuffer.hh" 4511666Stushar@ece.gatech.edu#include "mem/ruby/slicc_interface/Message.hh" 4611666Stushar@ece.gatech.edu 4711666Stushar@ece.gatech.eduusing namespace std; 4811666Stushar@ece.gatech.eduusing m5::stl_helpers::deletePointers; 4911666Stushar@ece.gatech.edu 5011666Stushar@ece.gatech.eduNetworkInterface::NetworkInterface(const Params *p) 5111666Stushar@ece.gatech.edu : ClockedObject(p), Consumer(this), m_id(p->id), 5211666Stushar@ece.gatech.edu m_virtual_networks(p->virt_nets), m_vc_per_vnet(p->vcs_per_vnet), 5311666Stushar@ece.gatech.edu m_num_vcs(m_vc_per_vnet * m_virtual_networks) 5411666Stushar@ece.gatech.edu{ 5511666Stushar@ece.gatech.edu m_router_id = -1; 5611666Stushar@ece.gatech.edu m_vc_round_robin = 0; 5711666Stushar@ece.gatech.edu m_ni_out_vcs.resize(m_num_vcs); 5811666Stushar@ece.gatech.edu m_ni_out_vcs_enqueue_time.resize(m_num_vcs); 5911666Stushar@ece.gatech.edu outCreditQueue = new flitBuffer(); 6011666Stushar@ece.gatech.edu 6111666Stushar@ece.gatech.edu // instantiating the NI flit buffers 6211666Stushar@ece.gatech.edu for (int i = 0; i < m_num_vcs; i++) { 6311666Stushar@ece.gatech.edu m_ni_out_vcs[i] = new flitBuffer(); 6411666Stushar@ece.gatech.edu m_ni_out_vcs_enqueue_time[i] = Cycles(INFINITE_); 6511666Stushar@ece.gatech.edu } 6611666Stushar@ece.gatech.edu 6711666Stushar@ece.gatech.edu m_vc_allocator.resize(m_virtual_networks); // 1 allocator per vnet 6811666Stushar@ece.gatech.edu for (int i = 0; i < m_virtual_networks; i++) { 6911666Stushar@ece.gatech.edu m_vc_allocator[i] = 0; 7011666Stushar@ece.gatech.edu } 7111666Stushar@ece.gatech.edu} 7211666Stushar@ece.gatech.edu 7311666Stushar@ece.gatech.eduvoid 7411666Stushar@ece.gatech.eduNetworkInterface::init() 7511666Stushar@ece.gatech.edu{ 7611666Stushar@ece.gatech.edu for (int i = 0; i < m_num_vcs; i++) { 7711666Stushar@ece.gatech.edu m_out_vc_state.push_back(new OutVcState(i, m_net_ptr)); 7811666Stushar@ece.gatech.edu } 7911666Stushar@ece.gatech.edu} 8011666Stushar@ece.gatech.edu 8111666Stushar@ece.gatech.eduNetworkInterface::~NetworkInterface() 8211666Stushar@ece.gatech.edu{ 8311666Stushar@ece.gatech.edu deletePointers(m_out_vc_state); 8411666Stushar@ece.gatech.edu deletePointers(m_ni_out_vcs); 8511666Stushar@ece.gatech.edu delete outCreditQueue; 8611666Stushar@ece.gatech.edu delete outFlitQueue; 8711666Stushar@ece.gatech.edu} 8811666Stushar@ece.gatech.edu 8911666Stushar@ece.gatech.eduvoid 9011666Stushar@ece.gatech.eduNetworkInterface::addInPort(NetworkLink *in_link, 9111666Stushar@ece.gatech.edu CreditLink *credit_link) 9211666Stushar@ece.gatech.edu{ 9311666Stushar@ece.gatech.edu inNetLink = in_link; 9411666Stushar@ece.gatech.edu in_link->setLinkConsumer(this); 9511666Stushar@ece.gatech.edu outCreditLink = credit_link; 9611666Stushar@ece.gatech.edu credit_link->setSourceQueue(outCreditQueue); 9711666Stushar@ece.gatech.edu} 9811666Stushar@ece.gatech.edu 9911666Stushar@ece.gatech.eduvoid 10011666Stushar@ece.gatech.eduNetworkInterface::addOutPort(NetworkLink *out_link, 10111666Stushar@ece.gatech.edu CreditLink *credit_link, 10211666Stushar@ece.gatech.edu SwitchID router_id) 10311666Stushar@ece.gatech.edu{ 10411666Stushar@ece.gatech.edu inCreditLink = credit_link; 10511666Stushar@ece.gatech.edu credit_link->setLinkConsumer(this); 10611666Stushar@ece.gatech.edu 10711666Stushar@ece.gatech.edu outNetLink = out_link; 10811666Stushar@ece.gatech.edu outFlitQueue = new flitBuffer(); 10911666Stushar@ece.gatech.edu out_link->setSourceQueue(outFlitQueue); 11011666Stushar@ece.gatech.edu 11111666Stushar@ece.gatech.edu m_router_id = router_id; 11211666Stushar@ece.gatech.edu} 11311666Stushar@ece.gatech.edu 11411666Stushar@ece.gatech.eduvoid 11511666Stushar@ece.gatech.eduNetworkInterface::addNode(vector<MessageBuffer *>& in, 11611666Stushar@ece.gatech.edu vector<MessageBuffer *>& out) 11711666Stushar@ece.gatech.edu{ 11811666Stushar@ece.gatech.edu inNode_ptr = in; 11911666Stushar@ece.gatech.edu outNode_ptr = out; 12011666Stushar@ece.gatech.edu 12111666Stushar@ece.gatech.edu for (auto& it : in) { 12211666Stushar@ece.gatech.edu if (it != nullptr) { 12311666Stushar@ece.gatech.edu it->setConsumer(this); 12411666Stushar@ece.gatech.edu } 12511666Stushar@ece.gatech.edu } 12611666Stushar@ece.gatech.edu} 12711666Stushar@ece.gatech.edu 12811666Stushar@ece.gatech.edu 12911666Stushar@ece.gatech.edu/* 13011666Stushar@ece.gatech.edu * The NI wakeup checks whether there are any ready messages in the protocol 13111666Stushar@ece.gatech.edu * buffer. If yes, it picks that up, flitisizes it into a number of flits and 13211666Stushar@ece.gatech.edu * puts it into an output buffer and schedules the output link. On a wakeup 13311666Stushar@ece.gatech.edu * it also checks whether there are flits in the input link. If yes, it picks 13411666Stushar@ece.gatech.edu * them up and if the flit is a tail, the NI inserts the corresponding message 13511666Stushar@ece.gatech.edu * into the protocol buffer. It also checks for credits being sent by the 13611666Stushar@ece.gatech.edu * downstream router. 13711666Stushar@ece.gatech.edu */ 13811666Stushar@ece.gatech.edu 13911666Stushar@ece.gatech.eduvoid 14011666Stushar@ece.gatech.eduNetworkInterface::wakeup() 14111666Stushar@ece.gatech.edu{ 14211666Stushar@ece.gatech.edu DPRINTF(RubyNetwork, "Network Interface %d connected to router %d " 14311666Stushar@ece.gatech.edu "woke up at time: %lld\n", m_id, m_router_id, curCycle()); 14411666Stushar@ece.gatech.edu 14511666Stushar@ece.gatech.edu MsgPtr msg_ptr; 14611666Stushar@ece.gatech.edu Tick curTime = clockEdge(); 14711666Stushar@ece.gatech.edu 14811666Stushar@ece.gatech.edu // Checking for messages coming from the protocol 14911666Stushar@ece.gatech.edu // can pick up a message/cycle for each virtual net 15011666Stushar@ece.gatech.edu for (int vnet = 0; vnet < inNode_ptr.size(); ++vnet) { 15111666Stushar@ece.gatech.edu MessageBuffer *b = inNode_ptr[vnet]; 15211666Stushar@ece.gatech.edu if (b == nullptr) { 15311666Stushar@ece.gatech.edu continue; 15411666Stushar@ece.gatech.edu } 15511666Stushar@ece.gatech.edu 15611666Stushar@ece.gatech.edu if (b->isReady(curTime)) { // Is there a message waiting 15711666Stushar@ece.gatech.edu msg_ptr = b->peekMsgPtr(); 15811666Stushar@ece.gatech.edu if (flitisizeMessage(msg_ptr, vnet)) { 15911666Stushar@ece.gatech.edu b->dequeue(curTime); 16011666Stushar@ece.gatech.edu } else { 16111666Stushar@ece.gatech.edu break; 16211666Stushar@ece.gatech.edu } 16311666Stushar@ece.gatech.edu } 16411666Stushar@ece.gatech.edu } 16511666Stushar@ece.gatech.edu 16611666Stushar@ece.gatech.edu scheduleOutputLink(); 16711666Stushar@ece.gatech.edu checkReschedule(); 16811666Stushar@ece.gatech.edu 16911666Stushar@ece.gatech.edu /*********** Check the incoming flit link **********/ 17011666Stushar@ece.gatech.edu 17111666Stushar@ece.gatech.edu if (inNetLink->isReady(curCycle())) { 17211666Stushar@ece.gatech.edu flit *t_flit = inNetLink->consumeLink(); 17311666Stushar@ece.gatech.edu bool free_signal = false; 17411666Stushar@ece.gatech.edu if (t_flit->get_type() == TAIL_ || t_flit->get_type() == HEAD_TAIL_) { 17511666Stushar@ece.gatech.edu free_signal = true; 17611666Stushar@ece.gatech.edu 17711666Stushar@ece.gatech.edu // enqueue into the protocol buffers 17811666Stushar@ece.gatech.edu outNode_ptr[t_flit->get_vnet()]->enqueue( 17911666Stushar@ece.gatech.edu t_flit->get_msg_ptr(), curTime, cyclesToTicks(Cycles(1))); 18011666Stushar@ece.gatech.edu } 18111666Stushar@ece.gatech.edu // Simply send a credit back since we are not buffering 18211666Stushar@ece.gatech.edu // this flit in the NI 18311666Stushar@ece.gatech.edu Credit *t_credit = new Credit(t_flit->get_vc(), free_signal, 18411666Stushar@ece.gatech.edu curCycle()); 18511666Stushar@ece.gatech.edu outCreditQueue->insert(t_credit); 18611666Stushar@ece.gatech.edu outCreditLink-> 18711666Stushar@ece.gatech.edu scheduleEventAbsolute(clockEdge(Cycles(1))); 18811666Stushar@ece.gatech.edu 18911666Stushar@ece.gatech.edu int vnet = t_flit->get_vnet(); 19011666Stushar@ece.gatech.edu 19111666Stushar@ece.gatech.edu // Update Stats 19211666Stushar@ece.gatech.edu 19311666Stushar@ece.gatech.edu // Latency 19411666Stushar@ece.gatech.edu m_net_ptr->increment_received_flits(vnet); 19511666Stushar@ece.gatech.edu Cycles network_delay = curCycle() - t_flit->get_enqueue_time(); 19611666Stushar@ece.gatech.edu Cycles queueing_delay = t_flit->get_src_delay(); 19711666Stushar@ece.gatech.edu 19811666Stushar@ece.gatech.edu m_net_ptr->increment_flit_network_latency(network_delay, vnet); 19911666Stushar@ece.gatech.edu m_net_ptr->increment_flit_queueing_latency(queueing_delay, vnet); 20011666Stushar@ece.gatech.edu 20111666Stushar@ece.gatech.edu if (t_flit->get_type() == TAIL_ || t_flit->get_type() == HEAD_TAIL_) { 20211666Stushar@ece.gatech.edu m_net_ptr->increment_received_packets(vnet); 20311666Stushar@ece.gatech.edu m_net_ptr->increment_packet_network_latency(network_delay, vnet); 20411666Stushar@ece.gatech.edu m_net_ptr->increment_packet_queueing_latency(queueing_delay, vnet); 20511666Stushar@ece.gatech.edu } 20611666Stushar@ece.gatech.edu 20711666Stushar@ece.gatech.edu // Hops 20811666Stushar@ece.gatech.edu m_net_ptr->increment_total_hops(t_flit->get_route().hops_traversed); 20911666Stushar@ece.gatech.edu 21011666Stushar@ece.gatech.edu delete t_flit; 21111666Stushar@ece.gatech.edu } 21211666Stushar@ece.gatech.edu 21311666Stushar@ece.gatech.edu /****************** Check the incoming credit link *******/ 21411666Stushar@ece.gatech.edu 21511666Stushar@ece.gatech.edu if (inCreditLink->isReady(curCycle())) { 21611666Stushar@ece.gatech.edu Credit *t_credit = (Credit*) inCreditLink->consumeLink(); 21711666Stushar@ece.gatech.edu m_out_vc_state[t_credit->get_vc()]->increment_credit(); 21811666Stushar@ece.gatech.edu if (t_credit->is_free_signal()) { 21911666Stushar@ece.gatech.edu m_out_vc_state[t_credit->get_vc()]->setState(IDLE_, curCycle()); 22011666Stushar@ece.gatech.edu } 22111666Stushar@ece.gatech.edu delete t_credit; 22211666Stushar@ece.gatech.edu } 22311666Stushar@ece.gatech.edu} 22411666Stushar@ece.gatech.edu 22511666Stushar@ece.gatech.edu 22611666Stushar@ece.gatech.edu// Embed the protocol message into flits 22711666Stushar@ece.gatech.edubool 22811666Stushar@ece.gatech.eduNetworkInterface::flitisizeMessage(MsgPtr msg_ptr, int vnet) 22911666Stushar@ece.gatech.edu{ 23011666Stushar@ece.gatech.edu Message *net_msg_ptr = msg_ptr.get(); 23111666Stushar@ece.gatech.edu NetDest net_msg_dest = net_msg_ptr->getDestination(); 23211666Stushar@ece.gatech.edu 23311666Stushar@ece.gatech.edu // gets all the destinations associated with this message. 23411666Stushar@ece.gatech.edu vector<NodeID> dest_nodes = net_msg_dest.getAllDest(); 23511666Stushar@ece.gatech.edu 23611666Stushar@ece.gatech.edu // Number of flits is dependent on the link bandwidth available. 23711666Stushar@ece.gatech.edu // This is expressed in terms of bytes/cycle or the flit size 23811666Stushar@ece.gatech.edu int num_flits = (int) ceil((double) m_net_ptr->MessageSizeType_to_int( 23911666Stushar@ece.gatech.edu net_msg_ptr->getMessageSize())/m_net_ptr->getNiFlitSize()); 24011666Stushar@ece.gatech.edu 24111666Stushar@ece.gatech.edu // loop to convert all multicast messages into unicast messages 24211666Stushar@ece.gatech.edu for (int ctr = 0; ctr < dest_nodes.size(); ctr++) { 24311666Stushar@ece.gatech.edu 24411666Stushar@ece.gatech.edu // this will return a free output virtual channel 24511666Stushar@ece.gatech.edu int vc = calculateVC(vnet); 24611666Stushar@ece.gatech.edu 24711666Stushar@ece.gatech.edu if (vc == -1) { 24811666Stushar@ece.gatech.edu return false ; 24911666Stushar@ece.gatech.edu } 25011666Stushar@ece.gatech.edu MsgPtr new_msg_ptr = msg_ptr->clone(); 25111666Stushar@ece.gatech.edu NodeID destID = dest_nodes[ctr]; 25211666Stushar@ece.gatech.edu 25311666Stushar@ece.gatech.edu Message *new_net_msg_ptr = new_msg_ptr.get(); 25411666Stushar@ece.gatech.edu if (dest_nodes.size() > 1) { 25511666Stushar@ece.gatech.edu NetDest personal_dest; 25611666Stushar@ece.gatech.edu for (int m = 0; m < (int) MachineType_NUM; m++) { 25711666Stushar@ece.gatech.edu if ((destID >= MachineType_base_number((MachineType) m)) && 25811666Stushar@ece.gatech.edu destID < MachineType_base_number((MachineType) (m+1))) { 25911666Stushar@ece.gatech.edu // calculating the NetDest associated with this destID 26011666Stushar@ece.gatech.edu personal_dest.clear(); 26111666Stushar@ece.gatech.edu personal_dest.add((MachineID) {(MachineType) m, (destID - 26211666Stushar@ece.gatech.edu MachineType_base_number((MachineType) m))}); 26311666Stushar@ece.gatech.edu new_net_msg_ptr->getDestination() = personal_dest; 26411666Stushar@ece.gatech.edu break; 26511666Stushar@ece.gatech.edu } 26611666Stushar@ece.gatech.edu } 26711666Stushar@ece.gatech.edu net_msg_dest.removeNetDest(personal_dest); 26811666Stushar@ece.gatech.edu // removing the destination from the original message to reflect 26911666Stushar@ece.gatech.edu // that a message with this particular destination has been 27011666Stushar@ece.gatech.edu // flitisized and an output vc is acquired 27111666Stushar@ece.gatech.edu net_msg_ptr->getDestination().removeNetDest(personal_dest); 27211666Stushar@ece.gatech.edu } 27311666Stushar@ece.gatech.edu 27411666Stushar@ece.gatech.edu // Embed Route into the flits 27511666Stushar@ece.gatech.edu // NetDest format is used by the routing table 27611666Stushar@ece.gatech.edu // Custom routing algorithms just need destID 27711666Stushar@ece.gatech.edu RouteInfo route; 27811666Stushar@ece.gatech.edu route.vnet = vnet; 27911666Stushar@ece.gatech.edu route.net_dest = new_net_msg_ptr->getDestination(); 28011666Stushar@ece.gatech.edu route.src_ni = m_id; 28111666Stushar@ece.gatech.edu route.src_router = m_router_id; 28211666Stushar@ece.gatech.edu route.dest_ni = destID; 28311666Stushar@ece.gatech.edu route.dest_router = m_net_ptr->get_router_id(destID); 28411666Stushar@ece.gatech.edu 28511666Stushar@ece.gatech.edu // initialize hops_traversed to -1 28611666Stushar@ece.gatech.edu // so that the first router increments it to 0 28711666Stushar@ece.gatech.edu route.hops_traversed = -1; 28811666Stushar@ece.gatech.edu 28911666Stushar@ece.gatech.edu m_net_ptr->increment_injected_packets(vnet); 29011666Stushar@ece.gatech.edu for (int i = 0; i < num_flits; i++) { 29111666Stushar@ece.gatech.edu m_net_ptr->increment_injected_flits(vnet); 29211666Stushar@ece.gatech.edu flit *fl = new flit(i, vc, vnet, route, num_flits, new_msg_ptr, 29311666Stushar@ece.gatech.edu curCycle()); 29411666Stushar@ece.gatech.edu 29511666Stushar@ece.gatech.edu fl->set_src_delay(curCycle() - ticksToCycles(msg_ptr->getTime())); 29611666Stushar@ece.gatech.edu m_ni_out_vcs[vc]->insert(fl); 29711666Stushar@ece.gatech.edu } 29811666Stushar@ece.gatech.edu 29911666Stushar@ece.gatech.edu m_ni_out_vcs_enqueue_time[vc] = curCycle(); 30011666Stushar@ece.gatech.edu m_out_vc_state[vc]->setState(ACTIVE_, curCycle()); 30111666Stushar@ece.gatech.edu } 30211666Stushar@ece.gatech.edu return true ; 30311666Stushar@ece.gatech.edu} 30411666Stushar@ece.gatech.edu 30511666Stushar@ece.gatech.edu// Looking for a free output vc 30611666Stushar@ece.gatech.eduint 30711666Stushar@ece.gatech.eduNetworkInterface::calculateVC(int vnet) 30811666Stushar@ece.gatech.edu{ 30911666Stushar@ece.gatech.edu for (int i = 0; i < m_vc_per_vnet; i++) { 31011666Stushar@ece.gatech.edu int delta = m_vc_allocator[vnet]; 31111666Stushar@ece.gatech.edu m_vc_allocator[vnet]++; 31211666Stushar@ece.gatech.edu if (m_vc_allocator[vnet] == m_vc_per_vnet) 31311666Stushar@ece.gatech.edu m_vc_allocator[vnet] = 0; 31411666Stushar@ece.gatech.edu 31511666Stushar@ece.gatech.edu if (m_out_vc_state[(vnet*m_vc_per_vnet) + delta]->isInState( 31611666Stushar@ece.gatech.edu IDLE_, curCycle())) { 31711666Stushar@ece.gatech.edu return ((vnet*m_vc_per_vnet) + delta); 31811666Stushar@ece.gatech.edu } 31911666Stushar@ece.gatech.edu } 32011666Stushar@ece.gatech.edu return -1; 32111666Stushar@ece.gatech.edu} 32211666Stushar@ece.gatech.edu 32311666Stushar@ece.gatech.edu 32411666Stushar@ece.gatech.edu/** This function looks at the NI buffers 32511666Stushar@ece.gatech.edu * if some buffer has flits which are ready to traverse the link in the next 32611666Stushar@ece.gatech.edu * cycle, and the downstream output vc associated with this flit has buffers 32711666Stushar@ece.gatech.edu * left, the link is scheduled for the next cycle 32811666Stushar@ece.gatech.edu */ 32911666Stushar@ece.gatech.edu 33011666Stushar@ece.gatech.eduvoid 33111666Stushar@ece.gatech.eduNetworkInterface::scheduleOutputLink() 33211666Stushar@ece.gatech.edu{ 33311666Stushar@ece.gatech.edu int vc = m_vc_round_robin; 33411666Stushar@ece.gatech.edu m_vc_round_robin++; 33511666Stushar@ece.gatech.edu if (m_vc_round_robin == m_num_vcs) 33611666Stushar@ece.gatech.edu m_vc_round_robin = 0; 33711666Stushar@ece.gatech.edu 33811666Stushar@ece.gatech.edu for (int i = 0; i < m_num_vcs; i++) { 33911666Stushar@ece.gatech.edu vc++; 34011666Stushar@ece.gatech.edu if (vc == m_num_vcs) 34111666Stushar@ece.gatech.edu vc = 0; 34211666Stushar@ece.gatech.edu 34311666Stushar@ece.gatech.edu // model buffer backpressure 34411666Stushar@ece.gatech.edu if (m_ni_out_vcs[vc]->isReady(curCycle()) && 34511666Stushar@ece.gatech.edu m_out_vc_state[vc]->has_credit()) { 34611666Stushar@ece.gatech.edu 34711666Stushar@ece.gatech.edu bool is_candidate_vc = true; 34811666Stushar@ece.gatech.edu int t_vnet = get_vnet(vc); 34911666Stushar@ece.gatech.edu int vc_base = t_vnet * m_vc_per_vnet; 35011666Stushar@ece.gatech.edu 35111666Stushar@ece.gatech.edu if (m_net_ptr->isVNetOrdered(t_vnet)) { 35211666Stushar@ece.gatech.edu for (int vc_offset = 0; vc_offset < m_vc_per_vnet; 35311666Stushar@ece.gatech.edu vc_offset++) { 35411666Stushar@ece.gatech.edu int t_vc = vc_base + vc_offset; 35511666Stushar@ece.gatech.edu if (m_ni_out_vcs[t_vc]->isReady(curCycle())) { 35611666Stushar@ece.gatech.edu if (m_ni_out_vcs_enqueue_time[t_vc] < 35711666Stushar@ece.gatech.edu m_ni_out_vcs_enqueue_time[vc]) { 35811666Stushar@ece.gatech.edu is_candidate_vc = false; 35911666Stushar@ece.gatech.edu break; 36011666Stushar@ece.gatech.edu } 36111666Stushar@ece.gatech.edu } 36211666Stushar@ece.gatech.edu } 36311666Stushar@ece.gatech.edu } 36411666Stushar@ece.gatech.edu if (!is_candidate_vc) 36511666Stushar@ece.gatech.edu continue; 36611666Stushar@ece.gatech.edu 36711666Stushar@ece.gatech.edu m_out_vc_state[vc]->decrement_credit(); 36811666Stushar@ece.gatech.edu // Just removing the flit 36911666Stushar@ece.gatech.edu flit *t_flit = m_ni_out_vcs[vc]->getTopFlit(); 37011666Stushar@ece.gatech.edu t_flit->set_time(curCycle() + Cycles(1)); 37111666Stushar@ece.gatech.edu outFlitQueue->insert(t_flit); 37211666Stushar@ece.gatech.edu // schedule the out link 37311666Stushar@ece.gatech.edu outNetLink->scheduleEventAbsolute(clockEdge(Cycles(1))); 37411666Stushar@ece.gatech.edu 37511666Stushar@ece.gatech.edu if (t_flit->get_type() == TAIL_ || 37611666Stushar@ece.gatech.edu t_flit->get_type() == HEAD_TAIL_) { 37711666Stushar@ece.gatech.edu m_ni_out_vcs_enqueue_time[vc] = Cycles(INFINITE_); 37811666Stushar@ece.gatech.edu } 37911666Stushar@ece.gatech.edu return; 38011666Stushar@ece.gatech.edu } 38111666Stushar@ece.gatech.edu } 38211666Stushar@ece.gatech.edu} 38311666Stushar@ece.gatech.edu 38411666Stushar@ece.gatech.eduint 38511666Stushar@ece.gatech.eduNetworkInterface::get_vnet(int vc) 38611666Stushar@ece.gatech.edu{ 38711666Stushar@ece.gatech.edu for (int i = 0; i < m_virtual_networks; i++) { 38811666Stushar@ece.gatech.edu if (vc >= (i*m_vc_per_vnet) && vc < ((i+1)*m_vc_per_vnet)) { 38911666Stushar@ece.gatech.edu return i; 39011666Stushar@ece.gatech.edu } 39111666Stushar@ece.gatech.edu } 39211666Stushar@ece.gatech.edu fatal("Could not determine vc"); 39311666Stushar@ece.gatech.edu} 39411666Stushar@ece.gatech.edu 39511666Stushar@ece.gatech.edu 39611666Stushar@ece.gatech.edu// Wakeup the NI in the next cycle if there are waiting 39711666Stushar@ece.gatech.edu// messages in the protocol buffer, or waiting flits in the 39811666Stushar@ece.gatech.edu// output VC buffer 39911666Stushar@ece.gatech.eduvoid 40011666Stushar@ece.gatech.eduNetworkInterface::checkReschedule() 40111666Stushar@ece.gatech.edu{ 40211666Stushar@ece.gatech.edu for (const auto& it : inNode_ptr) { 40311666Stushar@ece.gatech.edu if (it == nullptr) { 40411666Stushar@ece.gatech.edu continue; 40511666Stushar@ece.gatech.edu } 40611666Stushar@ece.gatech.edu 40711666Stushar@ece.gatech.edu while (it->isReady(clockEdge())) { // Is there a message waiting 40811666Stushar@ece.gatech.edu scheduleEvent(Cycles(1)); 40911666Stushar@ece.gatech.edu return; 41011666Stushar@ece.gatech.edu } 41111666Stushar@ece.gatech.edu } 41211666Stushar@ece.gatech.edu 41311666Stushar@ece.gatech.edu for (int vc = 0; vc < m_num_vcs; vc++) { 41411666Stushar@ece.gatech.edu if (m_ni_out_vcs[vc]->isReady(curCycle() + Cycles(1))) { 41511666Stushar@ece.gatech.edu scheduleEvent(Cycles(1)); 41611666Stushar@ece.gatech.edu return; 41711666Stushar@ece.gatech.edu } 41811666Stushar@ece.gatech.edu } 41911666Stushar@ece.gatech.edu} 42011666Stushar@ece.gatech.edu 42111666Stushar@ece.gatech.eduvoid 42211666Stushar@ece.gatech.eduNetworkInterface::print(std::ostream& out) const 42311666Stushar@ece.gatech.edu{ 42411666Stushar@ece.gatech.edu out << "[Network Interface]"; 42511666Stushar@ece.gatech.edu} 42611666Stushar@ece.gatech.edu 42711666Stushar@ece.gatech.eduuint32_t 42811666Stushar@ece.gatech.eduNetworkInterface::functionalWrite(Packet *pkt) 42911666Stushar@ece.gatech.edu{ 43011666Stushar@ece.gatech.edu uint32_t num_functional_writes = 0; 43111666Stushar@ece.gatech.edu for (unsigned int i = 0; i < m_num_vcs; ++i) { 43211666Stushar@ece.gatech.edu num_functional_writes += m_ni_out_vcs[i]->functionalWrite(pkt); 43311666Stushar@ece.gatech.edu } 43411666Stushar@ece.gatech.edu 43511666Stushar@ece.gatech.edu num_functional_writes += outFlitQueue->functionalWrite(pkt); 43611666Stushar@ece.gatech.edu return num_functional_writes; 43711666Stushar@ece.gatech.edu} 43811666Stushar@ece.gatech.edu 43911666Stushar@ece.gatech.eduNetworkInterface * 44011666Stushar@ece.gatech.eduGarnetNetworkInterfaceParams::create() 44111666Stushar@ece.gatech.edu{ 44211666Stushar@ece.gatech.edu return new NetworkInterface(this); 44311666Stushar@ece.gatech.edu} 444