src/mem/ruby/network/garnet/InputUnit.cc
/*
 * The InputUnit wakeup function reads the input flit from its input link.
 * Each flit arrives with an input VC.
 * For HEAD/HEAD_TAIL flits, performs route computation,
 * and updates route in the input VC.
 * The flit is buffered for (m_latency - 1) cycles in the input VC
 * and marked as valid for SwitchAllocation starting that cycle.
 *
 */
The InputUnit wakeup function reads the input flit from its input link.
Each flit arrives with an input VC.
For HEAD/HEAD_TAIL flits, performs route computation,
and updates route in the input VC.
The flit is buffered for (m_latency - 1) cycles in the input VC
and marked as valid for SwitchAllocation starting that cycle.
The InputUnit wakeup function reads the input flit from its input link . Each flit arrives with an input VC . For HEAD / HEAD_TAIL flits performs route computation and updates route in the input VC . The flit is buffered for ( m_latency - 1 ) cycles in the input VC and marked as valid for SwitchAllocation starting that cycle .
void
InputUnit::wakeup()
{
    flit *t_flit;
    if (m_in_link->isReady(curTick())) {
        t_flit = m_in_link->consumeLink();
        DPRINTF(RubyNetwork, "Router[%d] Consuming:%s Width: %d Flit:%s\n",
        m_router->get_id(), m_in_link->name(),
        m_router->getBitWidth(), *t_flit);
        assert(t_flit->m_width == m_router->getBitWidth());
        int vc = t_flit->get_vc();
        t_flit->increment_hops(); 
        if ((t_flit->get_type() == HEAD_) ||
            (t_flit->get_type() == HEAD_TAIL_)) {
            assert(virtualChannels[vc].get_state() == IDLE_);
            set_vc_active(vc, curTick());
            int outport = m_router->route_compute(t_flit->get_route(),
                m_id, m_direction);
            grant_outport(vc, outport);
        } else {
            assert(virtualChannels[vc].get_state() == ACTIVE_);
        }
        virtualChannels[vc].insertFlit(t_flit);
        int vnet = vc/m_vc_per_vnet;
        m_num_buffer_writes[vnet]++;
        m_num_buffer_reads[vnet]++;
        Cycles pipe_stages = m_router->get_pipe_stages();
        if (pipe_stages == 1) {
            t_flit->advance_stage(SA_, curTick());
        } else {
            assert(pipe_stages > 1);
            Cycles wait_time = pipe_stages - Cycles(1);
            t_flit->advance_stage(SA_, m_router->clockEdge(wait_time));
            m_router->schedule_wakeup(Cycles(wait_time));
        }
        if (m_in_link->isReady(curTick())) {
            m_router->schedule_wakeup(Cycles(1));
        }
    }
}
void InputUnit :: wakeup ( ) { flit * t_flit ; if ( m_in_link -> isReady ( curTick ( ) ) ) { t_flit = m_in_link -> consumeLink ( ) ; DPRINTF ( RubyNetwork , " \n " , m_router -> get_id ( ) , m_in_link -> name ( ) , m_router -> getBitWidth ( ) , * t_flit ) ; assert ( t_flit -> m_width == m_router -> getBitWidth ( ) ) ; int vc = t_flit -> get_vc ( ) ; t_flit -> increment_hops ( ) ; if ( ( t_flit -> get_type ( ) == HEAD_ ) || ( t_flit -> get_type ( ) == HEAD_TAIL_ ) ) { assert ( virtualChannels [ vc ] . get_state ( ) == IDLE_ ) ; set_vc_active ( vc , curTick ( ) ) ; int outport = m_router -> route_compute ( t_flit -> get_route ( ) , m_id , m_direction ) ; grant_outport ( vc , outport ) ; } else { assert ( virtualChannels [ vc ] . get_state ( ) == ACTIVE_ ) ; } virtualChannels [ vc ] . insertFlit ( t_flit ) ; int vnet = vc / m_vc_per_vnet ; m_num_buffer_writes [ vnet ] ++ ; m_num_buffer_reads [ vnet ] ++ ; Cycles pipe_stages = m_router -> get_pipe_stages ( ) ; if ( pipe_stages == 1 ) { t_flit -> advance_stage ( SA_ , curTick ( ) ) ; } else { assert ( pipe_stages > 1 ) ; Cycles wait_time = pipe_stages - Cycles ( 1 ) ; t_flit -> advance_stage ( SA_ , m_router -> clockEdge ( wait_time ) ) ; m_router -> schedule_wakeup ( Cycles ( wait_time ) ) ; } if ( m_in_link -> isReady ( curTick ( ) ) ) { m_router -> schedule_wakeup ( Cycles ( 1 ) ) ; } } }
The InputUnit wakeup function reads the input flit from its input link.
The InputUnit wakeup function reads the input flit from its input link .
// for stats // Route computation for this vc // Update output port in VC // All flits in this packet will use this output port // The output port field in the flit is updated after it wins SA // Buffer the flit // number of writes same as reads // any flit that is written will be read only once // 1-cycle router // Flit goes for SA directly // Router delay is modeled by making flit wait in buffer for // (pipe_stages cycles - 1) cycles before going for SA // Wakeup the router in that cycle to perform SA