diff options
author | Clifford Wolf <clifford@clifford.at> | 2018-08-18 19:25:19 +0200 |
---|---|---|
committer | GitHub <noreply@github.com> | 2018-08-18 19:25:19 +0200 |
commit | 26be6f9761bba9dff646c6b1d071b149bd26f950 (patch) | |
tree | 2d4f46e149cb7a96f91b801fd830458eea8f79ac | |
parent | 1e8e873c9fe4b0fdd69055b0251f9e71db3849c5 (diff) | |
parent | eaf824ca73241014a280b1bd787d8f83e772dd05 (diff) | |
download | nextpnr-26be6f9761bba9dff646c6b1d071b149bd26f950.tar.gz nextpnr-26be6f9761bba9dff646c6b1d071b149bd26f950.tar.bz2 nextpnr-26be6f9761bba9dff646c6b1d071b149bd26f950.zip |
Merge pull request #47 from YosysHQ/settings_propagate
Use settings for placer1 and router1
-rw-r--r-- | common/command.cc | 3 | ||||
-rw-r--r-- | common/command.h | 2 | ||||
-rw-r--r-- | common/placer1.cc | 9 | ||||
-rw-r--r-- | common/placer1.h | 6 | ||||
-rw-r--r-- | common/project.cc | 26 | ||||
-rw-r--r-- | common/router1.cc | 10 | ||||
-rw-r--r-- | common/router1.h | 13 | ||||
-rw-r--r-- | common/settings.h | 63 | ||||
-rw-r--r-- | ecp5/arch.cc | 8 | ||||
-rw-r--r-- | generic/arch.cc | 4 | ||||
-rw-r--r-- | gui/basewindow.cc | 2 | ||||
-rw-r--r-- | gui/ice40/mainwindow.cc | 2 | ||||
-rw-r--r-- | ice40/arch.cc | 13 | ||||
-rw-r--r-- | ice40/arch.h | 2 | ||||
-rw-r--r-- | ice40/pcf.cc | 2 | ||||
-rw-r--r-- | ice40/project.cc | 4 | ||||
-rw-r--r-- | json/jsonparse.cc | 2 |
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; |