Skip to content

Commit

Permalink
Merge pull request The-OpenROAD-Project#5541 from gadfort/pdn-generat…
Browse files Browse the repository at this point in the history
…e-techvia-blockvias

pdn: create block via arrays for techvias to reduce instance count
  • Loading branch information
eder-matheus authored Aug 10, 2024
2 parents fd30b67 + 14cc80d commit cb6f91e
Show file tree
Hide file tree
Showing 11 changed files with 1,927 additions and 69,012 deletions.
35 changes: 35 additions & 0 deletions src/pdn/src/techlayer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -107,6 +107,41 @@ int TechLayer::snapToGrid(int pos, int greater_than) const
return pos;
}

int TechLayer::snapToGridInterval(odb::dbBlock* block, int dist) const
{
odb::dbTechLayerDir dir = layer_->getDirection();

int origin = 0;
int num = 0;
int step = 0;
for (auto* grid : block->getTrackGrids()) {
if (grid->getTechLayer() != layer_) {
continue;
}

if (dir == odb::dbTechLayerDir::VERTICAL) {
if (grid->getNumGridPatternsX() < 1) {
continue;
}

grid->getGridPatternX(0, origin, num, step);
} else {
if (grid->getNumGridPatternsY() < 1) {
continue;
}

grid->getGridPatternY(0, origin, num, step);
}
}

if (num == 0 || step == 0) {
return dist;
}

const int count = std::max(1, dist / step);
return count * step;
}

