aboutsummaryrefslogtreecommitdiffstats
path: root/common
diff options
context:
space:
mode:
Diffstat (limited to 'common')
-rw-r--r--common/design_utils.cc32
-rw-r--r--common/design_utils.h6
-rw-r--r--common/nextpnr.cc5
-rw-r--r--common/timing.cc16
4 files changed, 59 insertions, 0 deletions
diff --git a/common/design_utils.cc b/common/design_utils.cc
index 7ad7f749..a0b87764 100644
--- a/common/design_utils.cc
+++ b/common/design_utils.cc
@@ -19,6 +19,7 @@
*/
#include "design_utils.h"
+#include <algorithm>
#include <map>
#include "log.h"
#include "util.h"
@@ -76,6 +77,8 @@ void print_utilisation(const Context *ctx)
// Connect a net to a port
void connect_port(const Context *ctx, NetInfo *net, CellInfo *cell, IdString port_name)
{
+ if (net == nullptr)
+ return;
PortInfo &port = cell->ports.at(port_name);
NPNR_ASSERT(port.net == nullptr);
port.net = net;
@@ -93,4 +96,33 @@ void connect_port(const Context *ctx, NetInfo *net, CellInfo *cell, IdString por
}
}
+void disconnect_port(const Context *ctx, CellInfo *cell, IdString port_name)
+{
+ if (!cell->ports.count(port_name))
+ return;
+ PortInfo &port = cell->ports.at(port_name);
+ if (port.net != nullptr) {
+ port.net->users.erase(std::remove_if(port.net->users.begin(), port.net->users.end(),
+ [cell, port_name](const PortRef &user) {
+ return user.cell == cell && user.port == port_name;
+ }),
+ port.net->users.end());
+ }
+}
+
+void connect_ports(Context *ctx, CellInfo *cell1, IdString port1_name, CellInfo *cell2, IdString port2_name)
+{
+ PortInfo &port1 = cell1->ports.at(port1_name);
+ if (port1.net == nullptr) {
+ // No net on port1; need to create one
+ std::unique_ptr<NetInfo> p1net(new NetInfo());
+ p1net->name = ctx->id(cell1->name.str(ctx) + "$conn$" + port1_name.str(ctx));
+ connect_port(ctx, p1net.get(), cell1, port1_name);
+ IdString p1name = p1net->name;
+ NPNR_ASSERT(!ctx->cells.count(p1name));
+ ctx->nets[p1name] = std::move(p1net);
+ }
+ connect_port(ctx, port1.net, cell2, port2_name);
+}
+
NEXTPNR_NAMESPACE_END
diff --git a/common/design_utils.h b/common/design_utils.h
index ccf2463b..8a42d21f 100644
--- a/common/design_utils.h
+++ b/common/design_utils.h
@@ -85,6 +85,12 @@ template <typename F1> CellInfo *net_driven_by(const Context *ctx, const NetInfo
// Connect a net to a port
void connect_port(const Context *ctx, NetInfo *net, CellInfo *cell, IdString port_name);
+// Disconnect a net from a port
+void disconnect_port(const Context *ctx, CellInfo *cell, IdString port_name);
+
+// Connect two ports together
+void connect_ports(Context *ctx, CellInfo *cell1, IdString port1_name, CellInfo *cell2, IdString port2_name);
+
void print_utilisation(const Context *ctx);
NEXTPNR_NAMESPACE_END
diff --git a/common/nextpnr.cc b/common/nextpnr.cc
index 068bca6f..4e6407b2 100644
--- a/common/nextpnr.cc
+++ b/common/nextpnr.cc
@@ -245,6 +245,11 @@ void Context::check() const
NPNR_ASSERT(ni == getBoundPipNet(w.second.pip));
}
}
+ if (ni->driver.cell != nullptr)
+ NPNR_ASSERT(ni->driver.cell->ports.at(ni->driver.port).net == ni);
+ for (auto user : ni->users) {
+ NPNR_ASSERT(user.cell->ports.at(user.port).net == ni);
+ }
}
for (auto w : getWires()) {
diff --git a/common/timing.cc b/common/timing.cc
index 62697353..e3a7635f 100644
--- a/common/timing.cc
+++ b/common/timing.cc
@@ -164,6 +164,22 @@ struct Timing
}
// Sanity check to ensure that all ports where fanins were recorded were indeed visited
+ if (!port_fanin.empty()) {
+ for (auto fanin : port_fanin) {
+ NetInfo *net = fanin.first->net;
+ if (net != nullptr) {
+ log_info(" remaining fanin includes %s (net %s)\n", fanin.first->name.c_str(ctx),
+ net->name.c_str(ctx));
+ if (net->driver.cell != nullptr)
+ log_info(" driver = %s.%s\n", net->driver.cell->name.c_str(ctx),
+ net->driver.port.c_str(ctx));
+ for (auto net_user : net->users)
+ log_info(" user: %s.%s\n", net_user.cell->name.c_str(ctx), net_user.port.c_str(ctx));
+ } else {
+ log_info(" remaining fanin includes %s (no net)\n", fanin.first->name.c_str(ctx));
+ }
+ }
+ }
NPNR_ASSERT(port_fanin.empty());
// Go forwards topographically to find the maximum arrival time and max path length for each net