aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--common/command.cc21
-rw-r--r--common/nextpnr.h18
-rw-r--r--common/place_common.cc2
-rw-r--r--common/placer1.cc14
-rw-r--r--common/placer_heap.cc2
-rw-r--r--common/timing.cc20
-rw-r--r--gui/worker.cc4
7 files changed, 47 insertions, 34 deletions
diff --git a/common/command.cc b/common/command.cc
index ca054532..89e05b4d 100644
--- a/common/command.cc
+++ b/common/command.cc
@@ -181,9 +181,9 @@ void CommandHandler::setupContext(Context *ctx)
}
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) {
- ctx->auto_freq = true;
+ ctx->settings[ctx->id("auto_freq")] = std::to_string(true);
#ifndef NO_GUI
if (!vm.count("gui"))
#endif
@@ -223,13 +223,22 @@ void CommandHandler::setupContext(Context *ctx)
if (vm.count("freq")) {
auto freq = vm["freq"].as<double>();
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"))
- 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.type")] = std::string(ctx->archArgsToId(ctx->archArgs()).c_str(ctx));
ctx->settings[ctx->id("seed")] = std::to_string(ctx->rngstate);
diff --git a/common/nextpnr.h b/common/nextpnr.h
index b796b8aa..e4461cb4 100644
--- a/common/nextpnr.h
+++ b/common/nextpnr.h
@@ -701,10 +701,6 @@ struct Context : Arch, DeterministicRNG
bool verbose = false;
bool debug = 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) {}
@@ -733,10 +729,18 @@ struct Context : Arch, DeterministicRNG
return boost::lexical_cast<T>(settings.find(new_id)->second.str);
else
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
diff --git a/common/place_common.cc b/common/place_common.cc
index 73a320d0..cb9799b5 100644
--- a/common/place_common.cc
+++ b/common/place_common.cc
@@ -37,7 +37,7 @@ wirelen_t get_net_metric(const Context *ctx, const NetInfo *net, MetricType type
if (driver_gb)
return 0;
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;
delay_t negative_slack = 0;
delay_t worst_slack = std::numeric_limits<delay_t>::max();
diff --git a/common/placer1.cc b/common/placer1.cc
index 89e4f919..a2272b83 100644
--- a/common/placer1.cc
+++ b/common/placer1.cc
@@ -219,7 +219,7 @@ class SAPlacer
if ((placed_cells - constr_placed_cells) % 500 != 0)
log_info(" initial placement placed %d/%d cells\n", int(placed_cells - constr_placed_cells),
int(autoplaced.size()));
- if (cfg.budgetBased && ctx->slack_redist_iter > 0)
+ if (cfg.budgetBased && ctx->setting<int>("slack_redist_iter") > 0)
assign_budget(ctx);
ctx->yield();
auto iplace_end = std::chrono::high_resolution_clock::now();
@@ -370,16 +370,16 @@ class SAPlacer
ctx->shuffle(autoplaced);
// 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 */);
}
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 */);
}
// 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);
// Need to rebuild costs after criticalities change
setup_costs();
@@ -804,7 +804,7 @@ class SAPlacer
if (ignore_net(ni))
continue;
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++)
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
if (port.second.type == PORT_OUT) {
int cc;
@@ -1061,7 +1061,7 @@ class SAPlacer
if (md.already_bounds_changed_x[bc] == MoveChangeData::NO_CHANGE)
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) {
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);
diff --git a/common/placer_heap.cc b/common/placer_heap.cc
index 4d1f4863..7b72200a 100644
--- a/common/placer_heap.cc
+++ b/common/placer_heap.cc
@@ -234,7 +234,7 @@ class HeAPPlacer
std::chrono::duration<double>(run_stopt - run_startt).count());
}
- if (ctx->timing_driven)
+ if (ctx->setting<bool>("timing_driven"))
get_criticalities(ctx, &net_crit);
if (legal_hpwl < best_hpwl) {
diff --git a/common/timing.cc b/common/timing.cc
index 2ce9eea3..582c347f 100644
--- a/common/timing.cc
+++ b/common/timing.cc
@@ -113,7 +113,7 @@ struct Timing
Timing(Context *ctx, bool net_delays, bool update, CriticalPathMap *crit_path = 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),
async_clock(ctx->id("$async$"))
{
@@ -121,7 +121,7 @@ struct Timing
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
// 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) {
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();
if (!quiet || ctx->verbose) {
for (auto &net : ctx->nets) {
for (auto &user : net.second->users) {
// 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 "
"timing budget of %fns\n",
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
// currently achieved maximum
- if (ctx->auto_freq && ctx->slack_redist_iter > 0) {
- delay_t default_slack = delay_t((1.0e9 / ctx->getDelayNS(1)) / ctx->target_freq);
- ctx->target_freq = 1.0e9 / ctx->getDelayNS(default_slack - timing.min_slack);
+ 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->setting<float>("target_freq"));
+ ctx->settings[ctx->id("target_freq")] = std::to_string(1.0e9 / ctx->getDelayNS(default_slack - timing.min_slack));
if (ctx->verbose)
log_info("minimum slack for this assign = %.2f ns, target Fmax for next "
"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)
@@ -896,7 +896,7 @@ void timing_analysis(Context *ctx, bool print_histogram, bool print_fmax, bool p
for (auto &clock : clock_reports) {
const auto &clock_name = clock.first.str(ctx);
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)
target = 1000 / ctx->getDelayNS(ctx->nets.at(clock.first)->clkconstr->period.minDelay());
diff --git a/gui/worker.cc b/gui/worker.cc
index 900883d4..bd14771b 100644
--- a/gui/worker.cc
+++ b/gui/worker.cc
@@ -68,7 +68,7 @@ void Worker::budget(double freq)
{
Q_EMIT taskStarted();
try {
- ctx->target_freq = freq;
+ ctx->settings[ctx->id("target_freq")] = std::to_string(freq);
assign_budget(ctx);
Q_EMIT budget_finish(true);
} catch (WorkerInterruptionRequested) {
@@ -80,7 +80,7 @@ void Worker::place(bool timing_driven)
{
Q_EMIT taskStarted();
try {
- ctx->timing_driven = timing_driven;
+ ctx->settings[ctx->id("timing_driven")] = std::to_string(timing_driven);
Q_EMIT place_finished(ctx->place());
} catch (WorkerInterruptionRequested) {
Q_EMIT taskCanceled();