From a49dd870dfc3e842a32a0f95feec6891204056e6 Mon Sep 17 00:00:00 2001 From: James Cherry Date: Sat, 11 Jul 2020 23:56:39 -0700 Subject: [PATCH] refactor sdc graph annotation --- CMakeLists.txt | 1 + include/sta/Sta.hh | 3 ++ sdc/Sdc.cc | 84 +----------------------------------------- sdc/SdcGraph.cc | 92 +++++++++++++++++++++++++++++++++++++++++++++- search/Sta.cc | 22 ++++++++++- 5 files changed, 115 insertions(+), 87 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 07ccac05..bf2fe384 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -141,6 +141,7 @@ set(STA_SOURCE sdc/RiseFallMinMax.cc sdc/RiseFallValues.cc sdc/Sdc.cc + sdc/SdcGraph.cc sdc/SdcCmdComment.cc sdc/WriteSdc.cc diff --git a/include/sta/Sta.hh b/include/sta/Sta.hh index e4e911a1..b7e78efe 100644 --- a/include/sta/Sta.hh +++ b/include/sta/Sta.hh @@ -1367,6 +1367,8 @@ protected: void replaceCell(Instance *inst, Cell *to_cell, LibertyCell *to_lib_cell); + void sdcChangedGraph(); + void ensureGraphSdcAnnotated(); CmdNamespace cmd_namespace_; Instance *current_instance_; @@ -1385,6 +1387,7 @@ protected: bool link_make_black_boxes_; bool update_genclks_; EquivCells *equiv_cells_; + bool graph_sdc_annotated_; // Singleton sta used by tcl command interpreter. static Sta *sta_; diff --git a/sdc/Sdc.cc b/sdc/Sdc.cc index eb68f39f..50c25ca8 100644 --- a/sdc/Sdc.cc +++ b/sdc/Sdc.cc @@ -31,7 +31,6 @@ #include "Transition.hh" #include "PortDirection.hh" #include "Network.hh" -#include "HpinDrvrLoad.hh" #include "RiseFallMinMax.hh" #include "Clock.hh" #include "ClockLatency.hh" @@ -48,6 +47,7 @@ #include "DeratingFactors.hh" #include "search/Levelize.hh" #include "Corner.hh" +#include "Graph.hh" namespace sta { @@ -1301,88 +1301,6 @@ ClkHpinDisableLess::operator()(const ClkHpinDisable *disable1, return clk_index1 < clk_index2; } -class FindClkHpinDisables : public HpinDrvrLoadVisitor -{ -public: - FindClkHpinDisables(Clock *clk, - const Network *network, - Sdc *sdc); - ~FindClkHpinDisables(); - bool drvrLoadExists(Pin *drvr, - Pin *load); - -protected: - virtual void visit(HpinDrvrLoad *drvr_load); - void makeClkHpinDisables(Pin *clk_src, - Pin *drvr, - Pin *load); - - Clock *clk_; - PinPairSet drvr_loads_; - const Network *network_; - Sdc *sdc_; - -private: - DISALLOW_COPY_AND_ASSIGN(FindClkHpinDisables); -}; - -FindClkHpinDisables::FindClkHpinDisables(Clock *clk, - const Network *network, - Sdc *sdc) : - HpinDrvrLoadVisitor(), - clk_(clk), - network_(network), - sdc_(sdc) -{ -} - -FindClkHpinDisables::~FindClkHpinDisables() -{ - drvr_loads_.deleteContents(); -} - -void -FindClkHpinDisables::visit(HpinDrvrLoad *drvr_load) -{ - Pin *drvr = drvr_load->drvr(); - Pin *load = drvr_load->load(); - - makeClkHpinDisables(drvr, drvr, load); - - PinSet *hpins_from_drvr = drvr_load->hpinsFromDrvr(); - PinSet::Iterator hpin_iter(hpins_from_drvr); - while (hpin_iter.hasNext()) { - Pin *hpin = hpin_iter.next(); - makeClkHpinDisables(hpin, drvr, load); - } - drvr_loads_.insert(new PinPair(drvr, load)); -} - -void -FindClkHpinDisables::makeClkHpinDisables(Pin *clk_src, - Pin *drvr, - Pin *load) -{ - ClockSet *clks = sdc_->findClocks(clk_src); - ClockSet::Iterator clk_iter(clks); - while (clk_iter.hasNext()) { - Clock *clk = clk_iter.next(); - if (clk != clk_) - // Do not propagate clock from source pin if another - // clock is defined on a hierarchical pin between the - // driver and load. - sdc_->makeClkHpinDisable(clk, drvr, load); - } -} - -bool -FindClkHpinDisables::drvrLoadExists(Pin *drvr, - Pin *load) -{ - PinPair probe(drvr, load); - return drvr_loads_.hasKey(&probe); -} - void Sdc::makeClkHpinDisable(Clock *clk, Pin *drvr, diff --git a/sdc/SdcGraph.cc b/sdc/SdcGraph.cc index 2237f6e7..b2a15fb8 100644 --- a/sdc/SdcGraph.cc +++ b/sdc/SdcGraph.cc @@ -14,9 +14,15 @@ // You should have received a copy of the GNU General Public License // along with this program. If not, see . -#include "SdcGraph.hh" - +#include "Stats.hh" +#include "PortDirection.hh" +#include "Network.hh" #include "Graph.hh" +#include "DisabledPorts.hh" +#include "PortDelay.hh" +#include "ClockLatency.hh" +#include "HpinDrvrLoad.hh" +#include "Sdc.hh" namespace sta { @@ -388,6 +394,88 @@ Sdc::clockLatency(Edge *edge, } } +class FindClkHpinDisables : public HpinDrvrLoadVisitor +{ +public: + FindClkHpinDisables(Clock *clk, + const Network *network, + Sdc *sdc); + ~FindClkHpinDisables(); + bool drvrLoadExists(Pin *drvr, + Pin *load); + +protected: + virtual void visit(HpinDrvrLoad *drvr_load); + void makeClkHpinDisables(Pin *clk_src, + Pin *drvr, + Pin *load); + + Clock *clk_; + PinPairSet drvr_loads_; + const Network *network_; + Sdc *sdc_; + +private: + DISALLOW_COPY_AND_ASSIGN(FindClkHpinDisables); +}; + +FindClkHpinDisables::FindClkHpinDisables(Clock *clk, + const Network *network, + Sdc *sdc) : + HpinDrvrLoadVisitor(), + clk_(clk), + network_(network), + sdc_(sdc) +{ +} + +FindClkHpinDisables::~FindClkHpinDisables() +{ + drvr_loads_.deleteContents(); +} + +void +FindClkHpinDisables::visit(HpinDrvrLoad *drvr_load) +{ + Pin *drvr = drvr_load->drvr(); + Pin *load = drvr_load->load(); + + makeClkHpinDisables(drvr, drvr, load); + + PinSet *hpins_from_drvr = drvr_load->hpinsFromDrvr(); + PinSet::Iterator hpin_iter(hpins_from_drvr); + while (hpin_iter.hasNext()) { + Pin *hpin = hpin_iter.next(); + makeClkHpinDisables(hpin, drvr, load); + } + drvr_loads_.insert(new PinPair(drvr, load)); +} + +void +FindClkHpinDisables::makeClkHpinDisables(Pin *clk_src, + Pin *drvr, + Pin *load) +{ + ClockSet *clks = sdc_->findClocks(clk_src); + ClockSet::Iterator clk_iter(clks); + while (clk_iter.hasNext()) { + Clock *clk = clk_iter.next(); + if (clk != clk_) + // Do not propagate clock from source pin if another + // clock is defined on a hierarchical pin between the + // driver and load. + sdc_->makeClkHpinDisable(clk, drvr, load); + } +} + +bool +FindClkHpinDisables::drvrLoadExists(Pin *drvr, + Pin *load) +{ + PinPair probe(drvr, load); + return drvr_loads_.hasKey(&probe); +} + void Sdc::ensureClkHpinDisables() { diff --git a/search/Sta.cc b/search/Sta.cc index f5984228..52c84af5 100644 --- a/search/Sta.cc +++ b/search/Sta.cc @@ -268,7 +268,8 @@ Sta::Sta() : power_(nullptr), link_make_black_boxes_(true), update_genclks_(false), - equiv_cells_(nullptr) + equiv_cells_(nullptr), + graph_sdc_annotated_(false) { } @@ -535,6 +536,7 @@ Sta::clear() // Constraints reference search filter, so clear search first. search_->clear(); sdc_->clear(); + graph_sdc_annotated_ = false; // corners are NOT cleared because they are used to index liberty files. levelize_->clear(); if (parasitics_) @@ -1202,6 +1204,19 @@ Sta::setClockLatency(Clock *clk, void Sta::sdcChangedGraph() { + if (graph_sdc_annotated_) + // Remove graph constraint annotations. + sdc_->annotateGraph(false); + graph_sdc_annotated_ = false; +} + +void +Sta::ensureGraphSdcAnnotated() +{ + if (!graph_sdc_annotated_) { + sdc_->annotateGraph(true); + graph_sdc_annotated_ = true; + } } void @@ -1421,6 +1436,7 @@ Sta::removeDataCheck(Pin *from, void Sta::disable(Pin *pin) { + sdcChangedGraph(); sdc_->disable(pin); // Levelization respects disabled edges. levelize_->invalid(); @@ -1431,6 +1447,7 @@ Sta::disable(Pin *pin) void Sta::removeDisable(Pin *pin) { + sdcChangedGraph(); sdc_->removeDisable(pin); disableAfter(); // Levelization respects disabled edges. @@ -3189,7 +3206,6 @@ Sta::ensureGraph() makeGraph(); // Update pointers to graph. updateComponentsState(); - sdc_->annotateGraph(true); } return graph_; } @@ -3205,6 +3221,7 @@ void Sta::ensureLevelized() { ensureGraph(); + ensureGraphSdcAnnotated(); // Need constant propagation before levelization to know edges that // are disabled by constants. sim_->ensureConstantsPropagated(); @@ -4403,6 +4420,7 @@ void Sta::findRegisterPreamble() { ensureGraph(); + ensureGraphSdcAnnotated(); sim_->ensureConstantsPropagated(); }