From fcaafbaa08d2e3f9b5a1da21c60c45c4c01643c8 Mon Sep 17 00:00:00 2001 From: gatecat Date: Wed, 4 Mar 2026 09:45:43 +0100 Subject: [PATCH] static: Fix NaN on a big xilinx design Signed-off-by: gatecat --- common/place/placer_static.cc | 7 ++++++- common/place/placer_static.h | 7 ++++--- himbaechel/uarch/xilinx/xilinx.cc | 5 +++++ 3 files changed, 15 insertions(+), 4 deletions(-) diff --git a/common/place/placer_static.cc b/common/place/placer_static.cc index 91c81e59..a26e4e26 100644 --- a/common/place/placer_static.cc +++ b/common/place/placer_static.cc @@ -343,7 +343,7 @@ class StaticPlacer auto &nd = nets.back(); nd.ni = ni; - nd.skip = (ni->driver.cell == nullptr); // (or global buffer?) + nd.skip = (ni->driver.cell == nullptr || cfg.glbBufTypes.count(ni->driver.cell->type)); nd.ports.resize(ni->users.capacity() + 1); // +1 for the driver nd.ports.back().ref = ni->driver; for (auto usr : ni->users.enumerate()) { @@ -798,6 +798,7 @@ class StaticPlacer port.max_exp.at(axis) = std::exp(emax); net.max_exp.at(axis) += port.max_exp.at(axis); net.x_max_exp.at(axis) += loc.at(axis) * port.max_exp.at(axis); + NPNR_ASSERT(std::isfinite(net.x_max_exp.at(axis))); } else { port.max_exp.at(axis) = PlacerPort::invalid; } @@ -831,12 +832,14 @@ class StaticPlacer d_min = (min_sum * (pd.min_exp.at(axis) * (1.0f - wl_coeff.at(axis) * loc.at(axis))) + wl_coeff.at(axis) * pd.min_exp.at(axis) * x_min_sum) / (min_sum * min_sum); + NPNR_ASSERT(std::isfinite(d_min)); } if (pd.has_max_exp(axis)) { double max_sum = nd.max_exp.at(axis), x_max_sum = nd.x_max_exp.at(axis); d_max = (max_sum * (pd.max_exp.at(axis) * (1.0f + wl_coeff.at(axis) * loc.at(axis))) - wl_coeff.at(axis) * pd.max_exp.at(axis) * x_max_sum) / (max_sum * max_sum); + NPNR_ASSERT(std::isfinite(d_max)); } float crit = 0.0; if (cfg.timing_driven) { @@ -853,6 +856,7 @@ class StaticPlacer gradient += weight * (d_min - d_max); } + NPNR_ASSERT(std::isfinite(gradient)); return gradient; } @@ -917,6 +921,7 @@ class StaticPlacer } const float eta = 1e-1; float init_dens_penalty = eta * (wirelen_sum / force_sum); + NPNR_ASSERT(std::isfinite(init_dens_penalty)); log_info("initial density penalty: %f\n", init_dens_penalty); dens_penalty.resize(groups.size(), init_dens_penalty); update_potentials(true); // set initial potential diff --git a/common/place/placer_static.h b/common/place/placer_static.h index dccbb4cc..757ced28 100644 --- a/common/place/placer_static.h +++ b/common/place/placer_static.h @@ -56,6 +56,8 @@ struct PlacerStaticCfg // These cell types will be randomly locked to prevent singular matrices pool ioBufTypes; + // Nets driven by these cell types will be ignored + pool glbBufTypes; int hpwl_scale_x = 1; int hpwl_scale_y = 1; bool timing_driven = false; @@ -68,9 +70,8 @@ struct PlacerStaticCfg int logic_groups = 2; // this is an optional callback to override the area of a cell e.g. based on configuration - std::function(Context *, const CellInfo *)> get_cell_area_override = [](Context *, const CellInfo *) { - return std::optional{}; - }; + std::function(Context *, const CellInfo *)> get_cell_area_override = + [](Context *, const CellInfo *) { return std::optional{}; }; }; extern bool placer_static(Context *ctx, PlacerStaticCfg cfg); diff --git a/himbaechel/uarch/xilinx/xilinx.cc b/himbaechel/uarch/xilinx/xilinx.cc index ee07e48e..cef6e96a 100644 --- a/himbaechel/uarch/xilinx/xilinx.cc +++ b/himbaechel/uarch/xilinx/xilinx.cc @@ -302,6 +302,11 @@ void XilinxImpl::configurePlacerStatic(PlacerStaticCfg &cfg) cfg.hpwl_scale_x = 2; cfg.hpwl_scale_y = 1; + cfg.glbBufTypes.insert(id_PSEUDO_GND); + cfg.glbBufTypes.insert(id_PSEUDO_VCC); + cfg.glbBufTypes.insert(id_BUFGCTRL); + cfg.glbBufTypes.insert(id_BUFG_BUFG); + { cfg.cell_groups.emplace_back(); auto &comb = cfg.cell_groups.back();