diff options
author | Clifford Wolf <clifford@clifford.at> | 2018-11-09 12:57:14 +0100 |
---|---|---|
committer | Clifford Wolf <clifford@clifford.at> | 2018-11-09 12:57:14 +0100 |
commit | 66dd17664c08aca17b53d2853558121aa9e702e4 (patch) | |
tree | b6bc5dd919e5f525ec7328861b81f616673a1ea6 /ecp5/lpf.cc | |
parent | e91241f10d68fcaaf0a81fa77e9a91666120ccee (diff) | |
parent | 15d9b3d3cc05656e58d01ba2f97ec92b6daaee1c (diff) | |
download | nextpnr-66dd17664c08aca17b53d2853558121aa9e702e4.tar.gz nextpnr-66dd17664c08aca17b53d2853558121aa9e702e4.tar.bz2 nextpnr-66dd17664c08aca17b53d2853558121aa9e702e4.zip |
Merge branch 'master' of github.com:YosysHQ/nextpnr into router_improve
Diffstat (limited to 'ecp5/lpf.cc')
-rw-r--r-- | ecp5/lpf.cc | 106 |
1 files changed, 106 insertions, 0 deletions
diff --git a/ecp5/lpf.cc b/ecp5/lpf.cc new file mode 100644 index 00000000..4bde660e --- /dev/null +++ b/ecp5/lpf.cc @@ -0,0 +1,106 @@ +/* + * nextpnr -- Next Generation Place and Route + * + * Copyright (C) 2018 David Shah <david@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 <sstream> +#include "log.h" + +NEXTPNR_NAMESPACE_BEGIN + +bool Arch::applyLPF(std::string filename, std::istream &in) +{ + auto isempty = [](const std::string &str) { + return std::all_of(str.begin(), str.end(), [](char c) { return isblank(c); }); + }; + auto strip_quotes = [](const std::string &str) { + if (str.at(0) == '"') { + NPNR_ASSERT(str.back() == '"'); + return str.substr(1, str.size() - 2); + } else { + return str; + } + }; + + try { + if (!in) + log_error("failed to open LPF file\n"); + std::string line; + std::string linebuf; + while (std::getline(in, line)) { + size_t cstart = line.find('#'); + if (cstart != std::string::npos) + line = line.substr(0, cstart); + if (isempty(line)) + continue; + linebuf += line; + // Look for a command up to a semicolon + size_t scpos = linebuf.find(';'); + while (scpos != std::string::npos) { + std::string command = linebuf.substr(0, scpos); + // Split command into words + std::stringstream ss(command); + std::vector<std::string> words; + std::string tmp; + while (ss >> tmp) + words.push_back(tmp); + if (words.size() >= 0) { + std::string verb = words.at(0); + if (verb == "BLOCK" || verb == "SYSCONFIG" || verb == "FREQUENCY") { + log_warning(" ignoring unsupported LPF command '%s'\n", command.c_str()); + } else if (verb == "LOCATE") { + NPNR_ASSERT(words.at(1) == "COMP"); + std::string cell = strip_quotes(words.at(2)); + NPNR_ASSERT(words.at(3) == "SITE"); + auto fnd_cell = cells.find(id(cell)); + if (fnd_cell == cells.end()) { + log_warning("unmatched LPF 'LOCATE COMP' '%s'\n", cell.c_str()); + } else { + fnd_cell->second->attrs[id("LOC")] = strip_quotes(words.at(4)); + } + } else if (verb == "IOBUF") { + NPNR_ASSERT(words.at(1) == "PORT"); + std::string cell = strip_quotes(words.at(2)); + auto fnd_cell = cells.find(id(cell)); + if (fnd_cell == cells.end()) { + log_warning("unmatched LPF 'IOBUF PORT' '%s'\n", cell.c_str()); + } else { + for (size_t i = 3; i < words.size(); i++) { + std::string setting = words.at(i); + size_t eqpos = setting.find('='); + NPNR_ASSERT(eqpos != std::string::npos); + std::string key = setting.substr(0, eqpos), value = setting.substr(eqpos + 1); + fnd_cell->second->attrs[id(key)] = value; + } + } + } + } + + linebuf = linebuf.substr(scpos + 1); + scpos = linebuf.find(';'); + } + } + if (!isempty(linebuf)) + log_error("unexpected end of LPF file\n"); + settings.emplace(id("input/lpf"), filename); + return true; + } catch (log_execution_error_exception) { + return false; + } +} + +NEXTPNR_NAMESPACE_END |