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 <mkurc@antmicro.com>
This commit is contained in:
Maciej Kurc 2021-11-22 13:13:28 +01:00
parent 5bc97c94ae
commit 238da79e52
2 changed files with 23 additions and 14 deletions

View File

@ -52,6 +52,7 @@ po::options_description NexusCommandHandler::getArchOptions()
specific.add_options()("pdc", po::value<std::string>(), "physical constraints file"); specific.add_options()("pdc", po::value<std::string>(), "physical constraints file");
specific.add_options()("no-post-place-opt", "disable post-place repacking (debugging use only)"); 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()("no-pack-lutff", "disable packing (clustering) LUTs and FFs together");
specific.add_options()("carry-lutff-ratio", po::value<float>(), "ratio of FFs to be added to carry-chain LUT clusters");
return specific; return specific;
} }
@ -79,6 +80,13 @@ std::unique_ptr<Context> NexusCommandHandler::createContext(dict<std::string, Pr
ctx->settings[ctx->id("no_post_place_opt")] = Property::State::S1; ctx->settings[ctx->id("no_post_place_opt")] = Property::State::S1;
if (vm.count("no-pack-lutff")) if (vm.count("no-pack-lutff"))
ctx->settings[ctx->id("no_pack_lutff")] = Property::State::S1; ctx->settings[ctx->id("no_pack_lutff")] = Property::State::S1;
if (vm.count("carry-lutff-ratio")) {
float ratio = vm["carry-lutff-ratio"].as<float>();
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; return ctx;
} }

View File

@ -2307,6 +2307,11 @@ struct NexusPacker
void pack_lutffs () { void pack_lutffs () {
log_info("Inferring LUT+FF pairs...\n"); 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<float>("carry_lutff_ratio");
}
size_t num_comb = 0; size_t num_comb = 0;
size_t num_ff = 0; size_t num_ff = 0;
size_t num_pair = 0; size_t num_pair = 0;
@ -2338,7 +2343,6 @@ struct NexusPacker
continue; continue;
} }
if (di->driver.port != id_F && if (di->driver.port != id_F &&
di->driver.port != id_F1 &&
di->driver.port != id_OFX) di->driver.port != id_OFX)
{ {
continue; continue;
@ -2377,27 +2381,24 @@ struct NexusPacker
// Attach the FF to the existing cluster of the LUT // Attach the FF to the existing cluster of the LUT
else { else {
// Find the cluster root // No order not to make too large carry clusters pack only the
CellInfo* root = nullptr; // given fraction of FFs there.
if (!lut->constr_children.empty()) { if(str_or_default(lut->params, id_MODE, "LOGIC") == "CCU2") {
root = lut; float r = (float)(ctx->rng() % 1000) * 1e-3f;
} if (r > carry_ratio) {
else { continue;
for (auto &it : ctx->cells) {
if (it.second->cluster == lut->cluster && !it.second->constr_children.empty()) {
root = it.second.get();
break;
} }
} }
}
NPNR_ASSERT(root != nullptr); // Get the cluster root
CellInfo* root = ctx->cells.at(lut->cluster).get();
// Constrain the FF relative to the LUT // Constrain the FF relative to the LUT
ff->cluster = root->cluster; ff->cluster = root->cluster;
ff->constr_x = lut->constr_x; ff->constr_x = lut->constr_x;
ff->constr_y = lut->constr_y; ff->constr_y = lut->constr_y;
ff->constr_z = lut->constr_z + 2; 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); root->constr_children.push_back(ff);
num_glue++; num_glue++;