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);