From 93a0d2456086b2c0e4a50d6ecc43ab028895bcad Mon Sep 17 00:00:00 2001 From: Miodrag Milanovic Date: Thu, 9 Aug 2018 18:39:10 +0200 Subject: Use settings for placer1 and router1 --- common/command.cc | 3 ++- common/command.h | 2 ++ common/placer1.cc | 9 +++++---- common/placer1.h | 6 ++++-- common/router1.cc | 10 +++++++++- common/router1.h | 13 ++++++++----- common/settings.h | 57 +++++++++++++++++++++++++++++++++++++++++++++++++++++++ ecp5/arch.cc | 8 ++------ generic/arch.cc | 4 ++-- ice40/arch.cc | 13 ++----------- ice40/arch.h | 2 -- 11 files changed, 93 insertions(+), 34 deletions(-) create mode 100644 common/settings.h 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(); + settings->set("placer1/constraintWeight", vm["cstrweight"].as()); } if (vm.count("freq")) { @@ -261,6 +261,7 @@ int CommandHandler::exec() } else { ctx = createContext(); } + settings = std::unique_ptr(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 #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; private: po::options_description options; diff --git a/common/placer1.cc b/common/placer1.cc index 91320240..4171e21b 100644 --- a/common/placer1.cc +++ b/common/placer1.cc @@ -23,6 +23,7 @@ #include "placer1.h" #include +#include #include #include #include @@ -95,14 +96,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); @@ -461,6 +460,8 @@ class SAPlacer Placer1Cfg cfg; }; +Placer1Cfg::Placer1Cfg(Context *ctx) : Settings(ctx) { constraintWeight = get("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/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("router1/maxIterCnt", 200); + cleanupReroute = get("router1/cleanupReroute", true); + fullCleanupReroute = get("router1/fullCleanupReroute", true); + useEstimate = get("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 *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..c7ef2016 --- /dev/null +++ b/common/settings.h @@ -0,0 +1,57 @@ +/* + * nextpnr -- Next Generation Place and Route + * + * Copyright (C) 2018 Miodrag Milanovic + * + * 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 +#include "nextpnr.h" + +NEXTPNR_NAMESPACE_BEGIN + +class Settings +{ + public: + explicit Settings(Context *ctx) : ctx(ctx) {} + + template T get(const char *name, T defaultValue) + { + IdString id = ctx->id(name); + if (ctx->settings.find(id) != ctx->settings.end()) + return boost::lexical_cast(ctx->settings[id]); + ctx->settings.emplace(id, std::to_string(defaultValue)); + return defaultValue; + } + + template void set(const char *name, T value) + { + IdString id = ctx->id(name); + if (ctx->settings.find(id) != ctx->settings.end()) { + ctx->settings[id] = value; + return; + } + ctx->settings.emplace(id, std::to_string(value)); + } + + private: + Context *ctx; +}; + +NEXTPNR_NAMESPACE_END + +#endif // SETTINGS_H diff --git a/ecp5/arch.cc b/ecp5/arch.cc index 4358fdaf..047f5518 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 d306a9ec..b37f53b8 100644 --- a/generic/arch.cc +++ b/generic/arch.cc @@ -425,9 +425,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/ice40/arch.cc b/ice40/arch.cc index 7e2dd7f7..357b3018 100644 --- a/ice40/arch.cc +++ b/ice40/arch.cc @@ -565,18 +565,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 4c093ef9..2f2a0f30 100644 --- a/ice40/arch.h +++ b/ice40/arch.h @@ -832,8 +832,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); -- cgit v1.2.3 From e5006d4f2f767aab5c06d4e95151687a54902ad9 Mon Sep 17 00:00:00 2001 From: Miodrag Milanovic Date: Fri, 10 Aug 2018 19:11:30 +0200 Subject: Save settings and give nicer names to some --- common/project.cc | 10 +++++++++- gui/basewindow.cc | 2 +- gui/ice40/mainwindow.cc | 2 +- ice40/pcf.cc | 2 +- ice40/project.cc | 4 ++-- json/jsonparse.cc | 2 +- 6 files changed, 15 insertions(+), 7 deletions(-) diff --git a/common/project.cc b/common/project.cc index 949f6878..8ee78c4a 100644 --- a/common/project.cc +++ b/common/project.cc @@ -18,6 +18,7 @@ */ #include "project.h" +#include #include #include #include @@ -64,11 +65,18 @@ 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"); 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/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 9e86f93e..d73525bc 100644 --- a/json/jsonparse.cc +++ b/json/jsonparse.cc @@ -754,7 +754,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; -- cgit v1.2.3 From b400cd8d7326ac798c9da76de3c2a11f2d96b6a7 Mon Sep 17 00:00:00 2001 From: Miodrag Milanovic Date: Sat, 11 Aug 2018 13:04:51 +0200 Subject: Read settings and check validity --- common/project.cc | 20 ++++++++++++++++++-- common/settings.h | 14 ++++++++++---- 2 files changed, 28 insertions(+), 6 deletions(-) diff --git a/common/project.cc b/common/project.cc index 8ee78c4a..b0ebe961 100644 --- a/common/project.cc +++ b/common/project.cc @@ -70,8 +70,7 @@ void ProjectHandler::save(Context *ctx, std::string filename) 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) - { + for (auto const &item : ctx->settings) { std::string path = "project.settings."; path += item.first.c_str(ctx); std::replace(path.begin(), path.end(), '/', '.'); @@ -83,6 +82,19 @@ void ProjectHandler::save(Context *ctx, std::string filename) } } +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().c_str()); + } else { + addSettings(ctx, path + key + "/", subtree); + } + } +} + std::unique_ptr ProjectHandler::load(std::string filename) { std::unique_ptr ctx; @@ -118,6 +130,10 @@ std::unique_ptr ProjectHandler::load(std::string filename) if (params.count("seed")) ctx->rngseed(params.get("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/settings.h b/common/settings.h index c7ef2016..8ced6560 100644 --- a/common/settings.h +++ b/common/settings.h @@ -20,6 +20,7 @@ #define SETTINGS_H #include +#include "log.h" #include "nextpnr.h" NEXTPNR_NAMESPACE_BEGIN @@ -31,10 +32,15 @@ class Settings template T get(const char *name, T defaultValue) { - IdString id = ctx->id(name); - if (ctx->settings.find(id) != ctx->settings.end()) - return boost::lexical_cast(ctx->settings[id]); - ctx->settings.emplace(id, std::to_string(defaultValue)); + try { + IdString id = ctx->id(name); + if (ctx->settings.find(id) != ctx->settings.end()) { + return boost::lexical_cast(ctx->settings[id]); + } + ctx->settings.emplace(id, std::to_string(defaultValue)); + } catch (boost::bad_lexical_cast &) { + log_error("Problem reading setting %s, using default value\n", name); + } return defaultValue; } -- cgit v1.2.3 From eaf824ca73241014a280b1bd787d8f83e772dd05 Mon Sep 17 00:00:00 2001 From: Miodrag Milanovic Date: Sun, 12 Aug 2018 10:02:32 +0200 Subject: Use emplace result for get,set of settings --- common/settings.h | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/common/settings.h b/common/settings.h index 8ced6560..e1f1166a 100644 --- a/common/settings.h +++ b/common/settings.h @@ -34,10 +34,11 @@ class Settings { try { IdString id = ctx->id(name); - if (ctx->settings.find(id) != ctx->settings.end()) { - return boost::lexical_cast(ctx->settings[id]); + auto pair = ctx->settings.emplace(id, std::to_string(defaultValue)); + if (!pair.second) { + return boost::lexical_cast(pair.first->second); } - ctx->settings.emplace(id, std::to_string(defaultValue)); + } catch (boost::bad_lexical_cast &) { log_error("Problem reading setting %s, using default value\n", name); } @@ -47,11 +48,10 @@ class Settings template void set(const char *name, T value) { IdString id = ctx->id(name); - if (ctx->settings.find(id) != ctx->settings.end()) { - ctx->settings[id] = value; - return; - } - ctx->settings.emplace(id, std::to_string(value)); + auto pair = ctx->settings.emplace(id, std::to_string(value)); + if (!pair.second) { + ctx->settings[pair.first->first] = value; + } } private: -- cgit v1.2.3