Skip to content

Commit 9715a1d

Browse files
authored
heap: Allow chains to ripup other chains (opt-in only) (#1552)
Signed-off-by: gatecat <[email protected]>
1 parent 141abe6 commit 9715a1d

File tree

3 files changed

+38
-18
lines changed

3 files changed

+38
-18
lines changed

common/place/placer_heap.cc

Lines changed: 33 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -865,6 +865,7 @@ class HeAPPlacer
865865
remaining.emplace(chain_size[cell->name] * cfg.get_cell_legalisation_weight(ctx, cell), cell->name);
866866
}
867867
int ripup_radius = 2;
868+
int chain_ripup_radius = std::max(max_x, max_y); // only ripup chains as last resort
868869
int total_iters = 0;
869870
int total_iters_noreset = 0;
870871
while (!remaining.empty()) {
@@ -1054,7 +1055,7 @@ class HeAPPlacer
10541055
// List of cells and their destination
10551056
std::vector<std::pair<CellInfo *, BelId>> targets;
10561057
// List of bels we placed things at; and the cell that was there before if applicable
1057-
std::vector<std::pair<BelId, CellInfo *>> swaps_made;
1058+
dict<BelId, CellInfo *> moves_made;
10581059

10591060
if (!ctx->getClusterPlacement(ci->cluster, sz, targets))
10601061
continue;
@@ -1065,31 +1066,45 @@ class HeAPPlacer
10651066
goto fail;
10661067
CellInfo *bound = ctx->getBoundBelCell(target.second);
10671068
// Chains cannot overlap; so if we have to ripup a cell make sure it isn't part of a chain
1068-
if (bound != nullptr)
1069-
if (bound->cluster != ClusterId() || bound->belStrength > STRENGTH_WEAK)
1069+
if (bound != nullptr) {
1070+
if (bound->belStrength > (cfg.chainRipup ? STRENGTH_STRONG : STRENGTH_WEAK))
10701071
goto fail;
1072+
if (bound->cluster != ClusterId() && (!cfg.chainRipup || radius < chain_ripup_radius))
1073+
goto fail;
1074+
}
10711075
}
10721076
// Actually perform the move; keeping track of the moves we make so we can revert them if needed
10731077
for (auto &target : targets) {
10741078
CellInfo *bound = ctx->getBoundBelCell(target.second);
1075-
if (bound != nullptr)
1076-
ctx->unbindBel(target.second);
1079+
if (bound != nullptr) {
1080+
if (bound->cluster != ClusterId()) {
1081+
for (auto cell : cluster2cells[bound->cluster]) {
1082+
if (cell->bel != BelId()) {
1083+
moves_made[cell->bel] = cell;
1084+
ctx->unbindBel(cell->bel);
1085+
}
1086+
}
1087+
} else {
1088+
ctx->unbindBel(target.second);
1089+
}
1090+
}
10771091
ctx->bindBel(target.second, target.first, STRENGTH_STRONG);
1078-
swaps_made.emplace_back(target.second, bound);
1092+
moves_made[target.second] = bound;
10791093
}
10801094
// Check that the move we have made is legal
1081-
for (auto &sm : swaps_made) {
1082-
if (!ctx->isBelLocationValid(sm.first))
1095+
for (auto &move : moves_made) {
1096+
if (!ctx->isBelLocationValid(move.first))
10831097
goto fail;
10841098
}
10851099

10861100
if (false) {
10871101
fail:
10881102
// If the move turned out to be illegal; revert all the moves we made
1089-
for (auto &swap : swaps_made) {
1090-
ctx->unbindBel(swap.first);
1091-
if (swap.second != nullptr)
1092-
ctx->bindBel(swap.first, swap.second, STRENGTH_WEAK);
1103+
for (auto &move : moves_made) {
1104+
if (ctx->getBoundBelCell(move.first))
1105+
ctx->unbindBel(move.first);
1106+
if (move.second != nullptr)
1107+
ctx->bindBel(move.first, move.second, STRENGTH_WEAK);
10931108
}
10941109
continue;
10951110
}
@@ -1099,12 +1114,12 @@ class HeAPPlacer
10991114
cell_locs[target.first->name].y = loc.y;
11001115
// log_info("%s %d %d %d\n", target.first->name.c_str(ctx), loc.x, loc.y, loc.z);
11011116
}
1102-
for (auto &swap : swaps_made) {
1117+
for (auto &move : moves_made) {
11031118
// Where we have ripped up cells; add them to the queue
1104-
if (swap.second != nullptr)
1105-
remaining.emplace(chain_size[swap.second->name] *
1106-
cfg.get_cell_legalisation_weight(ctx, swap.second),
1107-
swap.second->name);
1119+
if (move.second != nullptr && (move.second->cluster == ClusterId() || ctx->getClusterRootCell(move.second->cluster) == move.second))
1120+
remaining.emplace(chain_size[move.second->name] *
1121+
cfg.get_cell_legalisation_weight(ctx, move.second),
1122+
move.second->name);
11081123
}
11091124

11101125
placed = true;
@@ -1841,6 +1856,7 @@ PlacerHeapCfg::PlacerHeapCfg(Context *ctx)
18411856
timing_driven = ctx->setting<bool>("timing_driven");
18421857
solverTolerance = 1e-5;
18431858
placeAllAtOnce = false;
1859+
chainRipup = false;
18441860

18451861
int timeout_divisor = ctx->setting<int>("placerHeap/cellPlacementTimeout", 8);
18461862
if (timeout_divisor > 0) {

common/place/placer_heap.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,7 @@ struct PlacerHeapCfg
4545
bool placeAllAtOnce;
4646
float netShareWeight;
4747
bool parallelRefine;
48+
bool chainRipup;
4849
int cell_placement_timeout;
4950

5051
int hpwl_scale_x, hpwl_scale_y;

himbaechel/uarch/gatemate/gatemate.cc

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -456,7 +456,10 @@ void GateMateImpl::expandBoundingBox(BoundingBox &bb) const
456456
bb.y1 = std::min((bb.y1 & 0xfffe) + 5, ctx->getGridDimY());
457457
}
458458

459-
void GateMateImpl::configurePlacerHeap(PlacerHeapCfg &cfg) { cfg.placeAllAtOnce = true; }
459+
void GateMateImpl::configurePlacerHeap(PlacerHeapCfg &cfg) {
460+
cfg.chainRipup = true;
461+
cfg.placeAllAtOnce = true;
462+
}
460463

461464
int GateMateImpl::get_dff_config(CellInfo *dff) const
462465
{

0 commit comments

Comments
 (0)