aboutsummaryrefslogtreecommitdiffstats
path: root/nexus
diff options
context:
space:
mode:
authorMaciej Kurc <mkurc@antmicro.com>2021-11-19 09:15:59 +0100
committerMaciej Kurc <mkurc@antmicro.com>2021-11-22 10:23:24 +0100
commitd97f93ee8864f8cba14f62bd49dd2baf51b7b21c (patch)
tree5e62d66ebc14cb9a18b1a2ab829673ba512fdf93 /nexus
parentf5cc959c4efdc4e6922bc0a7bcbc9eb38c37248e (diff)
downloadnextpnr-d97f93ee8864f8cba14f62bd49dd2baf51b7b21c.tar.gz
nextpnr-d97f93ee8864f8cba14f62bd49dd2baf51b7b21c.tar.bz2
nextpnr-d97f93ee8864f8cba14f62bd49dd2baf51b7b21c.zip
Added clustering free LUTs and FFs
Signed-off-by: Maciej Kurc <mkurc@antmicro.com>
Diffstat (limited to 'nexus')
-rw-r--r--nexus/pack.cc73
1 files changed, 73 insertions, 0 deletions
diff --git a/nexus/pack.cc b/nexus/pack.cc
index 281a7cf2..ba6033f9 100644
--- a/nexus/pack.cc
+++ b/nexus/pack.cc
@@ -2304,6 +2304,78 @@ struct NexusPacker
}
}
+ void pack_lutffs () {
+ log_info("Inferring LUT+FF pairs...\n");
+
+ size_t num_comb = 0;
+ size_t num_ff = 0;
+ size_t num_pair = 0;
+
+ for (auto &cell : ctx->cells) {
+ CellInfo *ff = cell.second.get();
+ if (ff->type != id_OXIDE_FF) {
+ continue;
+ }
+
+ num_ff++;
+
+ // Get input net
+ NetInfo *di = get_net_or_empty(ff, id_M); // At the packing stage all inputs go to M
+ if (di == nullptr || di->driver.cell == nullptr) {
+ continue;
+ }
+
+ // Skip if there are multiple sinks
+ if (di->users.size() != 1) {
+ continue;
+ }
+
+ // Check if the driver is a LUT and the direct connection is from F
+ CellInfo* lut = di->driver.cell;
+ if (lut->type != id_OXIDE_COMB || di->driver.port != id_F) {
+ continue;
+ }
+
+ // The LUT must be in LOGIC mode
+ if (str_or_default(lut->params, id_MODE, "LOGIC") != "LOGIC") {
+ continue;
+ }
+
+ // Skip clusters
+ // FIXME: In case of carry chain make the LUTFF part of the chain
+ if (lut->cluster != ClusterId() || ff->cluster != ClusterId()) {
+ continue;
+ }
+
+ // Make a cluster
+ lut->cluster = lut->name;
+ lut->constr_children.push_back(ff);
+
+ ff->cluster = lut->name;
+ ff->constr_x = 0;
+ ff->constr_y = 0;
+ ff->constr_z = 2;
+ ff->constr_abs_z = false;
+
+ num_pair++;
+ }
+
+ // Count OXIDE_COMB, OXIDE_FF are already counted
+ for (auto &cell : ctx->cells) {
+ CellInfo *ff = cell.second.get();
+ if (ff->type == id_OXIDE_COMB) {
+ num_comb++;
+ }
+ }
+
+ // Print statistics
+ log_info(" Created %zu LUT+FF pairs from %zu FFs and %zu LUTs\n",
+ num_pair,
+ num_ff,
+ num_comb
+ );
+ }
+
explicit NexusPacker(Context *ctx) : ctx(ctx) {}
void operator()()
@@ -2323,6 +2395,7 @@ struct NexusPacker
pack_luts();
pack_ip();
handle_iologic();
+ pack_lutffs();
promote_globals();
place_globals();
generate_constraints();