diff --git a/doc/OpenSTA.odt b/doc/OpenSTA.odt index 51e2f56d..1d2d1519 100644 Binary files a/doc/OpenSTA.odt and b/doc/OpenSTA.odt differ diff --git a/doc/OpenSTA.pdf b/doc/OpenSTA.pdf index e540927d..5c1f9f84 100644 Binary files a/doc/OpenSTA.pdf and b/doc/OpenSTA.pdf differ diff --git a/include/sta/Sdc.hh b/include/sta/Sdc.hh index 62cdc583..803ab141 100644 --- a/include/sta/Sdc.hh +++ b/include/sta/Sdc.hh @@ -112,6 +112,18 @@ private: const Network *network_; }; +class NetWireCaps : public MinMaxFloatValues +{ +public: + NetWireCaps(); + bool subtractPinCap(const MinMax *min_max); + void setSubtractPinCap(bool subtrace_pin_cap, + const MinMax *min_max); + +private: + bool subtract_pin_cap_[MinMax::index_count]; +}; + typedef Map ClockNameMap; typedef UnorderedMap ClockPinMap; typedef Set InputDelaySet; @@ -149,8 +161,8 @@ typedef Map PinCapLimitMap; typedef Map PortFanoutLimitMap; typedef Map CellFanoutLimitMap; typedef Map PortExtCapMap; -typedef Map NetWireCapMap; -typedef Map PinWireCapMap; +typedef Map NetWireCapMap; +typedef Map PinWireCapMap; typedef Map InstancePvtMap; typedef Map EdgeClockLatencyMap; typedef Map PinMinPulseWidthMap; @@ -595,7 +607,7 @@ public: bool subtract_pin_cap, const Corner *corner, const MinMax *min_max, - float cap); + float wire_cap); bool hasNetWireCap(const Net *net) const; // True if driver pin net has wire capacitance. bool drvrPinHasWireCap(const Pin *pin, @@ -606,7 +618,8 @@ public: const MinMax *min_max, // Return values. float &cap, - bool &exists) const; + bool &exists, + bool &subtract_pin_cap) const; // Pin capacitance derated by operating conditions and instance pvt. float pinCapacitance(const Pin *pin, const RiseFall *rf, diff --git a/sdc/Sdc.cc b/sdc/Sdc.cc index c54acfe3..dfda89d0 100644 --- a/sdc/Sdc.cc +++ b/sdc/Sdc.cc @@ -3059,14 +3059,18 @@ Sdc::drvrPinWireCap(const Pin *pin, const MinMax *min_max, // Return values. float &cap, - bool &exists) const + bool &exists, + bool &subtract_pin_cap) const { - MinMaxFloatValues *values = drvr_pin_wire_cap_maps_[corner->index()].findKey(pin); - if (values) - values->value(min_max, cap, exists); + NetWireCaps *net_caps = drvr_pin_wire_cap_maps_[corner->index()].findKey(pin); + if (net_caps) { + net_caps->value(min_max, cap, exists); + subtract_pin_cap = net_caps->subtractPinCap(min_max); + } else { cap = 0.0; exists = false; + subtract_pin_cap = false; } } @@ -3075,27 +3079,15 @@ Sdc::setNetWireCap(const Net *net, bool subtract_pin_cap, const Corner *corner, const MinMax *min_max, - float cap) + float wire_cap) { - float wire_cap = cap; - if (subtract_pin_cap) { - NetConnectedPinIterator *pin_iter = network_->connectedPinIterator(net); - if (pin_iter->hasNext()) { - const Pin *pin = pin_iter->next(); - float pin_cap_rise = connectedPinCap(pin, RiseFall::rise(), corner, min_max); - float pin_cap_fall = connectedPinCap(pin, RiseFall::fall(), corner, min_max); - float pin_cap = (pin_cap_rise + pin_cap_fall) / 2.0F; - wire_cap -= pin_cap; - if ((wire_cap + pin_cap) < 0.0) - wire_cap = -pin_cap; - delete pin_iter; - } - } - MinMaxFloatValues &values = net_wire_cap_maps_[corner->index()][net]; - values.setValue(min_max, wire_cap); + NetWireCaps &net_caps = net_wire_cap_maps_[corner->index()][net]; + net_caps.setValue(min_max, wire_cap); + net_caps.setSubtractPinCap(subtract_pin_cap, min_max); + for (const Pin *pin : *network_->drivers(net)) - drvr_pin_wire_cap_maps_[corner->index()][pin] = &values; + drvr_pin_wire_cap_maps_[corner->index()][pin] = &net_caps; } bool @@ -3123,7 +3115,10 @@ Sdc::connectedCap(const Pin *pin, { netCaps(pin, rf, corner, min_max, pin_cap, wire_cap, fanout, has_net_load); float net_wire_cap; - drvrPinWireCap(pin, corner, min_max, net_wire_cap, has_net_load); + bool subtract_pin_cap; + drvrPinWireCap(pin, corner, min_max, net_wire_cap, has_net_load, subtract_pin_cap); + if (subtract_pin_cap) + pin_cap = 0.0; if (has_net_load) wire_cap += net_wire_cap; } @@ -5826,4 +5821,24 @@ findLeafDriverPins(const Pin *pin, leaf_pins->insert(pin); } +//////////////////////////////////////////////////////////////// + +NetWireCaps::NetWireCaps() : + subtract_pin_cap_{false, false} +{ +} + +bool +NetWireCaps::subtractPinCap(const MinMax *min_max) +{ + return subtract_pin_cap_[min_max->index()]; +} + +void +NetWireCaps::setSubtractPinCap(bool subtrace_pin_cap, + const MinMax *min_max) +{ + subtract_pin_cap_[min_max->index()] = subtrace_pin_cap; +} + } // namespace