1616// Note: The flag is only effective if compiled with VTR_ENABLE_DEBUG_LOGGING
1717bool f_placer_breakpoint_reached = false ;
1818
19+ /* *
20+ * @brief Adjust the search range based on how many blocks are in the column.
21+ * If the number of blocks in the column is less than MIN_NUM_BLOCKS_IN_COLUMN,
22+ * expand the search range to cover the entire column.
23+ *
24+ * @param block_type The type of the block to move
25+ * @param compressed_column_num The compressed column to move the block to
26+ * @param to_layer_num The layer that the block is moving to
27+ * @param is_range_fixed Whether the search range is fixed (e.g., in case of placement constraints)
28+ * @param search_range The search range to adjust
29+ *
30+ */
31+ static void adjust_search_range (t_logical_block_type_ptr block_type,
32+ const int compressed_column_num,
33+ const int to_layer_num,
34+ const bool is_range_fixed,
35+ t_bb& search_range);
36+
1937// Accessor for f_placer_breakpoint_reached
2038bool placer_breakpoint_reached () {
2139 return f_placer_breakpoint_reached;
@@ -666,10 +684,9 @@ bool find_to_loc_uniform(t_logical_block_type_ptr type,
666684 rlim);
667685 int delta_cx = search_range.xmax - search_range.xmin ;
668686
669- t_physical_tile_loc to_compressed_loc;
670- bool legal = false ;
687+ bool block_constrained = is_cluster_constrained (b_from);
671688
672- if (is_cluster_constrained (b_from) ) {
689+ if (block_constrained ) {
673690 bool intersect = intersect_range_limit_with_floorplan_constraints (b_from,
674691 search_range,
675692 delta_cx,
@@ -678,6 +695,9 @@ bool find_to_loc_uniform(t_logical_block_type_ptr type,
678695 return false ;
679696 }
680697 }
698+
699+ t_physical_tile_loc to_compressed_loc;
700+ bool legal = false ;
681701 // TODO: For now, we only move the blocks on the same tile
682702 legal = find_compatible_compressed_loc_in_range (type,
683703 delta_cx,
@@ -688,7 +708,8 @@ bool find_to_loc_uniform(t_logical_block_type_ptr type,
688708 to_layer_num,
689709 /* search_for_empty=*/ false ,
690710 blk_loc_registry,
691- rng);
711+ rng,
712+ block_constrained);
692713
693714 if (!legal) {
694715 // No valid position found
@@ -758,10 +779,9 @@ bool find_to_loc_median(t_logical_block_type_ptr blk_type,
758779 to_layer_num,
759780 to_layer_num);
760781
761- t_physical_tile_loc to_compressed_loc;
762- bool legal = false ;
782+ bool block_constrained = is_cluster_constrained (b_from);
763783
764- if (is_cluster_constrained (b_from) ) {
784+ if (block_constrained ) {
765785 bool intersect = intersect_range_limit_with_floorplan_constraints (b_from,
766786 search_range,
767787 delta_cx,
@@ -771,6 +791,8 @@ bool find_to_loc_median(t_logical_block_type_ptr blk_type,
771791 }
772792 }
773793
794+ t_physical_tile_loc to_compressed_loc;
795+ bool legal = false ;
774796 legal = find_compatible_compressed_loc_in_range (blk_type,
775797 delta_cx,
776798 from_compressed_locs[to_layer_num],
@@ -780,7 +802,8 @@ bool find_to_loc_median(t_logical_block_type_ptr blk_type,
780802 to_layer_num,
781803 /* search_for_empty=*/ false ,
782804 blk_loc_registry,
783- rng);
805+ rng,
806+ block_constrained);
784807
785808 if (!legal) {
786809 // No valid position found
@@ -847,10 +870,9 @@ bool find_to_loc_centroid(t_logical_block_type_ptr blk_type,
847870 }
848871 delta_cx = search_range.xmax - search_range.xmin ;
849872
850- t_physical_tile_loc to_compressed_loc;
851- bool legal = false ;
873+ bool block_constrained = is_cluster_constrained (b_from);
852874
853- if (is_cluster_constrained (b_from) ) {
875+ if (block_constrained ) {
854876 bool intersect = intersect_range_limit_with_floorplan_constraints (b_from,
855877 search_range,
856878 delta_cx,
@@ -860,7 +882,10 @@ bool find_to_loc_centroid(t_logical_block_type_ptr blk_type,
860882 }
861883 }
862884
863- // TODO: For now, we only move the blocks on the same tile
885+ t_physical_tile_loc to_compressed_loc;
886+ bool legal = false ;
887+
888+ // TODO: For now, we only move the blocks on the same layer
864889 legal = find_compatible_compressed_loc_in_range (blk_type,
865890 delta_cx,
866891 from_compressed_loc[to_layer_num],
@@ -870,7 +895,8 @@ bool find_to_loc_centroid(t_logical_block_type_ptr blk_type,
870895 to_layer_num,
871896 /* search_for_empty=*/ false ,
872897 blk_loc_registry,
873- rng);
898+ rng,
899+ block_constrained);
874900
875901 if (!legal) {
876902 // No valid position found
@@ -964,7 +990,8 @@ bool find_compatible_compressed_loc_in_range(t_logical_block_type_ptr type,
964990 int to_layer_num,
965991 bool search_for_empty,
966992 const BlkLocRegistry& blk_loc_registry,
967- vtr::RngContainer& rng) {
993+ vtr::RngContainer& rng,
994+ const bool is_range_fixed) {
968995 // TODO For the time being, the blocks only moved in the same layer. This assertion should be removed after VPR is updated to move blocks between layers
969996 VTR_ASSERT (to_layer_num == from_loc.layer_num );
970997 const auto & compressed_block_grid = g_vpr_ctx.placement ().compressed_block_grids [type->index ];
@@ -999,28 +1026,17 @@ bool find_compatible_compressed_loc_in_range(t_logical_block_type_ptr type,
9991026 // The candidates are stored in a flat_map so we can efficiently find the set of valid
10001027 // candidates with upper/lower bound.
10011028 const auto & block_rows = compressed_block_grid.get_column_block_map (to_loc.x , to_layer_num);
1029+ adjust_search_range (type,
1030+ to_loc.x ,
1031+ to_layer_num,
1032+ is_range_fixed,
1033+ search_range);
10021034 auto y_lower_iter = block_rows.lower_bound (search_range.ymin );
10031035 if (y_lower_iter == block_rows.end ()) {
10041036 continue ;
10051037 }
1006-
10071038 auto y_upper_iter = block_rows.upper_bound (search_range.ymax );
10081039
1009- if (y_lower_iter->first > search_range.ymin ) {
1010- // No valid blocks at this x location which are within rlim_y
1011- //
1012- if (type->index != 1 )
1013- continue ;
1014- else {
1015- // Fall back to allow the whole y range
1016- y_lower_iter = block_rows.begin ();
1017- y_upper_iter = block_rows.end ();
1018-
1019- search_range.ymin = y_lower_iter->first ;
1020- search_range.ymax = (y_upper_iter - 1 )->first ;
1021- }
1022- }
1023-
10241040 int y_range = std::distance (y_lower_iter, y_upper_iter);
10251041 VTR_ASSERT (y_range >= 0 );
10261042
@@ -1199,6 +1215,25 @@ bool intersect_range_limit_with_floorplan_constraints(ClusterBlockId b_from,
11991215 return true ;
12001216}
12011217
1218+ static void adjust_search_range (t_logical_block_type_ptr block_type,
1219+ const int compressed_column_num,
1220+ const int to_layer_num,
1221+ const bool is_range_fixed,
1222+ t_bb& search_range) {
1223+ // The value is chosen empirically to expand the search range for sparse blocks,
1224+ // or blocks located on the perimeter of the FPGA (e.g., IO blocks)
1225+ constexpr int MIN_NUM_BLOCKS_IN_COLUMN = 3 ;
1226+
1227+ const auto & compressed_block_grid = g_vpr_ctx.placement ().compressed_block_grids [block_type->index ];
1228+
1229+ size_t num_blocks_in_column = compressed_block_grid.get_column_block_map (compressed_column_num, to_layer_num).size ();
1230+
1231+ if (num_blocks_in_column < MIN_NUM_BLOCKS_IN_COLUMN && !is_range_fixed) {
1232+ search_range.ymin = 0 ;
1233+ search_range.ymax = compressed_block_grid.get_num_rows (to_layer_num) - 1 ;
1234+ }
1235+ }
1236+
12021237std::string e_move_result_to_string (e_move_result move_outcome) {
12031238 switch (move_outcome) {
12041239 case e_move_result::REJECTED:
0 commit comments