aboutsummaryrefslogtreecommitdiffstats
path: root/nexus/pack.cc
diff options
context:
space:
mode:
authorMaciej Kurc <mkurc@antmicro.com>2021-09-20 11:35:36 +0200
committerMaciej Kurc <mkurc@antmicro.com>2021-09-20 11:35:36 +0200
commit80e2f8a791ed60d48b1c3352a9c158eea7813191 (patch)
treebe557c37538c294a6f3c1833834bcada35dd447c /nexus/pack.cc
parent8ffd30cb2d4e1f9f231844280d5ad7a6b8c8b850 (diff)
downloadnextpnr-80e2f8a791ed60d48b1c3352a9c158eea7813191.tar.gz
nextpnr-80e2f8a791ed60d48b1c3352a9c158eea7813191.tar.bz2
nextpnr-80e2f8a791ed60d48b1c3352a9c158eea7813191.zip
Added support for syn_useioff for enabling tri-state control FF integration into IOLOGIC.
Signed-off-by: Maciej Kurc <mkurc@antmicro.com>
Diffstat (limited to 'nexus/pack.cc')
-rw-r--r--nexus/pack.cc36
1 files changed, 23 insertions, 13 deletions
diff --git a/nexus/pack.cc b/nexus/pack.cc
index 319eba7a..6913ef00 100644
--- a/nexus/pack.cc
+++ b/nexus/pack.cc
@@ -2134,6 +2134,7 @@ struct NexusPacker
// IOLOGIC requires some special handling around itself and IOB. This
// function does that.
void handle_iologic() {
+ log_info("Packing IOLOGIC...\n");
// Map of flip-flop cells that drive IOLOGIC+IOB pairs
dict<IdString, std::vector<std::pair<IdString,IdString>>> tff_map;
@@ -2228,13 +2229,20 @@ struct NexusPacker
connect_port(ctx, iob_t, iol, id_TSDATA0);
if (ctx->debug) {
- log_info("Reconnecting %s.TSDATA0 to %s\n", ctx->nameOf(iol), ctx->nameOf(iob_t));
+ log_info(" Reconnecting %s.TSDATA0 to %s\n", ctx->nameOf(iol), ctx->nameOf(iob_t));
+ }
+
+ // Check if the net wants to use the T flip-flop in
+ // IOLOGIC
+ bool syn_useioff = false;
+ if (iob_t->attrs.count(ctx->id("syn_useioff"))) {
+ syn_useioff = iob_t->attrs.at(ctx->id("syn_useioff")).as_bool();
}
// Check if the T input is driven by a flip-flop. Store
- // in the map.
+ // in the map for later integration with IOLOGIC.
CellInfo* ff = get_ff_for_iob(iob, id_T, iol);
- if (ff != nullptr) {
+ if (ff != nullptr && syn_useioff) {
tff_map[ff->name].push_back(std::make_pair(
iol->name, iob->name));
}
@@ -2253,16 +2261,11 @@ struct NexusPacker
NetInfo* ff_q = get_net_or_empty(ff, id_Q);
NPNR_ASSERT(ff_q != nullptr);
- log_info("FF '%s'\n", ctx->nameOf(ff));
- for (auto& it : ff->params) {
- log_info(" '%s'='%s'\n", it.first.c_str(ctx), it.second.as_string().c_str());
- }
-
for (auto& ios : it.second) {
CellInfo* iol = ctx->cells.at(ios.first).get();
CellInfo* iob = ctx->cells.at(ios.second).get();
- log_info("Integrating %s into %s\n", ctx->nameOf(ff), ctx->nameOf(iol));
+ log_info(" Integrating %s into %s\n", ctx->nameOf(ff), ctx->nameOf(iol));
// Disconnect "old" T net
disconnect_port(ctx, iol, id_TSDATA0);
@@ -2287,10 +2290,17 @@ struct NexusPacker
disconnect_port(ctx, ff, port.first);
}
- // Remove the flip-flop
- ctx->cells.erase(ff->name);
- // Remove its output net
- ctx->nets.erase(ff_q->name);
+ // Check if the flip-flop can be removed
+ bool can_remove = ff_q->users.empty();
+
+ // Remove the flip-flop and its output net
+ if (can_remove) {
+ if (ctx->debug) {
+ log_info(" Removing %s\n", ctx->nameOf(ff));
+ }
+ ctx->cells.erase(ff->name);
+ ctx->nets.erase(ff_q->name);
+ }
}
}