SwitchAllocator.cc revision 12071
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/SwitchAllocator.hh" 3511666Stushar@ece.gatech.edu 3611666Stushar@ece.gatech.edu#include "debug/RubyNetwork.hh" 3711666Stushar@ece.gatech.edu#include "mem/ruby/network/garnet2.0/GarnetNetwork.hh" 3811666Stushar@ece.gatech.edu#include "mem/ruby/network/garnet2.0/InputUnit.hh" 3911666Stushar@ece.gatech.edu#include "mem/ruby/network/garnet2.0/OutputUnit.hh" 4011666Stushar@ece.gatech.edu#include "mem/ruby/network/garnet2.0/Router.hh" 4111666Stushar@ece.gatech.edu 4211666Stushar@ece.gatech.eduSwitchAllocator::SwitchAllocator(Router *router) 4311666Stushar@ece.gatech.edu : Consumer(router) 4411666Stushar@ece.gatech.edu{ 4511666Stushar@ece.gatech.edu m_router = router; 4611666Stushar@ece.gatech.edu m_num_vcs = m_router->get_num_vcs(); 4711666Stushar@ece.gatech.edu m_vc_per_vnet = m_router->get_vc_per_vnet(); 4811666Stushar@ece.gatech.edu 4911666Stushar@ece.gatech.edu m_input_arbiter_activity = 0; 5011666Stushar@ece.gatech.edu m_output_arbiter_activity = 0; 5111666Stushar@ece.gatech.edu} 5211666Stushar@ece.gatech.edu 5311666Stushar@ece.gatech.eduvoid 5411666Stushar@ece.gatech.eduSwitchAllocator::init() 5511666Stushar@ece.gatech.edu{ 5611666Stushar@ece.gatech.edu m_input_unit = m_router->get_inputUnit_ref(); 5711666Stushar@ece.gatech.edu m_output_unit = m_router->get_outputUnit_ref(); 5811666Stushar@ece.gatech.edu 5911666Stushar@ece.gatech.edu m_num_inports = m_router->get_num_inports(); 6011666Stushar@ece.gatech.edu m_num_outports = m_router->get_num_outports(); 6111666Stushar@ece.gatech.edu m_round_robin_inport.resize(m_num_outports); 6211666Stushar@ece.gatech.edu m_round_robin_invc.resize(m_num_inports); 6311666Stushar@ece.gatech.edu m_port_requests.resize(m_num_outports); 6411666Stushar@ece.gatech.edu m_vc_winners.resize(m_num_outports); 6511666Stushar@ece.gatech.edu 6611666Stushar@ece.gatech.edu for (int i = 0; i < m_num_inports; i++) { 6711666Stushar@ece.gatech.edu m_round_robin_invc[i] = 0; 6811666Stushar@ece.gatech.edu } 6911666Stushar@ece.gatech.edu 7011666Stushar@ece.gatech.edu for (int i = 0; i < m_num_outports; i++) { 7111666Stushar@ece.gatech.edu m_port_requests[i].resize(m_num_inports); 7211666Stushar@ece.gatech.edu m_vc_winners[i].resize(m_num_inports); 7311666Stushar@ece.gatech.edu 7411666Stushar@ece.gatech.edu m_round_robin_inport[i] = 0; 7511666Stushar@ece.gatech.edu 7611666Stushar@ece.gatech.edu for (int j = 0; j < m_num_inports; j++) { 7711666Stushar@ece.gatech.edu m_port_requests[i][j] = false; // [outport][inport] 7811666Stushar@ece.gatech.edu } 7911666Stushar@ece.gatech.edu } 8011666Stushar@ece.gatech.edu} 8111666Stushar@ece.gatech.edu 8211666Stushar@ece.gatech.edu/* 8311666Stushar@ece.gatech.edu * The wakeup function of the SwitchAllocator performs a 2-stage 8411666Stushar@ece.gatech.edu * seperable switch allocation. At the end of the 2nd stage, a free 8511666Stushar@ece.gatech.edu * output VC is assigned to the winning flits of each output port. 8611666Stushar@ece.gatech.edu * There is no separate VCAllocator stage like the one in garnet1.0. 8711666Stushar@ece.gatech.edu * At the end of this function, the router is rescheduled to wakeup 8811666Stushar@ece.gatech.edu * next cycle for peforming SA for any flits ready next cycle. 8911666Stushar@ece.gatech.edu */ 9011666Stushar@ece.gatech.edu 9111666Stushar@ece.gatech.eduvoid 9211666Stushar@ece.gatech.eduSwitchAllocator::wakeup() 9311666Stushar@ece.gatech.edu{ 9411666Stushar@ece.gatech.edu arbitrate_inports(); // First stage of allocation 9511666Stushar@ece.gatech.edu arbitrate_outports(); // Second stage of allocation 9611666Stushar@ece.gatech.edu 9711666Stushar@ece.gatech.edu clear_request_vector(); 9811666Stushar@ece.gatech.edu check_for_wakeup(); 9911666Stushar@ece.gatech.edu} 10011666Stushar@ece.gatech.edu 10111666Stushar@ece.gatech.edu/* 10211666Stushar@ece.gatech.edu * SA-I (or SA-i) loops through all input VCs at every input port, 10311666Stushar@ece.gatech.edu * and selects one in a round robin manner. 10411666Stushar@ece.gatech.edu * - For HEAD/HEAD_TAIL flits only selects an input VC whose output port 10511666Stushar@ece.gatech.edu * has at least one free output VC. 10611666Stushar@ece.gatech.edu * - For BODY/TAIL flits, only selects an input VC that has credits 10711666Stushar@ece.gatech.edu * in its output VC. 10811666Stushar@ece.gatech.edu * Places a request for the output port from this input VC. 10911666Stushar@ece.gatech.edu */ 11011666Stushar@ece.gatech.edu 11111666Stushar@ece.gatech.eduvoid 11211666Stushar@ece.gatech.eduSwitchAllocator::arbitrate_inports() 11311666Stushar@ece.gatech.edu{ 11411666Stushar@ece.gatech.edu // Select a VC from each input in a round robin manner 11511666Stushar@ece.gatech.edu // Independent arbiter at each input port 11611666Stushar@ece.gatech.edu for (int inport = 0; inport < m_num_inports; inport++) { 11711666Stushar@ece.gatech.edu int invc = m_round_robin_invc[inport]; 11811666Stushar@ece.gatech.edu 11911666Stushar@ece.gatech.edu for (int invc_iter = 0; invc_iter < m_num_vcs; invc_iter++) { 12011666Stushar@ece.gatech.edu 12111666Stushar@ece.gatech.edu if (m_input_unit[inport]->need_stage(invc, SA_, 12211666Stushar@ece.gatech.edu m_router->curCycle())) { 12311666Stushar@ece.gatech.edu 12411666Stushar@ece.gatech.edu // This flit is in SA stage 12511666Stushar@ece.gatech.edu 12611666Stushar@ece.gatech.edu int outport = m_input_unit[inport]->get_outport(invc); 12711666Stushar@ece.gatech.edu int outvc = m_input_unit[inport]->get_outvc(invc); 12811666Stushar@ece.gatech.edu 12911666Stushar@ece.gatech.edu // check if the flit in this InputVC is allowed to be sent 13011666Stushar@ece.gatech.edu // send_allowed conditions described in that function. 13111666Stushar@ece.gatech.edu bool make_request = 13211666Stushar@ece.gatech.edu send_allowed(inport, invc, outport, outvc); 13311666Stushar@ece.gatech.edu 13411666Stushar@ece.gatech.edu if (make_request) { 13511666Stushar@ece.gatech.edu m_input_arbiter_activity++; 13611666Stushar@ece.gatech.edu m_port_requests[outport][inport] = true; 13711666Stushar@ece.gatech.edu m_vc_winners[outport][inport]= invc; 13811831Stushar@ece.gatech.edu 13911831Stushar@ece.gatech.edu // Update Round Robin pointer 14011831Stushar@ece.gatech.edu m_round_robin_invc[inport]++; 14111831Stushar@ece.gatech.edu if (m_round_robin_invc[inport] >= m_num_vcs) 14211831Stushar@ece.gatech.edu m_round_robin_invc[inport] = 0; 14311831Stushar@ece.gatech.edu 14411666Stushar@ece.gatech.edu break; // got one vc winner for this port 14511666Stushar@ece.gatech.edu } 14611666Stushar@ece.gatech.edu } 14711666Stushar@ece.gatech.edu 14811666Stushar@ece.gatech.edu invc++; 14911666Stushar@ece.gatech.edu if (invc >= m_num_vcs) 15011666Stushar@ece.gatech.edu invc = 0; 15111666Stushar@ece.gatech.edu } 15211666Stushar@ece.gatech.edu } 15311666Stushar@ece.gatech.edu} 15411666Stushar@ece.gatech.edu 15511666Stushar@ece.gatech.edu/* 15611666Stushar@ece.gatech.edu * SA-II (or SA-o) loops through all output ports, 15711666Stushar@ece.gatech.edu * and selects one input VC (that placed a request during SA-I) 15811666Stushar@ece.gatech.edu * as the winner for this output port in a round robin manner. 15911666Stushar@ece.gatech.edu * - For HEAD/HEAD_TAIL flits, performs simplified outvc allocation. 16011666Stushar@ece.gatech.edu * (i.e., select a free VC from the output port). 16111666Stushar@ece.gatech.edu * - For BODY/TAIL flits, decrement a credit in the output vc. 16211666Stushar@ece.gatech.edu * The winning flit is read out from the input VC and sent to the 16311666Stushar@ece.gatech.edu * CrossbarSwitch. 16411666Stushar@ece.gatech.edu * An increment_credit signal is sent from the InputUnit 16511666Stushar@ece.gatech.edu * to the upstream router. For HEAD_TAIL/TAIL flits, is_free_signal in the 16611666Stushar@ece.gatech.edu * credit is set to true. 16711666Stushar@ece.gatech.edu */ 16811666Stushar@ece.gatech.edu 16911666Stushar@ece.gatech.eduvoid 17011666Stushar@ece.gatech.eduSwitchAllocator::arbitrate_outports() 17111666Stushar@ece.gatech.edu{ 17211666Stushar@ece.gatech.edu // Now there are a set of input vc requests for output vcs. 17311666Stushar@ece.gatech.edu // Again do round robin arbitration on these requests 17411666Stushar@ece.gatech.edu // Independent arbiter at each output port 17511666Stushar@ece.gatech.edu for (int outport = 0; outport < m_num_outports; outport++) { 17611666Stushar@ece.gatech.edu int inport = m_round_robin_inport[outport]; 17711666Stushar@ece.gatech.edu 17811666Stushar@ece.gatech.edu for (int inport_iter = 0; inport_iter < m_num_inports; 17911666Stushar@ece.gatech.edu inport_iter++) { 18011666Stushar@ece.gatech.edu 18111666Stushar@ece.gatech.edu // inport has a request this cycle for outport 18211666Stushar@ece.gatech.edu if (m_port_requests[outport][inport]) { 18311666Stushar@ece.gatech.edu 18411666Stushar@ece.gatech.edu // grant this outport to this inport 18511666Stushar@ece.gatech.edu int invc = m_vc_winners[outport][inport]; 18611666Stushar@ece.gatech.edu 18711666Stushar@ece.gatech.edu int outvc = m_input_unit[inport]->get_outvc(invc); 18811666Stushar@ece.gatech.edu if (outvc == -1) { 18911666Stushar@ece.gatech.edu // VC Allocation - select any free VC from outport 19011666Stushar@ece.gatech.edu outvc = vc_allocate(outport, inport, invc); 19111666Stushar@ece.gatech.edu } 19211666Stushar@ece.gatech.edu 19311666Stushar@ece.gatech.edu // remove flit from Input VC 19411666Stushar@ece.gatech.edu flit *t_flit = m_input_unit[inport]->getTopFlit(invc); 19511666Stushar@ece.gatech.edu 19611666Stushar@ece.gatech.edu DPRINTF(RubyNetwork, "SwitchAllocator at Router %d " 19711666Stushar@ece.gatech.edu "granted outvc %d at outport %d " 19811666Stushar@ece.gatech.edu "to invc %d at inport %d to flit %s at " 19911666Stushar@ece.gatech.edu "time: %lld\n", 20011666Stushar@ece.gatech.edu m_router->get_id(), outvc, 20111666Stushar@ece.gatech.edu m_router->getPortDirectionName( 20211666Stushar@ece.gatech.edu m_output_unit[outport]->get_direction()), 20311666Stushar@ece.gatech.edu invc, 20411666Stushar@ece.gatech.edu m_router->getPortDirectionName( 20511666Stushar@ece.gatech.edu m_input_unit[inport]->get_direction()), 20611666Stushar@ece.gatech.edu *t_flit, 20711666Stushar@ece.gatech.edu m_router->curCycle()); 20811666Stushar@ece.gatech.edu 20911666Stushar@ece.gatech.edu 21011666Stushar@ece.gatech.edu // Update outport field in the flit since this is 21111666Stushar@ece.gatech.edu // used by CrossbarSwitch code to send it out of 21211666Stushar@ece.gatech.edu // correct outport. 21311666Stushar@ece.gatech.edu // Note: post route compute in InputUnit, 21411666Stushar@ece.gatech.edu // outport is updated in VC, but not in flit 21511666Stushar@ece.gatech.edu t_flit->set_outport(outport); 21611666Stushar@ece.gatech.edu 21711666Stushar@ece.gatech.edu // set outvc (i.e., invc for next hop) in flit 21811666Stushar@ece.gatech.edu // (This was updated in VC by vc_allocate, but not in flit) 21911666Stushar@ece.gatech.edu t_flit->set_vc(outvc); 22011666Stushar@ece.gatech.edu 22111666Stushar@ece.gatech.edu // decrement credit in outvc 22211666Stushar@ece.gatech.edu m_output_unit[outport]->decrement_credit(outvc); 22311666Stushar@ece.gatech.edu 22411666Stushar@ece.gatech.edu // flit ready for Switch Traversal 22511666Stushar@ece.gatech.edu t_flit->advance_stage(ST_, m_router->curCycle()); 22611666Stushar@ece.gatech.edu m_router->grant_switch(inport, t_flit); 22711666Stushar@ece.gatech.edu m_output_arbiter_activity++; 22811666Stushar@ece.gatech.edu 22911666Stushar@ece.gatech.edu if ((t_flit->get_type() == TAIL_) || 23011666Stushar@ece.gatech.edu t_flit->get_type() == HEAD_TAIL_) { 23111666Stushar@ece.gatech.edu 23211666Stushar@ece.gatech.edu // This Input VC should now be empty 23311666Stushar@ece.gatech.edu assert(!(m_input_unit[inport]->isReady(invc, 23411666Stushar@ece.gatech.edu m_router->curCycle()))); 23511666Stushar@ece.gatech.edu 23611666Stushar@ece.gatech.edu // Free this VC 23711666Stushar@ece.gatech.edu m_input_unit[inport]->set_vc_idle(invc, 23811666Stushar@ece.gatech.edu m_router->curCycle()); 23911666Stushar@ece.gatech.edu 24011666Stushar@ece.gatech.edu // Send a credit back 24111666Stushar@ece.gatech.edu // along with the information that this VC is now idle 24211666Stushar@ece.gatech.edu m_input_unit[inport]->increment_credit(invc, true, 24311666Stushar@ece.gatech.edu m_router->curCycle()); 24411666Stushar@ece.gatech.edu } else { 24511666Stushar@ece.gatech.edu // Send a credit back 24611666Stushar@ece.gatech.edu // but do not indicate that the VC is idle 24711666Stushar@ece.gatech.edu m_input_unit[inport]->increment_credit(invc, false, 24811666Stushar@ece.gatech.edu m_router->curCycle()); 24911666Stushar@ece.gatech.edu } 25011666Stushar@ece.gatech.edu 25111666Stushar@ece.gatech.edu // remove this request 25211666Stushar@ece.gatech.edu m_port_requests[outport][inport] = false; 25311666Stushar@ece.gatech.edu 25411831Stushar@ece.gatech.edu // Update Round Robin pointer 25511831Stushar@ece.gatech.edu m_round_robin_inport[outport]++; 25611831Stushar@ece.gatech.edu if (m_round_robin_inport[outport] >= m_num_inports) 25711831Stushar@ece.gatech.edu m_round_robin_inport[outport] = 0; 25811831Stushar@ece.gatech.edu 25911666Stushar@ece.gatech.edu break; // got a input winner for this outport 26011666Stushar@ece.gatech.edu } 26111666Stushar@ece.gatech.edu 26211666Stushar@ece.gatech.edu inport++; 26311666Stushar@ece.gatech.edu if (inport >= m_num_inports) 26411666Stushar@ece.gatech.edu inport = 0; 26511666Stushar@ece.gatech.edu } 26611666Stushar@ece.gatech.edu } 26711666Stushar@ece.gatech.edu} 26811666Stushar@ece.gatech.edu 26911666Stushar@ece.gatech.edu/* 27011666Stushar@ece.gatech.edu * A flit can be sent only if 27111666Stushar@ece.gatech.edu * (1) there is at least one free output VC at the 27211666Stushar@ece.gatech.edu * output port (for HEAD/HEAD_TAIL), 27311666Stushar@ece.gatech.edu * or 27411666Stushar@ece.gatech.edu * (2) if there is at least one credit (i.e., buffer slot) 27511666Stushar@ece.gatech.edu * within the VC for BODY/TAIL flits of multi-flit packets. 27611666Stushar@ece.gatech.edu * and 27711666Stushar@ece.gatech.edu * (3) pt-to-pt ordering is not violated in ordered vnets, i.e., 27811666Stushar@ece.gatech.edu * there should be no other flit in this input port 27911666Stushar@ece.gatech.edu * within an ordered vnet 28011666Stushar@ece.gatech.edu * that arrived before this flit and is requesting the same output port. 28111666Stushar@ece.gatech.edu */ 28211666Stushar@ece.gatech.edu 28311666Stushar@ece.gatech.edubool 28411666Stushar@ece.gatech.eduSwitchAllocator::send_allowed(int inport, int invc, int outport, int outvc) 28511666Stushar@ece.gatech.edu{ 28611666Stushar@ece.gatech.edu // Check if outvc needed 28711666Stushar@ece.gatech.edu // Check if credit needed (for multi-flit packet) 28811666Stushar@ece.gatech.edu // Check if ordering violated (in ordered vnet) 28911666Stushar@ece.gatech.edu 29011666Stushar@ece.gatech.edu int vnet = get_vnet(invc); 29111666Stushar@ece.gatech.edu bool has_outvc = (outvc != -1); 29211666Stushar@ece.gatech.edu bool has_credit = false; 29311666Stushar@ece.gatech.edu 29411666Stushar@ece.gatech.edu if (!has_outvc) { 29511666Stushar@ece.gatech.edu 29611666Stushar@ece.gatech.edu // needs outvc 29711666Stushar@ece.gatech.edu // this is only true for HEAD and HEAD_TAIL flits. 29811666Stushar@ece.gatech.edu 29911666Stushar@ece.gatech.edu if (m_output_unit[outport]->has_free_vc(vnet)) { 30011666Stushar@ece.gatech.edu 30111666Stushar@ece.gatech.edu has_outvc = true; 30211666Stushar@ece.gatech.edu 30311666Stushar@ece.gatech.edu // each VC has at least one buffer, 30411666Stushar@ece.gatech.edu // so no need for additional credit check 30511666Stushar@ece.gatech.edu has_credit = true; 30611666Stushar@ece.gatech.edu } 30711666Stushar@ece.gatech.edu } else { 30811666Stushar@ece.gatech.edu has_credit = m_output_unit[outport]->has_credit(outvc); 30911666Stushar@ece.gatech.edu } 31011666Stushar@ece.gatech.edu 31111666Stushar@ece.gatech.edu // cannot send if no outvc or no credit. 31211666Stushar@ece.gatech.edu if (!has_outvc || !has_credit) 31311666Stushar@ece.gatech.edu return false; 31411666Stushar@ece.gatech.edu 31511666Stushar@ece.gatech.edu 31611666Stushar@ece.gatech.edu // protocol ordering check 31711666Stushar@ece.gatech.edu if ((m_router->get_net_ptr())->isVNetOrdered(vnet)) { 31811666Stushar@ece.gatech.edu 31911666Stushar@ece.gatech.edu // enqueue time of this flit 32011666Stushar@ece.gatech.edu Cycles t_enqueue_time = m_input_unit[inport]->get_enqueue_time(invc); 32111666Stushar@ece.gatech.edu 32211666Stushar@ece.gatech.edu // check if any other flit is ready for SA and for same output port 32311666Stushar@ece.gatech.edu // and was enqueued before this flit 32411666Stushar@ece.gatech.edu int vc_base = vnet*m_vc_per_vnet; 32511666Stushar@ece.gatech.edu for (int vc_offset = 0; vc_offset < m_vc_per_vnet; vc_offset++) { 32611666Stushar@ece.gatech.edu int temp_vc = vc_base + vc_offset; 32711666Stushar@ece.gatech.edu if (m_input_unit[inport]->need_stage(temp_vc, SA_, 32811666Stushar@ece.gatech.edu m_router->curCycle()) && 32911666Stushar@ece.gatech.edu (m_input_unit[inport]->get_outport(temp_vc) == outport) && 33011666Stushar@ece.gatech.edu (m_input_unit[inport]->get_enqueue_time(temp_vc) < 33111666Stushar@ece.gatech.edu t_enqueue_time)) { 33211666Stushar@ece.gatech.edu return false; 33311666Stushar@ece.gatech.edu } 33411666Stushar@ece.gatech.edu } 33511666Stushar@ece.gatech.edu } 33611666Stushar@ece.gatech.edu 33711666Stushar@ece.gatech.edu return true; 33811666Stushar@ece.gatech.edu} 33911666Stushar@ece.gatech.edu 34011666Stushar@ece.gatech.edu// Assign a free VC to the winner of the output port. 34111666Stushar@ece.gatech.eduint 34211666Stushar@ece.gatech.eduSwitchAllocator::vc_allocate(int outport, int inport, int invc) 34311666Stushar@ece.gatech.edu{ 34411666Stushar@ece.gatech.edu // Select a free VC from the output port 34511666Stushar@ece.gatech.edu int outvc = m_output_unit[outport]->select_free_vc(get_vnet(invc)); 34611666Stushar@ece.gatech.edu 34711666Stushar@ece.gatech.edu // has to get a valid VC since it checked before performing SA 34811666Stushar@ece.gatech.edu assert(outvc != -1); 34911666Stushar@ece.gatech.edu m_input_unit[inport]->grant_outvc(invc, outvc); 35011666Stushar@ece.gatech.edu return outvc; 35111666Stushar@ece.gatech.edu} 35211666Stushar@ece.gatech.edu 35311666Stushar@ece.gatech.edu// Wakeup the router next cycle to perform SA again 35411666Stushar@ece.gatech.edu// if there are flits ready. 35511666Stushar@ece.gatech.eduvoid 35611666Stushar@ece.gatech.eduSwitchAllocator::check_for_wakeup() 35711666Stushar@ece.gatech.edu{ 35811666Stushar@ece.gatech.edu Cycles nextCycle = m_router->curCycle() + Cycles(1); 35911666Stushar@ece.gatech.edu 36011666Stushar@ece.gatech.edu for (int i = 0; i < m_num_inports; i++) { 36111666Stushar@ece.gatech.edu for (int j = 0; j < m_num_vcs; j++) { 36211666Stushar@ece.gatech.edu if (m_input_unit[i]->need_stage(j, SA_, nextCycle)) { 36311666Stushar@ece.gatech.edu m_router->schedule_wakeup(Cycles(1)); 36411666Stushar@ece.gatech.edu return; 36511666Stushar@ece.gatech.edu } 36611666Stushar@ece.gatech.edu } 36711666Stushar@ece.gatech.edu } 36811666Stushar@ece.gatech.edu} 36911666Stushar@ece.gatech.edu 37011666Stushar@ece.gatech.eduint 37111666Stushar@ece.gatech.eduSwitchAllocator::get_vnet(int invc) 37211666Stushar@ece.gatech.edu{ 37311666Stushar@ece.gatech.edu int vnet = invc/m_vc_per_vnet; 37411666Stushar@ece.gatech.edu assert(vnet < m_router->get_num_vnets()); 37511666Stushar@ece.gatech.edu return vnet; 37611666Stushar@ece.gatech.edu} 37711666Stushar@ece.gatech.edu 37811666Stushar@ece.gatech.edu 37911666Stushar@ece.gatech.edu// Clear the request vector within the allocator at end of SA-II. 38011666Stushar@ece.gatech.edu// Was populated by SA-I. 38111666Stushar@ece.gatech.eduvoid 38211666Stushar@ece.gatech.eduSwitchAllocator::clear_request_vector() 38311666Stushar@ece.gatech.edu{ 38411666Stushar@ece.gatech.edu for (int i = 0; i < m_num_outports; i++) { 38511666Stushar@ece.gatech.edu for (int j = 0; j < m_num_inports; j++) { 38611666Stushar@ece.gatech.edu m_port_requests[i][j] = false; 38711666Stushar@ece.gatech.edu } 38811666Stushar@ece.gatech.edu } 38911666Stushar@ece.gatech.edu} 39012071Sjavier.cano555@gmail.com 39112071Sjavier.cano555@gmail.comvoid 39212071Sjavier.cano555@gmail.comSwitchAllocator::resetStats() 39312071Sjavier.cano555@gmail.com{ 39412071Sjavier.cano555@gmail.com m_input_arbiter_activity = 0; 39512071Sjavier.cano555@gmail.com m_output_arbiter_activity = 0; 39612071Sjavier.cano555@gmail.com}