From a82361ce3d8cd34877c94d6e51c0efaee188f40b Mon Sep 17 00:00:00 2001 From: James Cherry Date: Sat, 7 Dec 2024 16:35:14 -0800 Subject: [PATCH] timing models rm clk tree delay clk->output w/ideal clk conttext commit 133cd3a33fe37d81a0a8f47c28c245b8de5507b4 Author: James Cherry Date: Sat Dec 7 16:24:38 2024 -0800 timing models rm clk tree delay clk->output w/ideal clk conttext Signed-off-by: James Cherry commit 6d17e2e29788ffc5ba65a2d0c34eb840fdd41486 Author: James Cherry Date: Fri Dec 6 16:57:31 2024 -0800 timing models rm clk tree delay from setup/hold w/ideal clk conttext Signed-off-by: James Cherry Signed-off-by: James Cherry --- include/sta/Clock.hh | 1 + include/sta/PathEnd.hh | 3 +++ liberty/LibertyWriter.cc | 1 + search/MakeTimingModel.cc | 7 +++---- search/MakeTimingModelPvt.hh | 2 +- search/PathEnd.cc | 34 ++++++++++++++++++++++++++++++++++ search/ReportPath.cc | 10 ++++++++-- search/Search.cc | 12 ++++++++++++ search/Search.i | 1 + 9 files changed, 64 insertions(+), 7 deletions(-) diff --git a/include/sta/Clock.hh b/include/sta/Clock.hh index b5568e3d..841dfed8 100644 --- a/include/sta/Clock.hh +++ b/include/sta/Clock.hh @@ -52,6 +52,7 @@ public: int index() const { return index_; } bool isPropagated() const { return is_propagated_; } void setIsPropagated(bool propagated); + bool isIdeal() const { return !is_propagated_; } // Ideal clock slew. void slew(const RiseFall *rf, const MinMax *min_max, diff --git a/include/sta/PathEnd.hh b/include/sta/PathEnd.hh index 6bca1f97..b004b36c 100644 --- a/include/sta/PathEnd.hh +++ b/include/sta/PathEnd.hh @@ -101,6 +101,7 @@ public: // Required time with source clock offset. virtual Required requiredTimeOffset(const StaState *sta) const; virtual ArcDelay margin(const StaState *sta) const = 0; + virtual float macroClkTreeDelay(const StaState *) const { return 0.0; } virtual Slack slack(const StaState *sta) const = 0; virtual Slack slackNoCrpr(const StaState *sta) const = 0; virtual Arrival borrow(const StaState *sta) const; @@ -324,6 +325,7 @@ public: virtual void reportFull(ReportPath *report) const; virtual bool isCheck() const { return true; } virtual ArcDelay margin(const StaState *sta) const; + virtual float macroClkTreeDelay(const StaState *sta) const; virtual TimingRole *checkRole(const StaState *sta) const; virtual TimingArc *checkArc() const { return check_arc_; } virtual int exceptPathCmp(const PathEnd *path_end, @@ -339,6 +341,7 @@ protected: Crpr crpr, bool crpr_valid); Delay sourceClkDelay(const StaState *sta) const; + virtual Required requiredTimeNoCrpr(const StaState *sta) const; TimingArc *check_arc_; Edge *check_edge_; diff --git a/liberty/LibertyWriter.cc b/liberty/LibertyWriter.cc index 63889584..5360ef0f 100644 --- a/liberty/LibertyWriter.cc +++ b/liberty/LibertyWriter.cc @@ -185,6 +185,7 @@ LibertyWriter::writeHeader() if (exists) fprintf(stream_, " default_fanout_load : %.2f;\n", fanout_load); fprintf(stream_, "\n"); + fprintf(stream_, " nom_process : %.1f;\n", library_->nominalProcess()); fprintf(stream_, " nom_temperature : %.1f;\n", diff --git a/search/MakeTimingModel.cc b/search/MakeTimingModel.cc index 235b8920..0b75e964 100644 --- a/search/MakeTimingModel.cc +++ b/search/MakeTimingModel.cc @@ -98,7 +98,7 @@ MakeTimingModel::makeTimingModel() findTimingFromInputs(); findClkedOutputPaths(); - findClkInsertionDelays(); + findClkTreeDelays(); cell_->finish(false, report_, debug_); restoreSdc(); @@ -525,7 +525,7 @@ MakeTimingModel::findClkedOutputPaths() //////////////////////////////////////////////////////////////// void -MakeTimingModel::findClkInsertionDelays() +MakeTimingModel::findClkTreeDelays() { Instance *top_inst = network_->topInstance(); Cell *top_cell = network_->cell(top_inst); @@ -539,8 +539,7 @@ MakeTimingModel::findClkInsertionDelays() if (pin && sdc_->isClock(pin)) { lib_port->setIsClock(true); ClockSet *clks = sdc_->findClocks(pin); - size_t clk_count = clks->size(); - if (clk_count == 1) { + if (clks->size() == 1) { for (const Clock *clk : *clks) { ClkDelays delays = sta_->findClkDelays(clk, true); for (const MinMax *min_max : MinMax::range()) { diff --git a/search/MakeTimingModelPvt.hh b/search/MakeTimingModelPvt.hh index 7e3b83e4..c22ad730 100644 --- a/search/MakeTimingModelPvt.hh +++ b/search/MakeTimingModelPvt.hh @@ -63,7 +63,7 @@ private: void findTimingFromInputs(); void findTimingFromInput(Port *input_port); void findClkedOutputPaths(); - void findClkInsertionDelays(); + void findClkTreeDelays(); void makeClkTreePaths(LibertyPort *lib_port, const MinMax *min_max, TimingSense sense, diff --git a/search/PathEnd.cc b/search/PathEnd.cc index 6527bf12..02fb39a2 100644 --- a/search/PathEnd.cc +++ b/search/PathEnd.cc @@ -1048,6 +1048,40 @@ PathEndCheck::sourceClkDelay(const StaState *sta) const return 0.0; } +Required +PathEndCheck::requiredTimeNoCrpr(const StaState *sta) const +{ + Arrival tgt_clk_arrival = targetClkArrivalNoCrpr(sta); + ArcDelay check_margin = margin(sta); + float macro_clk_tree_delay = macroClkTreeDelay(sta); + if (checkGenericRole(sta) == TimingRole::setup()) + return tgt_clk_arrival - (check_margin + macro_clk_tree_delay); + else + return tgt_clk_arrival + (check_margin - macro_clk_tree_delay); +} + +float +PathEndCheck::macroClkTreeDelay(const StaState *sta) const +{ + const ClockEdge *tgt_clk_edge = targetClkEdge(sta); + const Clock *tgt_clk = tgt_clk_edge->clock(); + const Network *network = sta->network(); + const Pin *clk_pin = clk_path_.pin(sta); + const Instance *inst = network->instance(clk_pin); + const LibertyCell *inst_cell = network->libertyCell(inst); + if (tgt_clk->isIdeal() + && inst_cell && inst_cell->isMacro()) { + LibertyPort *clk_port = network->libertyPort(clk_pin); + if (clk_port) { + const MinMax *min_max = clk_path_.minMax(sta); + const RiseFall *rf = clk_path_.transition(sta); + float slew = delayAsFloat(clk_path_.slew(sta)); + return clk_port->clkTreeDelay(slew, rf, min_max); + } + } + return 0.0; +} + //////////////////////////////////////////////////////////////// PathEndLatchCheck::PathEndLatchCheck(Path *path, diff --git a/search/ReportPath.cc b/search/ReportPath.cc index 2c59b890..1eec5327 100644 --- a/search/ReportPath.cc +++ b/search/ReportPath.cc @@ -2429,10 +2429,16 @@ ReportPath::reportRequired(const PathEnd *end, { Required req_time = end->requiredTimeOffset(this); const EarlyLate *early_late = end->clkEarlyLate(this); + float macro_clk_tree_delay = end->macroClkTreeDelay(this); ArcDelay margin = end->margin(this); - if (end->minMax(this) == MinMax::max()) + if (end->minMax(this) == MinMax::min()) { margin = -margin; - reportLine(margin_msg.c_str(), margin, req_time, early_late); + macro_clk_tree_delay = -macro_clk_tree_delay; + } + if (macro_clk_tree_delay != 0.0) + reportLine("macro clock tree delay", -macro_clk_tree_delay, + req_time + margin, early_late); + reportLine(margin_msg.c_str(), -margin, req_time, early_late); reportLine("data required time", req_time, early_late); reportDashLine(); } diff --git a/search/Search.cc b/search/Search.cc index b03d15b6..daa68fd1 100644 --- a/search/Search.cc +++ b/search/Search.cc @@ -2139,6 +2139,18 @@ PathVisitor::visitFromPath(const Pin *from_pin, if (clk == nullptr || !sdc_->clkStopPropagation(from_pin, clk)) { arc_delay = search_->deratedDelay(from_vertex, arc, edge, false, path_ap); + + // Remove clock network delay for macros created with propagated + // clocks when used in a context with ideal clocks. + if (clk && clk->isIdeal()) { + const LibertyPort *clk_port = network_->libertyPort(from_pin); + const LibertyCell *inst_cell = clk_port->libertyCell(); + if (inst_cell->isMacro()) { + float slew = delayAsFloat(from_path->slew(this)); + arc_delay -= clk_port->clkTreeDelay(slew, from_rf, min_max); + } + } + // Propagate from unclocked reg/latch clk pins, which have no // clk but are distinguished with a segment_start flag. if ((clk_edge == nullptr diff --git a/search/Search.i b/search/Search.i index 6d3a67ef..f5af17c3 100644 --- a/search/Search.i +++ b/search/Search.i @@ -154,6 +154,7 @@ init_sta() initSta(); } +// Clear all state except network. void clear_sta() {