Skip to content

Commit 7e4fb4a

Browse files
committed
Added read_place and read_constraints functions and made fixes to read_place_header and read_place_body
1 parent c512c70 commit 7e4fb4a

File tree

4 files changed

+106
-67
lines changed

4 files changed

+106
-67
lines changed

vpr/src/base/read_place.cpp

Lines changed: 92 additions & 59 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
#include <cstdio>
22
#include <cstring>
33
#include <fstream>
4+
#include <algorithm>
45

56
#include "vtr_assert.h"
67
#include "vtr_util.h"
@@ -15,30 +16,78 @@
1516
#include "read_place.h"
1617
#include "read_xml_arch_file.h"
1718

18-
/*This function reads the header of a placement file.
19-
* The header has two lines:
20-
* One for checking the netlist file
21-
* And another for checking grid dimensions
22-
*/
23-
void read_place_header(const char* net_file,
24-
const char* place_file,
25-
bool verify_file_digests,
26-
const DeviceGrid& grid) {
19+
void read_place_header(
20+
std::ifstream& placement_file,
21+
const char* net_file,
22+
const char* place_file,
23+
bool verify_file_hashes,
24+
const DeviceGrid& grid);
25+
26+
void read_place_body(
27+
std::ifstream& placement_file,
28+
const char* place_file,
29+
bool is_place_file);
30+
31+
void read_place(
32+
const char* net_file,
33+
const char* place_file,
34+
bool verify_file_digests,
35+
const DeviceGrid& grid,
36+
bool is_place_file) {
2737
std::ifstream fstream(place_file);
2838
if (!fstream) {
2939
VPR_FATAL_ERROR(VPR_ERROR_PLACE_F,
3040
"'%s' - Cannot open place file.\n",
3141
place_file);
3242
}
3343

44+
VTR_LOG("Reading %s.\n", place_file);
45+
VTR_LOG("\n");
46+
47+
read_place_header(fstream, net_file, place_file, verify_file_digests, grid);
48+
read_place_body(fstream, place_file, is_place_file);
49+
50+
VTR_LOG("Successfully read %s.\n", place_file);
51+
VTR_LOG("\n");
52+
}
53+
54+
void read_constraints(const char* constraints_file,
55+
bool is_place_file) {
56+
std::ifstream fstream(constraints_file);
57+
if (!fstream) {
58+
VPR_FATAL_ERROR(VPR_ERROR_PLACE_F,
59+
"'%s' - Cannot open constraints file.\n",
60+
constraints_file);
61+
}
62+
63+
VTR_LOG("Reading %s.\n", constraints_file);
64+
VTR_LOG("\n");
65+
66+
read_place_body(fstream, constraints_file, is_place_file);
67+
68+
VTR_LOG("Successfully read %s.\n", constraints_file);
69+
VTR_LOG("\n");
70+
}
71+
72+
/**
73+
* This function reads the header (first two lines) of a placement file.
74+
* It checks whether the packed netlist file that generated the placement matches the current netlist file.
75+
* It also checks whether the FPGA grid size has stayed the same from when the placement was generated.
76+
* The verify_file_digests bool is used to decide whether to give a warning or an error if the netlist files do not match.
77+
*/
78+
void read_place_header(std::ifstream& placement_file,
79+
const char* net_file,
80+
const char* place_file,
81+
bool verify_file_digests,
82+
const DeviceGrid& grid) {
3483
auto& cluster_ctx = g_vpr_ctx.clustering();
3584

3685
std::string line;
3786
int lineno = 0;
3887
bool seen_netlist_id = false;
39-
bool read_header_lines = false;
88+
bool seen_grid_dimensions = false;
4089

41-
while (std::getline(fstream, line) && !read_header_lines) { //Parse line-by-line
90+
while (std::getline(placement_file, line) && (!seen_netlist_id || !seen_grid_dimensions)) { //Parse line-by-line
4291
++lineno;
4392

4493
std::vector<std::string> tokens = vtr::split(line);
@@ -97,7 +146,7 @@ void read_place_header(const char* net_file,
97146
grid.width(), grid.height(), place_file_width, place_file_height);
98147
}
99148

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

102151
} else {
103152
//Unrecognized
@@ -108,35 +157,26 @@ void read_place_header(const char* net_file,
108157
}
109158
}
110159

111-
/*This function reads either the body of a placement file or a constraints file.
112-
* If it is reading a constraints file it marks blocks as locked as it reads in their locations.
160+
/**
161+
* This function reads either the body of a placement file or a constraints file.
162+
* If it is reading a place file it sets the x, y, and subtile locations of the blocks in the placement context.
163+
* If it is reading a constraints file it does the same and also marks the blocks as locked and marks the grid usage.
113164
* The bool is_place_file indicates if the file should be read as a place file (is_place_file = true)
114165
* or a constraints file (is_place_file = false).
115166
*/
116-
void read_place_body(const char* place_file,
167+
void read_place_body(std::ifstream& placement_file,
168+
const char* place_file,
117169
bool is_place_file) {
118-
std::ifstream fstream(place_file);
119-
if (!fstream) {
120-
VPR_FATAL_ERROR(VPR_ERROR_PLACE_F,
121-
"'%s' - Cannot open place file.\n",
122-
place_file);
123-
}
124-
125170
auto& cluster_ctx = g_vpr_ctx.clustering();
126171
auto& device_ctx = g_vpr_ctx.device();
127172
auto& place_ctx = g_vpr_ctx.mutable_placement();
128173

129-
//Mark unseen blocks for error-checking for constraints file
130-
if (!is_place_file) {
131-
for (auto block_id : cluster_ctx.clb_nlist.blocks()) {
132-
place_ctx.block_locs[block_id].loc.x = OPEN; //Mark as not seen yet
133-
}
134-
}
135-
136174
std::string line;
137175
int lineno = 0;
138176

139-
while (std::getline(fstream, line)) { //Parse line-by-line
177+
std::vector<ClusterBlockId> seen_blocks;
178+
179+
while (std::getline(placement_file, line)) { //Parse line-by-line
140180
++lineno;
141181

142182
std::vector<std::string> tokens = vtr::split(line);
@@ -147,21 +187,6 @@ void read_place_body(const char* place_file,
147187
} else if (tokens[0][0] == '#') {
148188
continue; //Skip commented lines
149189

150-
} else if (is_place_file
151-
&& tokens.size() == 4
152-
&& tokens[0] == "Netlist_File:"
153-
&& tokens[2] == "Netlist_ID:") {
154-
continue; //Skip netlist line if place file, already checked in read_place_header
155-
156-
} else if (is_place_file
157-
&& tokens.size() == 7
158-
&& tokens[0] == "Array"
159-
&& tokens[1] == "size:"
160-
&& tokens[3] == "x"
161-
&& tokens[5] == "logic"
162-
&& tokens[6] == "blocks") {
163-
continue; //Skip checking grid dimensions if place file, already checked in read_place_header
164-
165190
} else if (tokens.size() == 4 || (tokens.size() == 5 && tokens[4][0] == '#')) {
166191
//Load the block location
167192
//
@@ -176,18 +201,14 @@ void read_place_body(const char* place_file,
176201
ClusterBlockId blk_id = cluster_ctx.clb_nlist.find_block(block_name);
177202

178203
//Check if block is listed twice in constraints file
179-
if (!is_place_file) {
180-
if (place_ctx.block_locs[blk_id].loc.x != OPEN) {
181-
VPR_THROW(VPR_ERROR_PLACE, "The block with ID %d is listed twice in the constraints file.\n", blk_id);
182-
}
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);
183206
}
184207

185208
//Check if block location is out of range of grid dimensions
186-
if (!is_place_file) {
187-
if (block_x < 0 || block_x > int(device_ctx.grid.width() - 1)
188-
|| block_y < 0 || block_y > int(device_ctx.grid.height() - 1)) {
189-
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);
190-
}
209+
if (block_x < 0 || block_x > int(device_ctx.grid.width() - 1)
210+
|| 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);
191212
}
192213

193214
if (place_ctx.block_locs.size() != cluster_ctx.clb_nlist.blocks().size()) {
@@ -200,26 +221,38 @@ void read_place_body(const char* place_file,
200221
place_ctx.block_locs[blk_id].loc.y = block_y;
201222
place_ctx.block_locs[blk_id].loc.sub_tile = sub_tile_index;
202223

224+
//Check if block is at an illegal location
225+
auto physical_tile = device_ctx.grid[block_x][block_y].type;
226+
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 %s at illegal location (%d, %d). \n", block_name, block_x, block_y);
229+
}
230+
231+
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 %s subtile number (%d) is out of range. \n", block_name, sub_tile_index);
233+
}
234+
203235
//need to lock down blocks and mark grid block usage if it is a constraints file
204236
if (!is_place_file) {
205237
place_ctx.block_locs[blk_id].is_fixed = true;
206238
place_ctx.grid_blocks[block_x][block_y].blocks[sub_tile_index] = blk_id;
207239
place_ctx.grid_blocks[block_x][block_y].usage++;
208240
}
209241

242+
//add to vector of blocks that have been seen
243+
seen_blocks.push_back(blk_id);
244+
210245
} else {
211246
//Unrecognized
212247
vpr_throw(VPR_ERROR_PLACE_F, place_file, lineno,
213-
"Invalid line '%s' in placement file",
248+
"Invalid line '%s' in file",
214249
line.c_str());
215250
}
216251
}
217252

218-
if (!is_place_file) {
219-
VTR_LOG("Successfully read %s.\n", place_file);
220-
VTR_LOG("\n");
253+
if (is_place_file) {
254+
place_ctx.placement_id = vtr::secure_digest_file(place_file);
221255
}
222-
place_ctx.placement_id = vtr::secure_digest_file(place_file);
223256
}
224257

225258
/**

vpr/src/base/read_place.h

Lines changed: 11 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,21 @@
11
#ifndef READ_PLACE_H
22
#define READ_PLACE_H
33

4-
void read_place_header(
4+
/**
5+
* This function is used to read a placement file.
6+
*/
7+
void read_place(
58
const char* net_file,
69
const char* place_file,
710
bool verify_file_hashes,
8-
const DeviceGrid& grid);
11+
const DeviceGrid& grid,
12+
bool is_place_file);
913

10-
void read_place_body(
11-
const char* place_file,
14+
/**
15+
* This function is used to read a constraints file.
16+
*/
17+
void read_constraints(
18+
const char* constraints_file,
1219
bool is_place_file);
1320

1421
void print_place(const char* net_file,

vpr/src/base/vpr_api.cpp

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -664,8 +664,7 @@ void vpr_load_placement(t_vpr_setup& vpr_setup, const t_arch& arch) {
664664
bool is_a_placement_file = true;
665665

666666
//Load an existing placement from a file
667-
read_place_header(filename_opts.NetFile.c_str(), filename_opts.PlaceFile.c_str(), filename_opts.verify_file_digests, device_ctx.grid);
668-
read_place_body(filename_opts.PlaceFile.c_str(), is_a_placement_file);
667+
read_place(filename_opts.NetFile.c_str(), filename_opts.PlaceFile.c_str(), filename_opts.verify_file_digests, device_ctx.grid, is_a_placement_file);
669668

670669
//Ensure placement macros are loaded so that they can be drawn after placement (e.g. during routing)
671670
place_ctx.pl_macros = alloc_and_load_placement_macros(arch.Directs, arch.num_directs);

vpr/src/place/initial_placement.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -451,8 +451,8 @@ void initial_placement(enum e_pad_loc_type pad_loc_type, const char* constraints
451451

452452
/*Check whether the constraint file is NULL, if not, read in the block locations from the constraints file here*/
453453
if (strlen(constraints_file) != 0) {
454-
bool is_a_place_file = false; //specifies to read_place_body function that this is a constraints file and should be read as such
455-
read_place_body(constraints_file, is_a_place_file);
454+
bool is_a_place_file = false; //specifies that this is a constraints file, not a place file and should be read as such
455+
read_constraints(constraints_file, is_a_place_file);
456456
}
457457

458458
initial_placement_pl_macros(MAX_NUM_TRIES_TO_PLACE_MACROS_RANDOMLY, free_locations);

0 commit comments

Comments
 (0)