diff options
Diffstat (limited to 'ice40')
-rw-r--r-- | ice40/arch.cc | 16 | ||||
-rw-r--r-- | ice40/main.cc | 55 | ||||
-rw-r--r-- | ice40/pack.cc | 39 | ||||
-rw-r--r-- | ice40/pcf.cc | 2 | ||||
-rw-r--r-- | ice40/project.cc | 76 |
5 files changed, 90 insertions, 98 deletions
diff --git a/ice40/arch.cc b/ice40/arch.cc index 80e1fb4c..0b1d280c 100644 --- a/ice40/arch.cc +++ b/ice40/arch.cc @@ -683,16 +683,24 @@ bool Arch::place() } else { log_error("iCE40 architecture does not support placer '%s'\n", placer.c_str()); } + bool retVal = true; if (bool_or_default(settings, id("opt_timing"), false)) { TimingOptCfg tocfg(getCtx()); tocfg.cellTypes.insert(id_ICESTORM_LC); - return timing_opt(getCtx(), tocfg); - } else { - return true; + retVal = timing_opt(getCtx(), tocfg); } + getCtx()->settings[getCtx()->id("place")] = "1"; + archInfoToAttributes(); + return retVal; } -bool Arch::route() { return router1(getCtx(), Router1Cfg(getCtx())); } +bool Arch::route() +{ + bool retVal = router1(getCtx(), Router1Cfg(getCtx())); + getCtx()->settings[getCtx()->id("route")] = "1"; + archInfoToAttributes(); + return retVal; +} // ----------------------------------------------------------------------- diff --git a/ice40/main.cc b/ice40/main.cc index 9b79a08c..83cb04b0 100644 --- a/ice40/main.cc +++ b/ice40/main.cc @@ -36,7 +36,7 @@ class Ice40CommandHandler : public CommandHandler public: Ice40CommandHandler(int argc, char **argv); virtual ~Ice40CommandHandler(){}; - 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 validate() override; void customAfterLoad(Context *ctx) override; @@ -116,8 +116,10 @@ void Ice40CommandHandler::setupArchContext(Context *ctx) } } -std::unique_ptr<Context> Ice40CommandHandler::createContext() +std::unique_ptr<Context> Ice40CommandHandler::createContext(std::unordered_map<std::string, Property> &values) { + ArchArgs chipArgs; + chipArgs.type = ArchArgs::NONE; if (vm.count("lp384")) { chipArgs.type = ArchArgs::LP384; chipArgs.package = "qn32"; @@ -153,6 +155,49 @@ std::unique_ptr<Context> Ice40CommandHandler::createContext() chipArgs.package = "sg48"; } + if (vm.count("package")) + chipArgs.package = vm["package"].as<std::string>(); + + if (values.find("arch.name") != values.end()) { + std::string arch_name = values["arch.name"].str; + if (arch_name != "ice40") + 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 == "lp384") { + chipArgs.type = ArchArgs::LP384; + } + if (arch_type == "lp1k") { + chipArgs.type = ArchArgs::LP1K; + } + if (arch_type == "lp8k") { + chipArgs.type = ArchArgs::LP8K; + } + if (arch_type == "hx1k") { + chipArgs.type = ArchArgs::HX1K; + } + if (arch_type == "hx8k") { + chipArgs.type = ArchArgs::HX8K; + } + if (arch_type == "up5k") { + chipArgs.type = ArchArgs::UP5K; + } + if (arch_type == "u4k") { + chipArgs.type = ArchArgs::U4K; + } + 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 (chipArgs.type == ArchArgs::NONE) { chipArgs.type = ArchArgs::HX1K; chipArgs.package = "tq144"; @@ -163,11 +208,11 @@ std::unique_ptr<Context> Ice40CommandHandler::createContext() } #endif - if (vm.count("package")) - chipArgs.package = vm["package"].as<std::string>(); - 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; if (vm.count("promote-logic")) ctx->settings[ctx->id("promote_logic")] = "1"; if (vm.count("no-promote-globals")) diff --git a/ice40/pack.cc b/ice40/pack.cc index f520b295..d1366c9c 100644 --- a/ice40/pack.cc +++ b/ice40/pack.cc @@ -341,6 +341,11 @@ static void pack_constants(Context *ctx) gnd_net->driver.port = ctx->id("O"); gnd_cell->ports.at(ctx->id("O")).net = gnd_net.get(); + NetInfo *gnd_net_info = gnd_net.get(); + if (ctx->nets.find(ctx->id("$PACKER_GND_NET")) != ctx->nets.end()) { + gnd_net_info = ctx->nets.find(ctx->id("$PACKER_GND_NET"))->second.get(); + } + std::unique_ptr<CellInfo> vcc_cell = create_ice_cell(ctx, ctx->id("ICESTORM_LC"), "$PACKER_VCC"); vcc_cell->params[ctx->id("LUT_INIT")] = "1"; std::unique_ptr<NetInfo> vcc_net = std::unique_ptr<NetInfo>(new NetInfo); @@ -349,6 +354,11 @@ static void pack_constants(Context *ctx) vcc_net->driver.port = ctx->id("O"); vcc_cell->ports.at(ctx->id("O")).net = vcc_net.get(); + NetInfo *vcc_net_info = vcc_net.get(); + if (ctx->nets.find(ctx->id("$PACKER_VCC_NET")) != ctx->nets.end()) { + vcc_net_info = ctx->nets.find(ctx->id("$PACKER_VCC_NET"))->second.get(); + } + std::vector<IdString> dead_nets; bool gnd_used = false; @@ -357,26 +367,28 @@ static void pack_constants(Context *ctx) NetInfo *ni = net.second; if (ni->driver.cell != nullptr && ni->driver.cell->type == ctx->id("GND")) { IdString drv_cell = ni->driver.cell->name; - set_net_constant(ctx, ni, gnd_net.get(), false); + set_net_constant(ctx, ni, gnd_net_info, false); gnd_used = true; dead_nets.push_back(net.first); ctx->cells.erase(drv_cell); } else if (ni->driver.cell != nullptr && ni->driver.cell->type == ctx->id("VCC")) { IdString drv_cell = ni->driver.cell->name; - set_net_constant(ctx, ni, vcc_net.get(), true); + set_net_constant(ctx, ni, vcc_net_info, true); dead_nets.push_back(net.first); ctx->cells.erase(drv_cell); } } - if (gnd_used) { + if (gnd_used && (gnd_net_info == gnd_net.get())) { ctx->cells[gnd_cell->name] = std::move(gnd_cell); ctx->nets[gnd_net->name] = std::move(gnd_net); } // Vcc cell always inserted for now, as it may be needed during carry legalisation (TODO: trim later if actually // never used?) - ctx->cells[vcc_cell->name] = std::move(vcc_cell); - ctx->nets[vcc_net->name] = std::move(vcc_net); + if (vcc_net_info == vcc_net.get()) { + ctx->cells[vcc_cell->name] = std::move(vcc_cell); + ctx->nets[vcc_net->name] = std::move(vcc_net); + } for (auto dn : dead_nets) { ctx->nets.erase(dn); @@ -1224,13 +1236,14 @@ static void pack_special(Context *ctx) } auto feedback_path = packed->params[ctx->id("FEEDBACK_PATH")]; - std::string fbp_value = feedback_path == "DELAY" - ? "0" - : feedback_path == "SIMPLE" - ? "1" - : feedback_path == "PHASE_AND_DELAY" - ? "2" - : feedback_path == "EXTERNAL" ? "6" : feedback_path; + std::string fbp_value = + feedback_path == "DELAY" + ? "0" + : feedback_path == "SIMPLE" + ? "1" + : feedback_path == "PHASE_AND_DELAY" + ? "2" + : feedback_path == "EXTERNAL" ? "6" : std::string(feedback_path); if (!std::all_of(fbp_value.begin(), fbp_value.end(), isdigit)) log_error("PLL '%s' has unsupported FEEDBACK_PATH value '%s'\n", ci->name.c_str(ctx), feedback_path.c_str()); @@ -1435,6 +1448,8 @@ bool Arch::pack() ctx->assignArchInfo(); constrain_chains(ctx); ctx->assignArchInfo(); + ctx->settings[ctx->id("pack")] = "1"; + archInfoToAttributes(); log_info("Checksum: 0x%08x\n", ctx->checksum()); return true; } catch (log_execution_error_exception) { diff --git a/ice40/pcf.cc b/ice40/pcf.cc index 15132800..a854a780 100644 --- a/ice40/pcf.cc +++ b/ice40/pcf.cc @@ -119,7 +119,7 @@ bool apply_pcf(Context *ctx, std::string filename, std::istream &in) } } } - ctx->settings.emplace(ctx->id("input/pcf"), filename); + ctx->settings[ctx->id("input/pcf")] = filename; return true; } catch (log_execution_error_exception) { return false; diff --git a/ice40/project.cc b/ice40/project.cc deleted file mode 100644 index bbd82fd7..00000000 --- a/ice40/project.cc +++ /dev/null @@ -1,76 +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 <fstream> -#include "log.h" -#include "pcf.h" - -NEXTPNR_NAMESPACE_BEGIN - -void ProjectHandler::saveArch(Context *ctx, pt::ptree &root, std::string path) -{ - root.put("project.arch.package", ctx->archArgs().package); - if (ctx->settings.find(ctx->id("input/pcf")) != ctx->settings.end()) { - std::string fn = ctx->settings[ctx->id("input/pcf")]; - root.put("project.input.pcf", make_relative(fn, path).string()); - } -} - -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 == "lp384") { - chipArgs.type = ArchArgs::LP384; - } - if (arch_type == "lp1k") { - chipArgs.type = ArchArgs::LP1K; - } - if (arch_type == "lp8k") { - chipArgs.type = ArchArgs::LP8K; - } - if (arch_type == "hx1k") { - chipArgs.type = ArchArgs::HX1K; - } - if (arch_type == "hx8k") { - chipArgs.type = ArchArgs::HX8K; - } - if (arch_type == "up5k") { - chipArgs.type = ArchArgs::UP5K; - } - if (arch_type == "u4k") { - chipArgs.type = ArchArgs::U4K; - } - chipArgs.package = root.get<std::string>("project.arch.package"); - - return std::unique_ptr<Context>(new Context(chipArgs)); -} - -void ProjectHandler::loadArch(Context *ctx, pt::ptree &root, std::string path) -{ - auto input = root.get_child("project").get_child("input"); - boost::filesystem::path pcf = boost::filesystem::path(path) / input.get<std::string>("pcf"); - std::ifstream f(pcf.string()); - if (!apply_pcf(ctx, input.get<std::string>("pcf"), f)) - log_error("Loading PCF failed.\n"); -} - -NEXTPNR_NAMESPACE_END |