Skip to content

Commit 60c0f11

Browse files
committed
pad: add pushing for tunneling to push instances out of reach under obstructions
Signed-off-by: Peter Gadfort <[email protected]>
1 parent 7d20a8d commit 60c0f11

File tree

2 files changed

+117
-35
lines changed

2 files changed

+117
-35
lines changed

src/pad/src/PadPlacer.cpp

Lines changed: 109 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -1218,6 +1218,8 @@ bool PlacerPadPlacer::padSpreading(
12181218
const double dbus = getBlock()->getDbUnitsPerMicron();
12191219
const int site_width = getRow()->getSpacing();
12201220

1221+
std::map<int, int> failed_tunnel_positions;
1222+
12211223
int total_move = 0;
12221224
int net_move = 0;
12231225
debugPrint(getLogger(),
@@ -1310,9 +1312,12 @@ bool PlacerPadPlacer::padSpreading(
13101312
const int check_move
13111313
= std::max(prev_pos, std::min(next_pos, curr_pos + move_by));
13121314
if (move_by != 0) {
1313-
const int tunnel_move = getTunnelingPosition(
1315+
const auto& [tunnel_move, tunnel_ideal] = getTunnelingPosition(
13141316
curr, check_move, move_by > 0, prev_pos, curr_pos, next_pos, itr);
13151317
move_by = tunnel_move - curr_pos;
1318+
if (tunnel_move != tunnel_ideal) {
1319+
failed_tunnel_positions.emplace(i, tunnel_ideal);
1320+
}
13161321
}
13171322

13181323
// Record stats
@@ -1342,6 +1347,70 @@ bool PlacerPadPlacer::padSpreading(
13421347
total_force);
13431348
}
13441349

1350+
// Push instances causing tunneling to fail
1351+
for (const auto& [inst_idx, ideal_pos] : failed_tunnel_positions) {
1352+
const int delta_pos = ideal_pos - positions[insts[inst_idx]]->center;
1353+
const int push = ((delta_pos < 0) ? -1 : 1)
1354+
* std::ceil((damper * std::abs(delta_pos)) / site_width)
1355+
* site_width;
1356+
std::vector<odb::dbInst*> push_insts;
1357+
int last_idx = inst_idx;
1358+
int bound_pos;
1359+
if (delta_pos > 0) {
1360+
for (int j = inst_idx + 1; j < insts.size(); j++) {
1361+
if (positions[insts[j]]->center <= ideal_pos) {
1362+
push_insts.push_back(insts[j]);
1363+
last_idx = j;
1364+
}
1365+
}
1366+
bound_pos = last_idx == insts.size()
1367+
? getRowEnd(insts[last_idx])
1368+
: positions[insts[last_idx + 1]]->center;
1369+
} else {
1370+
for (int j = inst_idx - 1; j >= 0; j--) {
1371+
if (positions[insts[j]]->center >= ideal_pos) {
1372+
push_insts.push_back(insts[j]);
1373+
last_idx = j;
1374+
}
1375+
}
1376+
bound_pos = last_idx == 0 ? getRowStart(insts[last_idx])
1377+
: positions[insts[last_idx - 1]]->center;
1378+
}
1379+
debugPrint(getLogger(),
1380+
utl::PAD,
1381+
"Place",
1382+
2,
1383+
"{} / {}: Unable to tunnel to {:.4f}um, stuck at {:.4f}um, push "
1384+
"boundary at {:.4f}um, desired push {:.4f}um applies to: {}",
1385+
itr,
1386+
insts[inst_idx]->getName(),
1387+
ideal_pos / dbus,
1388+
positions[insts[inst_idx]]->center / dbus,
1389+
bound_pos / dbus,
1390+
push / dbus,
1391+
instNameList(push_insts));
1392+
// push instances
1393+
for (odb::dbInst* inst : push_insts) {
1394+
const int curr_pos = positions[inst]->center;
1395+
int desired_pos;
1396+
if (push < 0) {
1397+
desired_pos = std::max(bound_pos, curr_pos + push);
1398+
} else {
1399+
desired_pos = std::min(bound_pos, curr_pos + push);
1400+
}
1401+
const int move_to = convertRowIndexToPos(snapToRowSite(
1402+
desired_pos - (positions[inst]->width / 2)))
1403+
+ (positions[inst]->width / 2);
1404+
positions[inst]->setLocation(move_to - (positions[inst]->width / 2));
1405+
1406+
// Record stats
1407+
const int delta_move = move_to - curr_pos;
1408+
net_move += delta_move;
1409+
total_move += std::abs(delta_move);
1410+
}
1411+
has_violations = true;
1412+
}
1413+
13451414
placeInstances(positions);
13461415
addChartData(itr, estimateWirelengths(), total_move);
13471416
debugPrint(getLogger(),
@@ -1462,25 +1531,26 @@ int PlacerPadPlacer::getRowEnd(odb::dbInst* inst) const
14621531
return PadPlacer::getRowEnd() - (getInstWidths().at(inst) / 2);
14631532
}
14641533

1465-
int PlacerPadPlacer::getTunnelingPosition(odb::dbInst* inst,
1466-
int target,
1467-
bool move_up,
1468-
int low_bound,
1469-
int curr_pos,
1470-
int high_bound,
1471-
int itr) const
1534+
std::pair<int, int> PlacerPadPlacer::getTunnelingPosition(odb::dbInst* inst,
1535+
int target,
1536+
bool move_up,
1537+
int low_bound,
1538+
int curr_pos,
1539+
int high_bound,
1540+
int itr) const
14721541
{
14731542
const double dbus = getBlock()->getDbUnitsPerMicron();
14741543
placeInstanceSimple(inst, target, true);
1544+
const int ideal = getNearestLegalPosition(inst, target, !move_up, move_up);
14751545
if (move_up) {
14761546
// pad is moving up in the row
1477-
int next = getNearestLegalPosition(inst, target, false, true);
1478-
if (next != target) {
1479-
if (next > high_bound) {
1547+
if (ideal != target) {
1548+
if (ideal > high_bound) {
14801549
// check if high_bound is safe to pin to
14811550
placeInstanceSimple(inst, high_bound, true);
14821551
if (checkInstancePlacement(inst)) {
1483-
next = getNearestLegalPosition(inst, target, true, false);
1552+
// inst is obstructed, so move to the nearest edge of the obstruction
1553+
const int next = getNearestLegalPosition(inst, target, true, false);
14841554
if (next <= high_bound) {
14851555
debugPrint(getLogger(),
14861556
utl::PAD,
@@ -1497,7 +1567,7 @@ int PlacerPadPlacer::getTunnelingPosition(odb::dbInst* inst,
14971567
low_bound / dbus,
14981568
curr_pos / dbus,
14991569
high_bound / dbus);
1500-
return next;
1570+
return {next, ideal};
15011571
}
15021572
debugPrint(getLogger(),
15031573
utl::PAD,
@@ -1509,12 +1579,12 @@ int PlacerPadPlacer::getTunnelingPosition(odb::dbInst* inst,
15091579
itr,
15101580
inst->getName(),
15111581
target / dbus,
1512-
next / dbus,
1582+
curr_pos / dbus,
15131583
high_bound / dbus,
15141584
low_bound / dbus,
15151585
curr_pos / dbus,
15161586
high_bound / dbus);
1517-
return curr_pos;
1587+
return {curr_pos, ideal}; // stay in the same position
15181588
}
15191589
}
15201590
debugPrint(getLogger(),
@@ -1526,21 +1596,20 @@ int PlacerPadPlacer::getTunnelingPosition(odb::dbInst* inst,
15261596
itr,
15271597
inst->getName(),
15281598
target / dbus,
1529-
next / dbus,
1599+
ideal / dbus,
15301600
low_bound / dbus,
15311601
curr_pos / dbus,
15321602
high_bound / dbus);
1533-
return next;
1603+
return {ideal, ideal};
15341604
}
15351605
}
15361606
// pad is moving down in the row
1537-
int next = getNearestLegalPosition(inst, target, true, false);
1538-
if (next != target) {
1539-
if (next < low_bound) {
1607+
if (ideal != target) {
1608+
if (ideal < low_bound) {
15401609
// check if low_bound is safe to pin to
15411610
placeInstanceSimple(inst, low_bound, true);
15421611
if (checkInstancePlacement(inst)) {
1543-
next = getNearestLegalPosition(inst, target, true, false);
1612+
const int next = getNearestLegalPosition(inst, target, true, false);
15441613
if (next >= low_bound) {
15451614
debugPrint(getLogger(),
15461615
utl::PAD,
@@ -1557,9 +1626,8 @@ int PlacerPadPlacer::getTunnelingPosition(odb::dbInst* inst,
15571626
low_bound / dbus,
15581627
curr_pos / dbus,
15591628
high_bound / dbus);
1560-
return next;
1629+
return {next, ideal};
15611630
}
1562-
next = curr_pos;
15631631
debugPrint(getLogger(),
15641632
utl::PAD,
15651633
"Place",
@@ -1570,12 +1638,12 @@ int PlacerPadPlacer::getTunnelingPosition(odb::dbInst* inst,
15701638
itr,
15711639
inst->getName(),
15721640
target / dbus,
1573-
next / dbus,
1641+
curr_pos / dbus,
15741642
low_bound / dbus,
15751643
low_bound / dbus,
15761644
curr_pos / dbus,
15771645
high_bound / dbus);
1578-
return next;
1646+
return {curr_pos, ideal};
15791647
}
15801648
}
15811649
debugPrint(getLogger(),
@@ -1587,14 +1655,14 @@ int PlacerPadPlacer::getTunnelingPosition(odb::dbInst* inst,
15871655
itr,
15881656
inst->getName(),
15891657
target / dbus,
1590-
next / dbus,
1658+
ideal / dbus,
15911659
low_bound / dbus,
15921660
curr_pos / dbus,
15931661
high_bound / dbus);
1594-
return next;
1662+
return {ideal, ideal};
15951663
}
15961664

1597-
return target;
1665+
return {target, target};
15981666
}
15991667

16001668
void PlacerPadPlacer::debugCheckPlacement() const
@@ -1622,6 +1690,19 @@ void PlacerPadPlacer::debugCheckPlacement() const
16221690
}
16231691
}
16241692

1693+
std::string PlacerPadPlacer::instNameList(
1694+
const std::vector<odb::dbInst*>& insts) const
1695+
{
1696+
std::string inst_string;
1697+
for (auto* inst : insts) {
1698+
if (!inst_string.empty()) {
1699+
inst_string += ", ";
1700+
}
1701+
inst_string += inst->getName();
1702+
}
1703+
return inst_string;
1704+
}
1705+
16251706
//////////////////////////
16261707

16271708
int PlacerPadPlacer::InstAnchors::overlap(

src/pad/src/PadPlacer.h

Lines changed: 8 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -271,14 +271,15 @@ class PlacerPadPlacer : public PadPlacer
271271
bool round_up = false) const;
272272
int getRowStart(odb::dbInst* inst) const;
273273
int getRowEnd(odb::dbInst* inst) const;
274-
int getTunnelingPosition(odb::dbInst* inst,
275-
int target,
276-
bool move_up,
277-
int low_bound,
278-
int curr_pos,
279-
int high_bound,
280-
int itr) const;
274+
std::pair<int, int> getTunnelingPosition(odb::dbInst* inst,
275+
int target,
276+
bool move_up,
277+
int low_bound,
278+
int curr_pos,
279+
int high_bound,
280+
int itr) const;
281281
void debugCheckPlacement() const;
282+
std::string instNameList(const std::vector<odb::dbInst*>& insts) const;
282283

283284
std::map<odb::dbInst*, std::set<odb::dbITerm*>> iterm_connections_;
284285
std::map<odb::dbInst*, int> ideal_positions_;

0 commit comments

Comments
 (0)