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/Router.hh"
3511666Stushar@ece.gatech.edu
3611666Stushar@ece.gatech.edu#include "base/stl_helpers.hh"
3711666Stushar@ece.gatech.edu#include "debug/RubyNetwork.hh"
3811666Stushar@ece.gatech.edu#include "mem/ruby/network/garnet2.0/CreditLink.hh"
3911666Stushar@ece.gatech.edu#include "mem/ruby/network/garnet2.0/CrossbarSwitch.hh"
4011666Stushar@ece.gatech.edu#include "mem/ruby/network/garnet2.0/GarnetNetwork.hh"
4111666Stushar@ece.gatech.edu#include "mem/ruby/network/garnet2.0/InputUnit.hh"
4211666Stushar@ece.gatech.edu#include "mem/ruby/network/garnet2.0/NetworkLink.hh"
4311666Stushar@ece.gatech.edu#include "mem/ruby/network/garnet2.0/OutputUnit.hh"
4411666Stushar@ece.gatech.edu#include "mem/ruby/network/garnet2.0/RoutingUnit.hh"
4511666Stushar@ece.gatech.edu#include "mem/ruby/network/garnet2.0/SwitchAllocator.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.eduRouter::Router(const Params *p)
5111666Stushar@ece.gatech.edu    : BasicRouter(p), Consumer(this)
5211666Stushar@ece.gatech.edu{
5311666Stushar@ece.gatech.edu    m_latency = p->latency;
5411666Stushar@ece.gatech.edu    m_virtual_networks = p->virt_nets;
5511666Stushar@ece.gatech.edu    m_vc_per_vnet = p->vcs_per_vnet;
5611666Stushar@ece.gatech.edu    m_num_vcs = m_virtual_networks * m_vc_per_vnet;
5711666Stushar@ece.gatech.edu
5811666Stushar@ece.gatech.edu    m_routing_unit = new RoutingUnit(this);
5911666Stushar@ece.gatech.edu    m_sw_alloc = new SwitchAllocator(this);
6011666Stushar@ece.gatech.edu    m_switch = new CrossbarSwitch(this);
6111666Stushar@ece.gatech.edu
6211666Stushar@ece.gatech.edu    m_input_unit.clear();
6311666Stushar@ece.gatech.edu    m_output_unit.clear();
6411666Stushar@ece.gatech.edu}
6511666Stushar@ece.gatech.edu
6611666Stushar@ece.gatech.eduRouter::~Router()
6711666Stushar@ece.gatech.edu{
6811666Stushar@ece.gatech.edu    deletePointers(m_input_unit);
6911666Stushar@ece.gatech.edu    deletePointers(m_output_unit);
7011666Stushar@ece.gatech.edu    delete m_routing_unit;
7111666Stushar@ece.gatech.edu    delete m_sw_alloc;
7211666Stushar@ece.gatech.edu    delete m_switch;
7311666Stushar@ece.gatech.edu}
7411666Stushar@ece.gatech.edu
7511666Stushar@ece.gatech.eduvoid
7611666Stushar@ece.gatech.eduRouter::init()
7711666Stushar@ece.gatech.edu{
7811666Stushar@ece.gatech.edu    BasicRouter::init();
7911666Stushar@ece.gatech.edu
8011666Stushar@ece.gatech.edu    m_sw_alloc->init();
8111666Stushar@ece.gatech.edu    m_switch->init();
8211666Stushar@ece.gatech.edu}
8311666Stushar@ece.gatech.edu
8411666Stushar@ece.gatech.eduvoid
8511666Stushar@ece.gatech.eduRouter::wakeup()
8611666Stushar@ece.gatech.edu{
8711666Stushar@ece.gatech.edu    DPRINTF(RubyNetwork, "Router %d woke up\n", m_id);
8811666Stushar@ece.gatech.edu
8911666Stushar@ece.gatech.edu    // check for incoming flits
9011666Stushar@ece.gatech.edu    for (int inport = 0; inport < m_input_unit.size(); inport++) {
9111666Stushar@ece.gatech.edu        m_input_unit[inport]->wakeup();
9211666Stushar@ece.gatech.edu    }
9311666Stushar@ece.gatech.edu
9411666Stushar@ece.gatech.edu    // check for incoming credits
9511666Stushar@ece.gatech.edu    // Note: the credit update is happening before SA
9611666Stushar@ece.gatech.edu    // buffer turnaround time =
9711666Stushar@ece.gatech.edu    //     credit traversal (1-cycle) + SA (1-cycle) + Link Traversal (1-cycle)
9811666Stushar@ece.gatech.edu    // if we want the credit update to take place after SA, this loop should
9911666Stushar@ece.gatech.edu    // be moved after the SA request
10011666Stushar@ece.gatech.edu    for (int outport = 0; outport < m_output_unit.size(); outport++) {
10111666Stushar@ece.gatech.edu        m_output_unit[outport]->wakeup();
10211666Stushar@ece.gatech.edu    }
10311666Stushar@ece.gatech.edu
10411666Stushar@ece.gatech.edu    // Switch Allocation
10511666Stushar@ece.gatech.edu    m_sw_alloc->wakeup();
10611666Stushar@ece.gatech.edu
10711666Stushar@ece.gatech.edu    // Switch Traversal
10811666Stushar@ece.gatech.edu    m_switch->wakeup();
10911666Stushar@ece.gatech.edu}
11011666Stushar@ece.gatech.edu
11111666Stushar@ece.gatech.eduvoid
11211666Stushar@ece.gatech.eduRouter::addInPort(PortDirection inport_dirn,
11311666Stushar@ece.gatech.edu                  NetworkLink *in_link, CreditLink *credit_link)
11411666Stushar@ece.gatech.edu{
11511666Stushar@ece.gatech.edu    int port_num = m_input_unit.size();
11611666Stushar@ece.gatech.edu    InputUnit *input_unit = new InputUnit(port_num, inport_dirn, this);
11711666Stushar@ece.gatech.edu
11811666Stushar@ece.gatech.edu    input_unit->set_in_link(in_link);
11911666Stushar@ece.gatech.edu    input_unit->set_credit_link(credit_link);
12011666Stushar@ece.gatech.edu    in_link->setLinkConsumer(this);
12111666Stushar@ece.gatech.edu    credit_link->setSourceQueue(input_unit->getCreditQueue());
12211666Stushar@ece.gatech.edu
12311666Stushar@ece.gatech.edu    m_input_unit.push_back(input_unit);
12411666Stushar@ece.gatech.edu
12511666Stushar@ece.gatech.edu    m_routing_unit->addInDirection(inport_dirn, port_num);
12611666Stushar@ece.gatech.edu}
12711666Stushar@ece.gatech.edu
12811666Stushar@ece.gatech.eduvoid
12911666Stushar@ece.gatech.eduRouter::addOutPort(PortDirection outport_dirn,
13011666Stushar@ece.gatech.edu                   NetworkLink *out_link,
13111666Stushar@ece.gatech.edu                   const NetDest& routing_table_entry, int link_weight,
13211666Stushar@ece.gatech.edu                   CreditLink *credit_link)
13311666Stushar@ece.gatech.edu{
13411666Stushar@ece.gatech.edu    int port_num = m_output_unit.size();
13511666Stushar@ece.gatech.edu    OutputUnit *output_unit = new OutputUnit(port_num, outport_dirn, this);
13611666Stushar@ece.gatech.edu
13711666Stushar@ece.gatech.edu    output_unit->set_out_link(out_link);
13811666Stushar@ece.gatech.edu    output_unit->set_credit_link(credit_link);
13911666Stushar@ece.gatech.edu    credit_link->setLinkConsumer(this);
14011666Stushar@ece.gatech.edu    out_link->setSourceQueue(output_unit->getOutQueue());
14111666Stushar@ece.gatech.edu
14211666Stushar@ece.gatech.edu    m_output_unit.push_back(output_unit);
14311666Stushar@ece.gatech.edu
14411666Stushar@ece.gatech.edu    m_routing_unit->addRoute(routing_table_entry);
14511666Stushar@ece.gatech.edu    m_routing_unit->addWeight(link_weight);
14611666Stushar@ece.gatech.edu    m_routing_unit->addOutDirection(outport_dirn, port_num);
14711666Stushar@ece.gatech.edu}
14811666Stushar@ece.gatech.edu
14911666Stushar@ece.gatech.eduPortDirection
15011666Stushar@ece.gatech.eduRouter::getOutportDirection(int outport)
15111666Stushar@ece.gatech.edu{
15211666Stushar@ece.gatech.edu    return m_output_unit[outport]->get_direction();
15311666Stushar@ece.gatech.edu}
15411666Stushar@ece.gatech.edu
15511666Stushar@ece.gatech.eduPortDirection
15611666Stushar@ece.gatech.eduRouter::getInportDirection(int inport)
15711666Stushar@ece.gatech.edu{
15811666Stushar@ece.gatech.edu    return m_input_unit[inport]->get_direction();
15911666Stushar@ece.gatech.edu}
16011666Stushar@ece.gatech.edu
16111666Stushar@ece.gatech.eduint
16211666Stushar@ece.gatech.eduRouter::route_compute(RouteInfo route, int inport, PortDirection inport_dirn)
16311666Stushar@ece.gatech.edu{
16411666Stushar@ece.gatech.edu    return m_routing_unit->outportCompute(route, inport, inport_dirn);
16511666Stushar@ece.gatech.edu}
16611666Stushar@ece.gatech.edu
16711666Stushar@ece.gatech.eduvoid
16811666Stushar@ece.gatech.eduRouter::grant_switch(int inport, flit *t_flit)
16911666Stushar@ece.gatech.edu{
17011666Stushar@ece.gatech.edu    m_switch->update_sw_winner(inport, t_flit);
17111666Stushar@ece.gatech.edu}
17211666Stushar@ece.gatech.edu
17311666Stushar@ece.gatech.eduvoid
17411666Stushar@ece.gatech.eduRouter::schedule_wakeup(Cycles time)
17511666Stushar@ece.gatech.edu{
17611666Stushar@ece.gatech.edu    // wake up after time cycles
17711666Stushar@ece.gatech.edu    scheduleEvent(time);
17811666Stushar@ece.gatech.edu}
17911666Stushar@ece.gatech.edu
18011666Stushar@ece.gatech.edustd::string
18111666Stushar@ece.gatech.eduRouter::getPortDirectionName(PortDirection direction)
18211666Stushar@ece.gatech.edu{
18311666Stushar@ece.gatech.edu    // PortDirection is actually a string
18411666Stushar@ece.gatech.edu    // If not, then this function should add a switch
18511666Stushar@ece.gatech.edu    // statement to convert direction to a string
18611666Stushar@ece.gatech.edu    // that can be printed out
18711666Stushar@ece.gatech.edu    return direction;
18811666Stushar@ece.gatech.edu}
18911666Stushar@ece.gatech.edu
19011666Stushar@ece.gatech.eduvoid
19111666Stushar@ece.gatech.eduRouter::regStats()
19211666Stushar@ece.gatech.edu{
19311666Stushar@ece.gatech.edu    BasicRouter::regStats();
19411666Stushar@ece.gatech.edu
19511666Stushar@ece.gatech.edu    m_buffer_reads
19611666Stushar@ece.gatech.edu        .name(name() + ".buffer_reads")
19711666Stushar@ece.gatech.edu        .flags(Stats::nozero)
19811666Stushar@ece.gatech.edu    ;
19911666Stushar@ece.gatech.edu
20011666Stushar@ece.gatech.edu    m_buffer_writes
20111666Stushar@ece.gatech.edu        .name(name() + ".buffer_writes")
20211666Stushar@ece.gatech.edu        .flags(Stats::nozero)
20311666Stushar@ece.gatech.edu    ;
20411666Stushar@ece.gatech.edu
20511666Stushar@ece.gatech.edu    m_crossbar_activity
20611666Stushar@ece.gatech.edu        .name(name() + ".crossbar_activity")
20711666Stushar@ece.gatech.edu        .flags(Stats::nozero)
20811666Stushar@ece.gatech.edu    ;
20911666Stushar@ece.gatech.edu
21011666Stushar@ece.gatech.edu    m_sw_input_arbiter_activity
21111666Stushar@ece.gatech.edu        .name(name() + ".sw_input_arbiter_activity")
21211666Stushar@ece.gatech.edu        .flags(Stats::nozero)
21311666Stushar@ece.gatech.edu    ;
21411666Stushar@ece.gatech.edu
21511666Stushar@ece.gatech.edu    m_sw_output_arbiter_activity
21611666Stushar@ece.gatech.edu        .name(name() + ".sw_output_arbiter_activity")
21711666Stushar@ece.gatech.edu        .flags(Stats::nozero)
21811666Stushar@ece.gatech.edu    ;
21911666Stushar@ece.gatech.edu}
22011666Stushar@ece.gatech.edu
22111666Stushar@ece.gatech.eduvoid
22211666Stushar@ece.gatech.eduRouter::collateStats()
22311666Stushar@ece.gatech.edu{
22411666Stushar@ece.gatech.edu    for (int j = 0; j < m_virtual_networks; j++) {
22511666Stushar@ece.gatech.edu        for (int i = 0; i < m_input_unit.size(); i++) {
22611666Stushar@ece.gatech.edu            m_buffer_reads += m_input_unit[i]->get_buf_read_activity(j);
22711666Stushar@ece.gatech.edu            m_buffer_writes += m_input_unit[i]->get_buf_write_activity(j);
22811666Stushar@ece.gatech.edu        }
22911666Stushar@ece.gatech.edu    }
23011666Stushar@ece.gatech.edu
23111666Stushar@ece.gatech.edu    m_sw_input_arbiter_activity = m_sw_alloc->get_input_arbiter_activity();
23211666Stushar@ece.gatech.edu    m_sw_output_arbiter_activity = m_sw_alloc->get_output_arbiter_activity();
23311666Stushar@ece.gatech.edu    m_crossbar_activity = m_switch->get_crossbar_activity();
23411666Stushar@ece.gatech.edu}
23511666Stushar@ece.gatech.edu
23611666Stushar@ece.gatech.eduvoid
23711666Stushar@ece.gatech.eduRouter::resetStats()
23811666Stushar@ece.gatech.edu{
23911666Stushar@ece.gatech.edu    for (int j = 0; j < m_virtual_networks; j++) {
24011666Stushar@ece.gatech.edu        for (int i = 0; i < m_input_unit.size(); i++) {
24111666Stushar@ece.gatech.edu            m_input_unit[i]->resetStats();
24211666Stushar@ece.gatech.edu        }
24311666Stushar@ece.gatech.edu    }
24412071Sjavier.cano555@gmail.com
24512071Sjavier.cano555@gmail.com    m_switch->resetStats();
24612071Sjavier.cano555@gmail.com    m_sw_alloc->resetStats();
24711666Stushar@ece.gatech.edu}
24811666Stushar@ece.gatech.edu
24911666Stushar@ece.gatech.eduvoid
25011666Stushar@ece.gatech.eduRouter::printFaultVector(ostream& out)
25111666Stushar@ece.gatech.edu{
25211666Stushar@ece.gatech.edu    int temperature_celcius = BASELINE_TEMPERATURE_CELCIUS;
25311666Stushar@ece.gatech.edu    int num_fault_types = m_network_ptr->fault_model->number_of_fault_types;
25411666Stushar@ece.gatech.edu    float fault_vector[num_fault_types];
25511666Stushar@ece.gatech.edu    get_fault_vector(temperature_celcius, fault_vector);
25611666Stushar@ece.gatech.edu    out << "Router-" << m_id << " fault vector: " << endl;
25711666Stushar@ece.gatech.edu    for (int fault_type_index = 0; fault_type_index < num_fault_types;
25811666Stushar@ece.gatech.edu         fault_type_index++) {
25911666Stushar@ece.gatech.edu        out << " - probability of (";
26011666Stushar@ece.gatech.edu        out <<
26111666Stushar@ece.gatech.edu        m_network_ptr->fault_model->fault_type_to_string(fault_type_index);
26211666Stushar@ece.gatech.edu        out << ") = ";
26311666Stushar@ece.gatech.edu        out << fault_vector[fault_type_index] << endl;
26411666Stushar@ece.gatech.edu    }
26511666Stushar@ece.gatech.edu}
26611666Stushar@ece.gatech.edu
26711666Stushar@ece.gatech.eduvoid
26811666Stushar@ece.gatech.eduRouter::printAggregateFaultProbability(std::ostream& out)
26911666Stushar@ece.gatech.edu{
27011666Stushar@ece.gatech.edu    int temperature_celcius = BASELINE_TEMPERATURE_CELCIUS;
27111666Stushar@ece.gatech.edu    float aggregate_fault_prob;
27211666Stushar@ece.gatech.edu    get_aggregate_fault_probability(temperature_celcius,
27311666Stushar@ece.gatech.edu                                    &aggregate_fault_prob);
27411666Stushar@ece.gatech.edu    out << "Router-" << m_id << " fault probability: ";
27511666Stushar@ece.gatech.edu    out << aggregate_fault_prob << endl;
27611666Stushar@ece.gatech.edu}
27711666Stushar@ece.gatech.edu
27811666Stushar@ece.gatech.eduuint32_t
27911666Stushar@ece.gatech.eduRouter::functionalWrite(Packet *pkt)
28011666Stushar@ece.gatech.edu{
28111666Stushar@ece.gatech.edu    uint32_t num_functional_writes = 0;
28211666Stushar@ece.gatech.edu    num_functional_writes += m_switch->functionalWrite(pkt);
28311666Stushar@ece.gatech.edu
28411666Stushar@ece.gatech.edu    for (uint32_t i = 0; i < m_input_unit.size(); i++) {
28511666Stushar@ece.gatech.edu        num_functional_writes += m_input_unit[i]->functionalWrite(pkt);
28611666Stushar@ece.gatech.edu    }
28711666Stushar@ece.gatech.edu
28811666Stushar@ece.gatech.edu    for (uint32_t i = 0; i < m_output_unit.size(); i++) {
28911666Stushar@ece.gatech.edu        num_functional_writes += m_output_unit[i]->functionalWrite(pkt);
29011666Stushar@ece.gatech.edu    }
29111666Stushar@ece.gatech.edu
29211666Stushar@ece.gatech.edu    return num_functional_writes;
29311666Stushar@ece.gatech.edu}
29411666Stushar@ece.gatech.edu
29511666Stushar@ece.gatech.eduRouter *
29611666Stushar@ece.gatech.eduGarnetRouterParams::create()
29711666Stushar@ece.gatech.edu{
29811666Stushar@ece.gatech.edu    return new Router(this);
29911666Stushar@ece.gatech.edu}
300