int TechLayer::snapToManufacturingGrid(odb::dbTech* tech,
int pos,
bool round_up)
Expand Down
1 change: 1 addition & 0 deletions src/pdn/src/techlayer.h
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,7 @@ class TechLayer
void populateGrid(odb::dbBlock* block,
odb::dbTechLayerDir dir = odb::dbTechLayerDir::NONE);
int snapToGrid(int pos, int greater_than = 0) const;
int snapToGridInterval(odb::dbBlock* block, int dist) const;
bool hasGrid() const { return !grid_.empty(); }
const std::vector<int>& getGrid() const { return grid_; }
int snapToManufacturingGrid(int pos, bool round_up = false) const;
Expand Down
141 changes: 106 additions & 35 deletions src/pdn/src/via.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -261,6 +261,7 @@ DbTechVia::DbTechVia(odb::dbTechVia* via,
Enclosure* required_bottom_enc,
Enclosure* required_top_enc)
: via_(via),
cut_layer_(nullptr),
rows_(rows),
row_pitch_(row_pitch),
cols_(cols),
Expand All @@ -279,6 +280,8 @@ DbTechVia::DbTechVia(odb::dbTechVia* via,
odb::Rect rect = box->getBox();

if (layer->getType() == odb::dbTechLayerType::CUT) {
cut_layer_ = layer;
single_via_rect_ = rect;
via_rect_.merge(rect);
} else {
if (layer == via->getBottomLayer()) {
Expand Down Expand Up @@ -328,64 +331,108 @@ DbVia::ViaLayerShape DbTechVia::generate(
TechLayer bottom(via_->getBottomLayer());
TechLayer top(via_->getTopLayer());

bool do_bottom_snap = false;
if (ongrid.find(bottom.getLayer()) != ongrid.end()) {
bottom.populateGrid(block);
do_bottom_snap = true;
}

bool do_top_snap = false;
if (ongrid.find(top.getLayer()) != ongrid.end()) {
top.populateGrid(block);
do_top_snap = true;
}

TechLayer* row_snap = &top;
TechLayer* col_snap = &bottom;
bool* do_row_snap = &do_top_snap;
bool* do_col_snap = &do_bottom_snap;
if (top.getLayer()->getDirection() == odb::dbTechLayerDir::VERTICAL) {
std::swap(row_snap, col_snap);
std::swap(do_row_snap, do_col_snap);
}

ViaLayerShape via_shapes;
odb::Point new_via_center;
odb::dbSBox* via;

odb::Rect via_rect(0, 0, (cols_ - 1) * col_pitch_, (rows_ - 1) * row_pitch_);
via_rect.moveTo(x - via_rect.dx() / 2, y - via_rect.dy() / 2);
if (rows_ > 1 || cols_ > 1) {
const std::string via_name = getViaName(ongrid);
auto* bvia = block->findVia(via_name.c_str());

int row = via_rect.yMin() - via_center_.getY();
for (int r = 0; r < rows_; r++) {
const int row_center = row + via_center_.getY();
const int row_use
= row_snap->snapToGrid(row_center, row_center - 1) - via_center_.getY();
if (bvia == nullptr) {
const int cut_width = single_via_rect_.dx();
const int cut_height = single_via_rect_.dy();

int col = via_rect.xMin() - via_center_.getX();
for (int c = 0; c < cols_; c++) {
const int col_center = col + via_center_.getX();
const int col_use = col_snap->snapToGrid(col_center, col_center - 1)
- via_center_.getX();

const odb::Point new_via_center(col_use, row_use);

auto* via = odb::dbSBox::create(
wire, via_, new_via_center.getX(), new_via_center.getY(), type);
auto shapes = getLayerShapes(via);
const odb::dbTransform xfm(new_via_center);
odb::Rect top_shape = required_top_rect_;
xfm.apply(top_shape);
shapes.top.insert({top_shape, via});
odb::Rect bottom_shape = required_bottom_rect_;
xfm.apply(bottom_shape);
shapes.bottom.insert({bottom_shape, via});
combineLayerShapes(shapes, via_shapes);
incrementCount();
bvia = odb::dbVia::create(block, via_name.c_str());

col = col_use + col_pitch_;
odb::dbViaParams params = bvia->getViaParams();

if (col > via_rect.xMax()) {
break;
params.setBottomLayer(via_->getBottomLayer());
params.setCutLayer(cut_layer_);
params.setTopLayer(via_->getTopLayer());

params.setXCutSize(cut_width);
params.setYCutSize(cut_height);

// snap to track intervals
int x_pitch = col_pitch_;
if (*do_col_snap) {
x_pitch = col_snap->snapToGridInterval(block, col_pitch_);
}
int y_pitch = row_pitch_;
if (*do_row_snap) {
y_pitch = row_snap->snapToGridInterval(block, row_pitch_);
}
}

row = row_use + row_pitch_;
if (row > via_rect.yMax()) {
break;
params.setXCutSpacing(x_pitch - cut_width);
params.setYCutSpacing(y_pitch - cut_height);

params.setXBottomEnclosure(
std::min(via_rect_.xMin() - required_bottom_rect_.xMin(),
required_bottom_rect_.xMax() - via_rect_.xMax()));
params.setYBottomEnclosure(
std::min(via_rect_.yMin() - required_bottom_rect_.yMin(),
required_bottom_rect_.yMax() - via_rect_.yMax()));
params.setXTopEnclosure(
std::min(via_rect_.xMin() - required_top_rect_.xMin(),
required_top_rect_.xMax() - via_rect_.xMax()));
params.setYTopEnclosure(
std::min(via_rect_.yMin() - required_top_rect_.yMin(),
required_top_rect_.yMax() - via_rect_.yMax()));

params.setNumCutRows(rows_);
params.setNumCutCols(cols_);

params.setXOrigin(via_center_.x());
params.setYOrigin(via_center_.y());

bvia->setViaParams(params);
}

new_via_center
= odb::Point(col_snap->snapToGrid(x), row_snap->snapToGrid(y));

incrementCount(rows_ * cols_);
via = odb::dbSBox::create(
wire, bvia, new_via_center.x(), new_via_center.y(), type);
} else {
incrementCount();
new_via_center = odb::Point(col_snap->snapToGrid(x - via_center_.getX()),
row_snap->snapToGrid(y - via_center_.getY()));
via = odb::dbSBox::create(
wire, via_, new_via_center.x(), new_via_center.y(), type);
}

ViaLayerShape via_shapes = getLayerShapes(via);

const odb::dbTransform xfm(new_via_center);
odb::Rect top_shape = required_top_rect_;
xfm.apply(top_shape);
via_shapes.top.insert({top_shape, via});
odb::Rect bottom_shape = required_bottom_rect_;
xfm.apply(bottom_shape);
via_shapes.bottom.insert({bottom_shape, via});

return via_shapes;
}

Expand All @@ -411,6 +458,30 @@ odb::Rect DbTechVia::getViaRect(bool include_enclosure,
return via_rect_;
}

std::string DbTechVia::getViaName(
const std::set<odb::dbTechLayer*>& ongrid) const
{
const std::string seperator = "_";
std::string name = via_->getName();
// name after rows and columns
name += seperator;
name += std::to_string(rows_);
name += seperator;
name += std::to_string(cols_);
// name after pitch
name += seperator;
name += std::to_string(row_pitch_);
name += seperator;
name += std::to_string(col_pitch_);
// name on grid layers
for (auto* layer : ongrid) {
name += seperator;
name += layer->getName();
}

return name;
}

///////////

DbGenerateVia::DbGenerateVia(const odb::Rect& rect,
Expand Down
5 changes: 5 additions & 0 deletions src/pdn/src/via.h
Original file line number Diff line number Diff line change
Expand Up @@ -183,6 +183,7 @@ class DbBaseVia : public DbVia

protected:
void incrementCount() { count_++; }
void incrementCount(int count) { count_ += count; }

private:
int count_ = 0;
Expand Down Expand Up @@ -218,19 +219,23 @@ class DbTechVia : public DbBaseVia

private:
odb::dbTechVia* via_;
odb::dbTechLayer* cut_layer_;
int rows_;
int row_pitch_;
int cols_;
int col_pitch_;

odb::Rect via_rect_;
odb::Rect single_via_rect_;
odb::Rect enc_bottom_rect_;
odb::Rect enc_top_rect_;

odb::Rect required_bottom_rect_;
odb::Rect required_top_rect_;

odb::Point via_center_;

std::string getViaName(const std::set<odb::dbTechLayer*>& ongrid) const;
};

// Wrapper to handle building dbTechViaGenerate vias (GENERATE vias) as
Expand Down
Loading

0 comments on commit cb6f91e

Please sign in to comment.