diff --git a/libs/libarchfpga/src/physical_types.h b/libs/libarchfpga/src/physical_types.h index 3f9a94a61ef..422fb107535 100644 --- a/libs/libarchfpga/src/physical_types.h +++ b/libs/libarchfpga/src/physical_types.h @@ -1287,7 +1287,7 @@ class t_pb_graph_node { int num_output_pin_class; /* number of output pin classes that this pb_graph_node has */ int total_primitive_count; /* total number of this primitive type in the cluster */ - int flat_site_index; /* index of this primitive within sites of its type in this cluster */ + int flat_site_index; /* index of this primitive within sites of its type in this cluster */ /* Interconnect instances for this pb diff --git a/vpr/src/pack/cluster_placement.cpp b/vpr/src/pack/cluster_placement.cpp index c0458154cf1..7d4fa780dde 100644 --- a/vpr/src/pack/cluster_placement.cpp +++ b/vpr/src/pack/cluster_placement.cpp @@ -86,10 +86,14 @@ t_cluster_placement_stats* alloc_and_load_cluster_placement_stats() { * primitives_list - a list of primitives indexed to match atom_block_ids of molecule. * Expects an allocated array of primitives ptrs as inputs. * This function loads the array with the lowest cost primitives that implement molecule + * force_site - optional user-specified primitive site on which to place the molecule; if a force_site + * argument is provided, the function either selects the specified site or reports failure. + * If the force_site argument is set to its default value (-1), vpr selects an available site. */ bool get_next_primitive_list(t_cluster_placement_stats* cluster_placement_stats, const t_pack_molecule* molecule, - t_pb_graph_node** primitives_list) { + t_pb_graph_node** primitives_list, + int force_site) { std::unordered_multimap::iterator best; int i; @@ -136,6 +140,23 @@ bool get_next_primitive_list(t_cluster_placement_stats* cluster_placement_stats, continue; } + + /* check for force site match, if applicable */ + if (force_site > -1) { + if (force_site == it->second->pb_graph_node->flat_site_index) { + cost = try_place_molecule(molecule, it->second->pb_graph_node, primitives_list); + if (cost < HUGE_POSITIVE_FLOAT) { + cluster_placement_stats->move_primitive_to_inflight(i, it); + return true; + } else { + break; + } + } else { + ++it; + continue; + } + } + /* try place molecule at root location cur */ cost = try_place_molecule(molecule, it->second->pb_graph_node, primitives_list); @@ -153,6 +174,11 @@ bool get_next_primitive_list(t_cluster_placement_stats* cluster_placement_stats, } } + /* if force_site was specified but not found, fail */ + if (force_site > -1) { + found_best = false; + } + if (!found_best) { /* failed to find a placement */ for (i = 0; i < molecule->num_blocks; i++) { diff --git a/vpr/src/pack/cluster_placement.h b/vpr/src/pack/cluster_placement.h index 8715e611222..03089193a95 100644 --- a/vpr/src/pack/cluster_placement.h +++ b/vpr/src/pack/cluster_placement.h @@ -11,7 +11,8 @@ t_cluster_placement_stats* alloc_and_load_cluster_placement_stats(); bool get_next_primitive_list( t_cluster_placement_stats* cluster_placement_stats, const t_pack_molecule* molecule, - t_pb_graph_node** primitives_list); + t_pb_graph_node** primitives_list, + int force_site = -1); void commit_primitive(t_cluster_placement_stats* cluster_placement_stats, const t_pb_graph_node* primitive); void set_mode_cluster_placement_stats(const t_pb_graph_node* complex_block, diff --git a/vpr/src/pack/cluster_util.cpp b/vpr/src/pack/cluster_util.cpp index f8d0b5d9f9e..74dbfc33772 100644 --- a/vpr/src/pack/cluster_util.cpp +++ b/vpr/src/pack/cluster_util.cpp @@ -932,7 +932,8 @@ e_block_pack_status try_pack_molecule(t_cluster_placement_stats* cluster_placeme int feasible_block_array_size, t_ext_pin_util max_external_pin_util, PartitionRegion& temp_cluster_pr, - NocGroupId& temp_noc_grp_id) { + NocGroupId& temp_noc_grp_id, + int force_site) { t_pb* parent; t_pb* cur_pb; @@ -1009,7 +1010,7 @@ e_block_pack_status try_pack_molecule(t_cluster_placement_stats* cluster_placeme while (block_pack_status != e_block_pack_status::BLK_PASSED) { if (get_next_primitive_list(cluster_placement_stats_ptr, molecule, - primitives_list)) { + primitives_list, force_site)) { block_pack_status = e_block_pack_status::BLK_PASSED; int failed_location = 0; diff --git a/vpr/src/pack/cluster_util.h b/vpr/src/pack/cluster_util.h index 910bb69c932..31a829c82d0 100644 --- a/vpr/src/pack/cluster_util.h +++ b/vpr/src/pack/cluster_util.h @@ -214,7 +214,8 @@ e_block_pack_status try_pack_molecule(t_cluster_placement_stats* cluster_placeme int feasible_block_array_size, t_ext_pin_util max_external_pin_util, PartitionRegion& temp_cluster_pr, - NocGroupId& temp_noc_grp_id); + NocGroupId& temp_noc_grp_id, + int force_site = -1); void try_fill_cluster(const t_packer_opts& packer_opts, t_cluster_placement_stats* cur_cluster_placement_stats_ptr, @@ -493,4 +494,4 @@ bool cleanup_pb(t_pb* pb); void alloc_and_load_pb_stats(t_pb* pb, const int feasible_block_array_size); void init_clb_atoms_lookup(vtr::vector>& atoms_lookup); -#endif \ No newline at end of file +#endif diff --git a/vpr/src/pack/re_cluster_util.cpp b/vpr/src/pack/re_cluster_util.cpp index 68e04e4b888..01a24a73df9 100644 --- a/vpr/src/pack/re_cluster_util.cpp +++ b/vpr/src/pack/re_cluster_util.cpp @@ -130,7 +130,8 @@ bool start_new_cluster_for_mol(t_pack_molecule* molecule, t_lb_router_data** router_data, PartitionRegion& temp_cluster_pr, NocGroupId& temp_cluster_noc_grp_id, - enum e_detailed_routing_stages detailed_routing_stage) { + enum e_detailed_routing_stages detailed_routing_stage, + int force_site) { auto& atom_ctx = g_vpr_ctx.atom(); auto& floorplanning_ctx = g_vpr_ctx.mutable_floorplanning(); auto& helper_ctx = g_vpr_ctx.mutable_cl_helper(); @@ -172,7 +173,8 @@ bool start_new_cluster_for_mol(t_pack_molecule* molecule, 0, FULL_EXTERNAL_PIN_UTIL, temp_cluster_pr, - temp_cluster_noc_grp_id); + temp_cluster_noc_grp_id, + force_site); // If clustering succeeds, add it to the clb netlist if (pack_result == e_block_pack_status::BLK_PASSED) { @@ -215,7 +217,8 @@ bool pack_mol_in_existing_cluster(t_pack_molecule* molecule, t_clustering_data& clustering_data, t_lb_router_data*& router_data, enum e_detailed_routing_stages detailed_routing_stage, - bool enable_pin_feasibility_filter) { + bool enable_pin_feasibility_filter, + int force_site) { auto& helper_ctx = g_vpr_ctx.mutable_cl_helper(); auto& cluster_ctx = g_vpr_ctx.mutable_clustering(); @@ -250,7 +253,8 @@ bool pack_mol_in_existing_cluster(t_pack_molecule* molecule, helper_ctx.feasible_block_array_size, target_ext_pin_util, temp_cluster_pr, - temp_cluster_noc_grp_id); + temp_cluster_noc_grp_id, + force_site); // If clustering succeeds, add it to the clb netlist if (pack_result == e_block_pack_status::BLK_PASSED) { diff --git a/vpr/src/pack/re_cluster_util.h b/vpr/src/pack/re_cluster_util.h index 78606f51fce..a2a73e5a970 100644 --- a/vpr/src/pack/re_cluster_util.h +++ b/vpr/src/pack/re_cluster_util.h @@ -84,6 +84,10 @@ void remove_mol_from_cluster(const t_pack_molecule* molecule, * the function does not run a detailed intra-cluster routing-based legality check. * If many molecules will be added to a cluster, this option enables use of a single * routing check on the completed cluster (vs many incremental checks). + * @param force_site: optional user-specified primitive site on which to place the molecule; this is passed to + * try_pack_molecule and then to get_next_primitive_site. If a force_site argument is provided, + * the molecule is either placed on the specified site or fails to add to the cluster. + * If the force_site argument is set to its default value (-1), vpr selects an available site. */ bool start_new_cluster_for_mol(t_pack_molecule* molecule, const t_logical_block_type_ptr& type, @@ -97,7 +101,8 @@ bool start_new_cluster_for_mol(t_pack_molecule* molecule, t_lb_router_data** router_data, PartitionRegion& temp_cluster_pr, NocGroupId& temp_cluster_noc_grp_id, - enum e_detailed_routing_stages detailed_routing_stage = E_DETAILED_ROUTE_FOR_EACH_ATOM); + enum e_detailed_routing_stages detailed_routing_stage = E_DETAILED_ROUTE_FOR_EACH_ATOM, + int force_site = -1); /** * @brief A function that packs a molecule into an existing cluster @@ -118,6 +123,10 @@ bool start_new_cluster_for_mol(t_pack_molecule* molecule, * If many molecules will be added to a cluster, this option enables use of a single * routing check on the completed cluster (vs many incremental checks). * @param enable_pin_feasibility_filter: do a pin couting based legality check (before or in place of intra-cluster routing check). + * @param force_site: optional user-specified primitive site on which to place the molecule; this is passed to + * try_pack_molecule and then to get_next_primitive_site. If a force_site argument is provided, + * the molecule is either placed on the specified site or fails to add to the cluster. + * If the force_site argument is set to its default value (-1), vpr selects an available site. */ bool pack_mol_in_existing_cluster(t_pack_molecule* molecule, int molecule_size, @@ -127,7 +136,8 @@ bool pack_mol_in_existing_cluster(t_pack_molecule* molecule, t_clustering_data& clustering_data, t_lb_router_data*& router_data, enum e_detailed_routing_stages detailed_routing_stage = E_DETAILED_ROUTE_FOR_EACH_ATOM, - bool enable_pin_feasibility_filter = true); + bool enable_pin_feasibility_filter = true, + int force_site = -1); /** * @brief A function that fix the clustered netlist if the move is performed