diff --git a/liberty/Liberty.cc b/liberty/Liberty.cc index 7af31937..a28d4ab5 100644 --- a/liberty/Liberty.cc +++ b/liberty/Liberty.cc @@ -1440,11 +1440,12 @@ LibertyCell::setCornerCell(LibertyCell *corner_cell, //////////////////////////////////////////////////////////////// -// Use the worst "drive" for all the timing arcs in the cell. +// Use the min/max "drive" for all the timing arcs in the cell. float -LibertyCell::driveResistance(const TransRiseFall *tr) const +LibertyCell::driveResistance(const TransRiseFall *tr, + const MinMax *min_max) const { - float max_drive = 0.0; + float max_drive = min_max->initValue(); LibertyCellTimingArcSetIterator set_iter(this); while (set_iter.hasNext()) { TimingArcSet *set = set_iter.next(); @@ -1457,7 +1458,7 @@ LibertyCell::driveResistance(const TransRiseFall *tr) const GateTimingModel *model = dynamic_cast(arc->model()); if (model) { float drive = model->driveResistance(this, nullptr); - if (drive > max_drive) + if (min_max->compare(drive, max_drive)) max_drive = drive; } } @@ -1470,7 +1471,7 @@ LibertyCell::driveResistance(const TransRiseFall *tr) const float LibertyCell::driveResistance() const { - return driveResistance(nullptr); + return driveResistance(nullptr, MinMax::max()); } //////////////////////////////////////////////////////////////// diff --git a/liberty/Liberty.hh b/liberty/Liberty.hh index c5f9df35..f82fa793 100644 --- a/liberty/Liberty.hh +++ b/liberty/Liberty.hh @@ -490,7 +490,8 @@ public: virtual void finish(bool infer_latches, Report *report, Debug *debug); - float driveResistance(const TransRiseFall *tr) const; + float driveResistance(const TransRiseFall *tr, + const MinMax *min_max) const; // Max of rise/fall. float driveResistance() const; bool isBuffer() const; diff --git a/liberty/TableModel.cc b/liberty/TableModel.cc index a4b741e0..cf4d5a6c 100644 --- a/liberty/TableModel.cc +++ b/liberty/TableModel.cc @@ -288,8 +288,8 @@ GateTableModel::maxCapSlew(const LibertyCell *cell, } else { // Table not dependent on capacitance. - cap = 0.0; - slew = 1.0; + cap = 1.0; + slew = 0.0; } // Clip negative slews to zero. if (slew < 0.0) diff --git a/sdc/Sdc.cc b/sdc/Sdc.cc index 00665f0f..99a98038 100644 --- a/sdc/Sdc.cc +++ b/sdc/Sdc.cc @@ -2251,10 +2251,10 @@ Sdc::clockGroupsDeleteClkRefs(Clock *clk) void Sdc::setClockSense(PinSet *pins, - ClockSet *clks, - ClockSense sense) + ClockSet *clks, + ClockSense sense) { - if (clks->empty()) { + if (clks && clks->empty()) { delete clks; clks = nullptr; } diff --git a/search/Property.cc b/search/Property.cc index 6590baa6..c7121ee2 100644 --- a/search/Property.cc +++ b/search/Property.cc @@ -527,10 +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, "drive_resistance_rise_min")) + return PropertyValue(cell->driveResistance(TransRiseFall::rise(), + MinMax::min())); + else if (stringEqual(property, "drive_resistance_rise_max")) + return PropertyValue(cell->driveResistance(TransRiseFall::rise(), + MinMax::max())); + else if (stringEqual(property, "drive_resistance_fall_min")) + return PropertyValue(cell->driveResistance(TransRiseFall::fall(), + MinMax::min())); + else if (stringEqual(property, "drive_resistance_fall_max")) + return PropertyValue(cell->driveResistance(TransRiseFall::fall(), + MinMax::max())); else if (stringEqual(property, "is_buffer")) return PropertyValue(cell->isBuffer()); else if (stringEqual(property, "dont_use")) diff --git a/tcl/StaTcl.i b/tcl/StaTcl.i index fc135ba9..420a5456 100644 --- a/tcl/StaTcl.i +++ b/tcl/StaTcl.i @@ -172,105 +172,23 @@ cmdGraph() // type is not sufficient because then it chokes on the call to // SWIG_ConvertPtr because it is declared extern "C". -LibertyLibrarySeq * -TclListSeqLibertyLibrary(Tcl_Obj * const source, - Tcl_Interp *interp) -{ - int argc; - Tcl_Obj **argv; - - if (Tcl_ListObjGetElements(interp, source, &argc, &argv) == TCL_OK) { - LibertyLibrarySeq *seq = new LibertyLibrarySeq; - for (int i = 0; i < argc; i++) { - void *obj; - // Ignore returned TCL_ERROR because can't get swig_type_info. - SWIG_ConvertPtr(argv[i], &obj, SWIGTYPE_p_LibertyLibrary, false); - seq->push_back(reinterpret_cast(obj)); - } - return seq; - } - else - return nullptr; -} - -PortSeq * -TclListSeqPort(Tcl_Obj * const source, - Tcl_Interp *interp) -{ - int argc; - Tcl_Obj **argv; - - if (Tcl_ListObjGetElements(interp, source, &argc, &argv) == TCL_OK) { - PortSeq *seq = new PortSeq; - for (int i = 0; i < argc; i++) { - void *obj; - // Ignore returned TCL_ERROR because can't get swig_type_info. - SWIG_ConvertPtr(argv[i], &obj, SWIGTYPE_p_Port, false); - seq->push_back(reinterpret_cast(obj)); - } - return seq; - } - else - return nullptr; -} - -PinSeq * -TclListSeqPin(Tcl_Obj * const source, - Tcl_Interp *interp) -{ - int argc; - Tcl_Obj **argv; - - if (Tcl_ListObjGetElements(interp, source, &argc, &argv) == TCL_OK) { - PinSeq *seq = new PinSeq; - for (int i = 0; i < argc; i++) { - void *obj; - // Ignore returned TCL_ERROR because can't get swig_type_info. - SWIG_ConvertPtr(argv[i], &obj, SWIGTYPE_p_Pin, false); - seq->push_back(reinterpret_cast(obj)); - } - return seq; - } - else - return nullptr; -} - -InstanceSeq * -TclListSeqInstance(Tcl_Obj * const source, - Tcl_Interp *interp) -{ - int argc; - Tcl_Obj **argv; - - if (Tcl_ListObjGetElements(interp, source, &argc, &argv) == TCL_OK) { - InstanceSeq *seq = new InstanceSeq; - for (int i = 0; i < argc; i++) { - void *obj; - // Ignore returned TCL_ERROR because can't get swig_type_info. - SWIG_ConvertPtr(argv[i], &obj, SWIGTYPE_p_Instance, false); - seq->push_back(reinterpret_cast(obj)); - } - return seq; - } - else - return nullptr; -} - -ExceptionThruSeq * -TclListSeqExceptionThru(Tcl_Obj *const source, - Tcl_Interp *interp) +template +Vector * +tclListSeq(Tcl_Obj *const source, + swig_type_info *swig_type, + Tcl_Interp *interp) { int argc; Tcl_Obj **argv; if (Tcl_ListObjGetElements(interp, source, &argc, &argv) == TCL_OK && argc > 0) { - ExceptionThruSeq *seq = new ExceptionThruSeq; + Vector *seq = new Vector; for (int i = 0; i < argc; i++) { void *obj; // Ignore returned TCL_ERROR because can't get swig_type_info. - SWIG_ConvertPtr(argv[i], &obj, SWIGTYPE_p_ExceptionThru, false); - seq->push_back(reinterpret_cast(obj)); + SWIG_ConvertPtr(argv[i], &obj, swig_type, false); + seq->push_back(reinterpret_cast(obj)); } return seq; } @@ -278,104 +196,30 @@ TclListSeqExceptionThru(Tcl_Obj *const source, return nullptr; } -PortSet * -TclListSetPort(Tcl_Obj *const source, - Tcl_Interp *interp) +LibertyLibrarySeq * +tclListSeqLibertyLibrary(Tcl_Obj *const source, + Tcl_Interp *interp) { - int argc; - Tcl_Obj **argv; - - if (Tcl_ListObjGetElements(interp, source, &argc, &argv) == TCL_OK) { - PortSet *set = new PortSet; - for (int i = 0; i < argc; i++) { - void *obj; - // Ignore returned TCL_ERROR because can't get swig_type_info. - SWIG_ConvertPtr(argv[i], &obj, SWIGTYPE_p_Port, false); - set->insert(reinterpret_cast(obj)); - } - return set; - } - else - return nullptr; + return tclListSeq(source, SWIGTYPE_p_LibertyLibrary, interp); } -PinSet * -TclListSetPin(Tcl_Obj *const source, - Tcl_Interp *interp) +template +Set * +tclListSet(Tcl_Obj *const source, + swig_type_info *swig_type, + Tcl_Interp *interp) { int argc; Tcl_Obj **argv; - if (Tcl_ListObjGetElements(interp, source, &argc, &argv) == TCL_OK) { - PinSet *set = new PinSet; + if (Tcl_ListObjGetElements(interp, source, &argc, &argv) == TCL_OK + && argc > 0) { + Set *set = new Set; for (int i = 0; i < argc; i++) { void *obj; // Ignore returned TCL_ERROR because can't get swig_type_info. - SWIG_ConvertPtr(argv[i], &obj, SWIGTYPE_p_Pin, false); - set->insert(reinterpret_cast(obj)); - } - return set; - } - else - return nullptr; -} - -ClockSet * -TclListSetClock(Tcl_Obj *const source, - Tcl_Interp *interp) -{ - int argc; - Tcl_Obj **argv; - - if (Tcl_ListObjGetElements(interp, source, &argc, &argv) == TCL_OK) { - ClockSet *set = new ClockSet; - for (int i = 0; i < argc; i++) { - void *obj; - // Ignore returned TCL_ERROR because can't get swig_type_info. - SWIG_ConvertPtr(argv[i], &obj, SWIGTYPE_p_Clock, false); - set->insert(reinterpret_cast(obj)); - } - return set; - } - else - return nullptr; -} - -InstanceSet * -TclListSetInstance(Tcl_Obj *const source, - Tcl_Interp *interp) -{ - int argc; - Tcl_Obj **argv; - - if (Tcl_ListObjGetElements(interp, source, &argc, &argv) == TCL_OK) { - InstanceSet *set = new InstanceSet; - for (int i = 0; i < argc; i++) { - void *obj; - // Ignore returned TCL_ERROR because can't get swig_type_info. - SWIG_ConvertPtr(argv[i], &obj, SWIGTYPE_p_Instance, false); - set->insert(reinterpret_cast(obj)); - } - return set; - } - else - return nullptr; -} - -NetSet * -TclListSetNet(Tcl_Obj *const source, - Tcl_Interp *interp) -{ - int argc; - Tcl_Obj **argv; - - if (Tcl_ListObjGetElements(interp, source, &argc, &argv) == TCL_OK) { - NetSet *set = new NetSet; - for (int i = 0; i < argc; i++) { - void *obj; - // Ignore returned TCL_ERROR because can't get swig_type_info. - SWIG_ConvertPtr(argv[i], &obj, SWIGTYPE_p_Net, false); - set->insert(reinterpret_cast(obj)); + SWIG_ConvertPtr(argv[i], &obj, swig_type, false); + set->insert(reinterpret_cast(obj)); } return set; } @@ -384,7 +228,7 @@ TclListSetNet(Tcl_Obj *const source, } StringSet * -TclListSetConstChar(Tcl_Obj *const source, +tclListSetConstChar(Tcl_Obj *const source, Tcl_Interp *interp) { int argc; @@ -423,26 +267,6 @@ TclListSeqConstChar(Tcl_Obj *const source, return nullptr; } -EdgeSeq * -TclListSeqEdge(Tcl_Obj * const source, Tcl_Interp *interp) -{ - int argc; - Tcl_Obj **argv; - - if (Tcl_ListObjGetElements(interp, source, &argc, &argv) == TCL_OK) { - EdgeSeq *seq = new EdgeSeq; - for (int i = 0; i < argc; i++) { - void *obj; - // Ignore returned TCL_ERROR because can't get swig_type_info. - SWIG_ConvertPtr(argv[i], &obj, SWIGTYPE_p_Edge, false); - seq->push_back(reinterpret_cast(obj)); - } - return seq; - } - else - return nullptr; -} - //////////////////////////////////////////////////////////////// TmpPinSet * @@ -662,11 +486,11 @@ using namespace sta; } %typemap(in) PortSet* { - $1 = TclListSetPort($input, interp); + $1 = tclListSet($input, SWIGTYPE_p_Port, interp); } %typemap(in) PortSeq* { - $1 = TclListSeqPort($input, interp); + $1 = tclListSeq($input, SWIGTYPE_p_Port, interp); } %typemap(out) TmpPortSeq* { @@ -880,7 +704,7 @@ using namespace sta; } %typemap(in) InstanceSeq* { - $1 = TclListSeqInstance($input, interp); + $1 = tclListSeq($input, SWIGTYPE_p_Instance, interp); } %typemap(out) TmpInstanceSeq* { @@ -1248,11 +1072,11 @@ using namespace sta; } %typemap(in) PinSeq* { - $1 = TclListSeqPin($input, interp); + $1 = tclListSeq($input, SWIGTYPE_p_Pin, interp); } %typemap(in) PinSet* { - $1 = TclListSetPin($input, interp); + $1 = tclListSet($input, SWIGTYPE_p_Pin, interp); } %typemap(out) PinSet* { @@ -1270,7 +1094,7 @@ using namespace sta; } %typemap(in) ClockSet* { - $1 = TclListSetClock($input, interp); + $1 = tclListSet($input, SWIGTYPE_p_Clock, interp); } %typemap(out) ClockSet* { @@ -1303,7 +1127,7 @@ using namespace sta; } %typemap(in) InstanceSet* { - $1 = TclListSetInstance($input, interp); + $1 = tclListSet($input, SWIGTYPE_p_Instance, interp); } %typemap(out) TmpInstanceSet* { @@ -1320,11 +1144,11 @@ using namespace sta; } %typemap(in) NetSet* { - $1 = TclListSetNet($input, interp); + $1 = tclListSet($input, SWIGTYPE_p_Net, interp); } %typemap(in) ExceptionThruSeq* { - $1 = TclListSeqExceptionThru($input, interp); + $1 = tclListSeq($input, SWIGTYPE_p_ExceptionThru, interp); } %typemap(out) Vertex* { @@ -1345,7 +1169,7 @@ using namespace sta; } %typemap(in) EdgeSeq* { - $1 = TclListSeqEdge($input, interp); + $1 = tclListSeq($input, SWIGTYPE_p_Edge, interp); } %typemap(out) Edge* { @@ -1532,11 +1356,11 @@ using namespace sta; } %typemap(in) PathGroupNameSet* { - $1 = TclListSetConstChar($input, interp); + $1 = tclListSetConstChar($input, interp); } %typemap(in) StringSet* { - $1 = TclListSetConstChar($input, interp); + $1 = tclListSetConstChar($input, interp); } %typemap(out) Corner* {