src/mem/ruby/network/garnet/SwitchAllocator.cc
/*
 * A flit can be sent only if
 * (1) there is at least one free output VC at the
 *     output port (for HEAD/HEAD_TAIL),
 *  or
 * (2) if there is at least one credit (i.e., buffer slot)
 *     within the VC for BODY/TAIL flits of multi-flit packets.
 * and
 * (3) pt-to-pt ordering is not violated in ordered vnets, i.e.,
 *     there should be no other flit in this input port
 *     within an ordered vnet
 *     that arrived before this flit and is requesting the same output port.
 */
A flit can be sent only if
(1) there is at least one free output VC at the
output port (for HEAD/HEAD_TAIL),
or
(2) if there is at least one credit
within the VC for BODY/TAIL flits of multi-flit packets.
and
(3) pt-to-pt ordering is not violated in ordered vnets, i.e.,
there should be no other flit in this input port
within an ordered vnet
that arrived before this flit and is requesting the same output port.
A flit can be sent only if ( 1 ) there is at least one free output VC at the output port ( for HEAD / HEAD_TAIL ) or ( 2 ) if there is at least one credit within the VC for BODY / TAIL flits of multi - flit packets . and ( 3 ) pt - to - pt ordering is not violated in ordered vnets i . e . there should be no other flit in this input port within an ordered vnet that arrived before this flit and is requesting the same output port .
bool
SwitchAllocator::send_allowed(int inport, int invc, int outport, int outvc)
{
    int vnet = get_vnet(invc);
    bool has_outvc = (outvc != -1);
    bool has_credit = false;
    auto output_unit = m_router->getOutputUnit(outport);
    if (!has_outvc) {
        if (output_unit->has_free_vc(vnet)) {
            has_outvc = true;
            has_credit = true;
        }
    } else {
        has_credit = output_unit->has_credit(outvc);
    }
    if (!has_outvc || !has_credit)
        return false;
    if ((m_router->get_net_ptr())->isVNetOrdered(vnet)) {
        auto input_unit = m_router->getInputUnit(inport);
        Tick t_enqueue_time = input_unit->get_enqueue_time(invc);
        int vc_base = vnet*m_vc_per_vnet;
        for (int vc_offset = 0; vc_offset < m_vc_per_vnet; vc_offset++) {
            int temp_vc = vc_base + vc_offset;
            if (input_unit->need_stage(temp_vc, SA_, curTick()) &&
               (input_unit->get_outport(temp_vc) == outport) &&
               (input_unit->get_enqueue_time(temp_vc) < t_enqueue_time)) {
                return false;
            }
        }
    }
    return true;
}
bool SwitchAllocator :: send_allowed ( int inport , int invc , int outport , int outvc ) { int vnet = get_vnet ( invc ) ; bool has_outvc = ( outvc != -1 ) ; bool has_credit = false ; auto output_unit = m_router -> getOutputUnit ( outport ) ; if ( ! has_outvc ) { if ( output_unit -> has_free_vc ( vnet ) ) { has_outvc = true ; has_credit = true ; } } else { has_credit = output_unit -> has_credit ( outvc ) ; } if ( ! has_outvc || ! has_credit ) return false ; if ( ( m_router -> get_net_ptr ( ) ) -> isVNetOrdered ( vnet ) ) { auto input_unit = m_router -> getInputUnit ( inport ) ; Tick t_enqueue_time = input_unit -> get_enqueue_time ( invc ) ; int vc_base = vnet * m_vc_per_vnet ; for ( int vc_offset = 0 ; vc_offset < m_vc_per_vnet ; vc_offset ++ ) { int temp_vc = vc_base + vc_offset ; if ( input_unit -> need_stage ( temp_vc , SA_ , curTick ( ) ) && ( input_unit -> get_outport ( temp_vc ) == outport ) && ( input_unit -> get_enqueue_time ( temp_vc ) < t_enqueue_time ) ) { return false ; } } } return true ; }
A flit can be sent only if
 (1) there is at least one free output VC at the
     output port (for HEAD/HEAD_TAIL),
  or
 (2) if there is at least one credit (i.e., buffer slot)
     within the VC for BODY/TAIL flits of multi-flit packets.
A flit can be sent only if ( 1 ) there is at least one free output VC at the output port ( for HEAD / HEAD_TAIL ) or ( 2 ) if there is at least one credit ( i . e . buffer slot ) within the VC for BODY / TAIL flits of multi - flit packets .
// Check if outvc needed // Check if credit needed (for multi-flit packet) // Check if ordering violated (in ordered vnet) // needs outvc // this is only true for HEAD and HEAD_TAIL flits. // each VC has at least one buffer, // so no need for additional credit check // cannot send if no outvc or no credit. // protocol ordering check // enqueue time of this flit // check if any other flit is ready for SA and for same output port // and was enqueued before this flit