From 7123209324c93297efab6c2b2fc92286196be3fb Mon Sep 17 00:00:00 2001 From: David Shah Date: Mon, 3 Feb 2020 11:54:38 +0000 Subject: [PATCH] Allow selection of router algorithm Signed-off-by: David Shah --- common/command.cc | 17 +++++++++++++++++ docs/archapi.md | 12 +++++++++++- ecp5/arch.cc | 18 ++++++++++++++++-- ecp5/arch.h | 2 ++ generic/arch.cc | 18 ++++++++++++++++-- generic/arch.h | 2 ++ ice40/arch.cc | 17 +++++++++++++++-- ice40/arch.h | 2 ++ 8 files changed, 81 insertions(+), 7 deletions(-) diff --git a/common/command.cc b/common/command.cc index 3866caca..f652ce67 100644 --- a/common/command.cc +++ b/common/command.cc @@ -132,6 +132,12 @@ po::options_description CommandHandler::getGeneralOptions() "; default: " + Arch::defaultPlacer) .c_str()); + general.add_options()( + "router", po::value(), + std::string("router algorithm to use; available: " + boost::algorithm::join(Arch::availableRouters, ", ") + + "; default: " + Arch::defaultPlacer) + .c_str()); + general.add_options()("slack_redist_iter", po::value(), "number of iterations between slack redistribution"); general.add_options()("cstrweight", po::value(), "placer weighting for relative constraint satisfaction"); general.add_options()("starttemp", po::value(), "placer SA start temperature"); @@ -214,6 +220,15 @@ void CommandHandler::setupContext(Context *ctx) ctx->settings[ctx->id("placer")] = placer; } + if (vm.count("router")) { + std::string router = vm["router"].as(); + if (std::find(Arch::availableRouters.begin(), Arch::availableRouters.end(), router) == + Arch::availableRouters.end()) + log_error("Router algorithm '%s' is not supported (available options: %s)\n", router.c_str(), + boost::algorithm::join(Arch::availableRouters, ", ").c_str()); + ctx->settings[ctx->id("router")] = router; + } + if (vm.count("cstrweight")) { ctx->settings[ctx->id("placer1/constraintWeight")] = std::to_string(vm["cstrweight"].as()); } @@ -244,6 +259,8 @@ void CommandHandler::setupContext(Context *ctx) ctx->settings[ctx->id("auto_freq")] = false; if (ctx->settings.find(ctx->id("placer")) == ctx->settings.end()) ctx->settings[ctx->id("placer")] = Arch::defaultPlacer; + if (ctx->settings.find(ctx->id("router")) == ctx->settings.end()) + ctx->settings[ctx->id("router")] = Arch::defaultRouter; 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)); diff --git a/docs/archapi.md b/docs/archapi.md index c4020fa8..5e7562d3 100644 --- a/docs/archapi.md +++ b/docs/archapi.md @@ -507,4 +507,14 @@ Name of the default placement algorithm for the architecture, if ### static const std::vector\ availablePlacers Name of available placer algorithms for the architecture, used -to provide help for and validate `--placer`. \ No newline at end of file +to provide help for and validate `--placer`. + +### static const std::string defaultRouter + +Name of the default router algorithm for the architecture, if +`--router` isn't specified on the command line. + +### static const std::vector\ availableRouters + +Name of available router algorithms for the architecture, used +to provide help for and validate `--router`. \ No newline at end of file diff --git a/ecp5/arch.cc b/ecp5/arch.cc index 52cfc187..b8abec64 100644 --- a/ecp5/arch.cc +++ b/ecp5/arch.cc @@ -621,12 +621,23 @@ bool Arch::place() bool Arch::route() { + std::string router = str_or_default(settings, id("router"), defaultRouter); + setupWireLocations(); route_ecp5_globals(getCtx()); assignArchInfo(); assign_budget(getCtx(), true); - router2(getCtx(), Router2Cfg(getCtx())); - bool result = router1(getCtx(), Router1Cfg(getCtx())); + + bool result; + if (router == "router1") { + result = router1(getCtx(), Router1Cfg(getCtx())); + } else if (router == "router2") { + router2(getCtx(), Router2Cfg(getCtx())); + result = router1(getCtx(), Router1Cfg(getCtx())); + } else { + log_error("ECP5 architecture does not support router '%s'\n", router.c_str()); + } + #if 0 std::vector> fanout_vector; std::copy(wire_fanout.begin(), wire_fanout.end(), std::back_inserter(fanout_vector)); @@ -1173,6 +1184,9 @@ const std::vector Arch::availablePlacers = {"sa", #endif }; +const std::string Arch::defaultRouter = "router1"; +const std::vector Arch::availableRouters = {"router1", "router2"}; + // ----------------------------------------------------------------------- GroupId Arch::getGroupByName(IdString name) const diff --git a/ecp5/arch.h b/ecp5/arch.h index 24997768..55494b1f 100644 --- a/ecp5/arch.h +++ b/ecp5/arch.h @@ -1066,6 +1066,8 @@ struct Arch : BaseCtx static const std::string defaultPlacer; static const std::vector availablePlacers; + static const std::string defaultRouter; + static const std::vector availableRouters; }; NEXTPNR_NAMESPACE_END diff --git a/generic/arch.cc b/generic/arch.cc index c1c01d26..e4227c74 100644 --- a/generic/arch.cc +++ b/generic/arch.cc @@ -23,6 +23,7 @@ #include "placer1.h" #include "placer_heap.h" #include "router1.h" +#include "router2.h" #include "util.h" NEXTPNR_NAMESPACE_BEGIN @@ -553,10 +554,19 @@ bool Arch::place() bool Arch::route() { - bool retVal = router1(getCtx(), Router1Cfg(getCtx())); + std::string router = str_or_default(settings, id("router"), defaultRouter); + bool result; + if (router == "router1") { + result = router1(getCtx(), Router1Cfg(getCtx())); + } else if (router == "router2") { + router2(getCtx(), Router2Cfg(getCtx())); + result = router1(getCtx(), Router1Cfg(getCtx())); + } else { + log_error("iCE40 architecture does not support router '%s'\n", router.c_str()); + } getCtx()->settings[getCtx()->id("route")] = 1; archInfoToAttributes(); - return retVal; + return result; } // --------------------------------------------------------------- @@ -653,6 +663,10 @@ const std::vector Arch::availablePlacers = {"sa", "heap" #endif }; + +const std::string Arch::defaultRouter = "router1"; +const std::vector Arch::availableRouters = {"router1", "router2"}; + void Arch::assignArchInfo() { for (auto &cell : getCtx()->cells) { diff --git a/generic/arch.h b/generic/arch.h index 444d2636..21e78e9a 100644 --- a/generic/arch.h +++ b/generic/arch.h @@ -288,6 +288,8 @@ struct Arch : BaseCtx static const std::string defaultPlacer; static const std::vector availablePlacers; + static const std::string defaultRouter; + static const std::vector availableRouters; // --------------------------------------------------------------- // Internal usage diff --git a/ice40/arch.cc b/ice40/arch.cc index 0f8e5969..edc104f0 100644 --- a/ice40/arch.cc +++ b/ice40/arch.cc @@ -28,6 +28,7 @@ #include "placer1.h" #include "placer_heap.h" #include "router1.h" +#include "router2.h" #include "timing_opt.h" #include "util.h" NEXTPNR_NAMESPACE_BEGIN @@ -696,10 +697,19 @@ bool Arch::place() bool Arch::route() { - bool retVal = router1(getCtx(), Router1Cfg(getCtx())); + std::string router = str_or_default(settings, id("router"), defaultRouter); + bool result; + if (router == "router1") { + result = router1(getCtx(), Router1Cfg(getCtx())); + } else if (router == "router2") { + router2(getCtx(), Router2Cfg(getCtx())); + result = router1(getCtx(), Router1Cfg(getCtx())); + } else { + log_error("iCE40 architecture does not support router '%s'\n", router.c_str()); + } getCtx()->settings[getCtx()->id("route")] = 1; archInfoToAttributes(); - return retVal; + return result; } // ----------------------------------------------------------------------- @@ -1257,4 +1267,7 @@ const std::vector Arch::availablePlacers = {"sa", #endif }; +const std::string Arch::defaultRouter = "router1"; +const std::vector Arch::availableRouters = {"router1", "router2"}; + NEXTPNR_NAMESPACE_END diff --git a/ice40/arch.h b/ice40/arch.h index ea29f4f1..a6a3cd70 100644 --- a/ice40/arch.h +++ b/ice40/arch.h @@ -900,6 +900,8 @@ struct Arch : BaseCtx static const std::string defaultPlacer; static const std::vector availablePlacers; + static const std::string defaultRouter; + static const std::vector availableRouters; }; void ice40DelayFuzzerMain(Context *ctx);