From 4444a39fd481cafebb527850e9c7fff38d846154 Mon Sep 17 00:00:00 2001 From: David Shah Date: Wed, 26 Dec 2018 16:00:19 +0000 Subject: [PATCH] ice40: Improve handling of unconstrained IO Signed-off-by: David Shah --- ice40/main.cc | 7 +++++++ ice40/pack.cc | 3 --- ice40/pcf.cc | 16 ++++++++++++++++ 3 files changed, 23 insertions(+), 3 deletions(-) diff --git a/ice40/main.cc b/ice40/main.cc index 543bd229..286f68db 100644 --- a/ice40/main.cc +++ b/ice40/main.cc @@ -70,6 +70,8 @@ po::options_description Ice40CommandHandler::getArchOptions() specific.add_options()("no-promote-globals", "disable all global promotion"); specific.add_options()("opt-timing", "run post-placement timing optimisation pass (experimental)"); specific.add_options()("tmfuzz", "run path delay estimate fuzzer"); + specific.add_options()("pcf-allow-unconstrained", "don't require PCF to constrain all IO"); + return specific; } void Ice40CommandHandler::validate() @@ -87,6 +89,8 @@ void Ice40CommandHandler::customAfterLoad(Context *ctx) std::ifstream pcf(filename); if (!apply_pcf(ctx, filename, pcf)) log_error("Loading PCF failed.\n"); + } else { + log_warning("No PCF file specified; IO pins will be placed automatically\n"); } } void Ice40CommandHandler::customBitstream(Context *ctx) @@ -164,6 +168,9 @@ std::unique_ptr Ice40CommandHandler::createContext() ctx->settings[ctx->id("no_promote_globals")] = "1"; if (vm.count("opt-timing")) ctx->settings[ctx->id("opt_timing")] = "1"; + if (vm.count("pcf-allow-unconstrained")) + ctx->settings[ctx->id("pcf_allow_unconstrained")] = "1"; + return ctx; } diff --git a/ice40/pack.cc b/ice40/pack.cc index 536b1b16..27387a75 100644 --- a/ice40/pack.cc +++ b/ice40/pack.cc @@ -478,9 +478,6 @@ static void pack_io(Context *ctx) } packed_cells.insert(ci->name); std::copy(ci->attrs.begin(), ci->attrs.end(), std::inserter(sb->attrs, sb->attrs.begin())); - if (!sb->attrs.count(ctx->id("BEL"))) - log_warning("IO '%s' is not constrained to a pin and will be automatically placed\n", - ci->name.c_str(ctx)); } else if (is_sb_io(ctx, ci) || is_sb_gb_io(ctx, ci)) { NetInfo *net = ci->ports.at(ctx->id("PACKAGE_PIN")).net; if ((net != nullptr) && (net->users.size() > 1)) diff --git a/ice40/pcf.cc b/ice40/pcf.cc index a351b95d..a8273dd6 100644 --- a/ice40/pcf.cc +++ b/ice40/pcf.cc @@ -21,6 +21,7 @@ #include "pcf.h" #include #include "log.h" +#include "util.h" NEXTPNR_NAMESPACE_BEGIN @@ -100,6 +101,21 @@ bool apply_pcf(Context *ctx, std::string filename, std::istream &in) log_error("unsupported PCF command '%s' (on line %d)\n", cmd.c_str(), lineno); } } + for (auto cell : sorted(ctx->cells)) { + CellInfo *ci = cell.second; + if (ci->type == ctx->id("$nextpnr_ibuf") || ci->type == ctx->id("$nextpnr_obuf") || + ci->type == ctx->id("$nextpnr_iobuf")) { + if (!ci->attrs.count(ctx->id("BEL"))) { + if (bool_or_default(ctx->settings, ctx->id("pcf_allow_unconstrained"))) + log_warning("IO '%s' is unconstrained in PCF and will be automatically placed\n", + cell.first.c_str(ctx)); + else + log_error("IO '%s' is unconstrained in PCF (override this error with " + "--pcf-allow-unconstrained)\n", + cell.first.c_str(ctx)); + } + } + } ctx->settings.emplace(ctx->id("input/pcf"), filename); return true; } catch (log_execution_error_exception) {