Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

ppl: support multiple track patterns #6466

Open
wants to merge 5 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from 3 commits
Commits
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
38 changes: 20 additions & 18 deletions src/ppl/src/Core.h
Original file line number Diff line number Diff line change
Expand Up @@ -44,17 +44,19 @@ namespace ppl {
using odb::Point;
using odb::Rect;

using LayerToVector = std::map<int, std::vector<int>>;

class Core
{
public:
Core();
Core(const Rect& boundary,
const std::map<int, int>& min_dst_pins_x,
const std::map<int, int>& min_dst_pins_y,
const std::map<int, int>& init_tracks_x,
const std::map<int, int>& init_tracks_y,
const std::map<int, int>& num_tracks_x,
const std::map<int, int>& num_tracks_y,
const LayerToVector& min_dst_pins_x,
const LayerToVector& min_dst_pins_y,
const LayerToVector& init_tracks_x,
const LayerToVector& init_tracks_y,
const LayerToVector& num_tracks_x,
const LayerToVector& num_tracks_y,
const std::map<int, int>& min_area_x,
const std::map<int, int>& min_area_y,
const std::map<int, int>& min_width_x,
Expand All @@ -76,12 +78,12 @@ class Core
}

Rect getBoundary() const { return boundary_; }
std::map<int, int> getMinDstPinsX() const { return min_dst_pins_x_; }
std::map<int, int> getMinDstPinsY() const { return min_dst_pins_y_; }
std::map<int, int> getInitTracksX() const { return init_tracks_x_; }
std::map<int, int> getInitTracksY() const { return init_tracks_y_; }
std::map<int, int> getNumTracksX() const { return num_tracks_x_; }
std::map<int, int> getNumTracksY() const { return num_tracks_y_; }
const LayerToVector& getMinDstPinsX() const { return min_dst_pins_x_; }
const LayerToVector& getMinDstPinsY() const { return min_dst_pins_y_; }
const LayerToVector& getInitTracksX() const { return init_tracks_x_; }
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_; }
Expand All @@ -92,12 +94,12 @@ class Core

private:
Rect boundary_;
std::map<int, int> min_dst_pins_x_;
std::map<int, int> min_dst_pins_y_;
std::map<int, int> init_tracks_x_;
std::map<int, int> init_tracks_y_;
std::map<int, int> num_tracks_x_;
std::map<int, int> num_tracks_y_;
LayerToVector min_dst_pins_x_;
LayerToVector min_dst_pins_y_;
LayerToVector init_tracks_x_;
LayerToVector init_tracks_y_;
LayerToVector num_tracks_x_;
LayerToVector num_tracks_y_;
std::map<int, int> min_area_x_;
std::map<int, int> min_area_y_;
std::map<int, int> min_width_x_;
Expand Down
215 changes: 131 additions & 84 deletions src/ppl/src/IOPlacer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -812,16 +812,24 @@ void IOPlacer::computeRegionIncrease(const Interval& interval,
int min_dist = std::numeric_limits<int>::min();

if (interval.getLayer() != -1) {
min_dist = vertical_pin ? core_->getMinDstPinsX()[interval.getLayer()]
: core_->getMinDstPinsY()[interval.getLayer()];
const std::vector<int>& min_distances
= vertical_pin ? core_->getMinDstPinsX().at(interval.getLayer())
: core_->getMinDstPinsY().at(interval.getLayer());
min_dist = *(std::max_element(min_distances.begin(), min_distances.end()));
} else if (vertical_pin) {
for (int layer_idx : ver_layers_) {
const int layer_min_dist = core_->getMinDstPinsX()[layer_idx];
std::vector<int> layer_min_distances
= core_->getMinDstPinsX().at(layer_idx);
const int layer_min_dist = *(std::max_element(layer_min_distances.begin(),
layer_min_distances.end()));
min_dist = std::max(layer_min_dist, min_dist);
}
} else {
for (int layer_idx : hor_layers_) {
const int layer_min_dist = core_->getMinDstPinsY()[layer_idx];
std::vector<int> layer_min_distances
= core_->getMinDstPinsY().at(layer_idx);
const int layer_min_dist = *(std::max_element(layer_min_distances.begin(),
layer_min_distances.end()));
min_dist = std::max(layer_min_dist, min_dist);
}
}
Expand Down Expand Up @@ -871,80 +879,105 @@ void IOPlacer::findSlots(const std::set<int>& layers, Edge edge)
corner_avoidance_ = parms_->getCornerAvoidance();
bool dist_in_tracks = parms_->getMinDistanceInTracks();
for (int layer : layers) {
int curr_x, curr_y, start_idx, end_idx;
// get the on grid min distance
int tech_min_dst = vertical_pin ? core_->getMinDstPinsX()[layer]
: core_->getMinDstPinsY()[layer];
int min_dst_pins
= dist_in_tracks
? tech_min_dst * parms_->getMinDistance()
: tech_min_dst
* std::ceil(static_cast<float>(parms_->getMinDistance())
/ tech_min_dst);

min_dst_pins
= (min_dst_pins == 0) ? default_min_dist_ * tech_min_dst : min_dst_pins;

if (corner_avoidance_ == -1) {
corner_avoidance_ = num_tracks_offset_ * tech_min_dst;
// limit default offset to 1um
if (corner_avoidance_ > getBlock()->micronsToDbu(1.0)) {
corner_avoidance_ = getBlock()->micronsToDbu(1.0);
}
}
const std::vector<int>& layer_min_distances
= vertical_pin ? core_->getMinDstPinsX().at(layer)
: core_->getMinDstPinsY().at(layer);
const std::vector<int>& layer_init_tracks
= vertical_pin ? core_->getInitTracksX().at(layer)
: core_->getInitTracksY().at(layer);
const std::vector<int>& layer_num_tracks
= vertical_pin ? core_->getNumTracksX().at(layer)
: core_->getNumTracksY().at(layer);

int init_tracks = vertical_pin ? core_->getInitTracksX()[layer]
: core_->getInitTracksY()[layer];
int num_tracks = vertical_pin ? core_->getNumTracksX()[layer]
: core_->getNumTracksY()[layer];
std::vector<Point> slots;
int min_dst_pins;
for (int l = 0; l < layer_min_distances.size(); l++) {
int curr_x, curr_y, start_idx, end_idx;
int tech_min_dst = layer_min_distances[l];
min_dst_pins
= dist_in_tracks
? tech_min_dst * parms_->getMinDistance()
: tech_min_dst
* std::ceil(static_cast<float>(parms_->getMinDistance())
/ tech_min_dst);

min_dst_pins = (min_dst_pins == 0) ? default_min_dist_ * tech_min_dst
: min_dst_pins;

if (corner_avoidance_ == -1) {
corner_avoidance_ = num_tracks_offset_ * tech_min_dst;
// limit default offset to 1um
if (corner_avoidance_ > getBlock()->micronsToDbu(1.0)) {
corner_avoidance_ = getBlock()->micronsToDbu(1.0);
}
}

float thickness_multiplier
= vertical_pin ? parms_->getVerticalThicknessMultiplier()
: parms_->getHorizontalThicknessMultiplier();
int init_tracks = layer_init_tracks[l];
int num_tracks = layer_num_tracks[l];

int half_width = vertical_pin
? int(ceil(core_->getMinWidthX()[layer] / 2.0))
: int(ceil(core_->getMinWidthY()[layer] / 2.0));
float thickness_multiplier
= vertical_pin ? parms_->getVerticalThicknessMultiplier()
: parms_->getHorizontalThicknessMultiplier();

half_width *= thickness_multiplier;
int half_width = vertical_pin
? int(ceil(core_->getMinWidthX()[layer] / 2.0))
: int(ceil(core_->getMinWidthY()[layer] / 2.0));

int num_tracks_offset = std::ceil(corner_avoidance_ / min_dst_pins);
half_width *= thickness_multiplier;

start_idx
= std::max(0.0,
ceil(static_cast<double>((min + half_width - init_tracks))
/ min_dst_pins))
+ num_tracks_offset;
end_idx = std::min((num_tracks - 1),
static_cast<int>(floor((max - half_width - init_tracks)
/ min_dst_pins)))
- num_tracks_offset;
if (vertical_pin) {
curr_x = init_tracks + start_idx * min_dst_pins;
curr_y = (edge == Edge::bottom) ? lb_y : ub_y;
} else {
curr_y = init_tracks + start_idx * min_dst_pins;
curr_x = (edge == Edge::left) ? lb_x : ub_x;
}
int num_tracks_offset = std::ceil(corner_avoidance_ / min_dst_pins);

std::vector<Point> slots;
for (int i = start_idx; i <= end_idx; ++i) {
Point pos(curr_x, curr_y);
slots.push_back(pos);
start_idx
= std::max(0.0,
ceil(static_cast<double>((min + half_width - init_tracks))
/ min_dst_pins))
+ num_tracks_offset;
end_idx = std::min((num_tracks - 1),
static_cast<int>(floor((max - half_width - init_tracks)
eder-matheus marked this conversation as resolved.
Show resolved Hide resolved
/ min_dst_pins)))
- num_tracks_offset;
if (vertical_pin) {
curr_x += min_dst_pins;
curr_x = init_tracks + start_idx * min_dst_pins;
curr_y = (edge == Edge::bottom) ? lb_y : ub_y;
} else {
curr_y += min_dst_pins;
curr_y = init_tracks + start_idx * min_dst_pins;
curr_x = (edge == Edge::left) ? lb_x : ub_x;
}

for (int i = start_idx; i <= end_idx; ++i) {
odb::Point pos(curr_x, curr_y);
slots.push_back(pos);
if (vertical_pin) {
curr_x += min_dst_pins;
} else {
curr_y += min_dst_pins;
}
}
}

std::sort(slots.begin(),
slots.end(),
[&](const odb::Point& p1, const odb::Point& p2) {
if (vertical_pin) {
return p1.getX() < p2.getX();
}

return p1.getY() < p2.getY();
});

if (edge == Edge::top || edge == Edge::left) {
std::reverse(slots.begin(), slots.end());
}

Point last_pos = slots[0];
for (const Point& pos : slots) {
bool blocked = checkBlocked(edge, pos, layer);
slots_.push_back({blocked, false, pos, layer, edge});
if (pos == last_pos
|| std::abs(last_pos.getX() - pos.getX()) >= min_dst_pins
|| std::abs(last_pos.getY() - pos.getY()) >= min_dst_pins) {
slots_.push_back({blocked, false, pos, layer, edge});
last_pos = pos;
}
}
}
}
Expand Down Expand Up @@ -993,11 +1026,17 @@ void IOPlacer::defineSlots()
if (regular_pin_count > slots_.size()) {
int min_dist = std::numeric_limits<int>::min();
for (int layer_idx : ver_layers_) {
const int layer_min_dist = core_->getMinDstPinsX()[layer_idx];
std::vector<int> layer_min_distances
= core_->getMinDstPinsX().at(layer_idx);
const int layer_min_dist = *(std::max_element(layer_min_distances.begin(),
layer_min_distances.end()));
min_dist = std::max(layer_min_dist, min_dist);
}
for (int layer_idx : hor_layers_) {
const int layer_min_dist = core_->getMinDstPinsY()[layer_idx];
std::vector<int> layer_min_distances
= core_->getMinDstPinsY().at(layer_idx);
const int layer_min_dist = *(std::max_element(layer_min_distances.begin(),
layer_min_distances.end()));
min_dist = std::max(layer_min_dist, min_dist);
}

Expand Down Expand Up @@ -2666,28 +2705,32 @@ void IOPlacer::initCore(const std::set<int>& hor_layer_idxs,

Rect boundary = getBlock()->getDieArea();

std::map<int, int> min_spacings_x;
std::map<int, int> min_spacings_y;
std::map<int, int> init_tracks_x;
std::map<int, int> init_tracks_y;
LayerToVector min_spacings_x;
LayerToVector min_spacings_y;
LayerToVector init_tracks_x;
LayerToVector init_tracks_y;
LayerToVector num_tracks_x;
LayerToVector num_tracks_y;
std::map<int, int> min_areas_x;
std::map<int, int> min_areas_y;
std::map<int, int> min_widths_x;
std::map<int, int> min_widths_y;
std::map<int, int> num_tracks_x;
std::map<int, int> num_tracks_y;

for (int hor_layer_idx : hor_layer_idxs) {
int min_spacing_y = 0;
int init_track_y = 0;
int min_area_y = 0;
int min_width_y = 0;
int num_track_y = 0;

odb::dbTechLayer* hor_layer = getTech()->findRoutingLayer(hor_layer_idx);
odb::dbTrackGrid* hor_track_grid = getBlock()->findTrackGrid(hor_layer);
hor_track_grid->getGridPatternY(
0, init_track_y, num_track_y, min_spacing_y);
const int track_patterns_count = hor_track_grid->getNumGridPatternsY();

std::vector<int> init_track_y(track_patterns_count, 0);
std::vector<int> num_track_y(track_patterns_count, 0);
std::vector<int> min_spacing_y(track_patterns_count, 0);
int min_area_y;
int min_width_y;

for (int i = 0; i < hor_track_grid->getNumGridPatternsY(); i++) {
hor_track_grid->getGridPatternY(
i, init_track_y[i], num_track_y[i], min_spacing_y[i]);
}

min_area_y = hor_layer->getArea() * database_unit * database_unit;
min_width_y = hor_layer->getWidth();
Expand All @@ -2700,16 +2743,20 @@ void IOPlacer::initCore(const std::set<int>& hor_layer_idxs,
}

for (int ver_layer_idx : ver_layer_idxs) {
int min_spacing_x = 0;
int init_track_x = 0;
int min_area_x = 0;
int min_width_x = 0;
int num_track_x = 0;

odb::dbTechLayer* ver_layer = getTech()->findRoutingLayer(ver_layer_idx);
odb::dbTrackGrid* ver_track_grid = getBlock()->findTrackGrid(ver_layer);
ver_track_grid->getGridPatternX(
0, init_track_x, num_track_x, min_spacing_x);
const int track_patterns_count = ver_track_grid->getNumGridPatternsY();

std::vector<int> init_track_x(track_patterns_count, 0);
std::vector<int> num_track_x(track_patterns_count, 0);
std::vector<int> min_spacing_x(track_patterns_count, 0);
int min_area_x;
int min_width_x;

for (int i = 0; i < ver_track_grid->getNumGridPatternsX(); i++) {
ver_track_grid->getGridPatternX(
i, init_track_x[i], num_track_x[i], min_spacing_x[i]);
}

min_area_x = ver_layer->getArea() * database_unit * database_unit;
min_width_x = ver_layer->getWidth();
Expand Down
3 changes: 2 additions & 1 deletion src/ppl/test/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -73,8 +73,9 @@ or_integration_tests(
macro_not_placed_random
min_dist_in_tracks1
min_dist_in_tracks2
multi_layers
multiple_calls
multi_layers
multi_track_pattern
no_instance_pins
no_pins
no_tracks
Expand Down
Loading
Loading