aboutsummaryrefslogtreecommitdiffstats
path: root/ecp5/main.cc
diff options
context:
space:
mode:
Diffstat (limited to 'ecp5/main.cc')
-rw-r--r--ecp5/main.cc40
1 files changed, 35 insertions, 5 deletions
diff --git a/ecp5/main.cc b/ecp5/main.cc
index 12afb09d..bb18aa58 100644
--- a/ecp5/main.cc
+++ b/ecp5/main.cc
@@ -25,6 +25,7 @@
#include "design_utils.h"
#include "log.h"
#include "timing.h"
+#include "util.h"
USING_NEXTPNR_NAMESPACE
@@ -61,10 +62,14 @@ po::options_description ECP5CommandHandler::getArchOptions()
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)");
- specific.add_options()("basecfg", po::value<std::string>(), "base chip configuration in Trellis text format");
+ specific.add_options()("basecfg", po::value<std::string>(),
+ "base chip configuration in Trellis text format (deprecated)");
+ specific.add_options()("override-basecfg", po::value<std::string>(),
+ "base chip configuration in Trellis text format");
specific.add_options()("textcfg", po::value<std::string>(), "textual configuration in Trellis format to write");
specific.add_options()("lpf", po::value<std::vector<std::string>>(), "LPF pin constraint file(s)");
+ specific.add_options()("lpf-allow-unconstrained", "don't require LPF file(s) to constrain all IO");
return specific;
}
@@ -77,8 +82,14 @@ void ECP5CommandHandler::validate()
void ECP5CommandHandler::customBitstream(Context *ctx)
{
std::string basecfg;
- if (vm.count("basecfg"))
+ if (vm.count("basecfg")) {
+ log_warning("--basecfg is deprecated.\nIf you are using a default baseconfig (from prjtrellis/misc/basecfgs), "
+ "these are now embedded in nextpnr - please remove --basecfg.\nIf you are using a non-standard "
+ "baseconfig in a special application, switch to using --override-basecfg.\n");
basecfg = vm["basecfg"].as<std::string>();
+ } else if (vm.count("override-basecfg")) {
+ basecfg = vm["basecfg"].as<std::string>();
+ }
std::string textcfg;
if (vm.count("textcfg"))
@@ -138,8 +149,8 @@ std::unique_ptr<Context> ECP5CommandHandler::createContext()
chipArgs.speed = ArchArgs::SPEED_6;
}
}
-
- return std::unique_ptr<Context>(new Context(chipArgs));
+ auto ctx = std::unique_ptr<Context>(new Context(chipArgs));
+ return ctx;
}
void ECP5CommandHandler::customAfterLoad(Context *ctx)
@@ -148,7 +159,26 @@ void ECP5CommandHandler::customAfterLoad(Context *ctx)
std::vector<std::string> files = vm["lpf"].as<std::vector<std::string>>();
for (const auto &filename : files) {
std::ifstream in(filename);
- ctx->applyLPF(filename, in);
+ if (!in)
+ log_error("failed to open LPF file '%s'\n", filename.c_str());
+ if (!ctx->applyLPF(filename, in))
+ log_error("failed to parse LPF file '%s'\n", filename.c_str());
+ }
+
+ 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("LOC"))) {
+ if (vm.count("lpf-allow-unconstrained"))
+ log_warning("IO '%s' is unconstrained in LPF and will be automatically placed\n",
+ cell.first.c_str(ctx));
+ else
+ log_error("IO '%s' is unconstrained in LPF (override this error with "
+ "--lpf-allow-unconstrained)\n",
+ cell.first.c_str(ctx));
+ }
+ }
}
}
}