diff --git a/doc/OpenSTA.odt b/doc/OpenSTA.odt index 44c18ac5..5c2ba015 100644 Binary files a/doc/OpenSTA.odt and b/doc/OpenSTA.odt differ diff --git a/doc/OpenSTA.pdf b/doc/OpenSTA.pdf index b09c49c2..b2355614 100644 Binary files a/doc/OpenSTA.pdf and b/doc/OpenSTA.pdf differ diff --git a/include/sta/Sta.hh b/include/sta/Sta.hh index be5433d8..ebd0a1d8 100644 --- a/include/sta/Sta.hh +++ b/include/sta/Sta.hh @@ -914,8 +914,10 @@ public: void reportClkSkew(ConstClockSeq clks, const Corner *corner, const SetupHold *setup_hold, + bool include_internal_latency, int digits); - float findWorstClkSkew(const SetupHold *setup_hold); + float findWorstClkSkew(const SetupHold *setup_hold, + bool include_internal_latency); void reportClkLatency(ConstClockSeq clks, const Corner *corner, diff --git a/search/ClkSkew.cc b/search/ClkSkew.cc index 2f52d0c0..1e47247e 100644 --- a/search/ClkSkew.cc +++ b/search/ClkSkew.cc @@ -47,6 +47,7 @@ public: ClkSkew(); ClkSkew(PathVertex *src_path, PathVertex *tgt_path, + bool include_internal_latency, StaState *sta); ClkSkew(const ClkSkew &clk_skew); void operator=(const ClkSkew &clk_skew); @@ -54,8 +55,8 @@ public: PathVertex *tgtPath() { return &tgt_path_; } float srcLatency(StaState *sta); float tgtLatency(StaState *sta); - float srcClkTreeDelay(StaState *sta); - float tgtClkTreeDelay(StaState *sta); + float srcInternalClkLatency(StaState *sta); + float tgtInternalClkLatency(StaState *sta); Crpr crpr(StaState *sta); float uncertainty(StaState *sta); float skew() const { return skew_; } @@ -66,6 +67,7 @@ private: PathVertex src_path_; PathVertex tgt_path_; + bool include_internal_latency_; float skew_; }; @@ -76,10 +78,12 @@ ClkSkew::ClkSkew() : ClkSkew::ClkSkew(PathVertex *src_path, PathVertex *tgt_path, - StaState *sta) + bool include_internal_latency, + StaState *sta) : + src_path_(src_path), + tgt_path_(tgt_path), + include_internal_latency_(include_internal_latency) { - src_path_ = src_path; - tgt_path_ = tgt_path; skew_ = srcLatency(sta) - tgtLatency(sta) - delayAsFloat(crpr(sta)) @@ -90,6 +94,7 @@ ClkSkew::ClkSkew(const ClkSkew &clk_skew) { src_path_ = clk_skew.src_path_; tgt_path_ = clk_skew.tgt_path_; + include_internal_latency_ = clk_skew.include_internal_latency_; skew_ = clk_skew.skew_; } @@ -98,6 +103,7 @@ ClkSkew::operator=(const ClkSkew &clk_skew) { src_path_ = clk_skew.src_path_; tgt_path_ = clk_skew.tgt_path_; + include_internal_latency_ = clk_skew.include_internal_latency_; skew_ = clk_skew.skew_; } @@ -110,7 +116,7 @@ ClkSkew::srcLatency(StaState *sta) } float -ClkSkew::srcClkTreeDelay(StaState *sta) +ClkSkew::srcInternalClkLatency(StaState *sta) { return clkTreeDelay(src_path_, sta); } @@ -124,7 +130,7 @@ ClkSkew::tgtLatency(StaState *sta) } float -ClkSkew::tgtClkTreeDelay(StaState *sta) +ClkSkew::tgtInternalClkLatency(StaState *sta) { return clkTreeDelay(tgt_path_, sta); } @@ -133,13 +139,17 @@ float ClkSkew::clkTreeDelay(PathVertex &clk_path, StaState *sta) { - const Vertex *vertex = clk_path.vertex(sta); - const Pin *pin = vertex->pin(); - const LibertyPort *port = sta->network()->libertyPort(pin); - const MinMax *min_max = clk_path.minMax(sta); - const RiseFall *rf = clk_path.transition(sta); - float slew = delayAsFloat(clk_path.slew(sta)); - return port->clkTreeDelay(slew, rf, min_max); + if (include_internal_latency_) { + const Vertex *vertex = clk_path.vertex(sta); + const Pin *pin = vertex->pin(); + const LibertyPort *port = sta->network()->libertyPort(pin); + const MinMax *min_max = clk_path.minMax(sta); + const RiseFall *rf = clk_path.transition(sta); + float slew = delayAsFloat(clk_path.slew(sta)); + return port->clkTreeDelay(slew, rf, min_max); + } + else + return 0.0; } Crpr @@ -171,9 +181,11 @@ void ClkSkews::reportClkSkew(ConstClockSeq clks, const Corner *corner, const SetupHold *setup_hold, + bool include_internal_latency, int digits) { - ClkSkewMap skews = findClkSkew(clks, corner, setup_hold); + ClkSkewMap skews = findClkSkew(clks, corner, setup_hold, + include_internal_latency); // Sort the clocks to report in a stable order. ConstClockSeq sorted_clks; @@ -201,29 +213,29 @@ ClkSkews::reportClkSkew(ClkSkew &clk_skew, PathVertex *tgt_path = clk_skew.tgtPath(); float src_latency = clk_skew.srcLatency(this); 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 src_internal_clk_latency = clk_skew.srcInternalClkLatency(this); + float tgt_internal_clk_latency = clk_skew.tgtInternalClkLatency(this); float uncertainty = clk_skew.uncertainty(this); - if (src_clk_tree_delay != 0.0) - src_latency -= src_clk_tree_delay; + if (src_internal_clk_latency != 0.0) + src_latency -= src_internal_clk_latency; report_->reportLine("%7s source latency %s %s", time_unit->asString(src_latency, digits), sdc_network_->pathName(src_path->pin(this)), src_path->transition(this)->asString()); - if (src_clk_tree_delay != 0.0) + if (src_internal_clk_latency != 0.0) report_->reportLine("%7s source internal clock delay", - time_unit->asString(src_clk_tree_delay, digits)); + time_unit->asString(src_internal_clk_latency, digits)); - if (tgt_clk_tree_delay != 0.0) - tgt_latency -= tgt_clk_tree_delay; + if (tgt_internal_clk_latency != 0.0) + tgt_latency -= tgt_internal_clk_latency; report_->reportLine("%7s target latency %s %s", time_unit->asString(-tgt_latency, digits), sdc_network_->pathName(tgt_path->pin(this)), tgt_path->transition(this)->asString()); - if (tgt_clk_tree_delay != 0.0) + if (tgt_internal_clk_latency != 0.0) report_->reportLine("%7s target internal clock delay", - time_unit->asString(-tgt_clk_tree_delay, digits)); + time_unit->asString(-tgt_internal_clk_latency, digits)); if (uncertainty != 0.0) report_->reportLine("%7s clock uncertainty", time_unit->asString(uncertainty, digits)); @@ -238,12 +250,13 @@ ClkSkews::reportClkSkew(ClkSkew &clk_skew, float ClkSkews::findWorstClkSkew(const Corner *corner, - const SetupHold *setup_hold) + const SetupHold *setup_hold, + bool include_internal_latency) { ConstClockSeq clks; for (const Clock *clk : *sdc_->clocks()) clks.push_back(clk); - ClkSkewMap skews = findClkSkew(clks, corner, setup_hold); + ClkSkewMap skews = findClkSkew(clks, corner, setup_hold, include_internal_latency); float worst_skew = 0.0; for (auto clk_skew_itr : skews) { ClkSkew &clk_skew = clk_skew_itr.second; @@ -257,7 +270,8 @@ ClkSkews::findWorstClkSkew(const Corner *corner, ClkSkewMap ClkSkews::findClkSkew(ConstClockSeq &clks, const Corner *corner, - const SetupHold *setup_hold) + const SetupHold *setup_hold, + bool include_internal_latency) { ClkSkewMap skews; @@ -277,7 +291,8 @@ ClkSkews::findClkSkew(ConstClockSeq &clks, ? rf->asRiseFallBoth() : RiseFallBoth::riseFall(); findClkSkewFrom(src_vertex, q_vertex, src_rf, clk_set, - corner, setup_hold, skews); + corner, setup_hold, include_internal_latency, + skews); } } } @@ -306,6 +321,7 @@ ClkSkews::findClkSkewFrom(Vertex *src_vertex, ConstClockSet &clk_set, const Corner *corner, const SetupHold *setup_hold, + bool include_internal_latency, ClkSkewMap &skews) { VertexSet endpoints = findFanout(q_vertex); @@ -325,7 +341,8 @@ ClkSkews::findClkSkewFrom(Vertex *src_vertex, ? tgt_rf1->asRiseFallBoth() : RiseFallBoth::riseFall(); findClkSkew(src_vertex, src_rf, tgt_vertex, tgt_rf, - clk_set, corner, setup_hold, skews); + clk_set, corner, setup_hold, + include_internal_latency, skews); } } } @@ -339,6 +356,7 @@ ClkSkews::findClkSkew(Vertex *src_vertex, ConstClockSet &clk_set, const Corner *corner, const SetupHold *setup_hold, + bool include_internal_latency, ClkSkewMap &skews) { Unit *time_unit = units_->timeUnit(); @@ -362,7 +380,7 @@ ClkSkews::findClkSkew(Vertex *src_vertex, && tgt_rf->matches(tgt_path->transition(this)) && tgt_path->minMax(this) == tgt_min_max && tgt_path->pathAnalysisPt(this)->corner() == src_corner) { - ClkSkew probe(src_path, tgt_path, this); + ClkSkew probe(src_path, tgt_path, include_internal_latency, this); ClkSkew &clk_skew = skews[src_clk]; debugPrint(debug_, "clk_skew", 2, "%s %s %s -> %s %s %s crpr = %s skew = %s", diff --git a/search/ClkSkew.hh b/search/ClkSkew.hh index ca2491b3..36f3b6eb 100644 --- a/search/ClkSkew.hh +++ b/search/ClkSkew.hh @@ -39,15 +39,18 @@ public: void reportClkSkew(ConstClockSeq clks, const Corner *corner, const SetupHold *setup_hold, + bool include_internal_latency, int digits); // Find worst clock skew between src/target registers. float findWorstClkSkew(const Corner *corner, - const SetupHold *setup_hold); + const SetupHold *setup_hold, + bool include_internal_latency); protected: ClkSkewMap findClkSkew(ConstClockSeq &clks, const Corner *corner, - const SetupHold *setup_hold); + const SetupHold *setup_hold, + bool include_internal_latency); bool hasClkPaths(Vertex *vertex, ConstClockSet &clks); void findClkSkewFrom(Vertex *src_vertex, @@ -56,6 +59,7 @@ protected: ConstClockSet &clk_set, const Corner *corner, const SetupHold *setup_hold, + bool include_internal_latency, ClkSkewMap &skews); void findClkSkew(Vertex *src_vertex, const RiseFallBoth *src_rf, @@ -64,6 +68,7 @@ protected: ConstClockSet &clk_set, const Corner *corner, const SetupHold *setup_hold, + bool include_internal_latency, ClkSkewMap &skews); VertexSet findFanout(Vertex *from); void reportClkSkew(ClkSkew &clk_skew, diff --git a/search/Sta.cc b/search/Sta.cc index fd001418..546475a3 100644 --- a/search/Sta.cc +++ b/search/Sta.cc @@ -2604,17 +2604,21 @@ void Sta::reportClkSkew(ConstClockSeq clks, const Corner *corner, const SetupHold *setup_hold, + bool include_internal_latency, int digits) { clkSkewPreamble(); - clk_skews_->reportClkSkew(clks, corner, setup_hold, digits); + clk_skews_->reportClkSkew(clks, corner, setup_hold, + include_internal_latency, digits); } float -Sta::findWorstClkSkew(const SetupHold *setup_hold) +Sta::findWorstClkSkew(const SetupHold *setup_hold, + bool include_internal_latency) { clkSkewPreamble(); - return clk_skews_->findWorstClkSkew(cmd_corner_, setup_hold); + return clk_skews_->findWorstClkSkew(cmd_corner_, setup_hold, + include_internal_latency); } void diff --git a/tcl/Search.tcl b/tcl/Search.tcl index 9d4100c4..f93085e6 100644 --- a/tcl/Search.tcl +++ b/tcl/Search.tcl @@ -311,15 +311,17 @@ proc delays_are_inf { delays } { ################################################################ define_cmd_args "report_clock_skew" {[-setup|-hold]\ - [-clock clocks]\ - [-corner corner]\ - [-digits digits]} + [-clock clocks]\ + [-corner corner]\ + [-include_internal_latency] + [-digits digits]} proc_redirect report_clock_skew { global sta_report_default_digits parse_key_args "report_clock_skew" args \ - keys {-clock -corner -digits} flags {-setup -hold} + keys {-clock -corner -digits} \ + flags {-setup -hold -include_internal_latency} check_argc_eq0 "report_clock_skew" $args if { [info exists flags(-setup)] && [info exists flags(-hold)] } { @@ -338,6 +340,7 @@ proc_redirect report_clock_skew { set clks [all_clocks] } set corner [parse_corner_or_all keys] + set include_internal_latency [info exists flags(-include_internal_latency)] if [info exists keys(-digits)] { set digits $keys(-digits) check_positive_integer "-digits" $digits @@ -345,7 +348,7 @@ proc_redirect report_clock_skew { set digits $sta_report_default_digits } if { $clks != {} } { - report_clk_skew $clks $corner $setup_hold $digits + report_clk_skew $clks $corner $setup_hold $include_internal_latency $digits } } @@ -995,10 +998,12 @@ proc worst_slack1 { cmd args1 } { ################################################################ -define_hidden_cmd_args "worst_clock_skew" {[-setup]|[-hold]} +define_hidden_cmd_args "worst_clock_skew" \ + {[-setup]|[-hold][-include_internal_latency]} proc worst_clock_skew { args } { - parse_key_args "worst_clock_skew" args keys {} flags {-setup -hold} + parse_key_args "worst_clock_skew" args keys {} \ + flags {-setup -hold -include_internal_latency} check_argc_eq0 "worst_clock_skew" $args if { ([info exists flags(-setup)] && [info exists flags(-hold)]) \ || (![info exists flags(-setup)] && ![info exists flags(-hold)]) } { @@ -1008,7 +1013,8 @@ proc worst_clock_skew { args } { } elseif { [info exists flags(-hold)] } { set setup_hold "hold" } - return [time_sta_ui [worst_clk_skew_cmd $setup_hold]] + set include_internal_latency [info exists flags(-include_internal_latency)] + return [time_sta_ui [worst_clk_skew_cmd $setup_hold $include_internal_latency]] } ################################################################ diff --git a/tcl/StaTcl.i b/tcl/StaTcl.i index 1d45e6e1..6977cd87 100644 --- a/tcl/StaTcl.i +++ b/tcl/StaTcl.i @@ -3034,14 +3034,18 @@ report_path_cmd(PathRef *path) Sta::sta()->reportPath(path); } +//////////////////////////////////////////////////////////////// + void report_clk_skew(ConstClockSeq clks, const Corner *corner, const SetupHold *setup_hold, + bool include_internal_latency, int digits) { cmdLinkedNetwork(); - Sta::sta()->reportClkSkew(clks, corner, setup_hold, digits); + Sta::sta()->reportClkSkew(clks, corner, setup_hold, + include_internal_latency, digits); } void @@ -3054,12 +3058,15 @@ report_clk_latency(ConstClockSeq clks, } float -worst_clk_skew_cmd(const SetupHold *setup_hold) +worst_clk_skew_cmd(const SetupHold *setup_hold, + bool include_internal_latency) { cmdLinkedNetwork(); - return Sta::sta()->findWorstClkSkew(setup_hold); + return Sta::sta()->findWorstClkSkew(setup_hold, include_internal_latency); } +//////////////////////////////////////////////////////////////// + PinSet startpoints() {