diff --git a/vpr/src/base/SetupVPR.cpp b/vpr/src/base/SetupVPR.cpp index fb43fe921a2..2e7d273c267 100644 --- a/vpr/src/base/SetupVPR.cpp +++ b/vpr/src/base/SetupVPR.cpp @@ -640,6 +640,8 @@ static void SetupPlacerOpts(const t_options& Options, t_placer_opts* PlacerOpts) PlacerOpts->write_initial_place_file = Options.write_initial_place_file; + PlacerOpts->read_initial_place_file = Options.read_initial_place_file; + PlacerOpts->pad_loc_type = Options.pad_loc_type; PlacerOpts->place_chan_width = Options.PlaceChanWidth; diff --git a/vpr/src/base/read_options.cpp b/vpr/src/base/read_options.cpp index 5d925ddcf7d..9e737b78d57 100644 --- a/vpr/src/base/read_options.cpp +++ b/vpr/src/base/read_options.cpp @@ -1632,6 +1632,11 @@ argparse::ArgumentParser create_arg_parser(const std::string& prog_name, t_optio .metavar("INITIAL_PLACE_FILE") .show_in(argparse::ShowIn::HELP_ONLY); + file_grp.add_argument(args.read_initial_place_file, "--read_initial_place_file") + .help("Reads the initial placement and continues the rest of the placement process from there.") + .metavar("INITIAL_PLACE_FILE") + .show_in(argparse::ShowIn::HELP_ONLY); + file_grp.add_argument(args.read_vpr_constraints_file, "--read_vpr_constraints") .help("Reads the floorplanning constraints that packing and placement must respect from the specified XML file.") .show_in(argparse::ShowIn::HELP_ONLY); diff --git a/vpr/src/base/read_options.h b/vpr/src/base/read_options.h index feda94e9fa8..de98e9c3ca8 100644 --- a/vpr/src/base/read_options.h +++ b/vpr/src/base/read_options.h @@ -29,6 +29,7 @@ struct t_options { argparse::ArgValue write_rr_graph_file; argparse::ArgValue read_rr_graph_file; argparse::ArgValue write_initial_place_file; + argparse::ArgValue read_initial_place_file; argparse::ArgValue read_vpr_constraints_file; argparse::ArgValue write_vpr_constraints_file; argparse::ArgValue write_constraints_file; diff --git a/vpr/src/base/read_place.cpp b/vpr/src/base/read_place.cpp index f3374e89824..4e52df3b040 100644 --- a/vpr/src/base/read_place.cpp +++ b/vpr/src/base/read_place.cpp @@ -305,6 +305,14 @@ void read_place_body(std::ifstream& placement_file, loc.layer = block_layer; if (seen_blocks[blk_id] == 0) { + if (is_place_file && place_ctx.block_locs[blk_id].is_fixed) { + const auto& contraint_loc = place_ctx.block_locs[blk_id].loc; + if (loc != contraint_loc) { + VPR_THROW(VPR_ERROR_PLACE, + "The new location assigned to cluster #%d is (%d,%d,%d,%d), which is inconsistent with the location specified in the constraint file (%d,%d,%d,%d).", + blk_id, loc.x, loc.y, loc.layer, loc.sub_tile, contraint_loc.x, contraint_loc.y, contraint_loc.layer, contraint_loc.sub_tile); + } + } set_block_location(blk_id, loc); } diff --git a/vpr/src/base/vpr_types.h b/vpr/src/base/vpr_types.h index d776cc80c07..a6d78feb6f1 100644 --- a/vpr/src/base/vpr_types.h +++ b/vpr/src/base/vpr_types.h @@ -1236,6 +1236,7 @@ struct t_placer_opts { enum e_pad_loc_type pad_loc_type; std::string constraints_file; std::string write_initial_place_file; + std::string read_initial_place_file; enum pfreq place_freq; int recompute_crit_iter; int inner_loop_recompute_divider; diff --git a/vpr/src/place/initial_placement.cpp b/vpr/src/place/initial_placement.cpp index 2b4f9bfdf4f..f7644a2a808 100644 --- a/vpr/src/place/initial_placement.cpp +++ b/vpr/src/place/initial_placement.cpp @@ -1192,7 +1192,8 @@ void initial_placement(const t_placer_opts& placer_opts, propagate_place_constraints(); /*Mark the blocks that have already been locked to one spot via floorplan constraints - * as fixed, so they do not get moved during initial placement or later during the simulated annealing stage of placement*/ + * as fixed, so they do not get moved during initial placement or later during the simulated annealing stage of placement + */ mark_fixed_blocks(); // Compute and store compressed floorplanning constraints @@ -1204,17 +1205,22 @@ void initial_placement(const t_placer_opts& placer_opts, read_constraints(constraints_file); } - if (noc_opts.noc) { - // NoC routers are placed before other blocks - initial_noc_placement(noc_opts, placer_opts); - propagate_place_constraints(); - } + if(!placer_opts.read_initial_place_file.empty()) { + const auto& grid = g_vpr_ctx.device().grid; + read_place(nullptr, placer_opts.read_initial_place_file.c_str(), false, grid); + } else { + if (noc_opts.noc) { + // NoC routers are placed before other blocks + initial_noc_placement(noc_opts, placer_opts); + propagate_place_constraints(); + } - //Assign scores to blocks and placement macros according to how difficult they are to place - vtr::vector block_scores = assign_block_scores(); + //Assign scores to blocks and placement macros according to how difficult they are to place + vtr::vector block_scores = assign_block_scores(); - //Place all blocks - place_all_blocks(placer_opts, block_scores, placer_opts.pad_loc_type, constraints_file); + //Place all blocks + place_all_blocks(placer_opts, block_scores, placer_opts.pad_loc_type, constraints_file); + } alloc_and_load_movable_blocks(); diff --git a/vpr/src/place/place.cpp b/vpr/src/place/place.cpp index e07fd7fa01a..b0134fd31f5 100644 --- a/vpr/src/place/place.cpp +++ b/vpr/src/place/place.cpp @@ -462,7 +462,7 @@ void try_place(const Netlist<>& net_list, if (!placer_opts.write_initial_place_file.empty()) { print_place(nullptr, nullptr, - (placer_opts.write_initial_place_file + ".init.place").c_str()); + placer_opts.write_initial_place_file.c_str()); } #ifdef ENABLE_ANALYTIC_PLACE