aboutsummaryrefslogtreecommitdiffstats
path: root/frontend
diff options
context:
space:
mode:
authorDavid Shah <dave@ds0.me>2019-11-13 13:51:28 +0000
committerDavid Shah <dave@ds0.me>2019-12-27 10:44:29 +0000
commit25867e3f231cc8ffe3ce87e6f1af1ca1d4c46146 (patch)
treeec9836275b9cbe0b2b71787be576da0e5baf138e /frontend
parent6aaa9f5a3d02224f2760d993d114163ce7678e1f (diff)
downloadnextpnr-25867e3f231cc8ffe3ce87e6f1af1ca1d4c46146.tar.gz
nextpnr-25867e3f231cc8ffe3ce87e6f1af1ca1d4c46146.tar.bz2
nextpnr-25867e3f231cc8ffe3ce87e6f1af1ca1d4c46146.zip
frontend/base: Improve net indexing
Signed-off-by: David Shah <dave@ds0.me>
Diffstat (limited to 'frontend')
-rw-r--r--frontend/frontend_base.h35
1 files changed, 27 insertions, 8 deletions
diff --git a/frontend/frontend_base.h b/frontend/frontend_base.h
index 42be2bfd..35d4409c 100644
--- a/frontend/frontend_base.h
+++ b/frontend/frontend_base.h
@@ -205,9 +205,10 @@ template <typename FrontendType> struct GenericFrontend
return name;
}
- // A flat index of map; designed to cope with renaming
+ // A flat index of map; designed to cope with merging nets where pointers to nets would go stale
// A net's udata points into this index
std::vector<NetInfo *> net_flatindex;
+ std::vector<std::vector<int>> net_old_indices; // the other indices of a net in net_flatindex for merging
// This structure contains some structures specific to the import of a module at
// a certain point in the hierarchy
@@ -216,17 +217,17 @@ template <typename FrontendType> struct GenericFrontend
bool is_toplevel;
std::string prefix;
// Map from index in module to "flat" index of nets
- std::vector<NetInfo *> index_to_net_flatindex;
+ std::vector<int> index_to_net_flatindex;
// Get a reference to index_to_net; resizing if
// appropriate
- NetInfo *&net_by_idx(int idx)
+ int &net_by_idx(int idx)
{
NPNR_ASSERT(idx >= 0);
if (idx >= int(index_to_net_flatindex.size()))
- index_to_net_flatindex.resize(idx + 1, nullptr);
+ index_to_net_flatindex.resize(idx + 1, -1);
return index_to_net_flatindex.at(idx);
}
- std::unordered_map<IdString, std::vector<NetInfo *>> port_to_bus;
+ std::unordered_map<IdString, std::vector<int>> port_to_bus;
};
void import_module(HierModuleState &m, mod_dat_t *data)
@@ -287,7 +288,13 @@ template <typename FrontendType> struct GenericFrontend
// Create a new alias from mergee's name to new base name
ctx->net_aliases[mergee->name] = base->name;
// Update flat index of nets
+ for (auto old_idx : net_old_indices.at(mergee->udata)) {
+ net_old_indices.at(base).push_back(old_idx);
+ net_flatindex.at(old_idx) = base;
+ }
+ net_old_indices.at(base).push_back(mergee->udata);
net_flatindex.at(mergee->udata) = base;
+ net_old_indices.at(mergee->udata).clear();
// Remove merged net from context
ctx->nets.erase(mergee->name);
}
@@ -307,9 +314,11 @@ template <typename FrontendType> struct GenericFrontend
int bv_size = impl.get_vector_length(bv);
// Iterate over bits of port; making connections
for (int i = 0; i < std::min<int>(bv_size, p2b.size()); i++) {
- NetInfo *conn_net = p2b.at(i);
- if (conn_net == nullptr)
+ int conn_net = p2b.at(i);
+ if (conn_net == -1)
continue;
+ NetInfo *conn_ni = net_flatindex.at(conn_net);
+ NPNR_ASSERT(conn_ni != nullptr);
if (impl.is_vector_bit_constant(bv, i)) {
// It is a constant, we might need to insert a constant driver here to drive the corresponding
// net in the parent
@@ -319,10 +328,20 @@ template <typename FrontendType> struct GenericFrontend
log_error("Input port %s%s[%d] cannot be driving a constant '%c'.\n", m.prefix.c_str(),
port.c_str(), i, constval);
// Insert the constant driver
- add_constant_driver(m, conn_net, constval);
+ add_constant_driver(m, conn_ni, constval);
} else {
// If not driving a constant; simply make the port bit net index in the submodule correspond
// to connected net in the parent module
+ int &submod_net = m.net_by_idx(impl.get_vector_bit_signal(bv, i));
+ if (submod_net == -1) {
+ // A net at this index doesn't yet exist
+ // We can simply set this index to point to the net in the parent
+ submod_net = conn_net;
+ } else {
+ // A net at this index already exists (this would usually be a submodule net
+ // connected to more than one I/O port)
+ merge_nets(net_flatindex.at(submod_net), net_flatindex.at(conn_net));
+ }
}
}
});