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
13913736Ssrikant.bharadwaj@amd.com                    // Update Round Robin pointer to the next VC
14013736Ssrikant.bharadwaj@amd.com                    m_round_robin_invc[inport] = invc + 1;
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
25513736Ssrikant.bharadwaj@amd.com                m_round_robin_inport[outport] = inport + 1;
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;
39613736Ssrikant.bharadwaj@amd.com}
397