Add flag to restart place-and-route on failed target frequency
* Add --restart-on-failed-target-frequency flag and logic to restart the place-and-route process if the target frequency is not achieved. * This flag is intended to be used with the --randomize-seed option to generate a new random seed for every run. This can significantly improve the chances of achieving a higher clock frequency compared to using the default seed. * Move print_net_source out of log_crit_paths() to remove the 'static' keyword, which could otherwise cause a segmentation fault if the context is changed.
This commit is contained in:
parent
437fb70ed3
commit
a0356aa0fc
@ -345,7 +345,9 @@ po::options_description CommandHandler::getGeneralOptions()
|
||||
general.add_options()("top", po::value<std::string>(), "name of top module");
|
||||
general.add_options()("seed", po::value<uint64_t>(), "seed value for random number generator");
|
||||
general.add_options()("randomize-seed,r", "randomize seed value for random number generator");
|
||||
|
||||
general.add_options()("restart-on-failed-target-frequency",
|
||||
"restart place and route if target frequency is not achieved (use together with "
|
||||
"--randomize-seed option)");
|
||||
general.add_options()(
|
||||
"placer", po::value<std::string>(),
|
||||
std::string("placer algorithm to use; available: " + boost::algorithm::join(Arch::availablePlacers, ", ") +
|
||||
@ -673,6 +675,17 @@ int CommandHandler::executeMain(std::unique_ptr<Context> ctx)
|
||||
ctx->debug = true;
|
||||
if (!ctx->place() && !ctx->force)
|
||||
log_error("Placing design failed.\n");
|
||||
if (vm.count("restart-on-failed-target-frequency")) {
|
||||
if (!ctx->target_frequency_achieved) {
|
||||
log_break();
|
||||
log_info("Target frequency not achieved, restarting...\n");
|
||||
log_break();
|
||||
#ifndef NO_PYTHON
|
||||
deinit_python();
|
||||
#endif
|
||||
return 2;
|
||||
}
|
||||
}
|
||||
ctx->debug = saved_debug;
|
||||
ctx->check();
|
||||
if (vm.count("placed-svg"))
|
||||
@ -686,6 +699,17 @@ int CommandHandler::executeMain(std::unique_ptr<Context> ctx)
|
||||
ctx->debug = true;
|
||||
if (!ctx->route() && !ctx->force)
|
||||
log_error("Routing design failed.\n");
|
||||
if (vm.count("restart-on-failed-target-frequency")) {
|
||||
if (!ctx->target_frequency_achieved) {
|
||||
log_break();
|
||||
log_info("Target frequency not achieved, restarting...\n");
|
||||
log_break();
|
||||
#ifndef NO_PYTHON
|
||||
deinit_python();
|
||||
#endif
|
||||
return 2;
|
||||
}
|
||||
}
|
||||
ctx->debug = saved_debug;
|
||||
run_script_hook("post-route");
|
||||
if (vm.count("routed-svg"))
|
||||
@ -753,10 +777,15 @@ int CommandHandler::exec()
|
||||
return 0;
|
||||
|
||||
dict<std::string, Property> values;
|
||||
restart:
|
||||
std::unique_ptr<Context> ctx = createContext(values);
|
||||
setupContext(ctx.get());
|
||||
setupArchContext(ctx.get());
|
||||
int rc = executeMain(std::move(ctx));
|
||||
if (rc == 2) {
|
||||
ctx.reset();
|
||||
goto restart;
|
||||
}
|
||||
printFooter();
|
||||
log_break();
|
||||
log_info("Program finished normally.\n");
|
||||
|
@ -38,6 +38,8 @@ struct Context : Arch, DeterministicRNG
|
||||
bool disable_critical_path_source_print = false;
|
||||
// True when detailed per-net timing is to be stored / reported
|
||||
bool detailed_timing_report = false;
|
||||
// Default to true, will update when timing analysis is run
|
||||
bool target_frequency_achieved = true;
|
||||
|
||||
ArchArgs arch_args;
|
||||
|
||||
|
@ -1339,6 +1339,16 @@ void timing_analysis(Context *ctx, bool print_slack_histogram, bool print_fmax,
|
||||
|
||||
if (update_results)
|
||||
ctx->timing_result = result;
|
||||
|
||||
ctx->target_frequency_achieved = true;
|
||||
for (auto &clock : result.clock_paths) {
|
||||
float fmax = result.clock_fmax[clock.first].achieved;
|
||||
float target = result.clock_fmax[clock.first].constraint;
|
||||
bool passed = target < fmax;
|
||||
if (!passed) {
|
||||
ctx->target_frequency_achieved = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
NEXTPNR_NAMESPACE_END
|
||||
|
@ -38,9 +38,8 @@ static std::string clock_event_name(const Context *ctx, const ClockEvent &e, int
|
||||
return value;
|
||||
};
|
||||
|
||||
static void log_crit_paths(const Context *ctx, TimingResult &result)
|
||||
static void print_net_source(const Context *ctx, const NetInfo *net)
|
||||
{
|
||||
static auto print_net_source = [ctx](const NetInfo *net) {
|
||||
// Check if this net is annotated with a source list
|
||||
auto sources = net->attrs.find(ctx->id("src"));
|
||||
if (sources == net->attrs.end()) {
|
||||
@ -65,8 +64,10 @@ static void log_crit_paths(const Context *ctx, TimingResult &result)
|
||||
for (auto entry : source_entries) {
|
||||
log_info(" %s\n", entry.c_str());
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
static void log_crit_paths(const Context *ctx, TimingResult &result)
|
||||
{
|
||||
// A helper function for reporting one critical path
|
||||
auto print_path_report = [ctx](const CriticalPath &path) {
|
||||
delay_t total(0), logic_total(0), route_total(0);
|
||||
@ -137,7 +138,7 @@ static void log_crit_paths(const Context *ctx, TimingResult &result)
|
||||
}
|
||||
|
||||
if (!ctx->disable_critical_path_source_print) {
|
||||
print_net_source(net);
|
||||
print_net_source(ctx, net);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user