moved some context variables to settings
This commit is contained in:
parent
95280060b8
commit
8d5724f4fd
@ -181,9 +181,9 @@ void CommandHandler::setupContext(Context *ctx)
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (vm.count("slack_redist_iter")) {
|
if (vm.count("slack_redist_iter")) {
|
||||||
ctx->slack_redist_iter = vm["slack_redist_iter"].as<int>();
|
ctx->settings[ctx->id("slack_redist_iter")] = vm["slack_redist_iter"].as<std::string>();
|
||||||
if (vm.count("freq") && vm["freq"].as<double>() == 0) {
|
if (vm.count("freq") && vm["freq"].as<double>() == 0) {
|
||||||
ctx->auto_freq = true;
|
ctx->settings[ctx->id("auto_freq")] = std::to_string(true);
|
||||||
#ifndef NO_GUI
|
#ifndef NO_GUI
|
||||||
if (!vm.count("gui"))
|
if (!vm.count("gui"))
|
||||||
#endif
|
#endif
|
||||||
@ -223,13 +223,22 @@ void CommandHandler::setupContext(Context *ctx)
|
|||||||
if (vm.count("freq")) {
|
if (vm.count("freq")) {
|
||||||
auto freq = vm["freq"].as<double>();
|
auto freq = vm["freq"].as<double>();
|
||||||
if (freq > 0)
|
if (freq > 0)
|
||||||
ctx->target_freq = freq * 1e6;
|
ctx->settings[ctx->id("target_freq")] = std::to_string(freq * 1e6);
|
||||||
}
|
}
|
||||||
|
|
||||||
ctx->timing_driven = true;
|
|
||||||
if (vm.count("no-tmdriv"))
|
if (vm.count("no-tmdriv"))
|
||||||
ctx->timing_driven = false;
|
ctx->settings[ctx->id("timing_driven")] = std::to_string(false);
|
||||||
|
|
||||||
|
// Setting default values
|
||||||
|
if (ctx->settings.find(ctx->id("target_freq")) == ctx->settings.end())
|
||||||
|
ctx->settings[ctx->id("target_freq")] = std::to_string(12e6);
|
||||||
|
if (ctx->settings.find(ctx->id("timing_driven")) == ctx->settings.end())
|
||||||
|
ctx->settings[ctx->id("timing_driven")] = std::to_string(true);
|
||||||
|
if (ctx->settings.find(ctx->id("slack_redist_iter")) == ctx->settings.end())
|
||||||
|
ctx->settings[ctx->id("slack_redist_iter")] = "0";
|
||||||
|
if (ctx->settings.find(ctx->id("auto_freq")) == ctx->settings.end())
|
||||||
|
ctx->settings[ctx->id("auto_freq")] = std::to_string(false);
|
||||||
|
|
||||||
ctx->settings[ctx->id("arch.name")] = std::string(ctx->archId().c_str(ctx));
|
ctx->settings[ctx->id("arch.name")] = std::string(ctx->archId().c_str(ctx));
|
||||||
ctx->settings[ctx->id("arch.type")] = std::string(ctx->archArgsToId(ctx->archArgs()).c_str(ctx));
|
ctx->settings[ctx->id("arch.type")] = std::string(ctx->archArgsToId(ctx->archArgs()).c_str(ctx));
|
||||||
ctx->settings[ctx->id("seed")] = std::to_string(ctx->rngstate);
|
ctx->settings[ctx->id("seed")] = std::to_string(ctx->rngstate);
|
||||||
|
@ -701,10 +701,6 @@ struct Context : Arch, DeterministicRNG
|
|||||||
bool verbose = false;
|
bool verbose = false;
|
||||||
bool debug = false;
|
bool debug = false;
|
||||||
bool force = false;
|
bool force = false;
|
||||||
bool timing_driven = true;
|
|
||||||
float target_freq = 12e6;
|
|
||||||
bool auto_freq = false;
|
|
||||||
int slack_redist_iter = 0;
|
|
||||||
|
|
||||||
Context(ArchArgs args) : Arch(args) {}
|
Context(ArchArgs args) : Arch(args) {}
|
||||||
|
|
||||||
@ -733,10 +729,18 @@ struct Context : Arch, DeterministicRNG
|
|||||||
return boost::lexical_cast<T>(settings.find(new_id)->second.str);
|
return boost::lexical_cast<T>(settings.find(new_id)->second.str);
|
||||||
else
|
else
|
||||||
settings[id(name)] = std::to_string(defaultValue);
|
settings[id(name)] = std::to_string(defaultValue);
|
||||||
|
|
||||||
return defaultValue;
|
return defaultValue;
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename T> T setting(const char *name) const
|
||||||
|
{
|
||||||
|
IdString new_id = id(name);
|
||||||
|
if (settings.find(new_id) != settings.end())
|
||||||
|
return boost::lexical_cast<T>(settings.find(new_id)->second.str);
|
||||||
|
else
|
||||||
|
throw std::runtime_error("settings does not exists");
|
||||||
}
|
}
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
NEXTPNR_NAMESPACE_END
|
NEXTPNR_NAMESPACE_END
|
||||||
|
@ -37,7 +37,7 @@ wirelen_t get_net_metric(const Context *ctx, const NetInfo *net, MetricType type
|
|||||||
if (driver_gb)
|
if (driver_gb)
|
||||||
return 0;
|
return 0;
|
||||||
int clock_count;
|
int clock_count;
|
||||||
bool timing_driven = ctx->timing_driven && type == MetricType::COST &&
|
bool timing_driven = ctx->setting<bool>("timing_driven") && type == MetricType::COST &&
|
||||||
ctx->getPortTimingClass(driver_cell, net->driver.port, clock_count) != TMG_IGNORE;
|
ctx->getPortTimingClass(driver_cell, net->driver.port, clock_count) != TMG_IGNORE;
|
||||||
delay_t negative_slack = 0;
|
delay_t negative_slack = 0;
|
||||||
delay_t worst_slack = std::numeric_limits<delay_t>::max();
|
delay_t worst_slack = std::numeric_limits<delay_t>::max();
|
||||||
|
@ -219,7 +219,7 @@ class SAPlacer
|
|||||||
if ((placed_cells - constr_placed_cells) % 500 != 0)
|
if ((placed_cells - constr_placed_cells) % 500 != 0)
|
||||||
log_info(" initial placement placed %d/%d cells\n", int(placed_cells - constr_placed_cells),
|
log_info(" initial placement placed %d/%d cells\n", int(placed_cells - constr_placed_cells),
|
||||||
int(autoplaced.size()));
|
int(autoplaced.size()));
|
||||||
if (cfg.budgetBased && ctx->slack_redist_iter > 0)
|
if (cfg.budgetBased && ctx->setting<int>("slack_redist_iter") > 0)
|
||||||
assign_budget(ctx);
|
assign_budget(ctx);
|
||||||
ctx->yield();
|
ctx->yield();
|
||||||
auto iplace_end = std::chrono::high_resolution_clock::now();
|
auto iplace_end = std::chrono::high_resolution_clock::now();
|
||||||
@ -370,16 +370,16 @@ class SAPlacer
|
|||||||
ctx->shuffle(autoplaced);
|
ctx->shuffle(autoplaced);
|
||||||
|
|
||||||
// Legalisation is a big change so force a slack redistribution here
|
// Legalisation is a big change so force a slack redistribution here
|
||||||
if (ctx->slack_redist_iter > 0 && cfg.budgetBased)
|
if (ctx->setting<int>("slack_redist_iter") > 0 && cfg.budgetBased)
|
||||||
assign_budget(ctx, true /* quiet */);
|
assign_budget(ctx, true /* quiet */);
|
||||||
}
|
}
|
||||||
require_legal = false;
|
require_legal = false;
|
||||||
} else if (cfg.budgetBased && ctx->slack_redist_iter > 0 && iter % ctx->slack_redist_iter == 0) {
|
} else if (cfg.budgetBased && ctx->setting<int>("slack_redist_iter") > 0 && iter % ctx->setting<int>("slack_redist_iter") == 0) {
|
||||||
assign_budget(ctx, true /* quiet */);
|
assign_budget(ctx, true /* quiet */);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Invoke timing analysis to obtain criticalities
|
// Invoke timing analysis to obtain criticalities
|
||||||
if (!cfg.budgetBased && ctx->timing_driven)
|
if (!cfg.budgetBased && ctx->setting<bool>("timing_driven"))
|
||||||
get_criticalities(ctx, &net_crit);
|
get_criticalities(ctx, &net_crit);
|
||||||
// Need to rebuild costs after criticalities change
|
// Need to rebuild costs after criticalities change
|
||||||
setup_costs();
|
setup_costs();
|
||||||
@ -804,7 +804,7 @@ class SAPlacer
|
|||||||
if (ignore_net(ni))
|
if (ignore_net(ni))
|
||||||
continue;
|
continue;
|
||||||
net_bounds[ni->udata] = get_net_bounds(ni);
|
net_bounds[ni->udata] = get_net_bounds(ni);
|
||||||
if (ctx->timing_driven && int(ni->users.size()) < cfg.timingFanoutThresh)
|
if (ctx->setting<bool>("timing_driven") && int(ni->users.size()) < cfg.timingFanoutThresh)
|
||||||
for (size_t i = 0; i < ni->users.size(); i++)
|
for (size_t i = 0; i < ni->users.size(); i++)
|
||||||
net_arc_tcost[ni->udata][i] = get_timing_cost(ni, i);
|
net_arc_tcost[ni->udata][i] = get_timing_cost(ni, i);
|
||||||
}
|
}
|
||||||
@ -1021,7 +1021,7 @@ class SAPlacer
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (ctx->timing_driven && int(pn->users.size()) < cfg.timingFanoutThresh) {
|
if (ctx->setting<bool>("timing_driven") && int(pn->users.size()) < cfg.timingFanoutThresh) {
|
||||||
// Output ports - all arcs change timing
|
// Output ports - all arcs change timing
|
||||||
if (port.second.type == PORT_OUT) {
|
if (port.second.type == PORT_OUT) {
|
||||||
int cc;
|
int cc;
|
||||||
@ -1061,7 +1061,7 @@ class SAPlacer
|
|||||||
if (md.already_bounds_changed_x[bc] == MoveChangeData::NO_CHANGE)
|
if (md.already_bounds_changed_x[bc] == MoveChangeData::NO_CHANGE)
|
||||||
md.wirelen_delta += md.new_net_bounds[bc].hpwl() - net_bounds[bc].hpwl();
|
md.wirelen_delta += md.new_net_bounds[bc].hpwl() - net_bounds[bc].hpwl();
|
||||||
|
|
||||||
if (ctx->timing_driven) {
|
if (ctx->setting<bool>("timing_driven")) {
|
||||||
for (const auto &tc : md.changed_arcs) {
|
for (const auto &tc : md.changed_arcs) {
|
||||||
double old_cost = net_arc_tcost.at(tc.first).at(tc.second);
|
double old_cost = net_arc_tcost.at(tc.first).at(tc.second);
|
||||||
double new_cost = get_timing_cost(net_by_udata.at(tc.first), tc.second);
|
double new_cost = get_timing_cost(net_by_udata.at(tc.first), tc.second);
|
||||||
|
@ -234,7 +234,7 @@ class HeAPPlacer
|
|||||||
std::chrono::duration<double>(run_stopt - run_startt).count());
|
std::chrono::duration<double>(run_stopt - run_startt).count());
|
||||||
}
|
}
|
||||||
|
|
||||||
if (ctx->timing_driven)
|
if (ctx->setting<bool>("timing_driven"))
|
||||||
get_criticalities(ctx, &net_crit);
|
get_criticalities(ctx, &net_crit);
|
||||||
|
|
||||||
if (legal_hpwl < best_hpwl) {
|
if (legal_hpwl < best_hpwl) {
|
||||||
|
@ -113,7 +113,7 @@ struct Timing
|
|||||||
|
|
||||||
Timing(Context *ctx, bool net_delays, bool update, CriticalPathMap *crit_path = nullptr,
|
Timing(Context *ctx, bool net_delays, bool update, CriticalPathMap *crit_path = nullptr,
|
||||||
DelayFrequency *slack_histogram = nullptr, NetCriticalityMap *net_crit = nullptr)
|
DelayFrequency *slack_histogram = nullptr, NetCriticalityMap *net_crit = nullptr)
|
||||||
: ctx(ctx), net_delays(net_delays), update(update), min_slack(1.0e12 / ctx->target_freq),
|
: ctx(ctx), net_delays(net_delays), update(update), min_slack(1.0e12 / ctx->setting<float>("target_freq")),
|
||||||
crit_path(crit_path), slack_histogram(slack_histogram), net_crit(net_crit),
|
crit_path(crit_path), slack_histogram(slack_histogram), net_crit(net_crit),
|
||||||
async_clock(ctx->id("$async$"))
|
async_clock(ctx->id("$async$"))
|
||||||
{
|
{
|
||||||
@ -121,7 +121,7 @@ struct Timing
|
|||||||
|
|
||||||
delay_t walk_paths()
|
delay_t walk_paths()
|
||||||
{
|
{
|
||||||
const auto clk_period = ctx->getDelayFromNS(1.0e9 / ctx->target_freq).maxDelay();
|
const auto clk_period = ctx->getDelayFromNS(1.0e9 / ctx->setting<float>("target_freq")).maxDelay();
|
||||||
|
|
||||||
// First, compute the topographical order of nets to walk through the circuit, assuming it is a _acyclic_ graph
|
// First, compute the topographical order of nets to walk through the circuit, assuming it is a _acyclic_ graph
|
||||||
// TODO(eddieh): Handle the case where it is cyclic, e.g. combinatorial loops
|
// TODO(eddieh): Handle the case where it is cyclic, e.g. combinatorial loops
|
||||||
@ -657,17 +657,17 @@ void assign_budget(Context *ctx, bool quiet)
|
|||||||
{
|
{
|
||||||
if (!quiet) {
|
if (!quiet) {
|
||||||
log_break();
|
log_break();
|
||||||
log_info("Annotating ports with timing budgets for target frequency %.2f MHz\n", ctx->target_freq / 1e6);
|
log_info("Annotating ports with timing budgets for target frequency %.2f MHz\n", ctx->setting<float>("target_freq") / 1e6);
|
||||||
}
|
}
|
||||||
|
|
||||||
Timing timing(ctx, ctx->slack_redist_iter > 0 /* net_delays */, true /* update */);
|
Timing timing(ctx, ctx->setting<int>("slack_redist_iter")> 0 /* net_delays */, true /* update */);
|
||||||
timing.assign_budget();
|
timing.assign_budget();
|
||||||
|
|
||||||
if (!quiet || ctx->verbose) {
|
if (!quiet || ctx->verbose) {
|
||||||
for (auto &net : ctx->nets) {
|
for (auto &net : ctx->nets) {
|
||||||
for (auto &user : net.second->users) {
|
for (auto &user : net.second->users) {
|
||||||
// Post-update check
|
// Post-update check
|
||||||
if (!ctx->auto_freq && user.budget < 0)
|
if (!ctx->setting<bool>("auto_freq") && user.budget < 0)
|
||||||
log_info("port %s.%s, connected to net '%s', has negative "
|
log_info("port %s.%s, connected to net '%s', has negative "
|
||||||
"timing budget of %fns\n",
|
"timing budget of %fns\n",
|
||||||
user.cell->name.c_str(ctx), user.port.c_str(ctx), net.first.c_str(ctx),
|
user.cell->name.c_str(ctx), user.port.c_str(ctx), net.first.c_str(ctx),
|
||||||
@ -683,13 +683,13 @@ void assign_budget(Context *ctx, bool quiet)
|
|||||||
|
|
||||||
// For slack redistribution, if user has not specified a frequency dynamically adjust the target frequency to be the
|
// For slack redistribution, if user has not specified a frequency dynamically adjust the target frequency to be the
|
||||||
// currently achieved maximum
|
// currently achieved maximum
|
||||||
if (ctx->auto_freq && ctx->slack_redist_iter > 0) {
|
if (ctx->setting<bool>("auto_freq") && ctx->setting<int>("slack_redist_iter") > 0) {
|
||||||
delay_t default_slack = delay_t((1.0e9 / ctx->getDelayNS(1)) / ctx->target_freq);
|
delay_t default_slack = delay_t((1.0e9 / ctx->getDelayNS(1)) / ctx->setting<float>("target_freq"));
|
||||||
ctx->target_freq = 1.0e9 / ctx->getDelayNS(default_slack - timing.min_slack);
|
ctx->settings[ctx->id("target_freq")] = std::to_string(1.0e9 / ctx->getDelayNS(default_slack - timing.min_slack));
|
||||||
if (ctx->verbose)
|
if (ctx->verbose)
|
||||||
log_info("minimum slack for this assign = %.2f ns, target Fmax for next "
|
log_info("minimum slack for this assign = %.2f ns, target Fmax for next "
|
||||||
"update = %.2f MHz\n",
|
"update = %.2f MHz\n",
|
||||||
ctx->getDelayNS(timing.min_slack), ctx->target_freq / 1e6);
|
ctx->getDelayNS(timing.min_slack),ctx->setting<float>("target_freq") / 1e6);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!quiet)
|
if (!quiet)
|
||||||
@ -896,7 +896,7 @@ void timing_analysis(Context *ctx, bool print_histogram, bool print_fmax, bool p
|
|||||||
for (auto &clock : clock_reports) {
|
for (auto &clock : clock_reports) {
|
||||||
const auto &clock_name = clock.first.str(ctx);
|
const auto &clock_name = clock.first.str(ctx);
|
||||||
const int width = max_width - clock_name.size();
|
const int width = max_width - clock_name.size();
|
||||||
float target = ctx->target_freq / 1e6;
|
float target = ctx->setting<float>("target_freq") / 1e6;
|
||||||
if (ctx->nets.at(clock.first)->clkconstr)
|
if (ctx->nets.at(clock.first)->clkconstr)
|
||||||
target = 1000 / ctx->getDelayNS(ctx->nets.at(clock.first)->clkconstr->period.minDelay());
|
target = 1000 / ctx->getDelayNS(ctx->nets.at(clock.first)->clkconstr->period.minDelay());
|
||||||
|
|
||||||
|
@ -68,7 +68,7 @@ void Worker::budget(double freq)
|
|||||||
{
|
{
|
||||||
Q_EMIT taskStarted();
|
Q_EMIT taskStarted();
|
||||||
try {
|
try {
|
||||||
ctx->target_freq = freq;
|
ctx->settings[ctx->id("target_freq")] = std::to_string(freq);
|
||||||
assign_budget(ctx);
|
assign_budget(ctx);
|
||||||
Q_EMIT budget_finish(true);
|
Q_EMIT budget_finish(true);
|
||||||
} catch (WorkerInterruptionRequested) {
|
} catch (WorkerInterruptionRequested) {
|
||||||
@ -80,7 +80,7 @@ void Worker::place(bool timing_driven)
|
|||||||
{
|
{
|
||||||
Q_EMIT taskStarted();
|
Q_EMIT taskStarted();
|
||||||
try {
|
try {
|
||||||
ctx->timing_driven = timing_driven;
|
ctx->settings[ctx->id("timing_driven")] = std::to_string(timing_driven);
|
||||||
Q_EMIT place_finished(ctx->place());
|
Q_EMIT place_finished(ctx->place());
|
||||||
} catch (WorkerInterruptionRequested) {
|
} catch (WorkerInterruptionRequested) {
|
||||||
Q_EMIT taskCanceled();
|
Q_EMIT taskCanceled();
|
||||||
|
Loading…
Reference in New Issue
Block a user