aboutsummaryrefslogtreecommitdiffstats
path: root/common
diff options
context:
space:
mode:
authorMiodrag Milanović <mmicko@gmail.com>2020-11-30 10:56:59 +0100
committerGitHub <noreply@github.com>2020-11-30 10:56:59 +0100
commit8b5c0dc1e49b692b0bb598a90034c27db653622d (patch)
treeafd13c654df1faa0b5df9f11be74eede087fa564 /common
parent1afa494e69e3c8af3dd5d1685b9cd2b1d3bea4d0 (diff)
parent2fe8bebc6ce464afadef2403a8331031e16c5a5d (diff)
downloadnextpnr-8b5c0dc1e49b692b0bb598a90034c27db653622d.tar.gz
nextpnr-8b5c0dc1e49b692b0bb598a90034c27db653622d.tar.bz2
nextpnr-8b5c0dc1e49b692b0bb598a90034c27db653622d.zip
Merge pull request #524 from daveshah1/nextpnr-nexus
Upstreaming basic support for Nexus devices
Diffstat (limited to 'common')
-rw-r--r--common/arch_pybindings_shared.h5
-rw-r--r--common/design_utils.cc36
-rw-r--r--common/design_utils.h18
-rw-r--r--common/nextpnr.cc4
-rw-r--r--common/router1.cc14
-rw-r--r--common/router2.cc5
-rw-r--r--common/util.h18
7 files changed, 92 insertions, 8 deletions
diff --git a/common/arch_pybindings_shared.h b/common/arch_pybindings_shared.h
index 3f7efcc1..8bb93a80 100644
--- a/common/arch_pybindings_shared.h
+++ b/common/arch_pybindings_shared.h
@@ -103,11 +103,6 @@ fn_wrapper_1a<Context, decltype(&Context::getPipDstWire), &Context::getPipDstWir
fn_wrapper_1a<Context, decltype(&Context::getPipDelay), &Context::getPipDelay, pass_through<DelayInfo>,
conv_from_str<PipId>>::def_wrap(ctx_cls, "getPipDelay");
-fn_wrapper_1a<Context, decltype(&Context::getPackagePinBel), &Context::getPackagePinBel, conv_to_str<BelId>,
- pass_through<std::string>>::def_wrap(ctx_cls, "getPackagePinBel");
-fn_wrapper_1a<Context, decltype(&Context::getBelPackagePin), &Context::getBelPackagePin, pass_through<std::string>,
- conv_from_str<BelId>>::def_wrap(ctx_cls, "getBelPackagePin");
-
fn_wrapper_0a<Context, decltype(&Context::getChipName), &Context::getChipName, pass_through<std::string>>::def_wrap(
ctx_cls, "getChipName");
fn_wrapper_0a<Context, decltype(&Context::archId), &Context::archId, conv_to_str<IdString>>::def_wrap(ctx_cls,
diff --git a/common/design_utils.cc b/common/design_utils.cc
index dd866758..16cc2710 100644
--- a/common/design_utils.cc
+++ b/common/design_utils.cc
@@ -30,6 +30,13 @@ void replace_port(CellInfo *old_cell, IdString old_name, CellInfo *rep_cell, IdS
if (!old_cell->ports.count(old_name))
return;
PortInfo &old = old_cell->ports.at(old_name);
+
+ // Create port on the replacement cell if it doesn't already exist
+ if (!rep_cell->ports.count(rep_name)) {
+ rep_cell->ports[rep_name].name = rep_name;
+ rep_cell->ports[rep_name].type = old.type;
+ }
+
PortInfo &rep = rep_cell->ports.at(rep_name);
NPNR_ASSERT(old.type == rep.type);
@@ -157,4 +164,33 @@ void rename_net(Context *ctx, NetInfo *net, IdString new_name)
net->name = new_name;
}
+void replace_bus(Context *ctx, CellInfo *old_cell, IdString old_name, int old_offset, bool old_brackets,
+ CellInfo *new_cell, IdString new_name, int new_offset, bool new_brackets, int width)
+{
+ for (int i = 0; i < width; i++) {
+ IdString old_port = ctx->id(stringf(old_brackets ? "%s[%d]" : "%s%d", old_name.c_str(ctx), i + old_offset));
+ IdString new_port = ctx->id(stringf(new_brackets ? "%s[%d]" : "%s%d", new_name.c_str(ctx), i + new_offset));
+ replace_port(old_cell, old_port, new_cell, new_port);
+ }
+}
+
+void copy_port(Context *ctx, CellInfo *old_cell, IdString old_name, CellInfo *new_cell, IdString new_name)
+{
+ if (!old_cell->ports.count(old_name))
+ return;
+ new_cell->ports[new_name].name = new_name;
+ new_cell->ports[new_name].type = old_cell->ports.at(old_name).type;
+ connect_port(ctx, old_cell->ports.at(old_name).net, new_cell, new_name);
+}
+
+void copy_bus(Context *ctx, CellInfo *old_cell, IdString old_name, int old_offset, bool old_brackets,
+ CellInfo *new_cell, IdString new_name, int new_offset, bool new_brackets, int width)
+{
+ for (int i = 0; i < width; i++) {
+ IdString old_port = ctx->id(stringf(old_brackets ? "%s[%d]" : "%s%d", old_name.c_str(ctx), i + old_offset));
+ IdString new_port = ctx->id(stringf(new_brackets ? "%s[%d]" : "%s%d", new_name.c_str(ctx), i + new_offset));
+ copy_port(ctx, old_cell, old_port, new_cell, new_port);
+ }
+}
+
NEXTPNR_NAMESPACE_END
diff --git a/common/design_utils.h b/common/design_utils.h
index 1ae1d648..6f52eb0c 100644
--- a/common/design_utils.h
+++ b/common/design_utils.h
@@ -82,6 +82,13 @@ template <typename F1> CellInfo *net_driven_by(const Context *ctx, const NetInfo
}
}
+// Check if a port is used
+inline bool port_used(CellInfo *cell, IdString port_name)
+{
+ auto port_fnd = cell->ports.find(port_name);
+ return port_fnd != cell->ports.end() && port_fnd->second.net != nullptr;
+}
+
// Connect a net to a port
void connect_port(const Context *ctx, NetInfo *net, CellInfo *cell, IdString port_name);
@@ -99,6 +106,17 @@ void rename_net(Context *ctx, NetInfo *net, IdString new_name);
void print_utilisation(const Context *ctx);
+// Disconnect a bus of nets (if connected) from old, and connect it to the new ports
+void replace_bus(Context *ctx, CellInfo *old_cell, IdString old_name, int old_offset, bool old_brackets,
+ CellInfo *new_cell, IdString new_name, int new_offset, bool new_brackets, int width);
+
+// Copy a bus of nets (if connected) from old, and connect it to the new ports
+void copy_bus(Context *ctx, CellInfo *old_cell, IdString old_name, int old_offset, bool old_brackets,
+ CellInfo *new_cell, IdString new_name, int new_offset, bool new_brackets, int width);
+
+// Copy a port from one cell to another
+void copy_port(Context *ctx, CellInfo *old_cell, IdString old_name, CellInfo *new_cell, IdString new_name);
+
NEXTPNR_NAMESPACE_END
#endif
diff --git a/common/nextpnr.cc b/common/nextpnr.cc
index 07b88471..9a856b99 100644
--- a/common/nextpnr.cc
+++ b/common/nextpnr.cc
@@ -506,7 +506,7 @@ void Context::check() const
}
}
}
-
+#ifdef CHECK_WIRES
for (auto w : getWires()) {
auto ni = getBoundWireNet(w);
if (ni != nullptr) {
@@ -514,7 +514,7 @@ void Context::check() const
CHECK_FAIL("wire '%s' missing in wires map of bound net '%s'\n", nameOfWire(w), nameOf(ni));
}
}
-
+#endif
for (auto &c : cells) {
auto ci = c.second.get();
if (c.first != ci->name)
diff --git a/common/router1.cc b/common/router1.cc
index 946327d2..d2816c1e 100644
--- a/common/router1.cc
+++ b/common/router1.cc
@@ -469,6 +469,20 @@ struct Router1
}
}
+ // special case
+
+ if (src_wire == dst_wire) {
+ NetInfo *bound = ctx->getBoundWireNet(src_wire);
+ if (bound != nullptr)
+ NPNR_ASSERT(bound == net_info);
+ else {
+ ctx->bindWire(src_wire, net_info, STRENGTH_WEAK);
+ }
+ arc_to_wires[arc].insert(src_wire);
+ wire_to_arcs[src_wire].insert(arc);
+ return true;
+ }
+
// reset wire queue
if (!queue.empty()) {
diff --git a/common/router2.cc b/common/router2.cc
index 4dfd868b..15c97e52 100644
--- a/common/router2.cc
+++ b/common/router2.cc
@@ -774,8 +774,11 @@ struct Router2
if (dst == WireId() || ctx->getBoundWireNet(dst) == net)
return true;
// Skip routes where there is no routing (special cases)
- if (!ad.routed)
+ if (!ad.routed) {
+ if ((src == dst) && ctx->getBoundWireNet(dst) != net)
+ ctx->bindWire(src, net, STRENGTH_WEAK);
return true;
+ }
WireId cursor = dst;
diff --git a/common/util.h b/common/util.h
index 9512bd40..07ebac75 100644
--- a/common/util.h
+++ b/common/util.h
@@ -112,6 +112,24 @@ template <typename K, typename V> std::map<K, V *> sorted(const std::unordered_m
return retVal;
};
+// Wrap an unordered_map, and allow it to be iterated over sorted by key
+template <typename K, typename V> std::map<K, V &> sorted_ref(std::unordered_map<K, V> &orig)
+{
+ std::map<K, V &> retVal;
+ for (auto &item : orig)
+ retVal.emplace(std::make_pair(item.first, std::ref(item.second)));
+ return retVal;
+};
+
+// Wrap an unordered_map, and allow it to be iterated over sorted by key
+template <typename K, typename V> std::map<K, const V &> sorted_cref(const std::unordered_map<K, V> &orig)
+{
+ std::map<K, const V &> retVal;
+ for (auto &item : orig)
+ retVal.emplace(std::make_pair(item.first, std::ref(item.second)));
+ return retVal;
+};
+
// Wrap an unordered_set, and allow it to be iterated over sorted by key
template <typename K> std::set<K> sorted(const std::unordered_set<K> &orig)
{