aboutsummaryrefslogtreecommitdiffstats
path: root/nexus/pack.cc
diff options
context:
space:
mode:
authorDavid Shah <dave@ds0.me>2020-01-22 15:53:45 +0000
committerDavid Shah <dave@ds0.me>2020-11-30 08:45:27 +0000
commita586bfc290548d3a0f9a89f56743bddff408046c (patch)
treee7cc3511f2a75389939ed806fc1867a0c79b433c /nexus/pack.cc
parent84d542624213ab8639bac31ade79ce27097f4e06 (diff)
downloadnextpnr-a586bfc290548d3a0f9a89f56743bddff408046c.tar.gz
nextpnr-a586bfc290548d3a0f9a89f56743bddff408046c.tar.bz2
nextpnr-a586bfc290548d3a0f9a89f56743bddff408046c.zip
nexus: Support Lattice-style parameters
Signed-off-by: David Shah <dave@ds0.me>
Diffstat (limited to 'nexus/pack.cc')
-rw-r--r--nexus/pack.cc78
1 files changed, 78 insertions, 0 deletions
diff --git a/nexus/pack.cc b/nexus/pack.cc
index 2b88a095..35d67fb0 100644
--- a/nexus/pack.cc
+++ b/nexus/pack.cc
@@ -23,12 +23,78 @@
#include "nextpnr.h"
#include "util.h"
+#include <boost/algorithm/string.hpp>
+
NEXTPNR_NAMESPACE_BEGIN
namespace {
bool is_enabled(CellInfo *ci, IdString prop) { return str_or_default(ci->params, prop, "") == "ENABLED"; }
} // namespace
+// Parse a possibly-Lattice-style (C literal in Verilog string) style parameter
+Property Arch::parse_lattice_param(const CellInfo *ci, IdString prop, int width, int64_t defval) const
+{
+ auto fnd = ci->params.find(prop);
+ if (fnd == ci->params.end())
+ return Property(defval, width);
+ const auto &val = fnd->second;
+ if (val.is_string) {
+ const std::string &s = val.str;
+ Property temp;
+
+ if (boost::starts_with(s, "0b")) {
+ for (int i = int(s.length()) - 1; i >= 2; i--) {
+ char c = s.at(i);
+ if (c != '0' && c != '1' && c != 'x')
+ log_error("Invalid binary digit '%c' in property %s.%s\n", c, nameOf(ci), nameOf(prop));
+ temp.str.push_back(c);
+ }
+ } else if (boost::starts_with(s, "0x")) {
+ for (int i = int(s.length()) - 1; i >= 2; i--) {
+ char c = s.at(i);
+ int nibble;
+ if (c >= '0' && c <= '9')
+ nibble = (c - '0');
+ else if (c >= 'a' && c <= 'f')
+ nibble = (c - 'a');
+ else if (c >= 'A' && c <= 'F')
+ nibble = (c - 'A');
+ else
+ log_error("Invalid hex digit '%c' in property %s.%s\n", c, nameOf(ci), nameOf(prop));
+ for (int j = 0; j < 4; j++)
+ temp.str.push_back(((nibble >> j) & 0x1) ? Property::S1 : Property::S0);
+ }
+ } else {
+ int64_t ival = 0;
+ try {
+ if (boost::starts_with(s, "0d"))
+ ival = std::stoll(s.substr(2));
+ else
+ ival = std::stoll(s);
+ } catch (std::runtime_error &e) {
+ log_error("Invalid decimal value for property %s.%s", nameOf(ci), nameOf(prop));
+ }
+ temp = Property(ival);
+ }
+
+ for (auto b : temp.str.substr(width)) {
+ if (b == Property::S1)
+ log_error("Found value for property %s.%s with width greater than %d\n", nameOf(ci), nameOf(prop),
+ width);
+ }
+ temp.update_intval();
+ return temp.extract(0, width);
+ } else {
+ for (auto b : val.str.substr(width)) {
+ if (b == Property::S1)
+ log_error("Found bitvector value for property %s.%s with width greater than %d - perhaps a string was "
+ "converted to bits?\n",
+ nameOf(ci), nameOf(prop), width);
+ }
+ return val.extract(0, width);
+ }
+}
+
struct NexusPacker
{
Context *ctx;
@@ -45,6 +111,7 @@ struct NexusPacker
std::vector<std::pair<IdString, std::string>> set_attrs;
std::vector<std::pair<IdString, Property>> set_params;
std::vector<std::pair<IdString, Property>> default_params;
+ std::vector<std::tuple<IdString, IdString, int, int64_t>> parse_params;
};
void xform_cell(const std::unordered_map<IdString, XFormRule> &rules, CellInfo *ci)
@@ -96,6 +163,16 @@ struct NexusPacker
if (!ci->params.count(param.first))
ci->params[param.first] = param.second;
+ {
+ IdString old_param, new_param;
+ int width;
+ int64_t def;
+ for (const auto &p : rule.parse_params) {
+ std::tie(old_param, new_param, width, def) = p;
+ ci->params[new_param] = ctx->parse_lattice_param(ci, old_param, width, def);
+ }
+ }
+
for (auto &param : rule.set_params)
ci->params[param.first] = param.second;
}
@@ -130,6 +207,7 @@ struct NexusPacker
std::unordered_map<IdString, XFormRule> lut_rules;
lut_rules[id_LUT4].new_type = id_OXIDE_COMB;
lut_rules[id_LUT4].port_xform[id_Z] = id_F;
+ lut_rules[id_LUT4].parse_params.emplace_back(id_INIT, id_INIT, 16, 0);
generic_xform(lut_rules);
}