Skip to content

Commit eea0df0

Browse files
authored
Merge pull request #1817 from verilog-to-routing/refactor_init_place_for_floorplanning
Refactor init place for floorplanning
2 parents f437fbd + e073a4d commit eea0df0

File tree

6 files changed

+328
-68
lines changed

6 files changed

+328
-68
lines changed

vpr/src/place/grid_tile_lookup.cpp

Lines changed: 143 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,143 @@
1+
#include "grid_tile_lookup.h"
2+
3+
void GridTileLookup::initialize_grid_tile_matrices() {
4+
auto& device_ctx = g_vpr_ctx.device();
5+
6+
//Will store the max number of tile locations for each logical block type
7+
max_placement_locations.resize(device_ctx.logical_block_types.size());
8+
9+
for (const auto& type : device_ctx.logical_block_types) {
10+
vtr::NdMatrix<int, 2> type_count({device_ctx.grid.width(), device_ctx.grid.height()});
11+
fill_type_matrix(&type, type_count);
12+
block_type_matrices.push_back(type_count);
13+
}
14+
}
15+
16+
void GridTileLookup::fill_type_matrix(t_logical_block_type_ptr block_type, vtr::NdMatrix<int, 2>& type_count) {
17+
auto& device_ctx = g_vpr_ctx.device();
18+
19+
int num_rows = device_ctx.grid.height();
20+
int num_cols = device_ctx.grid.width();
21+
22+
/*
23+
* Iterating through every location on the grid to store the number of subtiles of
24+
* the correct type at each location. For each location, we store the cumulative
25+
* number of tiles of the type up to that location - meaning we store the number of
26+
* subtiles at the location, plus the number of subtiles at the locations above and to
27+
* the right of it.
28+
*/
29+
for (int i_col = type_count.dim_size(0) - 1; i_col >= 0; i_col--) {
30+
for (int j_row = type_count.dim_size(1) - 1; j_row >= 0; j_row--) {
31+
auto& tile = device_ctx.grid[i_col][j_row].type;
32+
type_count[i_col][j_row] = 0;
33+
34+
if (is_tile_compatible(tile, block_type)) {
35+
for (const auto& sub_tile : tile->sub_tiles) {
36+
if (is_sub_tile_compatible(tile, block_type, sub_tile.capacity.low)) {
37+
type_count[i_col][j_row] = sub_tile.capacity.total();
38+
}
39+
}
40+
}
41+
42+
if (i_col < num_cols - 1) {
43+
type_count[i_col][j_row] += type_count[i_col + 1][j_row];
44+
}
45+
if (j_row < num_rows - 1) {
46+
type_count[i_col][j_row] += type_count[i_col][j_row + 1];
47+
}
48+
if (i_col < (num_cols - 1) && j_row < (num_rows - 1)) {
49+
type_count[i_col][j_row] -= type_count[i_col + 1][j_row + 1];
50+
}
51+
}
52+
}
53+
54+
//The total number of subtiles for the block type will be at [0][0]
55+
max_placement_locations[block_type->index] = type_count[0][0];
56+
}
57+
58+
vtr::NdMatrix<int, 2>& GridTileLookup::get_type_grid(t_logical_block_type_ptr block_type) {
59+
return block_type_matrices[block_type->index];
60+
}
61+
62+
int GridTileLookup::total_type_tiles(t_logical_block_type_ptr block_type) {
63+
return max_placement_locations[block_type->index];
64+
}
65+
66+
/*
67+
* This routine uses pre-computed values from the grids for each block type to get the number of grid tiles
68+
* covered by a region.
69+
* For a region with no subtiles specified, the number of grid tiles can be calculated by adding
70+
* and subtracting four values from within/at the edge of the region.
71+
* The region with subtile case is taken care of by a helper routine, region_with_subtile_count().
72+
*/
73+
int GridTileLookup::region_tile_count(const Region& reg, t_logical_block_type_ptr block_type) {
74+
vtr::Rect<int> reg_rect = reg.get_region_rect();
75+
int subtile = reg.get_sub_tile();
76+
77+
int xmin = reg_rect.xmin();
78+
int ymin = reg_rect.ymin();
79+
int xmax = reg_rect.xmax();
80+
int ymax = reg_rect.ymax();
81+
auto& type_grid = block_type_matrices[block_type->index];
82+
83+
int xdim = type_grid.dim_size(0);
84+
int ydim = type_grid.dim_size(1);
85+
86+
int num_tiles = 0;
87+
88+
if (subtile == NO_SUBTILE) {
89+
num_tiles = type_grid[xmin][ymin];
90+
91+
if ((ymax + 1) < ydim) {
92+
num_tiles -= type_grid[xmin][ymax + 1];
93+
}
94+
95+
if ((xmax + 1) < xdim) {
96+
num_tiles -= type_grid[xmax + 1][ymin];
97+
}
98+
99+
if ((xmax + 1) < xdim && (ymax + 1) < ydim) {
100+
num_tiles += type_grid[xmax + 1][ymax + 1];
101+
}
102+
} else {
103+
num_tiles = region_with_subtile_count(reg, block_type);
104+
}
105+
106+
return num_tiles;
107+
}
108+
109+
/*
110+
* This routine is for the subtile specified case; an O(region_size) scan needs to be done to check whether each grid
111+
* location in the region is compatible for the block at the subtile specified.
112+
*/
113+
int GridTileLookup::region_with_subtile_count(const Region& reg, t_logical_block_type_ptr block_type) {
114+
auto& device_ctx = g_vpr_ctx.device();
115+
int num_sub_tiles = 0;
116+
vtr::Rect<int> reg_rect = reg.get_region_rect();
117+
int subtile = reg.get_sub_tile();
118+
119+
int xmin = reg_rect.xmin();
120+
int ymin = reg_rect.ymin();
121+
int xmax = reg_rect.xmax();
122+
int ymax = reg_rect.ymax();
123+
124+
for (int i = xmax; i >= xmin; i--) {
125+
for (int j = ymax; j >= ymin; j--) {
126+
auto& tile = device_ctx.grid[i][j].type;
127+
if (is_sub_tile_compatible(tile, block_type, subtile)) {
128+
num_sub_tiles++;
129+
}
130+
}
131+
}
132+
133+
return num_sub_tiles;
134+
}
135+
136+
void GridTileLookup::print_type_matrix(vtr::NdMatrix<int, 2>& type_count) {
137+
for (int i_col = type_count.dim_size(0) - 1; i_col >= 0; i_col--) {
138+
for (int j_row = type_count.dim_size(1) - 1; j_row >= 0; j_row--) {
139+
VTR_LOG("%d ", type_count[i_col][j_row]);
140+
}
141+
VTR_LOG("\n");
142+
}
143+
}

