@@ -60,9 +60,8 @@ constexpr int INVALID_X = -1;
60
60
// Keeps the first locations and number of remained blocks in each column for a specific block type.
61
61
static std::vector<std::vector<t_grid_empty_locs_block_type>> blk_types_empty_locs_in_grid;
62
62
63
-
64
63
// initialize the grid before each placement iteration
65
- static void init_grid ();
64
+ static void init_grid ();
66
65
67
66
/*
68
67
* Places the macro if the head position passed in is legal, and all the resulting
@@ -106,7 +105,7 @@ static int get_y_loc_based_on_macro_direction(t_grid_empty_locs_block_type first
106
105
* @param pl_macro The macro to be placed.
107
106
*
108
107
*/
109
- static void get_blk_type_first_loc (t_pl_loc& loc,t_logical_block_type_ptr block_type,t_pl_macro pl_macro);
108
+ static void get_blk_type_first_loc (t_pl_loc& loc, t_logical_block_type_ptr block_type, t_pl_macro pl_macro);
110
109
111
110
/* *
112
111
* @brief initialize empty locations of the grid with a specific block type into vector for dense initial placement
@@ -115,7 +114,7 @@ static void get_blk_type_first_loc(t_pl_loc& loc,t_logical_block_type_ptr block_
115
114
* @param block_type_empty_locs Vector that holds block type empty locations
116
115
*
117
116
*/
118
- static void init_blk_types_empty_locations (int block_type_index, std::vector <t_grid_empty_locs_block_type>& block_type_empty_locs);
117
+ static void init_blk_types_empty_locations (int block_type_index, std::vector<t_grid_empty_locs_block_type>& block_type_empty_locs);
119
118
120
119
/* *
121
120
* @brief mark the macro members' locations fixed if necessary
@@ -201,11 +200,11 @@ static void print_unplaced_blocks(int init_placement_iter, int unplaced_blocks)
201
200
auto & cluster_ctx = g_vpr_ctx.clustering ();
202
201
auto & place_ctx = g_vpr_ctx.placement ();
203
202
204
- VTR_LOG (" Initial placement iteration %d has finished with %d unplaced blocks\n " ,init_placement_iter,unplaced_blocks);
203
+ VTR_LOG (" Initial placement iteration %d has finished with %d unplaced blocks\n " , init_placement_iter, unplaced_blocks);
205
204
206
205
for (auto blk_id : cluster_ctx.clb_nlist .blocks ()) {
207
206
if (place_ctx.block_locs [blk_id].loc .x == INVALID_X) {
208
- VTR_LOG (" Block %s (# %d) of type %s could not be placed during initial placement iteration %d\n " , cluster_ctx.clb_nlist .block_name (blk_id).c_str (), blk_id, cluster_ctx.clb_nlist .block_type (blk_id)->name ,init_placement_iter);
207
+ VTR_LOG (" Block %s (# %d) of type %s could not be placed during initial placement iteration %d\n " , cluster_ctx.clb_nlist .block_name (blk_id).c_str (), blk_id, cluster_ctx.clb_nlist .block_type (blk_id)->name , init_placement_iter);
209
208
}
210
209
}
211
210
}
@@ -216,74 +215,73 @@ static bool is_block_placed(ClusterBlockId blk_id) {
216
215
return (!(place_ctx.block_locs [blk_id].loc .x == INVALID_X));
217
216
}
218
217
219
-
220
- static int get_y_loc_based_on_macro_direction (t_grid_empty_locs_block_type first_macro_loc, t_pl_macro pl_macro){
218
+ static int get_y_loc_based_on_macro_direction (t_grid_empty_locs_block_type first_macro_loc, t_pl_macro pl_macro) {
221
219
int y = first_macro_loc.first_avail_loc .y ;
222
-
220
+
223
221
/*
224
222
* if the macro member offset is positive, it means that macro head should be placed at the first location of first_macro_loc.
225
223
* otherwise, macro head should be placed at the last available location to ensure macro_can_be_placed can check macro location correctly.
226
224
*
227
- */
228
- if (pl_macro.members .size () > 1 ){
229
- if (pl_macro.members .at (1 ).offset .y < 0 ){
230
- y += (pl_macro.members .size ()- 1 )* abs (pl_macro.members .at (1 ).offset .y );
225
+ */
226
+ if (pl_macro.members .size () > 1 ) {
227
+ if (pl_macro.members .at (1 ).offset .y < 0 ) {
228
+ y += (pl_macro.members .size () - 1 ) * abs (pl_macro.members .at (1 ).offset .y );
231
229
}
232
230
}
233
-
231
+
234
232
return y;
235
233
}
236
234
237
- static void get_blk_type_first_loc (t_pl_loc& loc,t_logical_block_type_ptr block_type,t_pl_macro pl_macro){
235
+ static void get_blk_type_first_loc (t_pl_loc& loc, t_logical_block_type_ptr block_type, t_pl_macro pl_macro) {
238
236
const auto & device_ctx = g_vpr_ctx.device ();
239
237
240
238
// loop over all empty locations and choose first column that can accomodate macro blocks
241
- for (unsigned int empty_loc_index = 0 ; empty_loc_index < blk_types_empty_locs_in_grid[block_type->index ].size (); empty_loc_index++){
239
+ for (unsigned int empty_loc_index = 0 ; empty_loc_index < blk_types_empty_locs_in_grid[block_type->index ].size (); empty_loc_index++) {
242
240
auto first_empty_loc = blk_types_empty_locs_in_grid[block_type->index ].at (empty_loc_index);
243
-
241
+
244
242
// if macro size is larger than available locations in the specific column, should go to next available column
245
- if ((unsigned )first_empty_loc.num_of_empty_locs_in_y_axis < pl_macro.members .size ()){
243
+ if ((unsigned )first_empty_loc.num_of_empty_locs_in_y_axis < pl_macro.members .size ()) {
246
244
continue ;
247
245
}
248
246
249
247
// set the coordinate of first location that can accomodate macro blocks
250
248
loc.x = first_empty_loc.first_avail_loc .x ;
251
- loc.y = get_y_loc_based_on_macro_direction (first_empty_loc,pl_macro);
249
+ loc.y = get_y_loc_based_on_macro_direction (first_empty_loc, pl_macro);
252
250
loc.sub_tile = first_empty_loc.first_avail_loc .sub_tile ;
253
-
254
- // update the first available macro location in vector for the next macro
251
+
252
+ // update the first available macro location in vector for the next macro
255
253
first_empty_loc.first_avail_loc .y += device_ctx.physical_tile_types .at (block_type->index ).height * pl_macro.members .size ();
256
254
first_empty_loc.num_of_empty_locs_in_y_axis -= pl_macro.members .size ();
257
255
blk_types_empty_locs_in_grid[block_type->index ][empty_loc_index] = first_empty_loc;
258
-
256
+
259
257
break ;
260
258
}
261
259
}
262
260
263
- static void init_blk_types_empty_locations (int block_type_index, std::vector <t_grid_empty_locs_block_type>& block_type_empty_locs){
261
+ static void init_blk_types_empty_locations (int block_type_index, std::vector<t_grid_empty_locs_block_type>& block_type_empty_locs) {
264
262
const auto & compressed_block_grid = g_vpr_ctx.placement ().compressed_block_grids [block_type_index];
265
263
const auto & device_ctx = g_vpr_ctx.device ();
266
-
264
+
267
265
// create a region the size of grid to find out first location with a specific block type
268
266
Region reg;
269
267
reg.set_region_rect (0 , 0 , device_ctx.grid .width () - 1 , device_ctx.grid .height () - 1 );
270
268
reg.set_sub_tile (NO_SUBTILE);
271
269
272
- int min_cx = grid_to_compressed_approx (compressed_block_grid.compressed_to_grid_x ,reg.get_region_rect ().xmin ());
273
- int max_cx = grid_to_compressed_approx (compressed_block_grid.compressed_to_grid_x ,reg.get_region_rect ().xmax ());
270
+ int min_cx = grid_to_compressed_approx (compressed_block_grid.compressed_to_grid_x , reg.get_region_rect ().xmin ());
271
+ int max_cx = grid_to_compressed_approx (compressed_block_grid.compressed_to_grid_x , reg.get_region_rect ().xmax ());
274
272
275
273
// traverse all column and store their empty locations in block_type_empty_locs
276
- for (int x_loc = min_cx; x_loc <= max_cx; x_loc++){
274
+ for (int x_loc = min_cx; x_loc <= max_cx; x_loc++) {
277
275
t_grid_empty_locs_block_type empty_loc;
278
- empty_loc.first_avail_loc .x = compressed_block_grid.grid [x_loc].at (0 ).x ;
276
+ empty_loc.first_avail_loc .x = compressed_block_grid.grid [x_loc].at (0 ).x ;
279
277
empty_loc.first_avail_loc .y = compressed_block_grid.grid [x_loc].at (0 ).y ;
280
278
empty_loc.first_avail_loc .sub_tile = 0 ;
281
279
empty_loc.num_of_empty_locs_in_y_axis = compressed_block_grid.grid [x_loc].size ();
282
280
block_type_empty_locs.push_back (empty_loc);
283
281
}
284
282
}
285
283
286
- static inline void fix_IO_block_types (t_pl_macro pl_macro, t_pl_loc loc, enum e_pad_loc_type pad_loc_type){
284
+ static inline void fix_IO_block_types (t_pl_macro pl_macro, t_pl_loc loc, enum e_pad_loc_type pad_loc_type) {
287
285
const auto & device_ctx = g_vpr_ctx.device ();
288
286
auto & place_ctx = g_vpr_ctx.mutable_placement ();
289
287
// If the user marked the IO block pad_loc_type as RANDOM, that means it should be randomly
@@ -348,8 +346,8 @@ static bool try_random_placement(t_pl_macro pl_macro, PartitionRegion& pr, t_log
348
346
349
347
legal = try_place_macro (pl_macro, loc);
350
348
351
- if (legal){
352
- fix_IO_block_types (pl_macro,loc,pad_loc_type);
349
+ if (legal) {
350
+ fix_IO_block_types (pl_macro, loc, pad_loc_type);
353
351
}
354
352
355
353
return legal;
@@ -395,8 +393,8 @@ static bool try_exhaustive_placement(t_pl_macro pl_macro, PartitionRegion& pr, t
395
393
if (place_ctx.grid_blocks [to_loc.x ][to_loc.y ].blocks [to_loc.sub_tile ] == EMPTY_BLOCK_ID) {
396
394
placed = try_place_macro (pl_macro, to_loc);
397
395
398
- if (placed){
399
- fix_IO_block_types (pl_macro,to_loc,pad_loc_type);
396
+ if (placed) {
397
+ fix_IO_block_types (pl_macro, to_loc, pad_loc_type);
400
398
}
401
399
}
402
400
} else {
@@ -409,8 +407,8 @@ static bool try_exhaustive_placement(t_pl_macro pl_macro, PartitionRegion& pr, t
409
407
to_loc.sub_tile = st;
410
408
if (place_ctx.grid_blocks [to_loc.x ][to_loc.y ].blocks [to_loc.sub_tile ] == EMPTY_BLOCK_ID) {
411
409
placed = try_place_macro (pl_macro, to_loc);
412
- if (placed){
413
- fix_IO_block_types (pl_macro,to_loc,pad_loc_type);
410
+ if (placed) {
411
+ fix_IO_block_types (pl_macro, to_loc, pad_loc_type);
414
412
}
415
413
}
416
414
}
@@ -428,27 +426,26 @@ static bool try_exhaustive_placement(t_pl_macro pl_macro, PartitionRegion& pr, t
428
426
return placed;
429
427
}
430
428
431
- static bool try_dense_placement (t_pl_macro pl_macro, PartitionRegion& pr, t_logical_block_type_ptr block_type, enum e_pad_loc_type pad_loc_type){
432
-
429
+ static bool try_dense_placement (t_pl_macro pl_macro, PartitionRegion& pr, t_logical_block_type_ptr block_type, enum e_pad_loc_type pad_loc_type) {
433
430
t_pl_loc loc;
434
- get_blk_type_first_loc (loc,block_type,pl_macro);
431
+ get_blk_type_first_loc (loc, block_type, pl_macro);
435
432
436
433
bool legal = false ;
437
-
434
+
438
435
// check if first available location is within the chip and macro's partition region, otherwise placement is not legal
439
- if (!is_loc_on_chip (loc.x ,loc.y ) || !pr.is_loc_in_part_reg (loc)){
436
+ if (!is_loc_on_chip (loc.x , loc.y ) || !pr.is_loc_in_part_reg (loc)) {
440
437
return legal;
441
438
}
442
-
439
+
443
440
auto & device_ctx = g_vpr_ctx.device ();
444
441
445
442
VTR_ASSERT (device_ctx.grid [loc.x ][loc.y ].width_offset == 0 );
446
443
VTR_ASSERT (device_ctx.grid [loc.x ][loc.y ].height_offset == 0 );
447
-
444
+
448
445
legal = try_place_macro (pl_macro, loc);
449
-
450
- if (legal){
451
- fix_IO_block_types (pl_macro,loc,pad_loc_type);
446
+
447
+ if (legal) {
448
+ fix_IO_block_types (pl_macro, loc, pad_loc_type);
452
449
}
453
450
454
451
return legal;
@@ -518,7 +515,7 @@ static bool place_macro(int macros_max_num_tries, t_pl_macro pl_macro, enum e_pa
518
515
}
519
516
520
517
// if the block type has failed in previous iteration, we need to start place densly to be able to find a legal initial placement solution
521
- if (blk_types_empty_locs_in_grid[block_type->index ].size () != 0 ){
518
+ if (blk_types_empty_locs_in_grid[block_type->index ].size () != 0 ) {
522
519
macro_placed = try_dense_placement (pl_macro, pr, block_type, pad_loc_type);
523
520
}
524
521
@@ -647,13 +644,13 @@ static int place_all_blocks(enum e_pad_loc_type pad_loc_type) {
647
644
// keep tracks of which block types can not be placed in each iteration
648
645
std::unordered_set<int > unplaced_blk_type_in_curr_itr;
649
646
650
- for (auto iter_no = 0 ; iter_no < MAX_INIT_PLACE_ATTEMPTS; iter_no++){
647
+ for (auto iter_no = 0 ; iter_no < MAX_INIT_PLACE_ATTEMPTS; iter_no++) {
651
648
// clear grid for a new placement iteration
652
649
init_grid ();
653
-
650
+
654
651
// Sort blocks and placement macros according to how difficult they are to place
655
652
vtr::vector<ClusterBlockId, t_block_score> block_scores = assign_block_scores ();
656
- std::vector<ClusterBlockId> sorted_blocks = sort_blocks (block_scores);
653
+ std::vector<ClusterBlockId> sorted_blocks = sort_blocks (block_scores);
657
654
658
655
// resize the vector to store unplaced block types empty locations
659
656
blk_types_empty_locs_in_grid.resize (device_ctx.logical_block_types .size ());
@@ -662,42 +659,41 @@ static int place_all_blocks(enum e_pad_loc_type pad_loc_type) {
662
659
663
660
for (auto blk_id : sorted_blocks) {
664
661
bool block_placed = place_one_block (blk_id, pad_loc_type);
665
- if (!block_placed){
662
+ if (!block_placed) {
666
663
// add current block to list to ensure it will be placed sooner in the next iteration in initial placement
667
664
number_of_unplaced_blks_in_curr_itr++;
668
665
block_scores[blk_id].failed_to_place_in_prev_attempts ++;
669
666
int imacro;
670
667
get_imacro_from_iblk (&imacro, blk_id, place_ctx.pl_macros );
671
- if (imacro != -1 ){ // the block belongs to macro that contain a chain, we need to turn on dense placement in next iteration
668
+ if (imacro != -1 ) { // the block belongs to macro that contain a chain, we need to turn on dense placement in next iteration
672
669
unplaced_blk_type_in_curr_itr.insert (cluster_ctx.clb_nlist .block_type (blk_id)->index );
673
670
}
674
671
}
675
672
}
676
673
677
674
// current iteration could place all of design's blocks, initial placement succeed
678
- if (number_of_unplaced_blks_in_curr_itr == 0 ){
679
- VTR_LOG (" Initial placement iteration %d has finished successfully\n " ,iter_no);
675
+ if (number_of_unplaced_blks_in_curr_itr == 0 ) {
676
+ VTR_LOG (" Initial placement iteration %d has finished successfully\n " , iter_no);
680
677
return 0 ;
681
678
}
682
679
683
680
// loop over block types that have been failed to be placed, and add their locations in grid for the next iteration
684
- for (auto itype : unplaced_blk_type_in_curr_itr){
685
- init_blk_types_empty_locations (itype,blk_types_empty_locs_in_grid[itype]);
686
- }
687
-
688
- unplaced_blk_type_in_curr_itr.clear ();
689
-
681
+ for (auto itype : unplaced_blk_type_in_curr_itr) {
682
+ init_blk_types_empty_locations (itype, blk_types_empty_locs_in_grid[itype]);
683
+ }
684
+
685
+ unplaced_blk_type_in_curr_itr.clear ();
686
+
690
687
// print unplaced blocks in the current iteration
691
- print_unplaced_blocks (iter_no,number_of_unplaced_blks_in_curr_itr);
688
+ print_unplaced_blocks (iter_no, number_of_unplaced_blks_in_curr_itr);
692
689
}
693
690
694
691
return number_of_unplaced_blks_in_curr_itr;
695
692
}
696
693
697
- static void init_grid (){
698
-
694
+ static void init_grid () {
699
695
auto & place_ctx = g_vpr_ctx.mutable_placement ();
700
-
696
+
701
697
// Set every grid location to an INVALID block id
702
698
zero_initialize_grid_blocks ();
703
699
@@ -724,7 +720,6 @@ static void init_grid(){
724
720
for (auto blk_id : cluster_ctx.clb_nlist .blocks ()) {
725
721
place_ctx.block_locs [blk_id].loc = t_pl_loc ();
726
722
}
727
-
728
723
}
729
724
730
725
bool place_one_block (const ClusterBlockId& blk_id,
@@ -757,7 +752,7 @@ bool place_one_block(const ClusterBlockId& blk_id,
757
752
pl_macro.members .push_back (macro_member);
758
753
placed_macro = place_macro (MAX_NUM_TRIES_TO_PLACE_MACROS_RANDOMLY, pl_macro, pad_loc_type);
759
754
}
760
-
755
+
761
756
return placed_macro;
762
757
}
763
758
0 commit comments