Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add flag to restart place-and-route on failed target frequency #1373

Closed
wants to merge 1 commit into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
31 changes: 30 additions & 1 deletion common/kernel/command.cc
Original file line number Diff line number Diff line change
Expand Up @@ -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, ", ") +
Expand Down Expand Up @@ -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"))
Expand All @@ -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"))
Expand Down Expand Up @@ -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");
Expand Down
2 changes: 2 additions & 0 deletions common/kernel/context.h
Original file line number Diff line number Diff line change
Expand Up @@ -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;

Expand Down
10 changes: 10 additions & 0 deletions common/kernel/timing.cc
Original file line number Diff line number Diff line change
Expand Up @@ -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
51 changes: 26 additions & 25 deletions common/kernel/timing_log.cc
Original file line number Diff line number Diff line change
Expand Up @@ -38,35 +38,36 @@ 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()) {
// No sources for this net, can't print anything
return;
}
// Check if this net is annotated with a source list
auto sources = net->attrs.find(ctx->id("src"));
if (sources == net->attrs.end()) {
// No sources for this net, can't print anything
return;
}

// Sources are separated by pipe characters.
// There is no guaranteed ordering on sources, so we just print all
auto sourcelist = sources->second.as_string();
std::vector<std::string> source_entries;
size_t current = 0, prev = 0;
while ((current = sourcelist.find("|", prev)) != std::string::npos) {
source_entries.emplace_back(sourcelist.substr(prev, current - prev));
prev = current + 1;
}
// Ensure we emplace the final entry
// Sources are separated by pipe characters.
// There is no guaranteed ordering on sources, so we just print all
auto sourcelist = sources->second.as_string();
std::vector<std::string> source_entries;
size_t current = 0, prev = 0;
while ((current = sourcelist.find("|", prev)) != std::string::npos) {
source_entries.emplace_back(sourcelist.substr(prev, current - prev));
prev = current + 1;
}
// Ensure we emplace the final entry
source_entries.emplace_back(sourcelist.substr(prev, current - prev));

// Iterate and print our source list at the correct indentation level
log_info(" Defined in:\n");
for (auto entry : source_entries) {
log_info(" %s\n", entry.c_str());
}
};
// Iterate and print our source list at the correct indentation level
log_info(" Defined in:\n");
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);
Expand Down Expand Up @@ -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);
}
}
}
Expand Down