diff --git a/doc/OpenSTA.odt b/doc/OpenSTA.odt index b84d3b88..ddadb2cb 100644 Binary files a/doc/OpenSTA.odt and b/doc/OpenSTA.odt differ diff --git a/include/sta/Sta.hh b/include/sta/Sta.hh index 41470a9f..d083177b 100644 --- a/include/sta/Sta.hh +++ b/include/sta/Sta.hh @@ -1056,6 +1056,8 @@ public: Slew vertexSlew(Vertex *vertex, const RiseFall *rf, const MinMax *min_max); + Slew vertexSlew(Vertex *vertex, + const MinMax *min_max); ArcDelay arcDelay(Edge *edge, TimingArc *arc, const DcalcAnalysisPt *dcalc_ap); diff --git a/search/Property.cc b/search/Property.cc index bad74605..15a5f5d5 100644 --- a/search/Property.cc +++ b/search/Property.cc @@ -38,22 +38,38 @@ namespace sta { using std::string; using std::max; +static PropertyValue +pinSlewProperty(const Pin *pin, + const MinMax *min_max, + Sta *sta); static PropertyValue pinSlewProperty(const Pin *pin, const RiseFall *rf, const MinMax *min_max, Sta *sta); static PropertyValue +pinSlackProperty(const Pin *pin, + const MinMax *min_max, + Sta *sta); +static PropertyValue pinSlackProperty(const Pin *pin, const RiseFall *rf, const MinMax *min_max, Sta *sta); static PropertyValue +portSlewProperty(const Port *port, + const MinMax *min_max, + Sta *sta); +static PropertyValue portSlewProperty(const Port *port, const RiseFall *rf, const MinMax *min_max, Sta *sta); static PropertyValue +portSlackProperty(const Port *port, + const MinMax *min_max, + Sta *sta); +static PropertyValue portSlackProperty(const Port *port, const RiseFall *rf, const MinMax *min_max, @@ -659,28 +675,47 @@ getProperty(const Port *port, return PropertyValue(&activity); } - else if (stringEqual(property, "actual_fall_transition_min")) - return portSlewProperty(port, RiseFall::fall(), MinMax::min(), sta); - else if (stringEqual(property, "actual_fall_transition_max")) - return portSlewProperty(port, RiseFall::fall(), MinMax::max(), sta); - else if (stringEqual(property, "actual_rise_transition_min")) - return portSlewProperty(port, RiseFall::rise(), MinMax::min(), sta); - else if (stringEqual(property, "actual_rise_transition_max")) - return portSlewProperty(port, RiseFall::rise(), MinMax::max(), sta); - - else if (stringEqual(property, "min_fall_slack")) - return portSlackProperty(port, RiseFall::fall(), MinMax::min(), sta); - else if (stringEqual(property, "max_fall_slack")) + else if (stringEqual(property, "slack_max")) + return portSlackProperty(port, MinMax::max(), sta); + else if (stringEqual(property, "slack_max_fall")) return portSlackProperty(port, RiseFall::fall(), MinMax::max(), sta); - else if (stringEqual(property, "min_rise_slack")) - return portSlackProperty(port, RiseFall::rise(), MinMax::min(), sta); - else if (stringEqual(property, "max_rise_slack")) + else if (stringEqual(property, "slack_max_rise")) return portSlackProperty(port, RiseFall::rise(), MinMax::max(), sta); + else if (stringEqual(property, "slack_min")) + return portSlackProperty(port, MinMax::min(), sta); + else if (stringEqual(property, "slack_min_fall")) + return portSlackProperty(port, RiseFall::fall(), MinMax::min(), sta); + else if (stringEqual(property, "slack_min_rise")) + return portSlackProperty(port, RiseFall::rise(), MinMax::min(), sta); + + else if (stringEqual(property, "slew_max")) + return portSlewProperty(port, MinMax::max(), sta); + else if (stringEqual(property, "slew_max_fall")) + return portSlewProperty(port, RiseFall::fall(), MinMax::max(), sta); + else if (stringEqual(property, "slew_max_rise")) + return portSlewProperty(port, RiseFall::rise(), MinMax::max(), sta); + else if (stringEqual(property, "slew_min")) + return portSlewProperty(port, MinMax::min(), sta); + else if (stringEqual(property, "slew_min_rise")) + return portSlewProperty(port, RiseFall::rise(), MinMax::min(), sta); + else if (stringEqual(property, "slew_min_fall")) + return portSlewProperty(port, RiseFall::fall(), MinMax::min(), sta); else throw PropertyUnknown("port", property); } +static PropertyValue +portSlewProperty(const Port *port, + const MinMax *min_max, + Sta *sta) +{ + auto network = sta->cmdNetwork(); + Instance *top_inst = network->topInstance(); + Pin *pin = network->findPin(top_inst, port); + return pinSlewProperty(pin, min_max, sta); +} + static PropertyValue portSlewProperty(const Port *port, const RiseFall *rf, @@ -693,6 +728,17 @@ portSlewProperty(const Port *port, return pinSlewProperty(pin, rf, min_max, sta); } +static PropertyValue +portSlackProperty(const Port *port, + const MinMax *min_max, + Sta *sta) +{ + auto network = sta->cmdNetwork(); + Instance *top_inst = network->topInstance(); + Pin *pin = network->findPin(top_inst, port); + return pinSlackProperty(pin, min_max, sta); +} + static PropertyValue portSlackProperty(const Port *port, const RiseFall *rf, @@ -729,19 +775,19 @@ getProperty(const LibertyPort *port, float res = port->driveResistance(); return resistancePropertyValue(res, sta); } - else if (stringEqual(property, "drive_resistance_rise_min")) { + else if (stringEqual(property, "drive_resistance_min_rise")) { float res = port->driveResistance(RiseFall::rise(), MinMax::min()); return resistancePropertyValue(res, sta); } - else if (stringEqual(property, "drive_resistance_rise_max")) { + else if (stringEqual(property, "drive_resistance_max_rise")) { float res = port->driveResistance(RiseFall::rise(), MinMax::max()); return resistancePropertyValue(res, sta); } - else if (stringEqual(property, "drive_resistance_fall_min")) { + else if (stringEqual(property, "drive_resistance_min_fall")) { float res = port->driveResistance(RiseFall::fall(), MinMax::min()); return resistancePropertyValue(res, sta); } - else if (stringEqual(property, "drive_resistance_fall_max")) { + else if (stringEqual(property, "drive_resistance_max_fall")) { float res = port->driveResistance(RiseFall::fall(), MinMax::max()); return resistancePropertyValue(res, sta); } @@ -750,22 +796,22 @@ getProperty(const LibertyPort *port, ArcDelay delay = port->intrinsicDelay(sta); return delayPropertyValue(delay, sta); } - else if (stringEqual(property, "intrinsic_delay_rise_min")) { + else if (stringEqual(property, "intrinsic_delay_min_rise")) { ArcDelay delay = port->intrinsicDelay(RiseFall::rise(), MinMax::min(), sta); return delayPropertyValue(delay, sta); } - else if (stringEqual(property, "intrinsic_delay_rise_max")) { + else if (stringEqual(property, "intrinsic_delay_max_rise")) { ArcDelay delay = port->intrinsicDelay(RiseFall::rise(), MinMax::max(), sta); return delayPropertyValue(delay, sta); } - else if (stringEqual(property, "intrinsic_delay_fall_min")) { + else if (stringEqual(property, "intrinsic_delay_min_fall")) { ArcDelay delay = port->intrinsicDelay(RiseFall::fall(), MinMax::min(), sta); return delayPropertyValue(delay, sta); } - else if (stringEqual(property, "intrinsic_delay_fall_max")) { + else if (stringEqual(property, "intrinsic_delay_max_fall")) { ArcDelay delay = port->intrinsicDelay(RiseFall::fall(), MinMax::max(), sta); return delayPropertyValue(delay, sta); @@ -825,28 +871,45 @@ getProperty(const Pin *pin, return PropertyValue(&activity); } - else if (stringEqual(property, "max_fall_slack")) + else if (stringEqual(property, "slack_max")) + return pinSlackProperty(pin, MinMax::max(), sta); + else if (stringEqual(property, "slack_max_fall")) return pinSlackProperty(pin, RiseFall::fall(), MinMax::max(), sta); - else if (stringEqual(property, "max_rise_slack")) + else if (stringEqual(property, "slack_max_rise")) return pinSlackProperty(pin, RiseFall::rise(), MinMax::max(), sta); - else if (stringEqual(property, "min_fall_slack")) + else if (stringEqual(property, "slack_min")) + return pinSlackProperty(pin, MinMax::min(), sta); + else if (stringEqual(property, "slack_min_fall")) return pinSlackProperty(pin, RiseFall::fall(), MinMax::min(), sta); - else if (stringEqual(property, "min_rise_slack")) + else if (stringEqual(property, "slack_min_rise")) return pinSlackProperty(pin, RiseFall::rise(), MinMax::min(), sta); - else if (stringEqual(property, "actual_fall_transition_max")) + else if (stringEqual(property, "slew_max")) + return pinSlewProperty(pin, MinMax::max(), sta); + else if (stringEqual(property, "slew_max_fall")) return pinSlewProperty(pin, RiseFall::fall(), MinMax::max(), sta); - else if (stringEqual(property, "actual_rise_transition_max")) + else if (stringEqual(property, "slew_max_rise")) return pinSlewProperty(pin, RiseFall::rise(), MinMax::max(), sta); - else if (stringEqual(property, "actual_rise_transition_min")) + else if (stringEqual(property, "slew_min")) + return pinSlewProperty(pin, MinMax::min(), sta); + else if (stringEqual(property, "slew_min_rise")) return pinSlewProperty(pin, RiseFall::rise(), MinMax::min(), sta); - else if (stringEqual(property, "actual_fall_transition_min")) + else if (stringEqual(property, "slew_min_fall")) return pinSlewProperty(pin, RiseFall::fall(), MinMax::min(), sta); else throw PropertyUnknown("pin", property); } +static PropertyValue +pinSlackProperty(const Pin *pin, + const MinMax *min_max, + Sta *sta) +{ + Slack slack = sta->pinSlack(pin, min_max); + return PropertyValue(delayPropertyValue(slack, sta)); +} + static PropertyValue pinSlackProperty(const Pin *pin, const RiseFall *rf, @@ -857,6 +920,28 @@ pinSlackProperty(const Pin *pin, return PropertyValue(delayPropertyValue(slack, sta)); } +static PropertyValue +pinSlewProperty(const Pin *pin, + const MinMax *min_max, + Sta *sta) +{ + auto graph = sta->ensureGraph(); + Vertex *vertex, *bidirect_drvr_vertex; + graph->pinVertices(pin, vertex, bidirect_drvr_vertex); + Slew slew = min_max->initValue(); + if (vertex) { + Slew vertex_slew = sta->vertexSlew(vertex, min_max); + if (delayGreater(vertex_slew, slew, min_max, sta)) + slew = vertex_slew; + } + if (bidirect_drvr_vertex) { + Slew vertex_slew = sta->vertexSlew(bidirect_drvr_vertex, min_max); + if (delayGreater(vertex_slew, slew, min_max, sta)) + slew = vertex_slew; + } + return delayPropertyValue(slew, sta); +} + static PropertyValue pinSlewProperty(const Pin *pin, const RiseFall *rf, diff --git a/search/Sta.cc b/search/Sta.cc index 8efd3ea6..7bdac94b 100644 --- a/search/Sta.cc +++ b/search/Sta.cc @@ -3360,7 +3360,7 @@ Sta::vertexSlew(Vertex *vertex, { findDelays(vertex); Slew mm_slew = min_max->initValue(); - for (DcalcAnalysisPt *dcalc_ap : corners_->dcalcAnalysisPts()) { + for (const DcalcAnalysisPt *dcalc_ap : corners_->dcalcAnalysisPts()) { Slew slew = graph_->slew(vertex, rf, dcalc_ap->index()); if (delayGreater(slew, mm_slew, min_max, this)) mm_slew = slew; @@ -3368,6 +3368,22 @@ Sta::vertexSlew(Vertex *vertex, return mm_slew; } +Slew +Sta::vertexSlew(Vertex *vertex, + const MinMax *min_max) +{ + findDelays(vertex); + Slew mm_slew = min_max->initValue(); + for (const DcalcAnalysisPt *dcalc_ap : corners_->dcalcAnalysisPts()) { + for (const RiseFall *rf : RiseFall::range()) { + Slew slew = graph_->slew(vertex, rf, dcalc_ap->index()); + if (delayGreater(slew, mm_slew, min_max, this)) + mm_slew = slew; + } + } + return mm_slew; +} + //////////////////////////////////////////////////////////////// Graph *