Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
18 commits
Select commit Hold shift + click to select a range
82f5b00
ppl: avoid boundary PDN shapes when placing pins
eder-matheus Aug 6, 2026
dabc403
ppl: avoid slots with blocked mirrored slots for mirrored pins
eder-matheus Aug 6, 2026
2b97672
ppl: apply excluded intervals to polygon die slots
eder-matheus Aug 6, 2026
71f440c
ppl: make place_pin avoid boundary PDN shapes
eder-matheus Aug 6, 2026
68ccc3a
ppl: clear fixed pin shapes between placement runs
eder-matheus Aug 6, 2026
781a2bf
ppl: return core min width and area maps by reference
eder-matheus Aug 6, 2026
b9defd3
ppl: avoid routing obstructions at the die boundary
eder-matheus Aug 6, 2026
897b771
ppl: avoid special net via landing pads at the die boundary
eder-matheus Aug 6, 2026
1680856
ppl: floor the top layer keepout at the layer min spacing
eder-matheus Aug 6, 2026
e4ab356
ppl: consolidate pin geometry and boundary shape padding
eder-matheus Aug 6, 2026
1f2517b
ppl: share the checker procs of the boundary pdn tests
eder-matheus Aug 6, 2026
c3b3a4d
ppl: pad blocked regions with the actual pin size in place_pin
eder-matheus Aug 6, 2026
2c00e47
ppl: block polygon die slots on internal edges near boundary shapes
eder-matheus Aug 6, 2026
71c56a1
ppl: honor obstruction min spacing and effective width
eder-matheus Aug 6, 2026
7eaba15
ppl: honor spacing rules of top layer blocking shapes
eder-matheus Aug 6, 2026
08f010a
ppl: honor spacing rules of fixed pins and wide manual pins
eder-matheus Aug 6, 2026
81cecb2
ppl: skip non-routing layers and simplify top layer slot filtering
eder-matheus Aug 7, 2026
9eb3cb9
ppl: fix line length in obstruction_boundary test
eder-matheus Aug 7, 2026
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
34 changes: 34 additions & 0 deletions src/ppl/include/ppl/IOPlacer.h
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
#include <memory>
#include <set>
#include <string>
#include <tuple>
#include <utility>
#include <vector>

Expand Down Expand Up @@ -218,6 +219,32 @@ class IOPlacer
bool checkBlocked(Edge edge, odb::Line, const odb::Point& pos, int layer);
std::vector<Interval> findBlockedIntervals(const odb::Rect& die_area,
const odb::Rect& box);
struct PinSize
{
int half_width = 0;
int height = 0;
};
// a shape blocking pins, with the spacing rules it carries
struct BlockingShape
{
odb::Rect rect;
int min_spacing = 0;
int effective_width = 0;
};
PinSize computePinSize(int layer, bool vertical_pin);
int computeLayerSpacing(int layer, int shape_width, int parallel_length);
odb::Rect padShapeForPin(const odb::Rect& box,
int layer,
bool vertical_pin,
int min_spacing = 0,
int effective_width = 0);
void excludeBoundaryShape(const odb::Rect& box,
odb::dbTechLayer* tech_layer,
const odb::Rect& die_area,
int min_spacing = 0,
int effective_width = 0);
void getBlockedRegions();
void getBlockedRegionsFromPDN();
void getBlockedRegionsFromMacros();
void getBlockedRegionsFromDbObstructions();
Edge getMirroredEdge(const Edge& edge);
Expand Down Expand Up @@ -261,7 +288,14 @@ class IOPlacer
std::vector<Interval> excluded_intervals_;
std::vector<Constraint> constraints_;
FallbackPins fallback_pins_;
// fixed pin shapes padded by the pin size and spacing, per layer
std::map<int, std::vector<odb::Rect>> layer_fixed_pins_shapes_;
// padded boundary shapes blocking polygon die slots, per layer
std::map<int, std::vector<odb::Rect>> layer_blocked_shapes_;
std::map<std::pair<int, bool>, PinSize> pin_size_cache_;
std::map<std::tuple<int, int, int>, int> spacing_cache_;
// width of the pin being placed by place_pin, for the spacing rules
int manual_pin_width_ = 0;

utl::Logger* logger_ = nullptr;
std::unique_ptr<utl::Validator> validator_;
Expand Down
2 changes: 1 addition & 1 deletion src/ppl/src/Core.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ int Core::getPerimeter() const
return (x + y) * 2;
}

