Skip to content

Commit 6a4f0ca

Browse files
authored
Merge branch 'master' into openfpga
2 parents 2ff460a + 02b338a commit 6a4f0ca

16 files changed

+237
-18
lines changed

README.developers.md

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1092,6 +1092,12 @@ All tests passed (1 assertion in 1 test case)
10921092
# Debugging Aids
10931093
VTR has support for several additional tools/features to aid debugging.
10941094
1095+
## Basic
1096+
To build vpr with make in debug mode, simply add `BUILD_TYPE=debug` at the end of your make command.
1097+
```shell
1098+
$ make vpr BUILD_TYPE=debug
1099+
```
1100+
10951101
## Sanitizers
10961102
VTR can be compiled using *sanitizers* which will detect invalid memory accesses, memory leaks and undefined behaviour (supported by both GCC and LLVM):
10971103
```shell

vpr/src/base/CheckSetup.cpp

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,18 @@ void CheckSetup(const t_packer_opts& PackerOpts,
2323
"Packing cannot be timing driven without timing analysis enabled\n");
2424
}
2525

26+
if (PackerOpts.load_flat_placement) {
27+
if (PackerOpts.device_layout == "auto") {
28+
VPR_FATAL_ERROR(VPR_ERROR_OTHER,
29+
"Legalization requires a fixed device layout.\n");
30+
}
31+
if (!PlacerOpts.constraints_file.empty()) {
32+
VPR_FATAL_ERROR(VPR_ERROR_OTHER,
33+
"Cannot specify a fixed clusters file when running legalization.\n");
34+
}
35+
}
36+
37+
2638
if ((GLOBAL == RouterOpts.route_type)
2739
&& (PlacerOpts.place_algorithm.is_timing_driven())) {
2840
/* Works, but very weird. Can't optimize timing well, since you're

vpr/src/base/SetupGrid.h

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -13,10 +13,11 @@
1313
#include "physical_types.h"
1414

1515
///@brief Find the device satisfying the specified minimum resources
16+
/// minimum_instance_counts and target_device_utilization are not required when specifying a fixed layout
1617
DeviceGrid create_device_grid(const std::string& layout_name,
1718
const std::vector<t_grid_def>& grid_layouts,
18-
const std::map<t_logical_block_type_ptr, size_t>& minimum_instance_counts,
19-
float target_device_utilization);
19+
const std::map<t_logical_block_type_ptr, size_t>& minimum_instance_counts = {},
20+
float target_device_utilization = 0.0);
2021

2122
///@brief Find the device close in size to the specified dimensions
2223
DeviceGrid create_device_grid(const std::string& layout_name,

vpr/src/base/SetupVPR.cpp

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -128,6 +128,7 @@ void SetupVPR(const t_options* Options,
128128
FileNameOpts->ArchFile = Options->ArchFile;
129129
FileNameOpts->CircuitFile = Options->CircuitFile;
130130
FileNameOpts->NetFile = Options->NetFile;
131+
FileNameOpts->FlatPlaceFile = Options->FlatPlaceFile;
131132
FileNameOpts->PlaceFile = Options->PlaceFile;
132133
FileNameOpts->RouteFile = Options->RouteFile;
133134
FileNameOpts->ActFile = Options->ActFile;
@@ -136,6 +137,8 @@ void SetupVPR(const t_options* Options,
136137
FileNameOpts->out_file_prefix = Options->out_file_prefix;
137138
FileNameOpts->read_vpr_constraints_file = Options->read_vpr_constraints_file;
138139
FileNameOpts->write_vpr_constraints_file = Options->write_vpr_constraints_file;
140+
FileNameOpts->write_constraints_file = Options->write_constraints_file;
141+
FileNameOpts->write_flat_place_file = Options->write_flat_place_file;
139142
FileNameOpts->write_block_usage = Options->write_block_usage;
140143

141144
FileNameOpts->verify_file_digests = Options->verify_file_digests;
@@ -239,6 +242,7 @@ void SetupVPR(const t_options* Options,
239242
//Setup the default flow, if no specific stages specified
240243
//do all
241244
if (!Options->do_packing
245+
&& !Options->do_legalize
242246
&& !Options->do_placement
243247
&& !Options->do_routing
244248
&& !Options->do_analysis) {
@@ -275,6 +279,11 @@ void SetupVPR(const t_options* Options,
275279
if (Options->do_packing) {
276280
PackerOpts->doPacking = STAGE_DO;
277281
}
282+
283+
if (Options->do_legalize) {
284+
PackerOpts->doPacking = STAGE_LOAD;
285+
PackerOpts->load_flat_placement = true;
286+
}
278287
}
279288

280289
ShowSetup(*vpr_setup);

vpr/src/base/echo_files.cpp

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -80,6 +80,9 @@ void alloc_and_load_echo_file_info() {
8080
//Packing
8181
setEchoFileName(E_ECHO_CLUSTERS, "clusters.echo");
8282

83+
//Legalizer
84+
setEchoFileName(E_ECHO_FLAT_PLACE, "post_legalizer_flat_placement.echo");
85+
8386
//Intra-block routing
8487
setEchoFileName(E_ECHO_INTRA_LB_FAILED_ROUTE, "intra_lb_failed_route.echo");
8588

vpr/src/base/echo_files.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,9 @@ enum e_echo_files {
1616
//Packing
1717
E_ECHO_CLUSTERS,
1818

19+
//Legalizer
20+
E_ECHO_FLAT_PLACE,
21+
1922
// Intra-block routing
2023
E_ECHO_INTRA_LB_FAILED_ROUTE,
2124

vpr/src/base/load_flat_place.cpp

Lines changed: 55 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,55 @@
1+
#include "globals.h"
2+
#include "load_flat_place.h"
3+
#include "clustered_netlist_utils.h"
4+
5+
6+
/* @brief Prints flat placement file entries for the atoms in one placed cluster. */
7+
static void print_flat_cluster(FILE* fp, ClusterBlockId iblk,
8+
std::vector<AtomBlockId>& atoms);
9+
10+
static void print_flat_cluster(FILE* fp, ClusterBlockId iblk,
11+
std::vector<AtomBlockId>& atoms) {
12+
13+
auto& atom_ctx = g_vpr_ctx.atom();
14+
t_pl_loc loc = g_vpr_ctx.placement().block_locs[iblk].loc;
15+
size_t bnum = size_t(iblk);
16+
17+
for (auto atom : atoms) {
18+
t_pb_graph_node* atom_pbgn = atom_ctx.lookup.atom_pb(atom)->pb_graph_node;
19+
fprintf(fp, "%s %d %d %d %d #%zu %s\n", atom_ctx.nlist.block_name(atom).c_str(),
20+
loc.x, loc.y, loc.sub_tile,
21+
atom_pbgn->flat_site_index,
22+
bnum,
23+
atom_pbgn->pb_type->name);
24+
}
25+
}
26+
27+
/* prints a flat placement file */
28+
void print_flat_placement(const char* flat_place_file) {
29+
30+
FILE* fp;
31+
32+
ClusterAtomsLookup atoms_lookup;
33+
auto& cluster_ctx = g_vpr_ctx.clustering();
34+
35+
if (!g_vpr_ctx.placement().block_locs.empty()) {
36+
fp = fopen(flat_place_file, "w");
37+
for (auto iblk : cluster_ctx.clb_nlist.blocks()) {
38+
auto atoms = atoms_lookup.atoms_in_cluster(iblk);
39+
print_flat_cluster(fp, iblk, atoms);
40+
}
41+
fclose(fp);
42+
}
43+
44+
}
45+
46+
/* ingests and legalizes a flat placement file */
47+
bool load_flat_placement(t_vpr_setup& vpr_setup, const t_arch& arch) {
48+
VTR_LOG("load_flat_placement(); when implemented, this function:");
49+
VTR_LOG("\n\tLoads flat placement file: %s, ", vpr_setup.FileNameOpts.FlatPlaceFile.c_str());
50+
VTR_LOG("\n\tArch id: %s, ", arch.architecture_id);
51+
VTR_LOG("\n\tPrints clustered netlist file: %s, ", vpr_setup.FileNameOpts.NetFile.c_str());
52+
VTR_LOG("\n\tPrints fix clusters file: %s\n", vpr_setup.FileNameOpts.write_constraints_file.c_str());
53+
54+
return false;
55+
}

vpr/src/base/load_flat_place.h

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
#ifndef LOAD_FLAT_PLACE_H
2+
#define LOAD_FLAT_PLACE_H
3+
4+
#include "vpr_types.h"
5+
6+
/**
7+
* @brief A function that prints a flat placement file
8+
*/
9+
void print_flat_placement(const char* flat_place_file);
10+
11+
/**
12+
* @brief A function that loads and legalizes a flat placement file
13+
*/
14+
bool load_flat_placement(t_vpr_setup& vpr_setup, const t_arch& arch);
15+
16+
#endif

vpr/src/base/read_options.cpp

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1310,6 +1310,11 @@ argparse::ArgumentParser create_arg_parser(const std::string& prog_name, t_optio
13101310
.action(argparse::Action::STORE_TRUE)
13111311
.default_value("off");
13121312

1313+
stage_grp.add_argument<bool, ParseOnOff>(args.do_legalize, "--legalize")
1314+
.help("Legalize a flat placement, i.e. reconstruct and place clusters based on a flat placement file, which lists cluster and intra-cluster placement coordinates for each primitive.")
1315+
.action(argparse::Action::STORE_TRUE)
1316+
.default_value("off");
1317+
13131318
stage_grp.add_argument<bool, ParseOnOff>(args.do_placement, "--place")
13141319
.help("Run placement")
13151320
.action(argparse::Action::STORE_TRUE)
@@ -1590,6 +1595,10 @@ argparse::ArgumentParser create_arg_parser(const std::string& prog_name, t_optio
15901595
.help("Path to packed netlist file")
15911596
.show_in(argparse::ShowIn::HELP_ONLY);
15921597

1598+
file_grp.add_argument(args.FlatPlaceFile, "--flat_place_file")
1599+
.help("Path to input flat placement file")
1600+
.show_in(argparse::ShowIn::HELP_ONLY);
1601+
15931602
file_grp.add_argument(args.PlaceFile, "--place_file")
15941603
.help("Path to placement file")
15951604
.show_in(argparse::ShowIn::HELP_ONLY);
@@ -1627,6 +1636,17 @@ argparse::ArgumentParser create_arg_parser(const std::string& prog_name, t_optio
16271636
.help("Writes out new floorplanning constraints based on current placement to the specified XML file.")
16281637
.show_in(argparse::ShowIn::HELP_ONLY);
16291638

1639+
file_grp.add_argument(args.write_constraints_file, "--write_fix_clusters")
1640+
.help(
1641+
"Output file containing fixed locations of legalized input clusters - does not include clusters without placement coordinates; this file is used during post-legalization placement in order to hold input placement coordinates fixed while VPR places legalizer-generated orphan clusters.")
1642+
.default_value("fix_clusters.out")
1643+
.show_in(argparse::ShowIn::HELP_ONLY);
1644+
1645+
file_grp.add_argument(args.write_flat_place_file, "--write_flat_place")
1646+
.help(
1647+
"VPR's (or reconstructed external) placement solution in flat placement file format; this file lists cluster and intra-cluster placement coordinates for each atom and can be used to reconstruct a clustering and placement solution.")
1648+
.show_in(argparse::ShowIn::HELP_ONLY);
1649+
16301650
file_grp.add_argument(args.read_router_lookahead, "--read_router_lookahead")
16311651
.help(
16321652
"Reads the lookahead data from the specified file instead of computing it.")
@@ -2997,6 +3017,12 @@ void set_conditional_defaults(t_options& args) {
29973017
args.RouteFile.set(route_file, Provenance::INFERRED);
29983018
}
29993019

3020+
if (args.FlatPlaceFile.provenance() != Provenance::SPECIFIED) {
3021+
std::string flat_place_file = args.out_file_prefix;
3022+
flat_place_file += default_output_name + ".flat_place";
3023+
args.FlatPlaceFile.set(flat_place_file, Provenance::INFERRED);
3024+
}
3025+
30003026
if (args.ActFile.provenance() != Provenance::SPECIFIED) {
30013027
std::string activity_file = args.out_file_prefix;
30023028
activity_file += default_output_name + ".act";

vpr/src/base/read_options.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ struct t_options {
1212
argparse::ArgValue<std::string> ArchFile;
1313
argparse::ArgValue<std::string> CircuitName;
1414
argparse::ArgValue<std::string> NetFile;
15+
argparse::ArgValue<std::string> FlatPlaceFile;
1516
argparse::ArgValue<std::string> PlaceFile;
1617
argparse::ArgValue<std::string> RouteFile;
1718
argparse::ArgValue<std::string> CircuitFile;
@@ -30,6 +31,8 @@ struct t_options {
3031
argparse::ArgValue<std::string> write_initial_place_file;
3132
argparse::ArgValue<std::string> read_vpr_constraints_file;
3233
argparse::ArgValue<std::string> write_vpr_constraints_file;
34+
argparse::ArgValue<std::string> write_constraints_file;
35+
argparse::ArgValue<std::string> write_flat_place_file;
3336

3437
argparse::ArgValue<std::string> write_placement_delay_lookup;
3538
argparse::ArgValue<std::string> read_placement_delay_lookup;
@@ -44,6 +47,7 @@ struct t_options {
4447

4548
/* Stage Options */
4649
argparse::ArgValue<bool> do_packing;
50+
argparse::ArgValue<bool> do_legalize;
4751
argparse::ArgValue<bool> do_placement;
4852
argparse::ArgValue<bool> do_routing;
4953
argparse::ArgValue<bool> do_analysis;

vpr/src/base/read_place.cpp

Lines changed: 14 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -309,7 +309,8 @@ void read_place_body(std::ifstream& placement_file,
309309
*/
310310
void print_place(const char* net_file,
311311
const char* net_id,
312-
const char* place_file) {
312+
const char* place_file,
313+
bool is_place_file) {
313314
FILE* fp;
314315

315316
auto& device_ctx = g_vpr_ctx.device();
@@ -318,15 +319,21 @@ void print_place(const char* net_file,
318319

319320
fp = fopen(place_file, "w");
320321

321-
fprintf(fp, "Netlist_File: %s Netlist_ID: %s\n",
322-
net_file,
323-
net_id);
324-
fprintf(fp, "Array size: %zu x %zu logic blocks\n\n", device_ctx.grid.width(), device_ctx.grid.height());
325-
fprintf(fp, "#block name\tx\ty\tsubblk\tlayer\tblock number\n");
326-
fprintf(fp, "#----------\t--\t--\t------\t-----\t------------\n");
322+
if (is_place_file) {
323+
fprintf(fp, "Netlist_File: %s Netlist_ID: %s\n",
324+
net_file,
325+
net_id);
326+
fprintf(fp, "Array size: %zu x %zu logic blocks\n\n", device_ctx.grid.width(), device_ctx.grid.height());
327+
fprintf(fp, "#block name\tx\ty\tsubblk\tlayer\tblock number\n");
328+
fprintf(fp, "#----------\t--\t--\t------\t-----\t------------\n");
329+
}
327330

328331
if (!place_ctx.block_locs.empty()) { //Only if placement exists
329332
for (auto blk_id : cluster_ctx.clb_nlist.blocks()) {
333+
// if block is not placed, skip (useful for printing legalizer output)
334+
if (!is_place_file && (place_ctx.block_locs[blk_id].loc.x == INVALID_X)) {
335+
continue;
336+
}
330337
fprintf(fp, "%s\t", cluster_ctx.clb_nlist.block_pb(blk_id)->name);
331338
if (strlen(cluster_ctx.clb_nlist.block_pb(blk_id)->name) < 8)
332339
fprintf(fp, "\t");

vpr/src/base/read_place.h

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,8 +17,19 @@ void read_place(
1717
*/
1818
void read_constraints(const char* constraints_file);
1919

20+
/**
21+
* This function prints out a place file.
22+
* @param is_place_file: defaults to true. If false, does not print file header; this is useful if
23+
* the output will be used as a constraints file. If is_place_file is false,
24+
* net_file and net_id parameters are not used and can be set to nullptr.
25+
* Note: if false, only placed clusters are printed - clusters without
26+
* placement coordinates (e.g. orphan clusters created during legalization
27+
* will not be included; this file is used as a placement constraints
28+
* file when running placement in order to place orphan clusters.
29+
*/
2030
void print_place(const char* net_file,
2131
const char* net_id,
22-
const char* place_file);
32+
const char* place_file,
33+
bool is_place_file = true);
2334

2435
#endif

0 commit comments

Comments
 (0)