Skip to content

Commit 257b53e

Browse files
committed
Changed method of detecting duplicate blocks and added block name to error messages
1 parent d3a5046 commit 257b53e

File tree

2 files changed

+46
-17
lines changed

2 files changed

+46
-17
lines changed

vpr/src/base/read_place.cpp

Lines changed: 45 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -71,9 +71,11 @@ void read_constraints(const char* constraints_file,
7171

7272
/**
7373
* This function reads the header (first two lines) of a placement file.
74+
* The header consists of two lines that specify the netlist file and grid size that were used when generating placement.
7475
* It checks whether the packed netlist file that generated the placement matches the current netlist file.
7576
* It also checks whether the FPGA grid size has stayed the same from when the placement was generated.
7677
* The verify_file_digests bool is used to decide whether to give a warning or an error if the netlist files do not match.
78+
* An error is given if the grid size has changed.
7779
*/
7880
void read_place_header(std::ifstream& placement_file,
7981
const char* net_file,
@@ -146,7 +148,7 @@ void read_place_header(std::ifstream& placement_file,
146148
grid.width(), grid.height(), place_file_width, place_file_height);
147149
}
148150

149-
seen_grid_dimensions = true; //if you have read the grid dimensions you are done reading the place file header
151+
seen_grid_dimensions = true;
150152

151153
} else {
152154
//Unrecognized
@@ -159,6 +161,7 @@ void read_place_header(std::ifstream& placement_file,
159161

160162
/**
161163
* This function reads either the body of a placement file or a constraints file.
164+
* A constraints file is in the same format as a placement file, but without the first two header lines.
162165
* If it is reading a place file it sets the x, y, and subtile locations of the blocks in the placement context.
163166
* If it is reading a constraints file it does the same and also marks the blocks as locked and marks the grid usage.
164167
* The bool is_place_file indicates if the file should be read as a place file (is_place_file = true)
@@ -174,7 +177,19 @@ void read_place_body(std::ifstream& placement_file,
174177
std::string line;
175178
int lineno = 0;
176179

177-
std::vector<ClusterBlockId> seen_blocks;
180+
if (place_ctx.block_locs.size() != cluster_ctx.clb_nlist.blocks().size()) {
181+
//Resize if needed
182+
place_ctx.block_locs.resize(cluster_ctx.clb_nlist.blocks().size());
183+
}
184+
185+
//used to count how many times a block has been seen in the place/constraints file so duplicate blocks can be detected
186+
vtr::vector_map<ClusterBlockId, int> seen_blocks;
187+
188+
//initialize seen_blocks
189+
for (auto block_id : cluster_ctx.clb_nlist.blocks()) {
190+
int seen_count = 0;
191+
seen_blocks.insert(block_id, seen_count);
192+
}
178193

179194
while (std::getline(placement_file, line)) { //Parse line-by-line
180195
++lineno;
@@ -198,22 +213,25 @@ void read_place_body(std::ifstream& placement_file,
198213
int block_y = vtr::atoi(tokens[2]);
199214
int sub_tile_index = vtr::atoi(tokens[3]);
200215

216+
//c-style block name needed for printing block name in error messages
217+
char const* c_block_name = block_name.c_str();
218+
201219
ClusterBlockId blk_id = cluster_ctx.clb_nlist.find_block(block_name);
202220

221+
//Check if block name is valid
222+
if (blk_id == ClusterBlockId::INVALID()) {
223+
VPR_THROW(VPR_ERROR_PLACE, "Block %s has an invalid name.\n", c_block_name);
224+
}
225+
203226
//Check if block is listed twice in constraints file
204-
if (find(seen_blocks.begin(), seen_blocks.end(), blk_id) != seen_blocks.end()) {
205-
VPR_THROW(VPR_ERROR_PLACE, "The block with ID %d is listed twice in the constraints file.\n", blk_id);
227+
if (seen_blocks[blk_id] != 0) {
228+
VPR_THROW(VPR_ERROR_PLACE, "Block %s with ID %d is listed twice in the constraints file.\n", c_block_name, blk_id);
206229
}
207230

208231
//Check if block location is out of range of grid dimensions
209232
if (block_x < 0 || block_x > int(device_ctx.grid.width() - 1)
210233
|| block_y < 0 || block_y > int(device_ctx.grid.height() - 1)) {
211-
VPR_THROW(VPR_ERROR_PLACE, "The block with ID %d is out of range at location (%d, %d). \n", blk_id, block_x, block_y);
212-
}
213-
214-
if (place_ctx.block_locs.size() != cluster_ctx.clb_nlist.blocks().size()) {
215-
//Resize if needed
216-
place_ctx.block_locs.resize(cluster_ctx.clb_nlist.blocks().size());
234+
VPR_THROW(VPR_ERROR_PLACE, "Block %s with ID %d is out of range at location (%d, %d). \n", c_block_name, blk_id, block_x, block_y);
217235
}
218236

219237
//Set the location
@@ -222,14 +240,16 @@ void read_place_body(std::ifstream& placement_file,
222240
place_ctx.block_locs[blk_id].loc.sub_tile = sub_tile_index;
223241

224242
//Check if block is at an illegal location
243+
225244
auto physical_tile = device_ctx.grid[block_x][block_y].type;
226245
auto logical_block = cluster_ctx.clb_nlist.block_type(blk_id);
227-
if (!is_sub_tile_compatible(physical_tile, logical_block, place_ctx.block_locs[blk_id].loc.sub_tile)) {
228-
VPR_THROW(VPR_ERROR_PLACE, place_file, 0, "Attempt to place block %d at illegal location (%d, %d). \n", blk_id, block_x, block_y);
229-
}
230246

231247
if (sub_tile_index >= physical_tile->capacity || sub_tile_index < 0) {
232-
VPR_THROW(VPR_ERROR_PLACE, place_file, vtr::get_file_line_number_of_last_opened_file(), "Block %d subtile number (%d) is out of range. \n", blk_id, sub_tile_index);
248+
VPR_THROW(VPR_ERROR_PLACE, "Block %s subtile number (%d) is out of range. \n", c_block_name, sub_tile_index);
249+
}
250+
251+
if (!is_sub_tile_compatible(physical_tile, logical_block, place_ctx.block_locs[blk_id].loc.sub_tile)) {
252+
VPR_THROW(VPR_ERROR_PLACE, "Attempt to place block %s with ID %d at illegal location (%d, %d). \n", c_block_name, blk_id, block_x, block_y);
233253
}
234254

235255
//need to lock down blocks and mark grid block usage if it is a constraints file
@@ -239,8 +259,8 @@ void read_place_body(std::ifstream& placement_file,
239259
place_ctx.grid_blocks[block_x][block_y].usage++;
240260
}
241261

242-
//add to vector of blocks that have been seen
243-
seen_blocks.push_back(blk_id);
262+
//mark the block as seen
263+
seen_blocks[blk_id] = 1;
244264

245265
} else {
246266
//Unrecognized
@@ -250,6 +270,15 @@ void read_place_body(std::ifstream& placement_file,
250270
}
251271
}
252272

273+
//For place files, check that all blocks have been read
274+
if (is_place_file) {
275+
for (auto block_id : cluster_ctx.clb_nlist.blocks()) {
276+
if (seen_blocks[block_id] == 0) {
277+
VPR_THROW(VPR_ERROR_PLACE, "Block %d has not been read from the place file. \n", block_id);
278+
}
279+
}
280+
}
281+
253282
if (is_place_file) {
254283
place_ctx.placement_id = vtr::secure_digest_file(place_file);
255284
}

vpr/src/base/read_place.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ void read_place(
1212
bool is_place_file);
1313

1414
/**
15-
* This function is used to read a constraints file.
15+
* This function is used to read a constraints file that specifies the desired locations of blocks.
1616
*/
1717
void read_constraints(
1818
const char* constraints_file,

0 commit comments

Comments
 (0)