aboutsummaryrefslogtreecommitdiffstats
path: root/ice40
diff options
context:
space:
mode:
authorDavid Shah <dave@ds0.me>2018-12-26 16:00:19 +0000
committerDavid Shah <dave@ds0.me>2018-12-26 16:00:19 +0000
commit4444a39fd481cafebb527850e9c7fff38d846154 (patch)
treeb0d753a11046832d3940bae27d43c91d4216f4fc /ice40
parente76479f379e4ba15b8f788cfb171c0de10feb076 (diff)
downloadnextpnr-4444a39fd481cafebb527850e9c7fff38d846154.tar.gz
nextpnr-4444a39fd481cafebb527850e9c7fff38d846154.tar.bz2
nextpnr-4444a39fd481cafebb527850e9c7fff38d846154.zip
ice40: Improve handling of unconstrained IO
Signed-off-by: David Shah <dave@ds0.me>
Diffstat (limited to 'ice40')
-rw-r--r--ice40/main.cc7
-rw-r--r--ice40/pack.cc3
-rw-r--r--ice40/pcf.cc16
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<Context> 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 <sstream>
#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) {