Liberty cell drive_resistance property
This commit is contained in:
parent
96fcf1d8b2
commit
d9237aa3e5
|
|
@ -29,6 +29,8 @@
|
|||
|
||||
namespace sta {
|
||||
|
||||
using std::max;
|
||||
|
||||
typedef UnorderedMap<unsigned, LibertyCellSeq*> LibertyCellHashMap;
|
||||
typedef Set<LibertyCell*> 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<GateTimingModel*>(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)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -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<GateTimingModel*>(arc->model());
|
||||
if (model) {
|
||||
float drive = model->driveResistance(this, nullptr);
|
||||
if (drive > max_drive)
|
||||
max_drive = drive;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return max_drive;
|
||||
}
|
||||
|
||||
LibertyCell *
|
||||
LibertyCell::higherDrive() const
|
||||
{
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in New Issue