aboutsummaryrefslogtreecommitdiffstats
path: root/ecp5
diff options
context:
space:
mode:
Diffstat (limited to 'ecp5')
-rw-r--r--ecp5/arch.cc5
-rw-r--r--ecp5/globals.cc2
-rw-r--r--ecp5/lpf.cc2
-rw-r--r--ecp5/main.cc128
-rw-r--r--ecp5/pack.cc12
-rw-r--r--ecp5/project.cc55
6 files changed, 119 insertions, 85 deletions
diff --git a/ecp5/arch.cc b/ecp5/arch.cc
index 91db8d81..5b3cc660 100644
--- a/ecp5/arch.cc
+++ b/ecp5/arch.cc
@@ -526,12 +526,15 @@ bool Arch::place()
}
permute_luts();
+ getCtx()->settings[getCtx()->id("place")] = "1";
+ archInfoToAttributes();
return true;
}
bool Arch::route()
{
route_ecp5_globals(getCtx());
+ assignArchInfo();
assign_budget(getCtx(), true);
bool result = router1(getCtx(), Router1Cfg(getCtx()));
@@ -560,6 +563,8 @@ bool Arch::route()
log_info(" base %d adder %d\n", speed_grade->pip_classes[locInfo(slowest_pip)->pip_data[slowest_pip.index].timing_class].max_base_delay,
speed_grade->pip_classes[locInfo(slowest_pip)->pip_data[slowest_pip.index].timing_class].max_fanout_adder);
#endif
+ getCtx()->settings[getCtx()->id("route")] = "1";
+ archInfoToAttributes();
return result;
}
diff --git a/ecp5/globals.cc b/ecp5/globals.cc
index fae2c683..026f3a85 100644
--- a/ecp5/globals.cc
+++ b/ecp5/globals.cc
@@ -382,7 +382,7 @@ class Ecp5GlobalRouter
glbnet->name = ctx->id("$glbnet$" + net->name.str(ctx));
glbnet->driver.cell = dcc.get();
glbnet->driver.port = id_CLKO;
- glbnet->is_global = true;
+ glbnet->attrs[ctx->id("ECP5_IS_GLOBAL")] = "1";
dcc->ports[id_CLKO].net = glbnet.get();
std::vector<PortRef> keep_users;
diff --git a/ecp5/lpf.cc b/ecp5/lpf.cc
index 4ac70fc9..ceb1d7ae 100644
--- a/ecp5/lpf.cc
+++ b/ecp5/lpf.cc
@@ -133,7 +133,7 @@ bool Arch::applyLPF(std::string filename, std::istream &in)
}
if (!isempty(linebuf))
log_error("unexpected end of LPF file\n");
- settings.emplace(id("input/lpf"), filename);
+ settings[id("input/lpf")] = filename;
return true;
} catch (log_execution_error_exception) {
return false;
diff --git a/ecp5/main.cc b/ecp5/main.cc
index bb18aa58..75126cea 100644
--- a/ecp5/main.cc
+++ b/ecp5/main.cc
@@ -34,7 +34,7 @@ class ECP5CommandHandler : public CommandHandler
public:
ECP5CommandHandler(int argc, char **argv);
virtual ~ECP5CommandHandler(){};
- std::unique_ptr<Context> createContext() override;
+ std::unique_ptr<Context> createContext(std::unordered_map<std::string, Property> &values) override;
void setupArchContext(Context *ctx) override{};
void customAfterLoad(Context *ctx) override;
void validate() override;
@@ -98,9 +98,25 @@ void ECP5CommandHandler::customBitstream(Context *ctx)
write_bitstream(ctx, basecfg, textcfg);
}
-std::unique_ptr<Context> ECP5CommandHandler::createContext()
+static std::string speedString(ArchArgs::SpeedGrade speed)
{
- chipArgs.type = ArchArgs::LFE5U_45F;
+ switch (speed) {
+ case ArchArgs::SPEED_6:
+ return "6";
+ case ArchArgs::SPEED_7:
+ return "7";
+ case ArchArgs::SPEED_8:
+ return "8";
+ case ArchArgs::SPEED_8_5G:
+ return "8";
+ }
+ return "";
+}
+
+std::unique_ptr<Context> ECP5CommandHandler::createContext(std::unordered_map<std::string, Property> &values)
+{
+ ArchArgs chipArgs;
+ chipArgs.type = ArchArgs::NONE;
if (vm.count("25k"))
chipArgs.type = ArchArgs::LFE5U_25F;
@@ -122,34 +138,96 @@ std::unique_ptr<Context> ECP5CommandHandler::createContext()
chipArgs.type = ArchArgs::LFE5UM5G_85F;
if (vm.count("package"))
chipArgs.package = vm["package"].as<std::string>();
- else
+
+ if (vm.count("speed")) {
+ int speed = vm["speed"].as<int>();
+ switch (speed) {
+ case 6:
+ chipArgs.speed = ArchArgs::SPEED_6;
+ break;
+ case 7:
+ chipArgs.speed = ArchArgs::SPEED_7;
+ break;
+ case 8:
+ chipArgs.speed = ArchArgs::SPEED_8;
+ break;
+ default:
+ log_error("Unsupported speed grade '%d'\n", speed);
+ }
+ } else {
+ if (chipArgs.type == ArchArgs::LFE5UM5G_25F || chipArgs.type == ArchArgs::LFE5UM5G_45F ||
+ chipArgs.type == ArchArgs::LFE5UM5G_85F) {
+ chipArgs.speed = ArchArgs::SPEED_8;
+ } else
+ chipArgs.speed = ArchArgs::SPEED_6;
+ }
+ if (values.find("arch.name") != values.end()) {
+ std::string arch_name = values["arch.name"].str;
+ if (arch_name != "ecp5")
+ log_error("Unsuported architecture '%s'.\n", arch_name.c_str());
+ }
+ if (values.find("arch.type") != values.end()) {
+ std::string arch_type = values["arch.type"].str;
+ if (chipArgs.type != ArchArgs::NONE)
+ log_error("Overriding architecture is unsuported.\n");
+
+ if (arch_type == "lfe5u_25f")
+ chipArgs.type = ArchArgs::LFE5U_25F;
+ if (arch_type == "lfe5u_45f")
+ chipArgs.type = ArchArgs::LFE5U_45F;
+ if (arch_type == "lfe5u_85f")
+ chipArgs.type = ArchArgs::LFE5U_85F;
+ if (arch_type == "lfe5um_25f")
+ chipArgs.type = ArchArgs::LFE5UM_25F;
+ if (arch_type == "lfe5um_45f")
+ chipArgs.type = ArchArgs::LFE5UM_45F;
+ if (arch_type == "lfe5um_85f")
+ chipArgs.type = ArchArgs::LFE5UM_85F;
+ if (arch_type == "lfe5um5g_25f")
+ chipArgs.type = ArchArgs::LFE5UM5G_25F;
+ if (arch_type == "lfe5um5g_45f")
+ chipArgs.type = ArchArgs::LFE5UM5G_45F;
+ if (arch_type == "lfe5um5g_85f")
+ chipArgs.type = ArchArgs::LFE5UM5G_85F;
+
+ if (chipArgs.type == ArchArgs::NONE)
+ log_error("Unsuported FPGA type '%s'.\n", arch_type.c_str());
+ }
+ if (values.find("arch.package") != values.end()) {
+ if (vm.count("package"))
+ log_error("Overriding architecture is unsuported.\n");
+ chipArgs.package = values["arch.package"].str;
+ }
+ if (values.find("arch.speed") != values.end()) {
+ std::string arch_speed = values["arch.speed"].str;
+ if (arch_speed == "6")
+ chipArgs.speed = ArchArgs::SPEED_6;
+ else if (arch_speed == "7")
+ chipArgs.speed = ArchArgs::SPEED_7;
+ else if (arch_speed == "8")
+ chipArgs.speed = ArchArgs::SPEED_8;
+ else
+ log_error("Unsuported speed '%s'.\n", arch_speed.c_str());
+ }
+ if (chipArgs.type == ArchArgs::NONE)
+ chipArgs.type = ArchArgs::LFE5U_45F;
+
+ if (chipArgs.package.empty())
chipArgs.package = "CABGA381";
+
if (chipArgs.type == ArchArgs::LFE5UM5G_25F || chipArgs.type == ArchArgs::LFE5UM5G_45F ||
chipArgs.type == ArchArgs::LFE5UM5G_85F) {
- if (vm.count("speed") && vm["speed"].as<int>() != 8)
+ if (chipArgs.speed != ArchArgs::SPEED_8)
log_error("Only speed grade 8 is available for 5G parts\n");
- chipArgs.speed = ArchArgs::SPEED_8_5G;
- } else {
- if (vm.count("speed")) {
- int speed = vm["speed"].as<int>();
- switch (speed) {
- case 6:
- chipArgs.speed = ArchArgs::SPEED_6;
- break;
- case 7:
- chipArgs.speed = ArchArgs::SPEED_7;
- break;
- case 8:
- chipArgs.speed = ArchArgs::SPEED_8;
- break;
- default:
- log_error("Unsupported speed grade '%d'\n", speed);
- }
- } else {
- chipArgs.speed = ArchArgs::SPEED_6;
- }
+ else
+ chipArgs.speed = ArchArgs::SPEED_8_5G;
}
+
auto ctx = std::unique_ptr<Context>(new Context(chipArgs));
+ for (auto &val : values)
+ ctx->settings[ctx->id(val.first)] = val.second;
+ ctx->settings[ctx->id("arch.package")] = ctx->archArgs().package;
+ ctx->settings[ctx->id("arch.speed")] = speedString(ctx->archArgs().speed);
return ctx;
}
diff --git a/ecp5/pack.cc b/ecp5/pack.cc
index 7f00de1f..9e2bc326 100644
--- a/ecp5/pack.cc
+++ b/ecp5/pack.cc
@@ -1508,7 +1508,8 @@ class Ecp5Packer
std::unique_ptr<NetInfo> promoted_ecknet(new NetInfo);
promoted_ecknet->name = eckname;
- promoted_ecknet->is_global = true; // Prevents router etc touching this special net
+ promoted_ecknet->attrs[ctx->id("ECP5_IS_GLOBAL")] =
+ "1"; // Prevents router etc touching this special net
eclk.buf = promoted_ecknet.get();
NPNR_ASSERT(!ctx->nets.count(eckname));
ctx->nets[eckname] = std::move(promoted_ecknet);
@@ -1654,7 +1655,7 @@ class Ecp5Packer
port.c_str(ctx), ci->name.c_str(ctx), usr.port.c_str(ctx),
usr.cell->name.c_str(ctx));
}
- pn->is_global = true;
+ pn->attrs[ctx->id("ECP5_IS_GLOBAL")] = "1";
}
for (auto zport :
@@ -1896,7 +1897,7 @@ class Ecp5Packer
iol->params[ctx->id("DELAY.DEL_VALUE")] =
std::to_string(lookup_delay(str_or_default(ci->params, ctx->id("DEL_MODE"), "USER_DEFINED")));
if (ci->params.count(ctx->id("DEL_VALUE")) &&
- ci->params.at(ctx->id("DEL_VALUE")).substr(0, 5) != "DELAY")
+ std::string(ci->params.at(ctx->id("DEL_VALUE"))).substr(0, 5) != "DELAY")
iol->params[ctx->id("DELAY.DEL_VALUE")] = ci->params.at(ctx->id("DEL_VALUE"));
if (ci->ports.count(id_LOADN))
replace_port(ci, id_LOADN, iol, id_LOADN);
@@ -2428,6 +2429,8 @@ bool Arch::pack()
Ecp5Packer(ctx).pack();
log_info("Checksum: 0x%08x\n", ctx->checksum());
assignArchInfo();
+ ctx->settings[ctx->id("pack")] = "1";
+ archInfoToAttributes();
return true;
} catch (log_execution_error_exception) {
assignArchInfo();
@@ -2469,6 +2472,9 @@ void Arch::assignArchInfo()
ci->sliceInfo.has_l6mux = true;
}
}
+ for (auto net : sorted(nets)) {
+ net.second->is_global = bool_or_default(net.second->attrs, id("ECP5_IS_GLOBAL"));
+ }
}
NEXTPNR_NAMESPACE_END
diff --git a/ecp5/project.cc b/ecp5/project.cc
deleted file mode 100644
index 43318b1c..00000000
--- a/ecp5/project.cc
+++ /dev/null
@@ -1,55 +0,0 @@
-/*
- * nextpnr -- Next Generation Place and Route
- *
- * Copyright (C) 2018 Miodrag Milanovic <miodrag@symbioticeda.com>
- *
- * 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 "project.h"
-#include <boost/filesystem/convenience.hpp>
-#include <boost/property_tree/json_parser.hpp>
-#include <fstream>
-#include "log.h"
-
-NEXTPNR_NAMESPACE_BEGIN
-
-void ProjectHandler::saveArch(Context *ctx, pt::ptree &root, std::string path)
-{
- root.put("project.arch.package", ctx->archArgs().package);
- root.put("project.arch.speed", ctx->archArgs().speed);
-}
-
-std::unique_ptr<Context> ProjectHandler::createContext(pt::ptree &root)
-{
- ArchArgs chipArgs;
- std::string arch_type = root.get<std::string>("project.arch.type");
- if (arch_type == "25k") {
- chipArgs.type = ArchArgs::LFE5U_25F;
- }
- if (arch_type == "45k") {
- chipArgs.type = ArchArgs::LFE5U_45F;
- }
- if (arch_type == "85k") {
- chipArgs.type = ArchArgs::LFE5U_85F;
- }
- chipArgs.package = root.get<std::string>("project.arch.package");
- chipArgs.speed = ArchArgs::SpeedGrade(root.get<int>("project.arch.speed"));
-
- return std::unique_ptr<Context>(new Context(chipArgs));
-}
-
-void ProjectHandler::loadArch(Context *ctx, pt::ptree &root, std::string path) {}
-
-NEXTPNR_NAMESPACE_END