vpr/src/route/rr_graph.cpp
/* Determines whether the output pins of the specified block type should be perturbed.	*
 *  This is to prevent pathological cases where the output pin connections are		*
 *  spaced such that the connection pattern always skips some types of wire (w.r.t.	*
 *  starting points)									*/
Determines whether the output pins of the specified block type should be perturbed.
This is to prevent pathological cases where the output pin connections are
spaced such that the connection pattern always skips some types of wire (w.r.t.
starting points)
Determines whether the output pins of the specified block type should be perturbed . This is to prevent pathological cases where the output pin connections are spaced such that the connection pattern always skips some types of wire ( w . r . t . starting points )
static std::vector<bool> alloc_and_load_perturb_opins(const t_physical_tile_type_ptr type,
                                                      const vtr::Matrix<int>& Fc_out,
                                                      const int max_chan_width,
                                                      const std::vector<t_segment_inf>& segment_inf) {
    int i, Fc_max, iclass, num_wire_types;
    int num, max_primes, factor, num_factors;
    int* prime_factors;
    float step_size = 0;
    float n = 0;
    float threshold = 0.07;
    std::vector<bool> perturb_opins(segment_inf.size(), false);
    i = Fc_max = iclass = 0;
    if (segment_inf.size() > 1) {
        return perturb_opins;
    } else {
        num_wire_types = segment_inf[0].length;
    }
    for (i = 0; i < type->num_pins; ++i) {
        iclass = type->pin_class[i];
        if (Fc_out[i][0] > Fc_max && type->class_inf[iclass].type == DRIVER) {
            Fc_max = Fc_out[i][0];
        }
    }
    if (Fc_max == 0 || Fc_max == max_chan_width) {
        return perturb_opins;
    }
    max_primes = (int)floor(log((float)num_wire_types) / log(2.0));
    max_primes = std::max(max_primes, 1); 
    prime_factors = (int*)vtr::malloc(max_primes * sizeof(int));
    for (i = 0; i < max_primes; i++) {
        prime_factors[i] = 0;
    }
    num = num_wire_types;
    factor = 2;
    num_factors = 0;
    while (pow((float)factor, 2) <= num) {
        if (num % factor == 0) {
            num /= factor;
            if (factor != prime_factors[num_factors]) {
                prime_factors[num_factors] = factor;
                num_factors++;
            }
        } else {
            factor++;
        }
    }
    if (num_factors == 0) {
        prime_factors[num_factors++] = num_wire_types; 
    }
    step_size = (float)max_chan_width / Fc_max;
    for (i = 0; i < num_factors; i++) {
        if (vtr::nint(step_size) < prime_factors[i]) {
            perturb_opins[0] = false;
            break;
        }
        n = step_size / prime_factors[i];
        n = n - (float)vtr::nint(n); 
        if (fabs(n) < threshold) {
            perturb_opins[0] = true;
            break;
        } else {
            perturb_opins[0] = false;
        }
    }
    free(prime_factors);
    return perturb_opins;
}
static std :: vector < bool > alloc_and_load_perturb_opins ( const t_physical_tile_type_ptr type , const vtr :: Matrix < int > & Fc_out , const int max_chan_width , const std :: vector < t_segment_inf > & segment_inf ) { int i , Fc_max , iclass , num_wire_types ; int num , max_primes , factor , num_factors ; int * prime_factors ; float step_size = 0 ; float n = 0 ; float threshold = 0.07 ; std :: vector < bool > perturb_opins ( segment_inf . size ( ) , false ) ; i = Fc_max = iclass = 0 ; if ( segment_inf . size ( ) > 1 ) { return perturb_opins ; } else { num_wire_types = segment_inf [ 0 ] . length ; } for ( i = 0 ; i < type -> num_pins ; ++ i ) { iclass = type -> pin_class [ i ] ; if ( Fc_out [ i ] [ 0 ] > Fc_max && type -> class_inf [ iclass ] . type == DRIVER ) { Fc_max = Fc_out [ i ] [ 0 ] ; } } if ( Fc_max == 0 || Fc_max == max_chan_width ) { return perturb_opins ; } max_primes = ( int ) floor ( log ( ( float ) num_wire_types ) / log ( 2.0 ) ) ; max_primes = std :: max ( max_primes , 1 ) ; prime_factors = ( int * ) vtr :: malloc ( max_primes * sizeof ( int ) ) ; for ( i = 0 ; i < max_primes ; i ++ ) { prime_factors [ i ] = 0 ; } num = num_wire_types ; factor = 2 ; num_factors = 0 ; while ( pow ( ( float ) factor , 2 ) <= num ) { if ( num % factor == 0 ) { num /= factor ; if ( factor != prime_factors [ num_factors ] ) { prime_factors [ num_factors ] = factor ; num_factors ++ ; } } else { factor ++ ; } } if ( num_factors == 0 ) { prime_factors [ num_factors ++ ] = num_wire_types ; } step_size = ( float ) max_chan_width / Fc_max ; for ( i = 0 ; i < num_factors ; i ++ ) { if ( vtr :: nint ( step_size ) < prime_factors [ i ] ) { perturb_opins [ 0 ] = false ; break ; } n = step_size / prime_factors [ i ] ; n = n - ( float ) vtr :: nint ( n ) ; if ( fabs ( n ) < threshold ) { perturb_opins [ 0 ] = true ; break ; } else { perturb_opins [ 0 ] = false ; } } free ( prime_factors ) ; return perturb_opins ; }
Determines whether the output pins of the specified block type should be perturbed.
Determines whether the output pins of the specified block type should be perturbed .
/* Segments of one length are grouped together in the channel.	*
         *  In the future we can determine if any of these segments will	*
         *  encounter the pathological step size case, and determine if	*
         *  we need to perturb based on the segment's frequency (if 	*
         *  frequency is small we should not perturb - testing has found	*
         *  that perturbing a channel when unnecessary increases needed	*
         *  W to achieve the same delay); but for now we just return.	*/ /* There are as many wire start points as the value of L */ /* get Fc_max */ /* Nothing to perturb if Fc=0; no need to perturb if Fc = 1 */ /* Pathological cases occur when the step size, W/Fc, is a multiple of	*
     *  the number of wire starting points, L. Specifically, when the step 	*
     *  size is a multiple of a prime factor of L, the connection pattern	*
     *  will always skip some wires. Thus, we perturb pins if we detect this	*
     *  case.								*/ /* get an upper bound on the number of prime factors of num_wire_types	*/ //Minimum of 1 to ensure we allocate space for at least one prime_factor /* Find the prime factors of num_wire_types */ /* covers cases when num_wire_types is prime */ /* Now see if step size is an approximate multiple of one of the factors. A 	*
     *  threshold is used because step size may not be an integer.			*/ /* fractinal part */