diff --git a/liberty/EquivCells.cc b/liberty/EquivCells.cc index 953202ee..6afca9c9 100644 --- a/liberty/EquivCells.cc +++ b/liberty/EquivCells.cc @@ -29,6 +29,8 @@ namespace sta { +using std::max; + typedef UnorderedMap LibertyCellHashMap; typedef Set LibertyCellSet; @@ -116,6 +118,13 @@ struct CellDriveResistanceLess } }; +static float +cellDriveResistance(const LibertyCell *cell) +{ + return max(cell->driveResistance(TransRiseFall::rise()), + cell->driveResistance(TransRiseFall::fall())); +} + static void sortCellEquivs(LibertyCellSet &cell_equivs) { @@ -135,30 +144,6 @@ sortCellEquivs(LibertyCellSet &cell_equivs) } } -// Use the worst "drive" for all the timing arcs in the cell. -static float -cellDriveResistance(const LibertyCell *cell) -{ - float max_drive = 0.0; - LibertyCellTimingArcSetIterator set_iter(cell); - while (set_iter.hasNext()) { - TimingArcSet *set = set_iter.next(); - if (!set->role()->isTimingCheck()) { - TimingArcSetArcIterator arc_iter(set); - while (arc_iter.hasNext()) { - TimingArc *arc = arc_iter.next(); - GateTimingModel *model = dynamic_cast(arc->model()); - if (model) { - float drive = model->driveResistance(cell, nullptr); - if (drive > max_drive) - max_drive = drive; - } - } - } - } - return max_drive; -} - static unsigned hashCell(const LibertyCell *cell) { diff --git a/liberty/Liberty.cc b/liberty/Liberty.cc index 9d0a289f..7a3f03d2 100644 --- a/liberty/Liberty.cc +++ b/liberty/Liberty.cc @@ -1477,6 +1477,30 @@ LibertyCell::setEquivCells(LibertyCellSeq *equiv_cells) equiv_cells_ = equiv_cells; } +// Use the worst "drive" for all the timing arcs in the cell. +float +LibertyCell::driveResistance(const TransRiseFall *tr) const +{ + float max_drive = 0.0; + LibertyCellTimingArcSetIterator set_iter(this); + while (set_iter.hasNext()) { + TimingArcSet *set = set_iter.next(); + if (!set->role()->isTimingCheck()) { + TimingArcSetArcIterator arc_iter(set); + while (arc_iter.hasNext()) { + TimingArc *arc = arc_iter.next(); + GateTimingModel *model = dynamic_cast(arc->model()); + if (model) { + float drive = model->driveResistance(this, nullptr); + if (drive > max_drive) + max_drive = drive; + } + } + } + } + return max_drive; +} + LibertyCell * LibertyCell::higherDrive() const { diff --git a/liberty/Liberty.hh b/liberty/Liberty.hh index 9d1c8a91..f1809fc1 100644 --- a/liberty/Liberty.hh +++ b/liberty/Liberty.hh @@ -496,6 +496,7 @@ public: // Internal. LibertyCellSeq *equivCellsRaw() { return equiv_cells_; } void setEquivCells(LibertyCellSeq *equiv_cells); + float driveResistance(const TransRiseFall *tr) const; void setHigherDrive(LibertyCell *cell); void setLowerDrive(LibertyCell *cell); bool isBuffer() const; diff --git a/search/Property.cc b/search/Property.cc index b90e0941..7598298d 100644 --- a/search/Property.cc +++ b/search/Property.cc @@ -527,12 +527,18 @@ getProperty(const LibertyCell *cell, return PropertyValue(cell->filename()); else if (stringEqual(property, "library")) return PropertyValue(cell->libertyLibrary()); + else if (stringEqual(property, "drive_resistance_rise")) + return PropertyValue(cell->driveResistance(TransRiseFall::rise())); + else if (stringEqual(property, "drive_resistance_fall")) + return PropertyValue(cell->driveResistance(TransRiseFall::fall())); else if (stringEqual(property, "higher_drive")) return PropertyValue(cell->higherDrive()); else if (stringEqual(property, "lower_drive")) return PropertyValue(cell->lowerDrive()); else if (stringEqual(property, "is_buffer")) return PropertyValue(cell->isBuffer()); + else if (stringEqual(property, "dont_use")) + return PropertyValue(cell->dontUse()); else throw PropertyUnknown("liberty cell", property); }