diff --git a/include/sta/PathEnd.hh b/include/sta/PathEnd.hh index 425ec5e7..46a526a2 100644 --- a/include/sta/PathEnd.hh +++ b/include/sta/PathEnd.hh @@ -179,6 +179,11 @@ public: const PathVertex *tgt_clk_path, const TimingRole *check_role, const StaState *sta); + // Non inter-clock uncertainty. + static float checkTgtClkUncertainty(const PathVertex *tgt_clk_path, + const ClockEdge *tgt_clk_edge, + const TimingRole *check_role, + const StaState *sta); static float checkSetupMcpAdjustment(const ClockEdge *src_clk_edge, const ClockEdge *tgt_clk_edge, const MultiCyclePath *mcp, @@ -187,10 +192,6 @@ public: protected: PathEnd(Path *path); - static float checkNonInterClkUncertainty(const PathVertex *tgt_clk_path, - const ClockEdge *tgt_clk_edge, - const TimingRole *check_role, - const StaState *sta); static void checkInterClkUncertainty(const ClockEdge *src_clk_edge, const ClockEdge *tgt_clk_edge, const TimingRole *check_role, diff --git a/search/ClkSkew.cc b/search/ClkSkew.cc index 6a515d78..2f52d0c0 100644 --- a/search/ClkSkew.cc +++ b/search/ClkSkew.cc @@ -34,6 +34,7 @@ #include "SearchPred.hh" #include "Search.hh" #include "Crpr.hh" +#include "PathEnd.hh" namespace sta { @@ -56,6 +57,7 @@ public: float srcClkTreeDelay(StaState *sta); float tgtClkTreeDelay(StaState *sta); Crpr crpr(StaState *sta); + float uncertainty(StaState *sta); float skew() const { return skew_; } private: @@ -78,7 +80,10 @@ ClkSkew::ClkSkew(PathVertex *src_path, { src_path_ = src_path; tgt_path_ = tgt_path; - skew_ = srcLatency(sta) - tgtLatency(sta) - delayAsFloat(crpr(sta)); + skew_ = srcLatency(sta) + - tgtLatency(sta) + - delayAsFloat(crpr(sta)) + + uncertainty(sta); } ClkSkew::ClkSkew(const ClkSkew &clk_skew) @@ -144,6 +149,17 @@ ClkSkew::crpr(StaState *sta) return check_crpr->checkCrpr(&src_path_, &tgt_path_); } +float +ClkSkew::uncertainty(StaState *sta) +{ + TimingRole *check_role = (src_path_.minMax(sta) == SetupHold::max()) + ? TimingRole::setup() + : TimingRole::hold(); + // Uncertainty decreases slack, but increases skew. + return -PathEnd::checkTgtClkUncertainty(&tgt_path_, tgt_path_.clkEdge(sta), + check_role, sta); +} + //////////////////////////////////////////////////////////////// ClkSkews::ClkSkews(StaState *sta) : @@ -187,6 +203,7 @@ ClkSkews::reportClkSkew(ClkSkew &clk_skew, float tgt_latency = clk_skew.tgtLatency(this); float src_clk_tree_delay = clk_skew.srcClkTreeDelay(this); float tgt_clk_tree_delay = clk_skew.tgtClkTreeDelay(this); + float uncertainty = clk_skew.uncertainty(this); if (src_clk_tree_delay != 0.0) src_latency -= src_clk_tree_delay; @@ -195,7 +212,7 @@ ClkSkews::reportClkSkew(ClkSkew &clk_skew, sdc_network_->pathName(src_path->pin(this)), src_path->transition(this)->asString()); if (src_clk_tree_delay != 0.0) - report_->reportLine("%7s source clock tree delay", + report_->reportLine("%7s source internal clock delay", time_unit->asString(src_clk_tree_delay, digits)); if (tgt_clk_tree_delay != 0.0) @@ -205,9 +222,11 @@ ClkSkews::reportClkSkew(ClkSkew &clk_skew, sdc_network_->pathName(tgt_path->pin(this)), tgt_path->transition(this)->asString()); if (tgt_clk_tree_delay != 0.0) - report_->reportLine("%7s target clock tree delay", + report_->reportLine("%7s target internal clock delay", time_unit->asString(-tgt_clk_tree_delay, digits)); - + if (uncertainty != 0.0) + report_->reportLine("%7s clock uncertainty", + time_unit->asString(uncertainty, digits)); report_->reportLine("%7s CRPR", time_unit->asString(delayAsFloat(-clk_skew.crpr(this)), digits)); diff --git a/search/PathEnd.cc b/search/PathEnd.cc index c3def3ae..6c67ad40 100644 --- a/search/PathEnd.cc +++ b/search/PathEnd.cc @@ -355,15 +355,14 @@ PathEnd::checkClkUncertainty(const ClockEdge *src_clk_edge, if (inter_exists) return inter_clk; else - return checkNonInterClkUncertainty(tgt_clk_path, tgt_clk_edge, - check_role, sta); + return checkTgtClkUncertainty(tgt_clk_path, tgt_clk_edge, check_role, sta); } float -PathEnd::checkNonInterClkUncertainty(const PathVertex *tgt_clk_path, - const ClockEdge *tgt_clk_edge, - const TimingRole *check_role, - const StaState *sta) +PathEnd::checkTgtClkUncertainty(const PathVertex *tgt_clk_path, + const ClockEdge *tgt_clk_edge, + const TimingRole *check_role, + const StaState *sta) { MinMax *min_max = check_role->pathMinMax(); ClockUncertainties *uncertainties = nullptr; @@ -637,8 +636,7 @@ PathEndClkConstrained::targetClkArrivalNoCrpr(const StaState *sta) const Delay PathEndClkConstrained::targetClkDelay(const StaState *sta) const { - return checkTgtClkDelay(targetClkPath(), targetClkEdge(sta), - checkRole(sta), sta); + return checkTgtClkDelay(targetClkPath(), targetClkEdge(sta), checkRole(sta), sta); } Delay @@ -666,8 +664,7 @@ PathEndClkConstrained::targetNonInterClkUncertainty(const StaState *sta) const // This returns non inter-clock uncertainty. return 0.0; else - return checkNonInterClkUncertainty(targetClkPath(), tgt_clk_edge, - check_role, sta); + return checkTgtClkUncertainty(targetClkPath(), tgt_clk_edge, check_role, sta); } float @@ -1018,7 +1015,9 @@ Delay PathEndCheck::clkSkew(const StaState *sta) { commonClkPessimism(sta); - return sourceClkDelay(sta) - targetClkDelay(sta) - crpr_; + return sourceClkDelay(sta) - targetClkDelay(sta) - crpr_ + // Uncertainty decreases slack, but increases skew. + - checkTgtClkUncertainty(&clk_path_, clk_path_.clkEdge(sta), checkRole(sta), sta); } Delay