report_clock_skew -include_internal_latency

Signed-off-by: James Cherry <cherry@parallaxsw.com>
This commit is contained in:
James Cherry 2024-05-09 18:06:44 -07:00
parent 2ddd8900a9
commit 986260595f
8 changed files with 90 additions and 48 deletions

Binary file not shown.

Binary file not shown.

View File

@ -914,8 +914,10 @@ public:
void reportClkSkew(ConstClockSeq clks, void reportClkSkew(ConstClockSeq clks,
const Corner *corner, const Corner *corner,
const SetupHold *setup_hold, const SetupHold *setup_hold,
bool include_internal_latency,
int digits); int digits);
float findWorstClkSkew(const SetupHold *setup_hold); float findWorstClkSkew(const SetupHold *setup_hold,
bool include_internal_latency);
void reportClkLatency(ConstClockSeq clks, void reportClkLatency(ConstClockSeq clks,
const Corner *corner, const Corner *corner,

View File

@ -47,6 +47,7 @@ public:
ClkSkew(); ClkSkew();
ClkSkew(PathVertex *src_path, ClkSkew(PathVertex *src_path,
PathVertex *tgt_path, PathVertex *tgt_path,
bool include_internal_latency,
StaState *sta); StaState *sta);
ClkSkew(const ClkSkew &clk_skew); ClkSkew(const ClkSkew &clk_skew);
void operator=(const ClkSkew &clk_skew); void operator=(const ClkSkew &clk_skew);
@ -54,8 +55,8 @@ public:
PathVertex *tgtPath() { return &tgt_path_; } PathVertex *tgtPath() { return &tgt_path_; }
float srcLatency(StaState *sta); float srcLatency(StaState *sta);
float tgtLatency(StaState *sta); float tgtLatency(StaState *sta);
float srcClkTreeDelay(StaState *sta); float srcInternalClkLatency(StaState *sta);
float tgtClkTreeDelay(StaState *sta); float tgtInternalClkLatency(StaState *sta);
Crpr crpr(StaState *sta); Crpr crpr(StaState *sta);
float uncertainty(StaState *sta); float uncertainty(StaState *sta);
float skew() const { return skew_; } float skew() const { return skew_; }
@ -66,6 +67,7 @@ private:
PathVertex src_path_; PathVertex src_path_;
PathVertex tgt_path_; PathVertex tgt_path_;
bool include_internal_latency_;
float skew_; float skew_;
}; };
@ -76,10 +78,12 @@ ClkSkew::ClkSkew() :
ClkSkew::ClkSkew(PathVertex *src_path, ClkSkew::ClkSkew(PathVertex *src_path,
PathVertex *tgt_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) skew_ = srcLatency(sta)
- tgtLatency(sta) - tgtLatency(sta)
- delayAsFloat(crpr(sta)) - delayAsFloat(crpr(sta))
@ -90,6 +94,7 @@ ClkSkew::ClkSkew(const ClkSkew &clk_skew)
{ {
src_path_ = clk_skew.src_path_; src_path_ = clk_skew.src_path_;
tgt_path_ = clk_skew.tgt_path_; tgt_path_ = clk_skew.tgt_path_;
include_internal_latency_ = clk_skew.include_internal_latency_;
skew_ = clk_skew.skew_; skew_ = clk_skew.skew_;
} }
@ -98,6 +103,7 @@ ClkSkew::operator=(const ClkSkew &clk_skew)
{ {
src_path_ = clk_skew.src_path_; src_path_ = clk_skew.src_path_;
tgt_path_ = clk_skew.tgt_path_; tgt_path_ = clk_skew.tgt_path_;
include_internal_latency_ = clk_skew.include_internal_latency_;
skew_ = clk_skew.skew_; skew_ = clk_skew.skew_;
} }
@ -110,7 +116,7 @@ ClkSkew::srcLatency(StaState *sta)
} }
float float
ClkSkew::srcClkTreeDelay(StaState *sta) ClkSkew::srcInternalClkLatency(StaState *sta)
{ {
return clkTreeDelay(src_path_, sta); return clkTreeDelay(src_path_, sta);
} }
@ -124,7 +130,7 @@ ClkSkew::tgtLatency(StaState *sta)
} }
float float
ClkSkew::tgtClkTreeDelay(StaState *sta) ClkSkew::tgtInternalClkLatency(StaState *sta)
{ {
return clkTreeDelay(tgt_path_, sta); return clkTreeDelay(tgt_path_, sta);
} }
@ -133,13 +139,17 @@ float
ClkSkew::clkTreeDelay(PathVertex &clk_path, ClkSkew::clkTreeDelay(PathVertex &clk_path,
StaState *sta) StaState *sta)
{ {
const Vertex *vertex = clk_path.vertex(sta); if (include_internal_latency_) {
const Pin *pin = vertex->pin(); const Vertex *vertex = clk_path.vertex(sta);
const LibertyPort *port = sta->network()->libertyPort(pin); const Pin *pin = vertex->pin();
const MinMax *min_max = clk_path.minMax(sta); const LibertyPort *port = sta->network()->libertyPort(pin);
const RiseFall *rf = clk_path.transition(sta); const MinMax *min_max = clk_path.minMax(sta);
float slew = delayAsFloat(clk_path.slew(sta)); const RiseFall *rf = clk_path.transition(sta);
return port->clkTreeDelay(slew, rf, min_max); float slew = delayAsFloat(clk_path.slew(sta));
return port->clkTreeDelay(slew, rf, min_max);
}
else
return 0.0;
} }
Crpr Crpr
@ -171,9 +181,11 @@ void
ClkSkews::reportClkSkew(ConstClockSeq clks, ClkSkews::reportClkSkew(ConstClockSeq clks,
const Corner *corner, const Corner *corner,
const SetupHold *setup_hold, const SetupHold *setup_hold,
bool include_internal_latency,
int digits) 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. // Sort the clocks to report in a stable order.
ConstClockSeq sorted_clks; ConstClockSeq sorted_clks;
@ -201,29 +213,29 @@ ClkSkews::reportClkSkew(ClkSkew &clk_skew,
PathVertex *tgt_path = clk_skew.tgtPath(); PathVertex *tgt_path = clk_skew.tgtPath();
float src_latency = clk_skew.srcLatency(this); float src_latency = clk_skew.srcLatency(this);
float tgt_latency = clk_skew.tgtLatency(this); float tgt_latency = clk_skew.tgtLatency(this);
float src_clk_tree_delay = clk_skew.srcClkTreeDelay(this); float src_internal_clk_latency = clk_skew.srcInternalClkLatency(this);
float tgt_clk_tree_delay = clk_skew.tgtClkTreeDelay(this); float tgt_internal_clk_latency = clk_skew.tgtInternalClkLatency(this);
float uncertainty = clk_skew.uncertainty(this); float uncertainty = clk_skew.uncertainty(this);
if (src_clk_tree_delay != 0.0) if (src_internal_clk_latency != 0.0)
src_latency -= src_clk_tree_delay; src_latency -= src_internal_clk_latency;
report_->reportLine("%7s source latency %s %s", report_->reportLine("%7s source latency %s %s",
time_unit->asString(src_latency, digits), time_unit->asString(src_latency, digits),
sdc_network_->pathName(src_path->pin(this)), sdc_network_->pathName(src_path->pin(this)),
src_path->transition(this)->asString()); 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", 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) if (tgt_internal_clk_latency != 0.0)
tgt_latency -= tgt_clk_tree_delay; tgt_latency -= tgt_internal_clk_latency;
report_->reportLine("%7s target latency %s %s", report_->reportLine("%7s target latency %s %s",
time_unit->asString(-tgt_latency, digits), time_unit->asString(-tgt_latency, digits),
sdc_network_->pathName(tgt_path->pin(this)), sdc_network_->pathName(tgt_path->pin(this)),
tgt_path->transition(this)->asString()); 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", 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) if (uncertainty != 0.0)
report_->reportLine("%7s clock uncertainty", report_->reportLine("%7s clock uncertainty",
time_unit->asString(uncertainty, digits)); time_unit->asString(uncertainty, digits));
@ -238,12 +250,13 @@ ClkSkews::reportClkSkew(ClkSkew &clk_skew,
float float
ClkSkews::findWorstClkSkew(const Corner *corner, ClkSkews::findWorstClkSkew(const Corner *corner,
const SetupHold *setup_hold) const SetupHold *setup_hold,
bool include_internal_latency)
{ {
ConstClockSeq clks; ConstClockSeq clks;
for (const Clock *clk : *sdc_->clocks()) for (const Clock *clk : *sdc_->clocks())
clks.push_back(clk); 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; float worst_skew = 0.0;
for (auto clk_skew_itr : skews) { for (auto clk_skew_itr : skews) {
ClkSkew &clk_skew = clk_skew_itr.second; ClkSkew &clk_skew = clk_skew_itr.second;
@ -257,7 +270,8 @@ ClkSkews::findWorstClkSkew(const Corner *corner,
ClkSkewMap ClkSkewMap
ClkSkews::findClkSkew(ConstClockSeq &clks, ClkSkews::findClkSkew(ConstClockSeq &clks,
const Corner *corner, const Corner *corner,
const SetupHold *setup_hold) const SetupHold *setup_hold,
bool include_internal_latency)
{ {
ClkSkewMap skews; ClkSkewMap skews;
@ -277,7 +291,8 @@ ClkSkews::findClkSkew(ConstClockSeq &clks,
? rf->asRiseFallBoth() ? rf->asRiseFallBoth()
: RiseFallBoth::riseFall(); : RiseFallBoth::riseFall();
findClkSkewFrom(src_vertex, q_vertex, src_rf, clk_set, 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, ConstClockSet &clk_set,
const Corner *corner, const Corner *corner,
const SetupHold *setup_hold, const SetupHold *setup_hold,
bool include_internal_latency,
ClkSkewMap &skews) ClkSkewMap &skews)
{ {
VertexSet endpoints = findFanout(q_vertex); VertexSet endpoints = findFanout(q_vertex);
@ -325,7 +341,8 @@ ClkSkews::findClkSkewFrom(Vertex *src_vertex,
? tgt_rf1->asRiseFallBoth() ? tgt_rf1->asRiseFallBoth()
: RiseFallBoth::riseFall(); : RiseFallBoth::riseFall();
findClkSkew(src_vertex, src_rf, tgt_vertex, tgt_rf, 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, ConstClockSet &clk_set,
const Corner *corner, const Corner *corner,
const SetupHold *setup_hold, const SetupHold *setup_hold,
bool include_internal_latency,
ClkSkewMap &skews) ClkSkewMap &skews)
{ {
Unit *time_unit = units_->timeUnit(); Unit *time_unit = units_->timeUnit();
@ -362,7 +380,7 @@ ClkSkews::findClkSkew(Vertex *src_vertex,
&& tgt_rf->matches(tgt_path->transition(this)) && tgt_rf->matches(tgt_path->transition(this))
&& tgt_path->minMax(this) == tgt_min_max && tgt_path->minMax(this) == tgt_min_max
&& tgt_path->pathAnalysisPt(this)->corner() == src_corner) { && 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]; ClkSkew &clk_skew = skews[src_clk];
debugPrint(debug_, "clk_skew", 2, debugPrint(debug_, "clk_skew", 2,
"%s %s %s -> %s %s %s crpr = %s skew = %s", "%s %s %s -> %s %s %s crpr = %s skew = %s",

View File

@ -39,15 +39,18 @@ public:
void reportClkSkew(ConstClockSeq clks, void reportClkSkew(ConstClockSeq clks,
const Corner *corner, const Corner *corner,
const SetupHold *setup_hold, const SetupHold *setup_hold,
bool include_internal_latency,
int digits); int digits);
// Find worst clock skew between src/target registers. // Find worst clock skew between src/target registers.
float findWorstClkSkew(const Corner *corner, float findWorstClkSkew(const Corner *corner,
const SetupHold *setup_hold); const SetupHold *setup_hold,
bool include_internal_latency);
protected: protected:
ClkSkewMap findClkSkew(ConstClockSeq &clks, ClkSkewMap findClkSkew(ConstClockSeq &clks,
const Corner *corner, const Corner *corner,
const SetupHold *setup_hold); const SetupHold *setup_hold,
bool include_internal_latency);
bool hasClkPaths(Vertex *vertex, bool hasClkPaths(Vertex *vertex,
ConstClockSet &clks); ConstClockSet &clks);
void findClkSkewFrom(Vertex *src_vertex, void findClkSkewFrom(Vertex *src_vertex,
@ -56,6 +59,7 @@ protected:
ConstClockSet &clk_set, ConstClockSet &clk_set,
const Corner *corner, const Corner *corner,
const SetupHold *setup_hold, const SetupHold *setup_hold,
bool include_internal_latency,
ClkSkewMap &skews); ClkSkewMap &skews);
void findClkSkew(Vertex *src_vertex, void findClkSkew(Vertex *src_vertex,
const RiseFallBoth *src_rf, const RiseFallBoth *src_rf,
@ -64,6 +68,7 @@ protected:
ConstClockSet &clk_set, ConstClockSet &clk_set,
const Corner *corner, const Corner *corner,
const SetupHold *setup_hold, const SetupHold *setup_hold,
bool include_internal_latency,
ClkSkewMap &skews); ClkSkewMap &skews);
VertexSet findFanout(Vertex *from); VertexSet findFanout(Vertex *from);
void reportClkSkew(ClkSkew &clk_skew, void reportClkSkew(ClkSkew &clk_skew,

View File

@ -2604,17 +2604,21 @@ void
Sta::reportClkSkew(ConstClockSeq clks, Sta::reportClkSkew(ConstClockSeq clks,
const Corner *corner, const Corner *corner,
const SetupHold *setup_hold, const SetupHold *setup_hold,
bool include_internal_latency,
int digits) int digits)
{ {
clkSkewPreamble(); clkSkewPreamble();
clk_skews_->reportClkSkew(clks, corner, setup_hold, digits); clk_skews_->reportClkSkew(clks, corner, setup_hold,
include_internal_latency, digits);
} }
float float
Sta::findWorstClkSkew(const SetupHold *setup_hold) Sta::findWorstClkSkew(const SetupHold *setup_hold,
bool include_internal_latency)
{ {
clkSkewPreamble(); clkSkewPreamble();
return clk_skews_->findWorstClkSkew(cmd_corner_, setup_hold); return clk_skews_->findWorstClkSkew(cmd_corner_, setup_hold,
include_internal_latency);
} }
void void

View File

@ -311,15 +311,17 @@ proc delays_are_inf { delays } {
################################################################ ################################################################
define_cmd_args "report_clock_skew" {[-setup|-hold]\ define_cmd_args "report_clock_skew" {[-setup|-hold]\
[-clock clocks]\ [-clock clocks]\
[-corner corner]\ [-corner corner]\
[-digits digits]} [-include_internal_latency]
[-digits digits]}
proc_redirect report_clock_skew { proc_redirect report_clock_skew {
global sta_report_default_digits global sta_report_default_digits
parse_key_args "report_clock_skew" args \ 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 check_argc_eq0 "report_clock_skew" $args
if { [info exists flags(-setup)] && [info exists flags(-hold)] } { if { [info exists flags(-setup)] && [info exists flags(-hold)] } {
@ -338,6 +340,7 @@ proc_redirect report_clock_skew {
set clks [all_clocks] set clks [all_clocks]
} }
set corner [parse_corner_or_all keys] set corner [parse_corner_or_all keys]
set include_internal_latency [info exists flags(-include_internal_latency)]
if [info exists keys(-digits)] { if [info exists keys(-digits)] {
set digits $keys(-digits) set digits $keys(-digits)
check_positive_integer "-digits" $digits check_positive_integer "-digits" $digits
@ -345,7 +348,7 @@ proc_redirect report_clock_skew {
set digits $sta_report_default_digits set digits $sta_report_default_digits
} }
if { $clks != {} } { 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 } { 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 check_argc_eq0 "worst_clock_skew" $args
if { ([info exists flags(-setup)] && [info exists flags(-hold)]) \ if { ([info exists flags(-setup)] && [info exists flags(-hold)]) \
|| (![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)] } { } elseif { [info exists flags(-hold)] } {
set setup_hold "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]]
} }
################################################################ ################################################################

View File

@ -3034,14 +3034,18 @@ report_path_cmd(PathRef *path)
Sta::sta()->reportPath(path); Sta::sta()->reportPath(path);
} }
////////////////////////////////////////////////////////////////
void void
report_clk_skew(ConstClockSeq clks, report_clk_skew(ConstClockSeq clks,
const Corner *corner, const Corner *corner,
const SetupHold *setup_hold, const SetupHold *setup_hold,
bool include_internal_latency,
int digits) int digits)
{ {
cmdLinkedNetwork(); cmdLinkedNetwork();
Sta::sta()->reportClkSkew(clks, corner, setup_hold, digits); Sta::sta()->reportClkSkew(clks, corner, setup_hold,
include_internal_latency, digits);
} }
void void
@ -3054,12 +3058,15 @@ report_clk_latency(ConstClockSeq clks,
} }
float float
worst_clk_skew_cmd(const SetupHold *setup_hold) worst_clk_skew_cmd(const SetupHold *setup_hold,
bool include_internal_latency)
{ {
cmdLinkedNetwork(); cmdLinkedNetwork();
return Sta::sta()->findWorstClkSkew(setup_hold); return Sta::sta()->findWorstClkSkew(setup_hold, include_internal_latency);
} }
////////////////////////////////////////////////////////////////
PinSet PinSet
startpoints() startpoints()
{ {