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/InputUnit.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/Credit.hh"
3911666Stushar@ece.gatech.edu#include "mem/ruby/network/garnet2.0/Router.hh"
4011666Stushar@ece.gatech.edu
4111666Stushar@ece.gatech.eduusing namespace std;
4211666Stushar@ece.gatech.eduusing m5::stl_helpers::deletePointers;
4311666Stushar@ece.gatech.edu
4411666Stushar@ece.gatech.eduInputUnit::InputUnit(int id, PortDirection direction, Router *router)
4511666Stushar@ece.gatech.edu            : Consumer(router)
4611666Stushar@ece.gatech.edu{
4711666Stushar@ece.gatech.edu    m_id = id;
4811666Stushar@ece.gatech.edu    m_direction = direction;
4911666Stushar@ece.gatech.edu    m_router = router;
5011666Stushar@ece.gatech.edu    m_num_vcs = m_router->get_num_vcs();
5111666Stushar@ece.gatech.edu    m_vc_per_vnet = m_router->get_vc_per_vnet();
5211666Stushar@ece.gatech.edu
5311666Stushar@ece.gatech.edu    m_num_buffer_reads.resize(m_num_vcs/m_vc_per_vnet);
5411666Stushar@ece.gatech.edu    m_num_buffer_writes.resize(m_num_vcs/m_vc_per_vnet);
5511666Stushar@ece.gatech.edu    for (int i = 0; i < m_num_buffer_reads.size(); i++) {
5611666Stushar@ece.gatech.edu        m_num_buffer_reads[i] = 0;
5711666Stushar@ece.gatech.edu        m_num_buffer_writes[i] = 0;
5811666Stushar@ece.gatech.edu    }
5911666Stushar@ece.gatech.edu
6011666Stushar@ece.gatech.edu    creditQueue = new flitBuffer();
6111666Stushar@ece.gatech.edu    // Instantiating the virtual channels
6211666Stushar@ece.gatech.edu    m_vcs.resize(m_num_vcs);
6311666Stushar@ece.gatech.edu    for (int i=0; i < m_num_vcs; i++) {
6411666Stushar@ece.gatech.edu        m_vcs[i] = new VirtualChannel(i);
6511666Stushar@ece.gatech.edu    }
6611666Stushar@ece.gatech.edu}
6711666Stushar@ece.gatech.edu
6811666Stushar@ece.gatech.eduInputUnit::~InputUnit()
6911666Stushar@ece.gatech.edu{
7011666Stushar@ece.gatech.edu    delete creditQueue;
7111666Stushar@ece.gatech.edu    deletePointers(m_vcs);
7211666Stushar@ece.gatech.edu}
7311666Stushar@ece.gatech.edu
7411666Stushar@ece.gatech.edu/*
7511666Stushar@ece.gatech.edu * The InputUnit wakeup function reads the input flit from its input link.
7611666Stushar@ece.gatech.edu * Each flit arrives with an input VC.
7711666Stushar@ece.gatech.edu * For HEAD/HEAD_TAIL flits, performs route computation,
7811666Stushar@ece.gatech.edu * and updates route in the input VC.
7911666Stushar@ece.gatech.edu * The flit is buffered for (m_latency - 1) cycles in the input VC
8011666Stushar@ece.gatech.edu * and marked as valid for SwitchAllocation starting that cycle.
8111666Stushar@ece.gatech.edu *
8211666Stushar@ece.gatech.edu */
8311666Stushar@ece.gatech.edu
8411666Stushar@ece.gatech.eduvoid
8511666Stushar@ece.gatech.eduInputUnit::wakeup()
8611666Stushar@ece.gatech.edu{
8711666Stushar@ece.gatech.edu    flit *t_flit;
8811666Stushar@ece.gatech.edu    if (m_in_link->isReady(m_router->curCycle())) {
8911666Stushar@ece.gatech.edu
9011666Stushar@ece.gatech.edu        t_flit = m_in_link->consumeLink();
9111666Stushar@ece.gatech.edu        int vc = t_flit->get_vc();
9211666Stushar@ece.gatech.edu        t_flit->increment_hops(); // for stats
9311666Stushar@ece.gatech.edu
9411666Stushar@ece.gatech.edu        if ((t_flit->get_type() == HEAD_) ||
9511666Stushar@ece.gatech.edu            (t_flit->get_type() == HEAD_TAIL_)) {
9611666Stushar@ece.gatech.edu
9711666Stushar@ece.gatech.edu            assert(m_vcs[vc]->get_state() == IDLE_);
9811666Stushar@ece.gatech.edu            set_vc_active(vc, m_router->curCycle());
9911666Stushar@ece.gatech.edu
10011666Stushar@ece.gatech.edu            // Route computation for this vc
10111666Stushar@ece.gatech.edu            int outport = m_router->route_compute(t_flit->get_route(),
10211666Stushar@ece.gatech.edu                m_id, m_direction);
10311666Stushar@ece.gatech.edu
10411666Stushar@ece.gatech.edu            // Update output port in VC
10511666Stushar@ece.gatech.edu            // All flits in this packet will use this output port
10611666Stushar@ece.gatech.edu            // The output port field in the flit is updated after it wins SA
10711666Stushar@ece.gatech.edu            grant_outport(vc, outport);
10811666Stushar@ece.gatech.edu
10911666Stushar@ece.gatech.edu        } else {
11011666Stushar@ece.gatech.edu            assert(m_vcs[vc]->get_state() == ACTIVE_);
11111666Stushar@ece.gatech.edu        }
11211666Stushar@ece.gatech.edu
11311666Stushar@ece.gatech.edu
11411666Stushar@ece.gatech.edu        // Buffer the flit
11511666Stushar@ece.gatech.edu        m_vcs[vc]->insertFlit(t_flit);
11611666Stushar@ece.gatech.edu
11711666Stushar@ece.gatech.edu        int vnet = vc/m_vc_per_vnet;
11811666Stushar@ece.gatech.edu        // number of writes same as reads
11911666Stushar@ece.gatech.edu        // any flit that is written will be read only once
12011666Stushar@ece.gatech.edu        m_num_buffer_writes[vnet]++;
12111666Stushar@ece.gatech.edu        m_num_buffer_reads[vnet]++;
12211666Stushar@ece.gatech.edu
12311666Stushar@ece.gatech.edu        Cycles pipe_stages = m_router->get_pipe_stages();
12411666Stushar@ece.gatech.edu        if (pipe_stages == 1) {
12511666Stushar@ece.gatech.edu            // 1-cycle router
12611666Stushar@ece.gatech.edu            // Flit goes for SA directly
12711666Stushar@ece.gatech.edu            t_flit->advance_stage(SA_, m_router->curCycle());
12811666Stushar@ece.gatech.edu        } else {
12911666Stushar@ece.gatech.edu            assert(pipe_stages > 1);
13011666Stushar@ece.gatech.edu            // Router delay is modeled by making flit wait in buffer for
13111666Stushar@ece.gatech.edu            // (pipe_stages cycles - 1) cycles before going for SA
13211666Stushar@ece.gatech.edu
13311666Stushar@ece.gatech.edu            Cycles wait_time = pipe_stages - Cycles(1);
13411666Stushar@ece.gatech.edu            t_flit->advance_stage(SA_, m_router->curCycle() + wait_time);
13511666Stushar@ece.gatech.edu
13611666Stushar@ece.gatech.edu            // Wakeup the router in that cycle to perform SA
13711666Stushar@ece.gatech.edu            m_router->schedule_wakeup(Cycles(wait_time));
13811666Stushar@ece.gatech.edu        }
13911666Stushar@ece.gatech.edu    }
14011666Stushar@ece.gatech.edu}
14111666Stushar@ece.gatech.edu
14211666Stushar@ece.gatech.edu// Send a credit back to upstream router for this VC.
14311666Stushar@ece.gatech.edu// Called by SwitchAllocator when the flit in this VC wins the Switch.
14411666Stushar@ece.gatech.eduvoid
14511666Stushar@ece.gatech.eduInputUnit::increment_credit(int in_vc, bool free_signal, Cycles curTime)
14611666Stushar@ece.gatech.edu{
14711666Stushar@ece.gatech.edu    Credit *t_credit = new Credit(in_vc, free_signal, curTime);
14811666Stushar@ece.gatech.edu    creditQueue->insert(t_credit);
14911666Stushar@ece.gatech.edu    m_credit_link->scheduleEventAbsolute(m_router->clockEdge(Cycles(1)));
15011666Stushar@ece.gatech.edu}
15111666Stushar@ece.gatech.edu
15211666Stushar@ece.gatech.edu
15311666Stushar@ece.gatech.eduuint32_t
15411666Stushar@ece.gatech.eduInputUnit::functionalWrite(Packet *pkt)
15511666Stushar@ece.gatech.edu{
15611666Stushar@ece.gatech.edu    uint32_t num_functional_writes = 0;
15711666Stushar@ece.gatech.edu    for (int i=0; i < m_num_vcs; i++) {
15811666Stushar@ece.gatech.edu        num_functional_writes += m_vcs[i]->functionalWrite(pkt);
15911666Stushar@ece.gatech.edu    }
16011666Stushar@ece.gatech.edu
16111666Stushar@ece.gatech.edu    return num_functional_writes;
16211666Stushar@ece.gatech.edu}
16311666Stushar@ece.gatech.edu
16411666Stushar@ece.gatech.eduvoid
16511666Stushar@ece.gatech.eduInputUnit::resetStats()
16611666Stushar@ece.gatech.edu{
16711666Stushar@ece.gatech.edu    for (int j = 0; j < m_num_buffer_reads.size(); j++) {
16811666Stushar@ece.gatech.edu        m_num_buffer_reads[j] = 0;
16911666Stushar@ece.gatech.edu        m_num_buffer_writes[j] = 0;
17011666Stushar@ece.gatech.edu    }
17111666Stushar@ece.gatech.edu}
172