std::vector<odb::Line> Core::getDieAreaEdges()
const std::vector<odb::Line>& Core::getDieAreaEdges() const
{
return die_area_edges_;
}
Expand Down
10 changes: 5 additions & 5 deletions src/ppl/src/Core.h
Original file line number Diff line number Diff line change
Expand Up @@ -52,14 +52,14 @@ class Core
const LayerToVector& getInitTracksY() const { return init_tracks_y_; }
const LayerToVector& getNumTracksX() const { return num_tracks_x_; }
const LayerToVector& getNumTracksY() const { return num_tracks_y_; }
std::map<int, int> getMinAreaX() const { return min_area_x_; }
std::map<int, int> getMinAreaY() const { return min_area_y_; }
std::map<int, int> getMinWidthX() const { return min_width_x_; }
std::map<int, int> getMinWidthY() const { return min_width_y_; }
const std::map<int, int>& getMinAreaX() const { return min_area_x_; }
const std::map<int, int>& getMinAreaY() const { return min_area_y_; }
const std::map<int, int>& getMinWidthX() const { return min_width_x_; }
const std::map<int, int>& getMinWidthY() const { return min_width_y_; }
int getDatabaseUnit() const { return database_unit_; }
int getPerimeter() const;
odb::Point getMirroredPosition(const odb::Point& position) const;
std::vector<odb::Line> getDieAreaEdges();
const std::vector<odb::Line>& getDieAreaEdges() const;

private:
odb::Rect boundary_;
Expand Down
20 changes: 18 additions & 2 deletions src/ppl/src/HungarianMatching.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,7 @@ void HungarianMatching::createMatrix()
for (int idx : pin_indices_) {
IOPin& io_pin = netlist_->getIoPin(idx);
if (!io_pin.isInGroup()) {
const bool has_mirror = io_pin.getBTerm()->hasMirroredBTerm();
bool is_mirrored = false;
std::vector<int> larger_costs;
int slot_index = 0;
Expand All @@ -73,7 +74,11 @@ void HungarianMatching::createMatrix()
const int mirrored_cost = getMirroredPinCost(io_pin, slot_pos);
const int hpwl = io_net_hpwl + mirrored_cost;
larger_costs.push_back(std::max(io_net_hpwl, mirrored_cost));
hungarian_matrix_[slot_index][pin_index] = hpwl;
// avoid slots whose mirrored slot cannot receive the mirrored pin
hungarian_matrix_[slot_index][pin_index]
= has_mirror && isMirroredSlotBlocked(slot_pos, slots_[i].layer)
? hungarian_fail_
: hpwl;
is_mirrored = is_mirrored || mirrored_cost != 0;
slot_index++;
}
Expand All @@ -82,6 +87,9 @@ void HungarianMatching::createMatrix()
std::vector<uint8_t> rank = getTieBreakRank(larger_costs);
for (int idx = 0; idx < slot_index; idx++) {
const int hpwl = hungarian_matrix_[idx][pin_index];
if (hpwl == hungarian_fail_) {
continue;
}
if ((hpwl >> 24) != 0) {
logger_->critical(utl::PPL, 210, "Cost for pin exceeds 24 bits.");
}
Expand Down Expand Up @@ -161,7 +169,7 @@ void HungarianMatching::assignMirroredPins(IOPin& io_pin,
mirrored_pin.setPlaced();
assignment.push_back(mirrored_pin);
int slot_index = getSlotIdxByPosition(mirrored_pos, mirrored_pin.getLayer());
if (slot_index < 0 || slots_[slot_index].used) {
if (slot_index < 0 || !slots_[slot_index].isAvailable()) {
odb::dbTechLayer* layer
= db_->getTech()->findRoutingLayer(mirrored_pin.getLayer());
logger_->error(
Expand Down Expand Up @@ -348,6 +356,14 @@ void HungarianMatching::getAssignmentForGroups(std::vector<IOPin>& assignment,
assignment_.clear();
}

bool HungarianMatching::isMirroredSlotBlocked(const odb::Point& pos,
int layer) const
{
const int slot_index
= getSlotIdxByPosition(core_->getMirroredPosition(pos), layer);
return slot_index < 0 || !slots_[slot_index].isAvailable();
}

int HungarianMatching::getSlotIdxByPosition(const odb::Point& position,
int layer) const
{
Expand Down
1 change: 1 addition & 0 deletions src/ppl/src/HungarianMatching.h
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,7 @@ class HungarianMatching
void createMatrixForGroups();
void assignMirroredPins(IOPin& io_pin, std::vector<IOPin>& assignment);
int getSlotIdxByPosition(const odb::Point& position, int layer) const;
bool isMirroredSlotBlocked(const odb::Point& pos, int layer) const;
bool groupHasMirroredPin(const std::vector<int>& group);
int getMirroredPinCost(IOPin& io_pin, const odb::Point& position);
Edge getMirroredEdge(const Edge& edge);
Expand Down
Loading
Loading