Check if DFFs are compatible before merging

This commit is contained in:
Miodrag Milanovic 2025-07-09 09:23:32 +02:00
parent cd1217efdb
commit 16c94acda9
3 changed files with 38 additions and 17 deletions

View File

@ -205,6 +205,25 @@ void GateMateImpl::configurePlacerHeap(PlacerHeapCfg &cfg)
cfg.placeAllAtOnce = true;
}
int GateMateImpl::get_dff_config(CellInfo *dff) const
{
int val = 0;
val |= int_or_default(dff->params, id_C_CPE_EN, 0);
val <<= 2;
val |= int_or_default(dff->params, id_C_CPE_CLK, 0);
val <<= 2;
val |= int_or_default(dff->params, id_C_CPE_RES, 0);
val <<= 2;
val |= int_or_default(dff->params, id_C_CPE_SET, 0);
val <<= 2;
val |= int_or_default(dff->params, id_C_EN_SR, 0);
val <<= 1;
val |= int_or_default(dff->params, id_C_L_D, 0);
val <<= 1;
val |= int_or_default(dff->params, id_FF_INIT, 0);
return val;
}
void GateMateImpl::assign_cell_info()
{
fast_cell_info.resize(ctx->cells.size());
@ -215,20 +234,7 @@ void GateMateImpl::assign_cell_info()
fc.ff_en = ci->getPort(id_EN);
fc.ff_clk = ci->getPort(id_CLK);
fc.ff_sr = ci->getPort(id_SR);
fc.ff_config = 0;
fc.ff_config |= int_or_default(ci->params, id_C_CPE_EN, 0);
fc.ff_config <<= 2;
fc.ff_config |= int_or_default(ci->params, id_C_CPE_CLK, 0);
fc.ff_config <<= 2;
fc.ff_config |= int_or_default(ci->params, id_C_CPE_RES, 0);
fc.ff_config <<= 2;
fc.ff_config |= int_or_default(ci->params, id_C_CPE_SET, 0);
fc.ff_config <<= 2;
fc.ff_config |= int_or_default(ci->params, id_C_EN_SR, 0);
fc.ff_config <<= 1;
fc.ff_config |= int_or_default(ci->params, id_C_L_D, 0);
fc.ff_config <<= 1;
fc.ff_config |= int_or_default(ci->params, id_FF_INIT, 0);
fc.ff_config = get_dff_config(ci);
fc.dff_used = true;
}
}

View File

@ -64,6 +64,8 @@ struct GateMateImpl : HimbaechelAPI
const GateMateTileExtraDataPOD *tile_extra_data(int tile) const;
int get_dff_config(CellInfo *dff) const;
std::set<IdString> available_pads;
std::map<BelId, const PadInfoPOD *> bel_to_pad;
pool<IdString> ddr_nets;

View File

@ -461,11 +461,21 @@ void GateMatePacker::pack_addf()
}
};
auto merge_dff = [&](CellInfo *cell, IdString port) {
auto merge_dff = [&](CellInfo *cell, IdString port, CellInfo *other) -> CellInfo * {
NetInfo *o = cell->getPort(port);
if (o) {
CellInfo *dff = net_only_drives(ctx, o, is_dff, id_D, true);
if (dff) {
if (other) {
if (dff->getPort(id_CLK) != other->getPort(id_CLK))
return nullptr;
if (dff->getPort(id_EN) != other->getPort(id_EN))
return nullptr;
if (dff->getPort(id_SR) != other->getPort(id_SR))
return nullptr;
if (uarch->get_dff_config(dff) != uarch->get_dff_config(other))
return nullptr;
}
dff->cluster = cell->cluster;
dff->constr_abs_z = false;
dff->constr_z = +2;
@ -473,8 +483,10 @@ void GateMatePacker::pack_addf()
dff->renamePort(id_D, id_DIN);
dff->renamePort(id_Q, id_DOUT);
dff->type = (dff->type == id_CC_DLT) ? id_CPE_LATCH : id_CPE_FF;
return dff;
}
}
return nullptr;
};
for (auto &grp : splitNestedVector(groups)) {
@ -557,14 +569,15 @@ void GateMatePacker::pack_addf()
upper->constr_abs_z = false;
upper->constr_y = +i;
upper->constr_z = -1;
CellInfo *other_dff = nullptr;
if (merged) {
cy->movePortTo(id_S, upper, id_OUT);
cy->renamePort(id_S2, id_OUT);
merge_dff(upper, id_OUT);
other_dff = merge_dff(upper, id_OUT, other_dff);
} else {
cy->renamePort(id_S, id_OUT);
}
merge_dff(cy, id_OUT);
merge_dff(cy, id_OUT, other_dff);
merge_input(cy, upper, id_A, id_INIT_L00, id_IN1, id_IN2);
merge_input(cy, upper, id_B, id_INIT_L01, id_IN3, id_IN4);
upper->params[id_INIT_L10] = Property(LUT_XOR, 4); // XOR