Skip to content

Commit 68272ff

Browse files
acomodilitghost
authored andcommitted
placement: add possibility to constraint other blocks than IO pads
Signed-off-by: Alessandro Comodi <[email protected]>
1 parent 032520a commit 68272ff

File tree

2 files changed

+58
-57
lines changed

2 files changed

+58
-57
lines changed

vpr/src/base/read_place.cpp

Lines changed: 22 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -146,6 +146,7 @@ void read_user_pad_loc(const char* pad_loc_file) {
146146
int xtmp, ytmp;
147147
FILE* fp;
148148
char buf[vtr::bufsize], bname[vtr::bufsize], *ptr;
149+
std::unordered_set<ClusterBlockId> constrained_blocks;
149150

150151
auto& cluster_ctx = g_vpr_ctx.clustering();
151152
auto& device_ctx = g_vpr_ctx.device();
@@ -160,17 +161,14 @@ void read_user_pad_loc(const char* pad_loc_file) {
160161

161162
hash_table = alloc_hash_table();
162163
for (auto blk_id : cluster_ctx.clb_nlist.blocks()) {
163-
auto logical_block = cluster_ctx.clb_nlist.block_type(blk_id);
164-
if (is_io_type(pick_best_physical_type(logical_block))) {
165-
insert_in_hash_table(hash_table, cluster_ctx.clb_nlist.block_name(blk_id).c_str(), size_t(blk_id));
166-
place_ctx.block_locs[blk_id].loc.x = OPEN; /* Mark as not seen yet. */
167-
}
164+
insert_in_hash_table(hash_table, cluster_ctx.clb_nlist.block_name(blk_id).c_str(), size_t(blk_id));
165+
place_ctx.block_locs[blk_id].loc.x = OPEN; /* Mark as not seen yet. */
168166
}
169167

170168
for (size_t i = 0; i < device_ctx.grid.width(); i++) {
171169
for (size_t j = 0; j < device_ctx.grid.height(); j++) {
172170
auto type = device_ctx.grid[i][j].type;
173-
if (is_io_type(type)) {
171+
if (!is_empty_type(type)) {
174172
for (int k = 0; k < type->capacity; k++) {
175173
if (place_ctx.grid_blocks[i][j].blocks[k] != INVALID_BLOCK_ID) {
176174
place_ctx.grid_blocks[i][j].blocks[k] = EMPTY_BLOCK_ID; /* Flag for err. check */
@@ -236,12 +234,12 @@ void read_user_pad_loc(const char* pad_loc_file) {
236234
int j = ytmp;
237235

238236
if (place_ctx.block_locs[bnum].loc.x != OPEN) {
239-
vpr_throw(VPR_ERROR_PLACE_F, pad_loc_file, vtr::get_file_line_number_of_last_opened_file(),
237+
VPR_THROW(VPR_ERROR_PLACE_F, pad_loc_file, vtr::get_file_line_number_of_last_opened_file(),
240238
"Block %s is listed twice in pad file.\n", bname);
241239
}
242240

243241
if (i < 0 || i > int(device_ctx.grid.width() - 1) || j < 0 || j > int(device_ctx.grid.height() - 1)) {
244-
vpr_throw(VPR_ERROR_PLACE_F, pad_loc_file, 0,
242+
VPR_THROW(VPR_ERROR_PLACE_F, pad_loc_file, 0,
245243
"Block #%zu (%s) location, (%d,%d) is out of range.\n", size_t(bnum), bname, i, j);
246244
}
247245

@@ -250,27 +248,33 @@ void read_user_pad_loc(const char* pad_loc_file) {
250248
place_ctx.block_locs[bnum].loc.z = k;
251249
place_ctx.block_locs[bnum].is_fixed = true;
252250

253-
auto type = device_ctx.grid[i][j].type;
254-
if (!is_io_type(type)) {
255-
vpr_throw(VPR_ERROR_PLACE_F, pad_loc_file, 0,
256-
"Attempt to place IO block %s at illegal location (%d, %d).\n", bname, i, j);
251+
auto physical_tile = device_ctx.grid[i][j].type;
252+
auto logical_block = cluster_ctx.clb_nlist.block_type(bnum);
253+
if (!is_tile_compatible(physical_tile, logical_block)) {
254+
VPR_THROW(VPR_ERROR_PLACE_F, pad_loc_file, 0,
255+
"Attempt to place block %s at illegal location (%d, %d).\n", bname, i, j);
257256
}
258257

259-
if (k >= type->capacity || k < 0) {
260-
vpr_throw(VPR_ERROR_PLACE_F, pad_loc_file, vtr::get_file_line_number_of_last_opened_file(),
258+
if (k >= physical_tile->capacity || k < 0) {
259+
VPR_THROW(VPR_ERROR_PLACE_F, pad_loc_file, vtr::get_file_line_number_of_last_opened_file(),
261260
"Block %s subblock number (%d) is out of range.\n", bname, k);
262261
}
263262
place_ctx.grid_blocks[i][j].blocks[k] = bnum;
264263
place_ctx.grid_blocks[i][j].usage++;
265264

265+
constrained_blocks.insert(bnum);
266+
266267
ptr = vtr::fgets(buf, vtr::bufsize, fp);
267268
}
268269

269270
for (auto blk_id : cluster_ctx.clb_nlist.blocks()) {
270-
auto logical_block = cluster_ctx.clb_nlist.block_type(blk_id);
271-
auto type = pick_best_physical_type(logical_block);
272-
if (is_io_type(type) && place_ctx.block_locs[blk_id].loc.x == OPEN) {
273-
vpr_throw(VPR_ERROR_PLACE_F, pad_loc_file, 0,
271+
auto result = constrained_blocks.find(blk_id);
272+
if (result == constrained_blocks.end()) {
273+
continue;
274+
}
275+
276+
if (place_ctx.block_locs[blk_id].loc.x == OPEN) {
277+
VPR_THROW(VPR_ERROR_PLACE_F, pad_loc_file, 0,
274278
"IO block %s location was not specified in the pad file.\n", cluster_ctx.clb_nlist.block_name(blk_id).c_str());
275279
}
276280
}

vpr/src/place/initial_placement.cpp

Lines changed: 36 additions & 39 deletions
Original file line numberDiff line numberDiff line change
@@ -285,49 +285,46 @@ static void initial_placement_blocks(int* free_locations, enum e_pad_loc_type pa
285285

286286
auto logical_block = cluster_ctx.clb_nlist.block_type(blk_id);
287287

288-
/* Don't do IOs if the user specifies IOs; we'll read those locations later. */
289-
if (!(is_io_type(pick_best_physical_type(logical_block)) && pad_loc_type == USER)) {
290-
/* Randomly select a free location of the appropriate type for blk_id.
291-
* We have a linearized list of all the free locations that can
292-
* accommodate a block of that type in free_locations[itype].
293-
* Choose one randomly and put blk_id there. Then we don't want to pick
294-
* that location again, so remove it from the free_locations array.
295-
*/
296-
297-
auto type = pick_placement_type(logical_block, 1, free_locations);
298-
299-
if (type == nullptr) {
300-
VPR_FATAL_ERROR(VPR_ERROR_PLACE,
301-
"Initial placement failed.\n"
302-
"Could not place block %s (#%zu); no free locations of type %s (#%d).\n",
303-
cluster_ctx.clb_nlist.block_name(blk_id).c_str(), size_t(blk_id), logical_block->name, logical_block->index);
304-
}
288+
/* Randomly select a free location of the appropriate type for blk_id.
289+
* We have a linearized list of all the free locations that can
290+
* accommodate a block of that type in free_locations[itype].
291+
* Choose one randomly and put blk_id there. Then we don't want to pick
292+
* that location again, so remove it from the free_locations array.
293+
*/
305294

306-
itype = type->index;
295+
auto type = pick_placement_type(logical_block, 1, free_locations);
296+
297+
if (type == nullptr) {
298+
VPR_FATAL_ERROR(VPR_ERROR_PLACE,
299+
"Initial placement failed.\n"
300+
"Could not place block %s (#%zu); no free locations of type %s (#%d).\n",
301+
cluster_ctx.clb_nlist.block_name(blk_id).c_str(), size_t(blk_id), logical_block->name, logical_block->index);
302+
}
307303

308-
t_pl_loc to;
309-
initial_placement_location(free_locations, ipos, itype, to);
304+
itype = type->index;
310305

311-
// Make sure that the position is EMPTY_BLOCK before placing the block down
312-
VTR_ASSERT(place_ctx.grid_blocks[to.x][to.y].blocks[to.z] == EMPTY_BLOCK_ID);
306+
t_pl_loc to;
307+
initial_placement_location(free_locations, ipos, itype, to);
313308

314-
place_ctx.grid_blocks[to.x][to.y].blocks[to.z] = blk_id;
315-
place_ctx.grid_blocks[to.x][to.y].usage++;
309+
// Make sure that the position is EMPTY_BLOCK before placing the block down
310+
VTR_ASSERT(place_ctx.grid_blocks[to.x][to.y].blocks[to.z] == EMPTY_BLOCK_ID);
316311

317-
place_ctx.block_locs[blk_id].loc = to;
312+
place_ctx.grid_blocks[to.x][to.y].blocks[to.z] = blk_id;
313+
place_ctx.grid_blocks[to.x][to.y].usage++;
318314

319-
//Mark IOs as fixed if specifying a (fixed) random placement
320-
if (is_io_type(pick_best_physical_type(logical_block)) && pad_loc_type == RANDOM) {
321-
place_ctx.block_locs[blk_id].is_fixed = true;
322-
}
315+
place_ctx.block_locs[blk_id].loc = to;
323316

324-
/* Ensure randomizer doesn't pick this location again, since it's occupied. Could shift all the
325-
* legal positions in legal_pos to remove the entry (choice) we just used, but faster to
326-
* just move the last entry in legal_pos to the spot we just used and decrement the
327-
* count of free_locations. */
328-
legal_pos[itype][ipos] = legal_pos[itype][free_locations[itype] - 1]; /* overwrite used block position */
329-
free_locations[itype]--;
317+
//Mark IOs as fixed if specifying a (fixed) random placement
318+
if (is_io_type(pick_best_physical_type(logical_block)) && pad_loc_type == RANDOM) {
319+
place_ctx.block_locs[blk_id].is_fixed = true;
330320
}
321+
322+
/* Ensure randomizer doesn't pick this location again, since it's occupied. Could shift all the
323+
* legal positions in legal_pos to remove the entry (choice) we just used, but faster to
324+
* just move the last entry in legal_pos to the spot we just used and decrement the
325+
* count of free_locations. */
326+
legal_pos[itype][ipos] = legal_pos[itype][free_locations[itype] - 1]; /* overwrite used block position */
327+
free_locations[itype]--;
331328
}
332329
}
333330

@@ -397,6 +394,10 @@ void initial_placement(enum e_pad_loc_type pad_loc_type,
397394
place_ctx.block_locs[blk_id].loc = t_pl_loc();
398395
}
399396

397+
if (pad_loc_type == USER) {
398+
read_user_pad_loc(pad_loc_file);
399+
}
400+
400401
initial_placement_pl_macros(MAX_NUM_TRIES_TO_PLACE_MACROS_RANDOMLY, free_locations);
401402

402403
// All the macros are placed, update the legal_pos[][] array
@@ -420,10 +421,6 @@ void initial_placement(enum e_pad_loc_type pad_loc_type,
420421

421422
initial_placement_blocks(free_locations, pad_loc_type);
422423

423-
if (pad_loc_type == USER) {
424-
read_user_pad_loc(pad_loc_file);
425-
}
426-
427424
/* Restore legal_pos */
428425
load_legal_placement_locations();
429426

0 commit comments

Comments
 (0)