vpr/src/place/grid_tile_lookup.h

Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,49 @@
1+
/*
2+
* This class is used to store a grid for each logical block type that stores the cumulative number of subtiles
3+
* for that type available at each location in the grid. The cumulative number of subtiles is the subtiles at the
4+
* location plus the subtiles available at the grid locations above and to the right of the locations.
5+
* Having these grids allows for O(1) lookups about the number of subtiles available for a given type of block
6+
* in a rectangular region.
7+
* This lookup class is used during initial placement when sorting blocks by the size of their floorplan constraint
8+
* regions.
9+
*/
10+
#ifndef VPR_SRC_PLACE_GRID_TILE_LOOKUP_H_
11+
#define VPR_SRC_PLACE_GRID_TILE_LOOKUP_H_
12+
13+
#include "place_util.h"
14+
#include "globals.h"
15+
16+
class GridTileLookup {
17+
public:
18+
vtr::NdMatrix<int, 2>& get_type_grid(t_logical_block_type_ptr block_type);
19+
20+
void initialize_grid_tile_matrices();
21+
22+
void fill_type_matrix(t_logical_block_type_ptr block_type, vtr::NdMatrix<int, 2>& type_count);
23+
24+
void print_type_matrix(vtr::NdMatrix<int, 2>& type_count);
25+
26+
int region_tile_count(const Region& reg, t_logical_block_type_ptr block_type);
27+
28+
int region_with_subtile_count(const Region& reg, t_logical_block_type_ptr block_type);
29+
30+
int total_type_tiles(t_logical_block_type_ptr block_type);
31+
32+
private:
33+
/*
34+
* Stores the cumulative total of subtiles available at each location in the grid for each block type.
35+
* Therefore, the length of the vector will be the number of logical block types. To access the cumulative
36+
* number of subtiles at a location, you would use block_type_matrices[iblock_type][x][y] - this would
37+
* give the number of placement locations that are at, or above and to the right of the given [x,y] for
38+
* the given block type.
39+
*/
40+
std::vector<vtr::NdMatrix<int, 2>> block_type_matrices;
41+
42+
/*
43+
* Stores the total number of placement locations (i.e. compatible subtiles) for each block type.
44+
* To access the max_placement locations for a particular block type, use max_placement_locations[block_type->index]
45+
*/
46+
std::vector<int> max_placement_locations;
47+
};
48+
49+
#endif /* VPR_SRC_PLACE_GRID_TILE_LOOKUP_H_ */

0 commit comments

Comments
 (0)