vpr/src/pack/cluster.cpp
/* Check if the number of available inputs/outputs for a pin class is sufficient for speculatively packed blocks */
Check if the number of available inputs/outputs for a pin class is sufficient for speculatively packed blocks
Check if the number of available inputs / outputs for a pin class is sufficient for speculatively packed blocks
static bool check_lookahead_pins_used(t_pb* cur_pb, t_ext_pin_util max_external_pin_util) {
    const t_pb_type* pb_type = cur_pb->pb_graph_node->pb_type;
    if (pb_type->num_modes > 0 && cur_pb->name) {
        for (int i = 0; i < cur_pb->pb_graph_node->num_input_pin_class; i++) {
            size_t class_size = cur_pb->pb_graph_node->input_pin_class_size[i];
            if (cur_pb->is_root()) {
                class_size = std::ceil(max_external_pin_util.input_pin_util * class_size);
                class_size = std::max<size_t>(class_size, cur_pb->pb_stats->input_pins_used[i].size());
            }
            if (cur_pb->pb_stats->lookahead_input_pins_used[i].size() > class_size) {
                return false;
            }
        }
        for (int i = 0; i < cur_pb->pb_graph_node->num_output_pin_class; i++) {
            size_t class_size = cur_pb->pb_graph_node->output_pin_class_size[i];
            if (cur_pb->is_root()) {
                class_size = std::ceil(max_external_pin_util.output_pin_util * class_size);
                class_size = std::max<size_t>(class_size, cur_pb->pb_stats->output_pins_used[i].size());
            }
            if (cur_pb->pb_stats->lookahead_output_pins_used[i].size() > class_size) {
                return false;
            }
        }
        if (cur_pb->child_pbs) {
            for (int i = 0; i < pb_type->modes[cur_pb->mode].num_pb_type_children; i++) {
                if (cur_pb->child_pbs[i]) {
                    for (int j = 0; j < pb_type->modes[cur_pb->mode].pb_type_children[i].num_pb; j++) {
                        if (!check_lookahead_pins_used(&cur_pb->child_pbs[i][j], max_external_pin_util))
                            return false;
                    }
                }
            }
        }
    }
    return true;
}
static bool check_lookahead_pins_used ( t_pb * cur_pb , t_ext_pin_util max_external_pin_util ) { const t_pb_type * pb_type = cur_pb -> pb_graph_node -> pb_type ; if ( pb_type -> num_modes > 0 && cur_pb -> name ) { for ( int i = 0 ; i < cur_pb -> pb_graph_node -> num_input_pin_class ; i ++ ) { size_t class_size = cur_pb -> pb_graph_node -> input_pin_class_size [ i ] ; if ( cur_pb -> is_root ( ) ) { class_size = std :: ceil ( max_external_pin_util . input_pin_util * class_size ) ; class_size = std :: max < size_t > ( class_size , cur_pb -> pb_stats -> input_pins_used [ i ] . size ( ) ) ; } if ( cur_pb -> pb_stats -> lookahead_input_pins_used [ i ] . size ( ) > class_size ) { return false ; } } for ( int i = 0 ; i < cur_pb -> pb_graph_node -> num_output_pin_class ; i ++ ) { size_t class_size = cur_pb -> pb_graph_node -> output_pin_class_size [ i ] ; if ( cur_pb -> is_root ( ) ) { class_size = std :: ceil ( max_external_pin_util . output_pin_util * class_size ) ; class_size = std :: max < size_t > ( class_size , cur_pb -> pb_stats -> output_pins_used [ i ] . size ( ) ) ; } if ( cur_pb -> pb_stats -> lookahead_output_pins_used [ i ] . size ( ) > class_size ) { return false ; } } if ( cur_pb -> child_pbs ) { for ( int i = 0 ; i < pb_type -> modes [ cur_pb -> mode ] . num_pb_type_children ; i ++ ) { if ( cur_pb -> child_pbs [ i ] ) { for ( int j = 0 ; j < pb_type -> modes [ cur_pb -> mode ] . pb_type_children [ i ] . num_pb ; j ++ ) { if ( ! check_lookahead_pins_used ( & cur_pb -> child_pbs [ i ] [ j ] , max_external_pin_util ) ) return false ; } } } } } return true ; }
Check if the number of available inputs/outputs for a pin class is sufficient for speculatively packed blocks
Check if the number of available inputs / outputs for a pin class is sufficient for speculatively packed blocks
// Scale the class size by the maximum external pin utilization factor // Use ceil to avoid classes of size 1 from being scaled to zero // if the number of pins already used is larger than class size, then the number of // cluster inputs already used should be our constraint. Why is this needed? This is // needed since when packing the seed block the maximum external pin utilization is // used as 1.0 allowing molecules that are using up to all the cluster inputs to be // packed legally. Therefore, if the seed block is already using more inputs than // the allowed maximum utilization, this should become the new maximum pin utilization. // Scale the class size by the maximum external pin utilization factor // Use ceil to avoid classes of size 1 from being scaled to zero // if the number of pins already used is larger than class size, then the number of // cluster outputs already used should be our constraint. Why is this needed? This is // needed since when packing the seed block the maximum external pin utilization is // used as 1.0 allowing molecules that are using up to all the cluster inputs to be // packed legally. Therefore, if the seed block is already using more inputs than // the allowed maximum utilization, this should become the new maximum pin utilization.