diff options
| -rw-r--r-- | common/bits.cc | 51 | ||||
| -rw-r--r-- | common/bits.h | 73 | ||||
| -rw-r--r-- | common/command.cc | 28 | ||||
| -rw-r--r-- | common/placer_heap.cc | 8 | ||||
| m--------- | tests | 0 | 
5 files changed, 156 insertions, 4 deletions
| diff --git a/common/bits.cc b/common/bits.cc new file mode 100644 index 00000000..1fe65544 --- /dev/null +++ b/common/bits.cc @@ -0,0 +1,51 @@ +/* + *  nextpnr -- Next Generation Place and Route + * + *  Copyright (c) 2013  Mike Pedersen + *  Copyright (C) 2021  Symbiflow Authors + * + *  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. + * + */ + +#include "bits.h" +#include <limits> +#include <stdexcept> + +namespace nextpnr { + +int Bits::generic_popcount(unsigned int v) { +    unsigned int c; // c accumulates the total bits set in v +    for (c = 0; v; c++) { +        v &= v - 1; // clear the least significant bit set +    } + +    return c; +} + +int Bits::generic_ctz(unsigned int x) { +    if(x == 0) { +        throw std::runtime_error("Cannot call ctz with arg = 0"); +    } + +    for(size_t i = 0; i < std::numeric_limits<unsigned int>::digits; ++i) { +        if((x & (1 << i)) != 0) { +            return i; +        } +    } + +    // Unreachable! +    throw std::runtime_error("Unreachable!"); +} + +}; diff --git a/common/bits.h b/common/bits.h new file mode 100644 index 00000000..1abf6735 --- /dev/null +++ b/common/bits.h @@ -0,0 +1,73 @@ +/* + *  nextpnr -- Next Generation Place and Route + * + *  Copyright (c) 2013  Mike Pedersen + *  Copyright (C) 2021  Symbiflow Authors + * + *  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. + * + */ + +// This is a small library for implementing common bit vector utilities, +// namely: +// +//  - popcount : The number of bits set in an unsigned int +//  - ctz : The number of trailing zero bits in an unsigned int. +//          Must be called with a value that has at least 1 bit set. +// +// These methods will typically use instrinics when available, and have a +// generic fallback in the event that the instrinic is not available. +// +// If clz (count leading zeros) is needed, it can be added when needed. +#ifndef BITS_H +#define BITS_H + +#if defined(_MSC_VER) && (defined(_M_X64) || defined(_M_IX86)) +#include <intrin.h> +#pragma intrinsic(_BitScanForward,_BitScanReverse,__popcnt) +#endif + +// Uses plain nextpnr namespace to avoid header inclusion nightmare that is +// "nextpnr.h". +namespace nextpnr { + +struct Bits { +    static int generic_popcount(unsigned int x); +    static int generic_ctz(unsigned int x); + +    static int popcount(unsigned int x) { +#if defined(__GNUC__) || defined(__clang__) +        return __builtin_popcount(x); +#elif defined(_MSC_VER) && (defined(_M_X64) || defined(_M_IX86)) +        return __popcnt(v); +#else +        return generic_popcount(x); +#endif +    } + +    static int ctz(unsigned int x) { +#if defined(__GNUC__) || defined(__clang__) +        return __builtin_ctz(x); +#elif defined(_MSC_VER) && (defined(_M_X64) || defined(_M_IX86)) +        unsigned long result; +        _BitScanForward(&result, v); +        return result; +#else +        return generic_ctz(x); +#endif +    } +}; + +}; + +#endif /* BITS_H */ diff --git a/common/command.cc b/common/command.cc index d3e8af8d..2303ad91 100644 --- a/common/command.cc +++ b/common/command.cc @@ -161,6 +161,11 @@ po::options_description CommandHandler::getGeneralOptions()      general.add_options()("no-print-critical-path-source",                            "disable printing of the line numbers associated with each net in the critical path"); +    general.add_options()("placer-heap-alpha", po::value<float>(), "placer heap alpha value (float, default: 0.1)"); +    general.add_options()("placer-heap-beta", po::value<float>(), "placer heap beta value (float, default: 0.9)"); +    general.add_options()("placer-heap-critexp", po::value<int>(), "placer heap criticality exponent (int, default: 2)"); +    general.add_options()("placer-heap-timingweight", po::value<int>(), "placer heap timing weight (int, default: 10)"); +      general.add_options()("placed-svg", po::value<std::string>(), "write render of placement to SVG file");      general.add_options()("routed-svg", po::value<std::string>(), "write render of routing to SVG file"); @@ -258,6 +263,18 @@ void CommandHandler::setupContext(Context *ctx)      if (vm.count("no-tmdriv"))          ctx->settings[ctx->id("timing_driven")] = false; +    if (vm.count("placer-heap-alpha")) +        ctx->settings[ctx->id("placerHeap/alpha")] = std::to_string(vm["placer-heap-alpha"].as<float>()); + +    if (vm.count("placer-heap-beta")) +        ctx->settings[ctx->id("placerHeap/beta")] = std::to_string(vm["placer-heap-beta"].as<float>()); + +    if (vm.count("placer-heap-critexp")) +        ctx->settings[ctx->id("placerHeap/criticalityExponent")] = std::to_string(vm["placer-heap-critexp"].as<int>()); + +    if (vm.count("placer-heap-timingweight")) +        ctx->settings[ctx->id("placerHeap/timingWeight")] = std::to_string(vm["placer-heap-timingweight"].as<int>()); +      // Setting default values      if (ctx->settings.find(ctx->id("target_freq")) == ctx->settings.end())          ctx->settings[ctx->id("target_freq")] = std::to_string(12e6); @@ -275,6 +292,15 @@ void CommandHandler::setupContext(Context *ctx)      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));      ctx->settings[ctx->id("seed")] = ctx->rngstate; + +    if (ctx->settings.find(ctx->id("placerHeap/alpha")) == ctx->settings.end()) +        ctx->settings[ctx->id("placerHeap/alpha")] = std::to_string(0.1); +    if (ctx->settings.find(ctx->id("placerHeap/beta")) == ctx->settings.end()) +        ctx->settings[ctx->id("placerHeap/beta")] = std::to_string(0.9); +    if (ctx->settings.find(ctx->id("placerHeap/criticalityExponent")) == ctx->settings.end()) +        ctx->settings[ctx->id("placerHeap/criticalityExponent")] = std::to_string(2); +    if (ctx->settings.find(ctx->id("placerHeap/timingWeight")) == ctx->settings.end()) +        ctx->settings[ctx->id("placerHeap/timingWeight")] = std::to_string(10);  }  int CommandHandler::executeMain(std::unique_ptr<Context> ctx) @@ -421,6 +447,8 @@ int CommandHandler::exec()          setupArchContext(ctx.get());          int rc = executeMain(std::move(ctx));          printFooter(); +        log_break(); +        log_info("Program finished normally.\n");          return rc;      } catch (log_execution_error_exception) {          printFooter(); diff --git a/common/placer_heap.cc b/common/placer_heap.cc index 7d529401..92caaf09 100644 --- a/common/placer_heap.cc +++ b/common/placer_heap.cc @@ -1764,10 +1764,10 @@ bool placer_heap(Context *ctx, PlacerHeapCfg cfg) { return HeAPPlacer(ctx, cfg).  PlacerHeapCfg::PlacerHeapCfg(Context *ctx)  { -    alpha = ctx->setting<float>("placerHeap/alpha", 0.1); -    beta = ctx->setting<float>("placerHeap/beta", 0.9); -    criticalityExponent = ctx->setting<int>("placerHeap/criticalityExponent", 2); -    timingWeight = ctx->setting<int>("placerHeap/timingWeight", 10); +    alpha = ctx->setting<float>("placerHeap/alpha"); +    beta = ctx->setting<float>("placerHeap/beta"); +    criticalityExponent = ctx->setting<int>("placerHeap/criticalityExponent"); +    timingWeight = ctx->setting<int>("placerHeap/timingWeight");      timing_driven = ctx->setting<bool>("timing_driven");      solverTolerance = 1e-5;      placeAllAtOnce = false; diff --git a/tests b/tests -Subproject 2aa02a28d4078c616d96400973d3b5e4cf1e454 +Subproject 0162fd062f58600c46919356fc7aac21339fcf8 | 
