aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--common/command.cc3
-rw-r--r--common/command.h2
-rw-r--r--common/placer1.cc9
-rw-r--r--common/placer1.h6
-rw-r--r--common/project.cc26
-rw-r--r--common/router1.cc10
-rw-r--r--common/router1.h13
-rw-r--r--common/settings.h63
-rw-r--r--ecp5/arch.cc8
-rw-r--r--generic/arch.cc4
-rw-r--r--gui/basewindow.cc2
-rw-r--r--gui/ice40/mainwindow.cc2
-rw-r--r--ice40/arch.cc13
-rw-r--r--ice40/arch.h2
-rw-r--r--ice40/pcf.cc2
-rw-r--r--ice40/project.cc4
-rw-r--r--json/jsonparse.cc2
17 files changed, 130 insertions, 41 deletions
diff --git a/common/command.cc b/common/command.cc
index d5639e9a..ab0c92f2 100644
--- a/common/command.cc
+++ b/common/command.cc
@@ -144,7 +144,7 @@ void CommandHandler::setupContext(Context *ctx)
}
if (vm.count("cstrweight")) {
- // ctx->placer_constraintWeight = vm["cstrweight"].as<float>();
+ settings->set("placer1/constraintWeight", vm["cstrweight"].as<float>());
}
if (vm.count("freq")) {
@@ -261,6 +261,7 @@ int CommandHandler::exec()
} else {
ctx = createContext();
}
+ settings = std::unique_ptr<Settings>(new Settings(ctx.get()));
setupContext(ctx.get());
setupArchContext(ctx.get());
return executeMain(std::move(ctx));
diff --git a/common/command.h b/common/command.h
index 13d5a250..900cf74b 100644
--- a/common/command.h
+++ b/common/command.h
@@ -24,6 +24,7 @@
#include <boost/program_options.hpp>
#include "nextpnr.h"
#include "project.h"
+#include "settings.h"
NEXTPNR_NAMESPACE_BEGIN
@@ -56,6 +57,7 @@ class CommandHandler
protected:
po::variables_map vm;
ArchArgs chipArgs;
+ std::unique_ptr<Settings> settings;
private:
po::options_description options;
diff --git a/common/placer1.cc b/common/placer1.cc
index 88f2fc47..363b4d58 100644
--- a/common/placer1.cc
+++ b/common/placer1.cc
@@ -23,6 +23,7 @@
#include "placer1.h"
#include <algorithm>
+#include <boost/lexical_cast.hpp>
#include <cmath>
#include <iostream>
#include <limits>
@@ -108,14 +109,12 @@ class SAPlacer
if (bel_type != cell->type) {
log_error("Bel \'%s\' of type \'%s\' does not match cell "
"\'%s\' of type \'%s\'\n",
- loc_name.c_str(), bel_type.c_str(ctx), cell->name.c_str(ctx),
- cell->type.c_str(ctx));
+ loc_name.c_str(), bel_type.c_str(ctx), cell->name.c_str(ctx), cell->type.c_str(ctx));
}
if (!ctx->isValidBelForCell(cell, bel)) {
log_error("Bel \'%s\' of type \'%s\' is not valid for cell "
"\'%s\' of type \'%s\'\n",
- loc_name.c_str(), bel_type.c_str(ctx), cell->name.c_str(ctx),
- cell->type.c_str(ctx));
+ loc_name.c_str(), bel_type.c_str(ctx), cell->name.c_str(ctx), cell->type.c_str(ctx));
}
ctx->bindBel(bel, cell, STRENGTH_USER);
@@ -492,6 +491,8 @@ class SAPlacer
std::vector<decltype(NetInfo::udata)> old_udata;
};
+Placer1Cfg::Placer1Cfg(Context *ctx) : Settings(ctx) { constraintWeight = get<float>("placer1/constraintWeight", 10); }
+
bool placer1(Context *ctx, Placer1Cfg cfg)
{
try {
diff --git a/common/placer1.h b/common/placer1.h
index d8f64b84..55db1fa5 100644
--- a/common/placer1.h
+++ b/common/placer1.h
@@ -20,12 +20,14 @@
#define PLACE_H
#include "nextpnr.h"
+#include "settings.h"
NEXTPNR_NAMESPACE_BEGIN
-struct Placer1Cfg
+struct Placer1Cfg : public Settings
{
- float constraintWeight = 10;
+ Placer1Cfg(Context *ctx);
+ float constraintWeight;
};
extern bool placer1(Context *ctx, Placer1Cfg cfg);
diff --git a/common/project.cc b/common/project.cc
index 949f6878..b0ebe961 100644
--- a/common/project.cc
+++ b/common/project.cc
@@ -18,6 +18,7 @@
*/
#include "project.h"
+#include <algorithm>
#include <boost/filesystem/convenience.hpp>
#include <boost/property_tree/json_parser.hpp>
#include <fstream>
@@ -64,17 +65,36 @@ void ProjectHandler::save(Context *ctx, std::string filename)
root.put("project.name", boost::filesystem::basename(filename));
root.put("project.arch.name", ctx->archId().c_str(ctx));
root.put("project.arch.type", ctx->archArgsToId(ctx->archArgs()).c_str(ctx));
- std::string fn = ctx->settings[ctx->id("project/input/json")];
+ std::string fn = ctx->settings[ctx->id("input/json")];
root.put("project.input.json", make_relative(fn, proj.parent_path()).string());
root.put("project.params.freq", int(ctx->target_freq / 1e6));
root.put("project.params.seed", ctx->rngstate);
saveArch(ctx, root, proj.parent_path().string());
+ for (auto const &item : ctx->settings) {
+ std::string path = "project.settings.";
+ path += item.first.c_str(ctx);
+ std::replace(path.begin(), path.end(), '/', '.');
+ root.put(path, item.second);
+ }
pt::write_json(f, root);
} catch (...) {
log_error("Error saving project file.\n");
}
}
+void addSettings(Context *ctx, std::string path, pt::ptree sub)
+{
+ for (pt::ptree::value_type &v : sub) {
+ const std::string &key = v.first;
+ const boost::property_tree::ptree &subtree = v.second;
+ if (subtree.empty()) {
+ ctx->settings.emplace(ctx->id(path + key), subtree.get_value<std::string>().c_str());
+ } else {
+ addSettings(ctx, path + key + "/", subtree);
+ }
+ }
+}
+
std::unique_ptr<Context> ProjectHandler::load(std::string filename)
{
std::unique_ptr<Context> ctx;
@@ -110,6 +130,10 @@ std::unique_ptr<Context> ProjectHandler::load(std::string filename)
if (params.count("seed"))
ctx->rngseed(params.get<uint64_t>("seed"));
}
+ if (project.count("settings")) {
+ addSettings(ctx.get(), "", project.get_child("settings"));
+ }
+
loadArch(ctx.get(), root, proj.parent_path().string());
} catch (...) {
log_error("Error loading project file.\n");
diff --git a/common/router1.cc b/common/router1.cc
index 0733a61e..5cd4414c 100644
--- a/common/router1.cc
+++ b/common/router1.cc
@@ -682,6 +682,14 @@ void cleanupReroute(Context *ctx, const Router1Cfg &cfg, RipupScoreboard &scores
NEXTPNR_NAMESPACE_BEGIN
+Router1Cfg::Router1Cfg(Context *ctx) : Settings(ctx)
+{
+ maxIterCnt = get<int>("router1/maxIterCnt", 200);
+ cleanupReroute = get<bool>("router1/cleanupReroute", true);
+ fullCleanupReroute = get<bool>("router1/fullCleanupReroute", true);
+ useEstimate = get<bool>("router1/useEstimate", true);
+}
+
bool router1(Context *ctx, const Router1Cfg &cfg)
{
try {
@@ -953,7 +961,7 @@ bool Context::getActualRouteDelay(WireId src_wire, WireId dst_wire, delay_t *del
std::unordered_map<WireId, PipId> *route, bool useEstimate)
{
RipupScoreboard scores;
- Router1Cfg cfg;
+ Router1Cfg cfg(this);
cfg.useEstimate = useEstimate;
Router router(this, cfg, scores, src_wire, dst_wire);
diff --git a/common/router1.h b/common/router1.h
index 0380adc2..a184cbe7 100644
--- a/common/router1.h
+++ b/common/router1.h
@@ -21,15 +21,18 @@
#define ROUTER1_H
#include "nextpnr.h"
+#include "settings.h"
NEXTPNR_NAMESPACE_BEGIN
-struct Router1Cfg
+struct Router1Cfg : Settings
{
- int maxIterCnt = 200;
- bool cleanupReroute = true;
- bool fullCleanupReroute = true;
- bool useEstimate = true;
+ Router1Cfg(Context *ctx);
+
+ int maxIterCnt;
+ bool cleanupReroute;
+ bool fullCleanupReroute;
+ bool useEstimate;
};
extern bool router1(Context *ctx, const Router1Cfg &cfg);
diff --git a/common/settings.h b/common/settings.h
new file mode 100644
index 00000000..e1f1166a
--- /dev/null
+++ b/common/settings.h
@@ -0,0 +1,63 @@
+/*
+ * nextpnr -- Next Generation Place and Route
+ *
+ * Copyright (C) 2018 Miodrag Milanovic <miodrag@symbioticeda.com>
+ *
+ * Permission to use, copy, modify, and/or distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ *
+ */
+#ifndef SETTINGS_H
+#define SETTINGS_H
+
+#include <boost/lexical_cast.hpp>
+#include "log.h"
+#include "nextpnr.h"
+
+NEXTPNR_NAMESPACE_BEGIN
+
+class Settings
+{
+ public:
+ explicit Settings(Context *ctx) : ctx(ctx) {}
+
+ template <typename T> T get(const char *name, T defaultValue)
+ {
+ try {
+ IdString id = ctx->id(name);
+ auto pair = ctx->settings.emplace(id, std::to_string(defaultValue));
+ if (!pair.second) {
+ return boost::lexical_cast<T>(pair.first->second);
+ }
+
+ } catch (boost::bad_lexical_cast &) {
+ log_error("Problem reading setting %s, using default value\n", name);
+ }
+ return defaultValue;
+ }
+
+ template <typename T> void set(const char *name, T value)
+ {
+ IdString id = ctx->id(name);
+ auto pair = ctx->settings.emplace(id, std::to_string(value));
+ if (!pair.second) {
+ ctx->settings[pair.first->first] = value;
+ }
+ }
+
+ private:
+ Context *ctx;
+};
+
+NEXTPNR_NAMESPACE_END
+
+#endif // SETTINGS_H
diff --git a/ecp5/arch.cc b/ecp5/arch.cc
index fec1011c..acf1b42e 100644
--- a/ecp5/arch.cc
+++ b/ecp5/arch.cc
@@ -383,13 +383,9 @@ bool Arch::getBudgetOverride(const NetInfo *net_info, const PortRef &sink, delay
// -----------------------------------------------------------------------
-bool Arch::place() { return placer1(getCtx(), Placer1Cfg()); }
+bool Arch::place() { return placer1(getCtx(), Placer1Cfg(getCtx())); }
-bool Arch::route()
-{
- Router1Cfg cfg;
- return router1(getCtx(), cfg);
-}
+bool Arch::route() { return router1(getCtx(), Router1Cfg(getCtx())); }
// -----------------------------------------------------------------------
diff --git a/generic/arch.cc b/generic/arch.cc
index 7f464206..583c74d8 100644
--- a/generic/arch.cc
+++ b/generic/arch.cc
@@ -446,9 +446,9 @@ bool Arch::getBudgetOverride(const NetInfo *net_info, const PortRef &sink, delay
// ---------------------------------------------------------------
-bool Arch::place() { return placer1(getCtx(), Placer1Cfg()); }
+bool Arch::place() { return placer1(getCtx(), Placer1Cfg(getCtx())); }
-bool Arch::route() { return router1(getCtx(), Router1Cfg()); }
+bool Arch::route() { return router1(getCtx(), Router1Cfg(getCtx())); }
// ---------------------------------------------------------------
diff --git a/gui/basewindow.cc b/gui/basewindow.cc
index 66df3ca4..4444c8e9 100644
--- a/gui/basewindow.cc
+++ b/gui/basewindow.cc
@@ -420,7 +420,7 @@ void BaseMainWindow::disableActions()
actionNew->setEnabled(true);
actionOpen->setEnabled(true);
- if (ctx->settings.find(ctx->id("project/input/json")) != ctx->settings.end())
+ if (ctx->settings.find(ctx->id("input/json")) != ctx->settings.end())
actionSave->setEnabled(true);
else
actionSave->setEnabled(false);
diff --git a/gui/ice40/mainwindow.cc b/gui/ice40/mainwindow.cc
index 9fe80717..f270b112 100644
--- a/gui/ice40/mainwindow.cc
+++ b/gui/ice40/mainwindow.cc
@@ -191,7 +191,7 @@ void MainWindow::onRouteFinished() { actionSaveAsc->setEnabled(true); }
void MainWindow::onProjectLoaded()
{
- if (ctx->settings.find(ctx->id("project/input/pcf")) != ctx->settings.end())
+ if (ctx->settings.find(ctx->id("input/pcf")) != ctx->settings.end())
actionLoadPCF->setEnabled(false);
}
diff --git a/ice40/arch.cc b/ice40/arch.cc
index 58789043..91dc5d66 100644
--- a/ice40/arch.cc
+++ b/ice40/arch.cc
@@ -602,18 +602,9 @@ bool Arch::getBudgetOverride(const NetInfo *net_info, const PortRef &sink, delay
// -----------------------------------------------------------------------
-bool Arch::place()
-{
- Placer1Cfg cfg;
- cfg.constraintWeight = placer_constraintWeight;
- return placer1(getCtx(), cfg);
-}
+bool Arch::place() { return placer1(getCtx(), Placer1Cfg(getCtx())); }
-bool Arch::route()
-{
- Router1Cfg cfg;
- return router1(getCtx(), cfg);
-}
+bool Arch::route() { return router1(getCtx(), Router1Cfg(getCtx())); }
// -----------------------------------------------------------------------
diff --git a/ice40/arch.h b/ice40/arch.h
index 7f61c376..871b25fb 100644
--- a/ice40/arch.h
+++ b/ice40/arch.h
@@ -839,8 +839,6 @@ struct Arch : BaseCtx
}
NPNR_ASSERT_FALSE("Expected PLL pin to share an output with an SB_IO D_IN_{0,1}");
}
-
- float placer_constraintWeight = 10;
};
void ice40DelayFuzzerMain(Context *ctx);
diff --git a/ice40/pcf.cc b/ice40/pcf.cc
index d9fc4e68..af5b3e17 100644
--- a/ice40/pcf.cc
+++ b/ice40/pcf.cc
@@ -66,7 +66,7 @@ bool apply_pcf(Context *ctx, std::string filename, std::istream &in)
log_error("unsupported pcf command '%s'\n", cmd.c_str());
}
}
- ctx->settings.emplace(ctx->id("project/input/pcf"), filename);
+ ctx->settings.emplace(ctx->id("input/pcf"), filename);
return true;
} catch (log_execution_error_exception) {
return false;
diff --git a/ice40/project.cc b/ice40/project.cc
index 8ca10e36..47c0903d 100644
--- a/ice40/project.cc
+++ b/ice40/project.cc
@@ -28,8 +28,8 @@ NEXTPNR_NAMESPACE_BEGIN
void ProjectHandler::saveArch(Context *ctx, pt::ptree &root, std::string path)
{
root.put("project.arch.package", ctx->archArgs().package);
- if (ctx->settings.find(ctx->id("project/input/pcf")) != ctx->settings.end()) {
- std::string fn = ctx->settings[ctx->id("project/input/pcf")];
+ if (ctx->settings.find(ctx->id("input/pcf")) != ctx->settings.end()) {
+ std::string fn = ctx->settings[ctx->id("input/pcf")];
root.put("project.input.pcf", make_relative(fn, path).string());
}
}
diff --git a/json/jsonparse.cc b/json/jsonparse.cc
index ab01e01b..a690bf18 100644
--- a/json/jsonparse.cc
+++ b/json/jsonparse.cc
@@ -768,7 +768,7 @@ bool parse_json_file(std::istream &f, std::string &filename, Context *ctx)
log_info("Checksum: 0x%08x\n", ctx->checksum());
log_break();
- ctx->settings.emplace(ctx->id("project/input/json"), filename);
+ ctx->settings.emplace(ctx->id("input/json"), filename);
return true;
} catch (log_execution_error_exception) {
return false;