Skip to content

Commit 062b9ef

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

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
@@ -282,49 +282,46 @@ static void initial_placement_blocks(int* free_locations, enum e_pad_loc_type pa
282282

283283
auto logical_block = cluster_ctx.clb_nlist.block_type(blk_id);
284284

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

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

305-
t_pl_loc to;
306-
initial_placement_location(free_locations, ipos, itype, to);
301+
itype = type->index;
307302

308-
// Make sure that the position is EMPTY_BLOCK before placing the block down
309-
VTR_ASSERT(place_ctx.grid_blocks[to.x][to.y].blocks[to.z] == EMPTY_BLOCK_ID);
303+
t_pl_loc to;
304+
initial_placement_location(free_locations, ipos, itype, to);
310305

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

314-
place_ctx.block_locs[blk_id].loc = to;
309+
place_ctx.grid_blocks[to.x][to.y].blocks[to.z] = blk_id;
310+
place_ctx.grid_blocks[to.x][to.y].usage++;
315311

316-
//Mark IOs as fixed if specifying a (fixed) random placement
317-
if (is_io_type(pick_best_physical_type(logical_block)) && pad_loc_type == RANDOM) {
318-
place_ctx.block_locs[blk_id].is_fixed = true;
319-
}
312+
place_ctx.block_locs[blk_id].loc = to;
320313

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

@@ -394,6 +391,10 @@ void initial_placement(enum e_pad_loc_type pad_loc_type,
394391
place_ctx.block_locs[blk_id].loc = t_pl_loc();
395392
}
396393

394+
if (pad_loc_type == USER) {
395+
read_user_pad_loc(pad_loc_file);
396+
}
397+
397398
initial_placement_pl_macros(MAX_NUM_TRIES_TO_PLACE_MACROS_RANDOMLY, free_locations);
398399

399400
// All the macros are placed, update the legal_pos[][] array
@@ -417,10 +418,6 @@ void initial_placement(enum e_pad_loc_type pad_loc_type,
417418

418419
initial_placement_blocks(free_locations, pad_loc_type);
419420

420-
if (pad_loc_type == USER) {
421-
read_user_pad_loc(pad_loc_file);
422-
}
423-
424421
/* Restore legal_pos */
425422
load_legal_placement_locations();
426423

0 commit comments

Comments
 (0)