From 238da79e524ba47e28aac7b30df692f55be3f2d2 Mon Sep 17 00:00:00 2001 From: Maciej Kurc Date: Mon, 22 Nov 2021 13:13:28 +0100 Subject: Fixed potential issues with carry-chain cluster expansion, added a parameter controlling the ratio of FFs that got glued to carry-chain clusters. Signed-off-by: Maciej Kurc --- nexus/main.cc | 8 ++++++++ nexus/pack.cc | 29 +++++++++++++++-------------- 2 files changed, 23 insertions(+), 14 deletions(-) diff --git a/nexus/main.cc b/nexus/main.cc index 83bb02d8..667b6d80 100644 --- a/nexus/main.cc +++ b/nexus/main.cc @@ -52,6 +52,7 @@ po::options_description NexusCommandHandler::getArchOptions() specific.add_options()("pdc", po::value(), "physical constraints file"); specific.add_options()("no-post-place-opt", "disable post-place repacking (debugging use only)"); specific.add_options()("no-pack-lutff", "disable packing (clustering) LUTs and FFs together"); + specific.add_options()("carry-lutff-ratio", po::value(), "ratio of FFs to be added to carry-chain LUT clusters"); return specific; } @@ -79,6 +80,13 @@ std::unique_ptr NexusCommandHandler::createContext(dictsettings[ctx->id("no_post_place_opt")] = Property::State::S1; if (vm.count("no-pack-lutff")) ctx->settings[ctx->id("no_pack_lutff")] = Property::State::S1; + if (vm.count("carry-lutff-ratio")) { + float ratio = vm["carry-lutff-ratio"].as(); + if (ratio < 0.0f || ratio > 1.0f) { + log_error("Carry LUT+FF packing ration must be between 0.0 and 1.0"); + } + ctx->settings[ctx->id("carry_lutff_ratio")] = ratio; + } return ctx; } diff --git a/nexus/pack.cc b/nexus/pack.cc index be298ef0..8200f845 100644 --- a/nexus/pack.cc +++ b/nexus/pack.cc @@ -2307,6 +2307,11 @@ struct NexusPacker void pack_lutffs () { log_info("Inferring LUT+FF pairs...\n"); + float carry_ratio = 1.0f; + if (ctx->settings.find(ctx->id("carry_lutff_ratio")) != ctx->settings.end()) { + carry_ratio = ctx->setting("carry_lutff_ratio"); + } + size_t num_comb = 0; size_t num_ff = 0; size_t num_pair = 0; @@ -2338,7 +2343,6 @@ struct NexusPacker continue; } if (di->driver.port != id_F && - di->driver.port != id_F1 && di->driver.port != id_OFX) { continue; @@ -2377,27 +2381,24 @@ struct NexusPacker // Attach the FF to the existing cluster of the LUT else { - // Find the cluster root - CellInfo* root = nullptr; - if (!lut->constr_children.empty()) { - root = lut; - } - else { - for (auto &it : ctx->cells) { - if (it.second->cluster == lut->cluster && !it.second->constr_children.empty()) { - root = it.second.get(); - break; - } + // No order not to make too large carry clusters pack only the + // given fraction of FFs there. + if(str_or_default(lut->params, id_MODE, "LOGIC") == "CCU2") { + float r = (float)(ctx->rng() % 1000) * 1e-3f; + if (r > carry_ratio) { + continue; } } - NPNR_ASSERT(root != nullptr); + + // Get the cluster root + CellInfo* root = ctx->cells.at(lut->cluster).get(); // Constrain the FF relative to the LUT ff->cluster = root->cluster; ff->constr_x = lut->constr_x; ff->constr_y = lut->constr_y; ff->constr_z = lut->constr_z + 2; - ff->constr_abs_z = false; + ff->constr_abs_z = lut->constr_abs_z; root->constr_children.push_back(ff); num_glue++; -- cgit v1.2.3