static: Fix NaN on a big xilinx design

Signed-off-by: gatecat <gatecat@ds0.me>
This commit is contained in:
gatecat 2026-03-04 09:45:43 +01:00
parent dd4d3056eb
commit fcaafbaa08
3 changed files with 15 additions and 4 deletions

View File

@ -343,7 +343,7 @@ class StaticPlacer
auto &nd = nets.back(); auto &nd = nets.back();
nd.ni = ni; 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.resize(ni->users.capacity() + 1); // +1 for the driver
nd.ports.back().ref = ni->driver; nd.ports.back().ref = ni->driver;
for (auto usr : ni->users.enumerate()) { for (auto usr : ni->users.enumerate()) {
@ -798,6 +798,7 @@ class StaticPlacer
port.max_exp.at(axis) = std::exp(emax); port.max_exp.at(axis) = std::exp(emax);
net.max_exp.at(axis) += port.max_exp.at(axis); net.max_exp.at(axis) += port.max_exp.at(axis);
net.x_max_exp.at(axis) += loc.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 { } else {
port.max_exp.at(axis) = PlacerPort::invalid; 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))) + 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) / wl_coeff.at(axis) * pd.min_exp.at(axis) * x_min_sum) /
(min_sum * min_sum); (min_sum * min_sum);
NPNR_ASSERT(std::isfinite(d_min));
} }
if (pd.has_max_exp(axis)) { if (pd.has_max_exp(axis)) {
double max_sum = nd.max_exp.at(axis), x_max_sum = nd.x_max_exp.at(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))) - 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) / wl_coeff.at(axis) * pd.max_exp.at(axis) * x_max_sum) /
(max_sum * max_sum); (max_sum * max_sum);
NPNR_ASSERT(std::isfinite(d_max));
} }
float crit = 0.0; float crit = 0.0;
if (cfg.timing_driven) { if (cfg.timing_driven) {
@ -853,6 +856,7 @@ class StaticPlacer
gradient += weight * (d_min - d_max); gradient += weight * (d_min - d_max);
} }
NPNR_ASSERT(std::isfinite(gradient));
return gradient; return gradient;
} }
@ -917,6 +921,7 @@ class StaticPlacer
} }
const float eta = 1e-1; const float eta = 1e-1;
float init_dens_penalty = eta * (wirelen_sum / force_sum); 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); log_info("initial density penalty: %f\n", init_dens_penalty);
dens_penalty.resize(groups.size(), init_dens_penalty); dens_penalty.resize(groups.size(), init_dens_penalty);
update_potentials(true); // set initial potential update_potentials(true); // set initial potential

View File

@ -56,6 +56,8 @@ struct PlacerStaticCfg
// These cell types will be randomly locked to prevent singular matrices // These cell types will be randomly locked to prevent singular matrices
pool<IdString> ioBufTypes; pool<IdString> ioBufTypes;
// Nets driven by these cell types will be ignored
pool<IdString> glbBufTypes;
int hpwl_scale_x = 1; int hpwl_scale_x = 1;
int hpwl_scale_y = 1; int hpwl_scale_y = 1;
bool timing_driven = false; bool timing_driven = false;
@ -68,9 +70,8 @@ struct PlacerStaticCfg
int logic_groups = 2; int logic_groups = 2;
// this is an optional callback to override the area of a cell e.g. based on configuration // this is an optional callback to override the area of a cell e.g. based on configuration
std::function<std::optional<StaticRect>(Context *, const CellInfo *)> get_cell_area_override = [](Context *, const CellInfo *) { std::function<std::optional<StaticRect>(Context *, const CellInfo *)> get_cell_area_override =
return std::optional<StaticRect>{}; [](Context *, const CellInfo *) { return std::optional<StaticRect>{}; };
};
}; };
extern bool placer_static(Context *ctx, PlacerStaticCfg cfg); extern bool placer_static(Context *ctx, PlacerStaticCfg cfg);

View File

@ -302,6 +302,11 @@ void XilinxImpl::configurePlacerStatic(PlacerStaticCfg &cfg)
cfg.hpwl_scale_x = 2; cfg.hpwl_scale_x = 2;
cfg.hpwl_scale_y = 1; 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(); cfg.cell_groups.emplace_back();
auto &comb = cfg.cell_groups.back(); auto &comb = cfg.cell_groups.back();