diff options
author | David Shah <dave@ds0.me> | 2019-02-25 11:56:10 +0000 |
---|---|---|
committer | David Shah <dave@ds0.me> | 2019-03-22 10:31:54 +0000 |
commit | 7142db28a8b828da557729a706c20c8f330ba129 (patch) | |
tree | ad9898be5e31227bcfeabde06b4c24c5455d143b /ecp5 | |
parent | 1c824709e21b18073bfdc182793351e40269c373 (diff) | |
download | nextpnr-7142db28a8b828da557729a706c20c8f330ba129.tar.gz nextpnr-7142db28a8b828da557729a706c20c8f330ba129.tar.bz2 nextpnr-7142db28a8b828da557729a706c20c8f330ba129.zip |
HeAP: Make HeAP placer optional
A CMake option 'BUILD_HEAP' (default on) configures building of the
HeAP placer and the associated Eigen3 dependency.
Default for the iCE40 is SA placer, with --heap-placer to use HeAP
Default for the ECP5 is HeAP placer, as SA placer can take 1hr+ for
large ECP5 designs and HeAP tends to give better QoR. --sa-placer can
be used to use SA instead, and auto-fallback to SA if HeAP not built.
Signed-off-by: David Shah <dave@ds0.me>
Diffstat (limited to 'ecp5')
-rw-r--r-- | ecp5/arch.cc | 19 | ||||
-rw-r--r-- | ecp5/main.cc | 8 |
2 files changed, 25 insertions, 2 deletions
diff --git a/ecp5/arch.cc b/ecp5/arch.cc index 5ea6a7c3..8385e57b 100644 --- a/ecp5/arch.cc +++ b/ecp5/arch.cc @@ -457,6 +457,7 @@ delay_t Arch::estimateDelay(WireId src, WireId dst) const auto src_loc = est_location(src), dst_loc = est_location(dst); int dx = abs(src_loc.first - dst_loc.first), dy = abs(src_loc.second - dst_loc.second); + return (130 - 25 * args.speed) * (6 + std::max(dx - 5, 0) + std::max(dy - 5, 0) + 2 * (std::min(dx, 5) + std::min(dy, 5))); @@ -486,6 +487,7 @@ delay_t Arch::predictDelay(const NetInfo *net_info, const PortRef &sink) const } int dx = abs(driver_loc.x - sink_loc.x), dy = abs(driver_loc.y - sink_loc.y); + return (130 - 25 * args.speed) * (6 + std::max(dx - 5, 0) + std::max(dy - 5, 0) + 2 * (std::min(dx, 5) + std::min(dy, 5))); } @@ -505,7 +507,22 @@ bool Arch::getBudgetOverride(const NetInfo *net_info, const PortRef &sink, delay // ----------------------------------------------------------------------- -bool Arch::place() { return placer_heap(getCtx()); } +bool Arch::place() +{ + // HeAP is the default unless overriden or not built +#ifdef WITH_HEAP + if (bool_or_default(settings, id("sa_placer"), false)) { +#endif + if (!placer1(getCtx(), Placer1Cfg(getCtx()))) + return false; +#ifdef WITH_HEAP + } else { + if (!placer_heap(getCtx())) + return false; + } +#endif + return true; +} bool Arch::route() { diff --git a/ecp5/main.cc b/ecp5/main.cc index 15027a5a..de279e63 100644 --- a/ecp5/main.cc +++ b/ecp5/main.cc @@ -59,6 +59,8 @@ po::options_description ECP5CommandHandler::getArchOptions() specific.add_options()("um5g-45k", "set device type to LFE5UM5G-45F"); specific.add_options()("um5g-85k", "set device type to LFE5UM5G-85F"); + specific.add_options()("sa-placer", "use pure simulated annealing placer instead of HeAP analytic placer"); + specific.add_options()("package", po::value<std::string>(), "select device package (defaults to CABGA381)"); specific.add_options()("speed", po::value<int>(), "select device speedgrade (6, 7 or 8)"); @@ -149,8 +151,12 @@ std::unique_ptr<Context> ECP5CommandHandler::createContext() chipArgs.speed = ArchArgs::SPEED_6; } } + auto ctx = std::unique_ptr<Context>(new Context(chipArgs)); + + if (vm.count("sa-placer")) + ctx->settings[ctx->id("sa_placer")] = "1"; - return std::unique_ptr<Context>(new Context(chipArgs)); + return ctx; } void ECP5CommandHandler::customAfterLoad(Context *ctx) |