From beb5f46b391f273a340474f76ca2b80f339f9e13 Mon Sep 17 00:00:00 2001 From: Akash Levy Date: Sun, 28 Sep 2025 09:36:58 -0700 Subject: [PATCH 01/12] Support more useful properties --- include/sta/Liberty.hh | 3 ++ include/sta/Network.hh | 3 ++ liberty/Liberty.cc | 25 ++++++++++++ liberty/Liberty.i | 9 +++++ network/Network.cc | 49 +++++++++++++++++++++++ search/Property.cc | 78 +++++++++++++++++++++++++++++-------- test/get_property_flags.ok | 44 +++++++++++++++++++++ test/get_property_flags.tcl | 44 +++++++++++++++++++++ test/regression_vars.tcl | 1 + 9 files changed, 239 insertions(+), 17 deletions(-) create mode 100644 test/get_property_flags.ok create mode 100644 test/get_property_flags.tcl diff --git a/include/sta/Liberty.hh b/include/sta/Liberty.hh index 7fe410bb4..1ecb02b98 100644 --- a/include/sta/Liberty.hh +++ b/include/sta/Liberty.hh @@ -434,6 +434,7 @@ public: void setArea(float area); bool dontUse() const { return dont_use_; } void setDontUse(bool dont_use); + bool isPhysicalOnly() const; bool isMacro() const { return is_macro_; } void setIsMacro(bool is_macro); bool isMemory() const { return is_memory_; } @@ -459,6 +460,7 @@ public: bool isClockGateOther() const; bool isClockGate() const; void setClockGateType(ClockGateType type); + const char *getDesignType() const; const TimingArcSetSeq &timingArcSets() const { return timing_arc_sets_; } // from or to may be nullptr to wildcard. const TimingArcSetSeq &timingArcSets(const LibertyPort *from, @@ -467,6 +469,7 @@ public: // Find a timing arc set equivalent to key. TimingArcSet *findTimingArcSet(TimingArcSet *key) const; TimingArcSet *findTimingArcSet(unsigned arc_set_index) const; + bool hasTimingArcs() const; bool hasTimingArcs(LibertyPort *port) const; const InternalPowerSeq &internalPowers() const { return internal_powers_; } diff --git a/include/sta/Network.hh b/include/sta/Network.hh index 00566c10b..fd6d804f3 100644 --- a/include/sta/Network.hh +++ b/include/sta/Network.hh @@ -313,6 +313,9 @@ public: const Instance *hier_inst) const; bool isDriver(const Pin *pin) const; bool isLoad(const Pin *pin) const; + bool isClock(const Pin *pin) const; + bool isRiseEdgeTriggered(const Pin *pin) const; + bool isFallEdgeTriggered(const Pin *pin) const; // Has register/latch rise/fall edges from pin. bool isRegClkPin(const Pin *pin) const; // Pin clocks a timing check. diff --git a/liberty/Liberty.cc b/liberty/Liberty.cc index ecf81f246..ef2b0a4e7 100644 --- a/liberty/Liberty.cc +++ b/liberty/Liberty.cc @@ -1077,6 +1077,18 @@ LibertyCell::setDontUse(bool dont_use) dont_use_ = dont_use; } +bool +LibertyCell::isPhysicalOnly() const +{ + // This is an approximation via typical features of a physical-only cell. + // The correct way to do this would be to load this info from a LEF file. + + // Assumption: Diodes are not counted for the purposes of this property. + + LibertyCellPortIterator port_it(this); // only iterates on signal ports + return !port_it.hasNext(); // zero ports +} + void LibertyCell::setIsMacro(bool is_macro) { @@ -1167,6 +1179,12 @@ LibertyCell::setClockGateType(ClockGateType type) clock_gate_type_ = type; } +const char * +LibertyCell::getDesignType() const +{ + return isMacro() ? "macro": "cell"; +} + bool LibertyCell::isBuffer() const { @@ -1480,6 +1498,13 @@ LibertyCell::timingArcSetCount() const return timing_arc_sets_.size(); } +bool +LibertyCell::hasTimingArcs() const +{ + return !timing_arc_set_from_map_.empty() + || !timing_arc_set_to_map_.empty(); +} + bool LibertyCell::hasTimingArcs(LibertyPort *port) const { diff --git a/liberty/Liberty.i b/liberty/Liberty.i index 4dd5d7a87..e332e4123 100644 --- a/liberty/Liberty.i +++ b/liberty/Liberty.i @@ -265,9 +265,18 @@ default_operating_conditions() %extend LibertyCell { const char *name() { return self->name(); } +bool has_timing_model() { return self->hasTimingArcs(); } bool is_leaf() { return self->isLeaf(); } bool is_buffer() { return self->isBuffer(); } bool is_inverter() { return self->isInverter(); } +bool is_clock_gate() { return self->isClockGate(); } +bool is_integrated_clock_gating_cell() { return self->isClockGate(); } +bool is_memory() { return self->isMemory(); } +bool is_physical_only() { return self->isPhysicalOnly(); } +bool is_sequential() { return self->hasSequentials(); } +bool dont_use() { return self->dontUse(); } +void set_dont_use() { return self->setDontUse(true); } +void unset_dont_use() { return self->setDontUse(false); } LibertyLibrary *liberty_library() { return self->libertyLibrary(); } Cell *cell() { return reinterpret_cast(self); } LibertyPort * diff --git a/network/Network.cc b/network/Network.cc index 578c06645..38fdcfecb 100644 --- a/network/Network.cc +++ b/network/Network.cc @@ -22,8 +22,11 @@ // // This notice may not be removed or altered from any source distribution. +#include #include "Network.hh" +#include "Sequential.hh" +#include "FuncExpr.hh" #include "StringUtil.hh" #include "PatternMatch.hh" @@ -636,6 +639,52 @@ Network::isLoad(const Pin *pin) const || dir->isUnknown(); } +bool +Network::isClock(const Pin *pin) const +{ + const LibertyPort *port = libertyPort(pin); + return port && port->isClock(); +} + +bool +Network::isRiseEdgeTriggered(const Pin *pin) const +{ + LibertyPort *port = libertyPort(pin); + if (!port) { + return false; + } + LibertyCell *cell = port->libertyCell(); + const Sequential *seq = cell->outputPortSequential(port); + if (!seq) { + return false; + } + FuncExpr *clk_func = seq->clock(); + + // Assumption: the clock function is exactly CLK for rising-edge triggered + // sequentials + return clk_func->op() == FuncExpr::op_port; +} + +bool +Network::isFallEdgeTriggered(const Pin *pin) const +{ + LibertyPort *port = libertyPort(pin); + if (!port) { + return false; + } + LibertyCell *cell = port->libertyCell(); + const Sequential *seq = cell->outputPortSequential(port); + if (!seq) { + return false; + } + FuncExpr *clk_func = seq->clock(); + + // Assumption: the clock function is exactly !CLK for falling-edge triggered + // sequentials + return clk_func->op() == FuncExpr::op_not; +} + + bool Network::isRegClkPin(const Pin *pin) const { diff --git a/search/Property.cc b/search/Property.cc index ad63155c4..c4c24ef73 100644 --- a/search/Property.cc +++ b/search/Property.cc @@ -40,6 +40,8 @@ #include "Path.hh" #include "power/Power.hh" #include "Sta.hh" +#include "Search.hh" +#include "PathGroup.hh" namespace sta { @@ -732,11 +734,19 @@ Properties::getProperty(const LibertyCell *cell, return PropertyValue(cell->filename()); else if (property == "library") return PropertyValue(cell->libertyLibrary()); + else if (property == "is_sequential") + return PropertyValue(cell->hasSequentials()); + else if (property == "has_timing_model") + return PropertyValue(cell->hasTimingArcs()); else if (property == "is_buffer") return PropertyValue(cell->isBuffer()); - else if (property =="is_inverter") + else if (property == "is_clock_gate" || property == "is_integrated_clock_gating_cell") + return PropertyValue(cell->isClockGate()); + else if (property == "is_inverter") return PropertyValue(cell->isInverter()); - else if (property == "is_memory") + else if (property == "is_physical_only") + return PropertyValue(cell->isPhysicalOnly()); + else if (property == "is_memory" || property == "is_memory_cell") return PropertyValue(cell->isMemory()); else if (property == "dont_use") return PropertyValue(cell->dontUse()); @@ -767,7 +777,26 @@ Properties::getProperty(const Port *port, return PropertyValue(network->direction(port)->name()); else if (property == "liberty_port") return PropertyValue(network->libertyPort(port)); - + else if (property == "capacitance" + || property == "pin_capacitance") { + int fanout = 0; + float cap = 0.0, wire_cap = 0.0; + for (const Corner *corner : *sta_->corners()) + sta_->portExtCaps(port, corner, MinMax::max(), cap, wire_cap, fanout); + return capacitancePropertyValue(cap); + } + else if (property == "clocks") { + const Instance *top_inst = network->topInstance(); + const Pin *pin = network->findPin(top_inst, port); + ClockSet clks = sta_->clocks(pin); + return PropertyValue(&clks); + } + else if (property == "clock_domains") { + const Instance *top_inst = network->topInstance(); + const Pin *pin = network->findPin(top_inst, port); + ClockSet clk_domains = sta_->clockDomains(pin); + return PropertyValue(&clk_domains); + } else if (property == "activity") { const Instance *top_inst = network->topInstance(); const Pin *pin = network->findPin(top_inst, port); @@ -868,7 +897,8 @@ Properties::getProperty(const LibertyPort *port, else if (property == "direction" || property == "port_direction") return PropertyValue(port->direction()->name()); - else if (property == "capacitance") { + else if (property == "capacitance" + || property == "pin_capacitance") { float cap = port->capacitance(RiseFall::rise(), MinMax::max()); return capacitancePropertyValue(cap); } @@ -960,8 +990,10 @@ Properties::getProperty(const Instance *inst, return PropertyValue(liberty_cell && liberty_cell->isInverter()); else if (property == "is_macro") return PropertyValue(liberty_cell && liberty_cell->isMacro()); - else if (property == "is_memory") + else if (property == "is_memory" || property == "is_memory_cell") return PropertyValue(liberty_cell && liberty_cell->isMemory()); + else if (property == "design_type") + return PropertyValue(liberty_cell ? liberty_cell->getDesignType() : "module"); else { PropertyValue value = registry_instance_.getProperty(inst, property, "instance", sta_); @@ -991,14 +1023,14 @@ Properties::getProperty(const Pin *pin, return PropertyValue(network->isHierarchical(pin)); else if (property == "is_port") return PropertyValue(network->isTopLevelPort(pin)); - else if (property == "is_clock") { - const LibertyPort *port = network->libertyPort(pin); - return PropertyValue(port->isClock()); - } - else if (property == "is_register_clock") { - const LibertyPort *port = network->libertyPort(pin); - return PropertyValue(port && port->isRegClk()); - } + else if (property == "is_register_clock") + return PropertyValue(network->isRegClkPin(pin)); + else if (property == "is_clock") + return PropertyValue(network->isClock(pin)); + else if (property == "is_rise_edge_triggered") + return PropertyValue(network->isRiseEdgeTriggered(pin)); + else if (property == "is_fall_edge_triggered") + return PropertyValue(network->isFallEdgeTriggered(pin)); else if (property == "clocks") { ClockSet clks = sta_->clocks(pin); return PropertyValue(&clks); @@ -1260,14 +1292,26 @@ Properties::getProperty(PathEnd *end, PathExpanded expanded(end->path(), sta_); return PropertyValue(expanded.startPath()->pin(sta_)); } - else if (property == "startpoint_clock") - return PropertyValue(end->path()->clock(sta_)); + else if (property == "startpoint_clock"){ + const Clock *clk = end->path()->clock(sta_); + if (clk) + return PropertyValue(clk->name()); + else + return PropertyValue(); + } else if (property == "endpoint") return PropertyValue(end->path()->pin(sta_)); - else if (property == "endpoint_clock") - return PropertyValue(end->targetClk(sta_)); + else if (property == "endpoint_clock") { + const Clock *clk = end->targetClk(sta_); + if (clk) + return PropertyValue(clk->name()); + else + return PropertyValue(); + } else if (property == "endpoint_clock_pin") return PropertyValue(end->targetClkPath()->pin(sta_)); + else if (property == "path_group") + return PropertyValue(sta_->search()->pathGroup(end)->name()); else if (property == "slack") return PropertyValue(delayPropertyValue(end->slack(sta_))); else if (property == "points") { diff --git a/test/get_property_flags.ok b/test/get_property_flags.ok new file mode 100644 index 000000000..5622d4cbe --- /dev/null +++ b/test/get_property_flags.ok @@ -0,0 +1,44 @@ +TEST 1 +get_clocks +clk +get_clocks 2 +vclk +get_lib_cells +asap7_small/BUFx2_ASAP7_75t_R +get_lib_cells 2 +asap7_small/AND2x2_ASAP7_75t_R +asap7_small/BUFx2_ASAP7_75t_R +asap7_small/DFFHQx4_ASAP7_75t_R +get_pins +r1/CLK +r1/D +r2/CLK +r2/D +r3/CLK +r3/D +u1/A +u2/A +u2/B +get_pins 2 +r1/Q +r2/Q +r3/Q +u1/Y +u2/Y +get_ports +clk1 +clk2 +clk3 +in1 +in2 +get_ports 2 +out +TEST 2 +get_clocks +get_clocks 2 +get_lib_cells +get_lib_cells 2 +get_pins +get_pins 2 +get_ports +get_ports 2 diff --git a/test/get_property_flags.tcl b/test/get_property_flags.tcl new file mode 100644 index 000000000..d310430dc --- /dev/null +++ b/test/get_property_flags.tcl @@ -0,0 +1,44 @@ +# get_* -filter with property flags + +# Read in design and libraries +read_liberty asap7_small.lib.gz +read_verilog reg1_asap7.v +link_design top +create_clock -name clk -period 500 {clk1 clk2 clk3} +create_clock -name vclk -period 1000 + +puts "TEST 1" +puts "get_clocks" +report_object_full_names [get_clocks -filter is_virtual==0 *] +puts "get_clocks 2" +report_object_full_names [get_clocks -filter is_virtual==1 *] +puts "get_lib_cells" +report_object_full_names [get_lib_cells -filter is_buffer==1 *] +puts "get_lib_cells 2" +report_object_full_names [get_lib_cells -filter is_inverter==0 *] +puts "get_pins" +report_object_full_names [get_pins -filter direction==input *] +puts "get_pins 2" +report_object_full_names [get_pins -filter direction==output *] +puts "get_ports" +report_object_full_names [get_ports -filter direction==input *] +puts "get_ports 2" +report_object_full_names [get_ports -filter direction==output *] + +puts "TEST 2" +puts "get_clocks" +report_object_full_names [get_clocks -filter is_virtual==false *] +puts "get_clocks 2" +report_object_full_names [get_clocks -filter is_virtual==true *] +puts "get_lib_cells" +report_object_full_names [get_lib_cells -filter is_buffer==true *] +puts "get_lib_cells 2" +report_object_full_names [get_lib_cells -filter is_inverter==false *] +puts "get_pins" +report_object_full_names [get_pins -filter direction==in *] +puts "get_pins 2" +report_object_full_names [get_pins -filter direction==out *] +puts "get_ports" +report_object_full_names [get_ports -filter direction==in *] +puts "get_ports 2" +report_object_full_names [get_ports -filter direction==out *] diff --git a/test/regression_vars.tcl b/test/regression_vars.tcl index 02bdadcdd..0041efb68 100644 --- a/test/regression_vars.tcl +++ b/test/regression_vars.tcl @@ -143,6 +143,7 @@ record_sta_tests { get_lib_pins_of_objects get_noargs get_objrefs + get_property_flags liberty_arcs_one2one_1 liberty_arcs_one2one_2 liberty_backslash_eol From 487aa7bed6ddac2f64afcdc2c93dbce3a8baf7ff Mon Sep 17 00:00:00 2001 From: Akash Levy Date: Sun, 28 Sep 2025 10:15:23 -0700 Subject: [PATCH 02/12] Fix return in void function --- liberty/Liberty.i | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/liberty/Liberty.i b/liberty/Liberty.i index e332e4123..205290ffc 100644 --- a/liberty/Liberty.i +++ b/liberty/Liberty.i @@ -275,8 +275,8 @@ bool is_memory() { return self->isMemory(); } bool is_physical_only() { return self->isPhysicalOnly(); } bool is_sequential() { return self->hasSequentials(); } bool dont_use() { return self->dontUse(); } -void set_dont_use() { return self->setDontUse(true); } -void unset_dont_use() { return self->setDontUse(false); } +void set_dont_use() { self->setDontUse(true); } +void unset_dont_use() { self->setDontUse(false); } LibertyLibrary *liberty_library() { return self->libertyLibrary(); } Cell *cell() { return reinterpret_cast(self); } LibertyPort * From 7d26dd4edd324a61e40749f3ef0d552f304363d8 Mon Sep 17 00:00:00 2001 From: Akash Levy Date: Sun, 28 Sep 2025 10:19:47 -0700 Subject: [PATCH 03/12] Minor line length fixes --- search/Property.cc | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/search/Property.cc b/search/Property.cc index c4c24ef73..f36970d41 100644 --- a/search/Property.cc +++ b/search/Property.cc @@ -740,7 +740,8 @@ Properties::getProperty(const LibertyCell *cell, return PropertyValue(cell->hasTimingArcs()); else if (property == "is_buffer") return PropertyValue(cell->isBuffer()); - else if (property == "is_clock_gate" || property == "is_integrated_clock_gating_cell") + else if (property == "is_clock_gate" + || property == "is_integrated_clock_gating_cell") return PropertyValue(cell->isClockGate()); else if (property == "is_inverter") return PropertyValue(cell->isInverter()); @@ -993,7 +994,8 @@ Properties::getProperty(const Instance *inst, else if (property == "is_memory" || property == "is_memory_cell") return PropertyValue(liberty_cell && liberty_cell->isMemory()); else if (property == "design_type") - return PropertyValue(liberty_cell ? liberty_cell->getDesignType() : "module"); + return PropertyValue(liberty_cell ? + liberty_cell->getDesignType() : "module"); else { PropertyValue value = registry_instance_.getProperty(inst, property, "instance", sta_); From b4a8900cedc227af24ef95c1a8b9207141b4235c Mon Sep 17 00:00:00 2001 From: Akash Levy Date: Sun, 28 Sep 2025 10:53:05 -0700 Subject: [PATCH 04/12] Remove physical_only to prevent conflicts with OpenROAD --- include/sta/Liberty.hh | 1 - liberty/Liberty.cc | 12 ------------ liberty/Liberty.i | 1 - search/Property.cc | 2 -- 4 files changed, 16 deletions(-) diff --git a/include/sta/Liberty.hh b/include/sta/Liberty.hh index 1ecb02b98..6d96ea838 100644 --- a/include/sta/Liberty.hh +++ b/include/sta/Liberty.hh @@ -434,7 +434,6 @@ public: void setArea(float area); bool dontUse() const { return dont_use_; } void setDontUse(bool dont_use); - bool isPhysicalOnly() const; bool isMacro() const { return is_macro_; } void setIsMacro(bool is_macro); bool isMemory() const { return is_memory_; } diff --git a/liberty/Liberty.cc b/liberty/Liberty.cc index ef2b0a4e7..ccbcb53cd 100644 --- a/liberty/Liberty.cc +++ b/liberty/Liberty.cc @@ -1077,18 +1077,6 @@ LibertyCell::setDontUse(bool dont_use) dont_use_ = dont_use; } -bool -LibertyCell::isPhysicalOnly() const -{ - // This is an approximation via typical features of a physical-only cell. - // The correct way to do this would be to load this info from a LEF file. - - // Assumption: Diodes are not counted for the purposes of this property. - - LibertyCellPortIterator port_it(this); // only iterates on signal ports - return !port_it.hasNext(); // zero ports -} - void LibertyCell::setIsMacro(bool is_macro) { diff --git a/liberty/Liberty.i b/liberty/Liberty.i index 205290ffc..30b681c88 100644 --- a/liberty/Liberty.i +++ b/liberty/Liberty.i @@ -272,7 +272,6 @@ bool is_inverter() { return self->isInverter(); } bool is_clock_gate() { return self->isClockGate(); } bool is_integrated_clock_gating_cell() { return self->isClockGate(); } bool is_memory() { return self->isMemory(); } -bool is_physical_only() { return self->isPhysicalOnly(); } bool is_sequential() { return self->hasSequentials(); } bool dont_use() { return self->dontUse(); } void set_dont_use() { self->setDontUse(true); } diff --git a/search/Property.cc b/search/Property.cc index f36970d41..25e077d1e 100644 --- a/search/Property.cc +++ b/search/Property.cc @@ -745,8 +745,6 @@ Properties::getProperty(const LibertyCell *cell, return PropertyValue(cell->isClockGate()); else if (property == "is_inverter") return PropertyValue(cell->isInverter()); - else if (property == "is_physical_only") - return PropertyValue(cell->isPhysicalOnly()); else if (property == "is_memory" || property == "is_memory_cell") return PropertyValue(cell->isMemory()); else if (property == "dont_use") From 882b57725c59085bff200feaf5a14da92151f1f0 Mon Sep 17 00:00:00 2001 From: Akash Levy Date: Mon, 10 Nov 2025 04:26:46 -0800 Subject: [PATCH 05/12] Remove design_type property --- include/sta/Liberty.hh | 1 - liberty/Liberty.cc | 6 ------ search/Property.cc | 3 --- 3 files changed, 10 deletions(-) diff --git a/include/sta/Liberty.hh b/include/sta/Liberty.hh index 6d96ea838..350afa2a5 100644 --- a/include/sta/Liberty.hh +++ b/include/sta/Liberty.hh @@ -459,7 +459,6 @@ public: bool isClockGateOther() const; bool isClockGate() const; void setClockGateType(ClockGateType type); - const char *getDesignType() const; const TimingArcSetSeq &timingArcSets() const { return timing_arc_sets_; } // from or to may be nullptr to wildcard. const TimingArcSetSeq &timingArcSets(const LibertyPort *from, diff --git a/liberty/Liberty.cc b/liberty/Liberty.cc index ccbcb53cd..05eb8d1f7 100644 --- a/liberty/Liberty.cc +++ b/liberty/Liberty.cc @@ -1167,12 +1167,6 @@ LibertyCell::setClockGateType(ClockGateType type) clock_gate_type_ = type; } -const char * -LibertyCell::getDesignType() const -{ - return isMacro() ? "macro": "cell"; -} - bool LibertyCell::isBuffer() const { diff --git a/search/Property.cc b/search/Property.cc index 25e077d1e..91ce1c9e3 100644 --- a/search/Property.cc +++ b/search/Property.cc @@ -991,9 +991,6 @@ Properties::getProperty(const Instance *inst, return PropertyValue(liberty_cell && liberty_cell->isMacro()); else if (property == "is_memory" || property == "is_memory_cell") return PropertyValue(liberty_cell && liberty_cell->isMemory()); - else if (property == "design_type") - return PropertyValue(liberty_cell ? - liberty_cell->getDesignType() : "module"); else { PropertyValue value = registry_instance_.getProperty(inst, property, "instance", sta_); From 4fa605565d927007cf33319f24c5bb8b1f818c1a Mon Sep 17 00:00:00 2001 From: Akash Levy Date: Mon, 10 Nov 2025 04:31:09 -0800 Subject: [PATCH 06/12] Remove set_dont_use and unset_dont_use from API --- liberty/Liberty.i | 2 -- 1 file changed, 2 deletions(-) diff --git a/liberty/Liberty.i b/liberty/Liberty.i index 30b681c88..9f3cc52a3 100644 --- a/liberty/Liberty.i +++ b/liberty/Liberty.i @@ -274,8 +274,6 @@ bool is_integrated_clock_gating_cell() { return self->isClockGate(); } bool is_memory() { return self->isMemory(); } bool is_sequential() { return self->hasSequentials(); } bool dont_use() { return self->dontUse(); } -void set_dont_use() { self->setDontUse(true); } -void unset_dont_use() { self->setDontUse(false); } LibertyLibrary *liberty_library() { return self->libertyLibrary(); } Cell *cell() { return reinterpret_cast(self); } LibertyPort * From 73500691b6df3aae6de2930dcbdfe20ea60bd836 Mon Sep 17 00:00:00 2001 From: Akash Levy Date: Mon, 10 Nov 2025 04:34:09 -0800 Subject: [PATCH 07/12] Remove port capacitance/pin_capacitance properties --- search/Property.cc | 8 -------- 1 file changed, 8 deletions(-) diff --git a/search/Property.cc b/search/Property.cc index 91ce1c9e3..7a809bfa1 100644 --- a/search/Property.cc +++ b/search/Property.cc @@ -776,14 +776,6 @@ Properties::getProperty(const Port *port, return PropertyValue(network->direction(port)->name()); else if (property == "liberty_port") return PropertyValue(network->libertyPort(port)); - else if (property == "capacitance" - || property == "pin_capacitance") { - int fanout = 0; - float cap = 0.0, wire_cap = 0.0; - for (const Corner *corner : *sta_->corners()) - sta_->portExtCaps(port, corner, MinMax::max(), cap, wire_cap, fanout); - return capacitancePropertyValue(cap); - } else if (property == "clocks") { const Instance *top_inst = network->topInstance(); const Pin *pin = network->findPin(top_inst, port); From d42291123b7b1f279f9f960a43551e807aa9d1f2 Mon Sep 17 00:00:00 2001 From: Akash Levy Date: Mon, 10 Nov 2025 04:36:02 -0800 Subject: [PATCH 08/12] Remove is_rise_edge_triggered and is_fall_edge_triggered --- network/Network.cc | 39 --------------------------------------- search/Property.cc | 4 ---- 2 files changed, 43 deletions(-) diff --git a/network/Network.cc b/network/Network.cc index 38fdcfecb..dccf7f6a2 100644 --- a/network/Network.cc +++ b/network/Network.cc @@ -646,45 +646,6 @@ Network::isClock(const Pin *pin) const return port && port->isClock(); } -bool -Network::isRiseEdgeTriggered(const Pin *pin) const -{ - LibertyPort *port = libertyPort(pin); - if (!port) { - return false; - } - LibertyCell *cell = port->libertyCell(); - const Sequential *seq = cell->outputPortSequential(port); - if (!seq) { - return false; - } - FuncExpr *clk_func = seq->clock(); - - // Assumption: the clock function is exactly CLK for rising-edge triggered - // sequentials - return clk_func->op() == FuncExpr::op_port; -} - -bool -Network::isFallEdgeTriggered(const Pin *pin) const -{ - LibertyPort *port = libertyPort(pin); - if (!port) { - return false; - } - LibertyCell *cell = port->libertyCell(); - const Sequential *seq = cell->outputPortSequential(port); - if (!seq) { - return false; - } - FuncExpr *clk_func = seq->clock(); - - // Assumption: the clock function is exactly !CLK for falling-edge triggered - // sequentials - return clk_func->op() == FuncExpr::op_not; -} - - bool Network::isRegClkPin(const Pin *pin) const { diff --git a/search/Property.cc b/search/Property.cc index 7a809bfa1..b703d4526 100644 --- a/search/Property.cc +++ b/search/Property.cc @@ -1016,10 +1016,6 @@ Properties::getProperty(const Pin *pin, return PropertyValue(network->isRegClkPin(pin)); else if (property == "is_clock") return PropertyValue(network->isClock(pin)); - else if (property == "is_rise_edge_triggered") - return PropertyValue(network->isRiseEdgeTriggered(pin)); - else if (property == "is_fall_edge_triggered") - return PropertyValue(network->isFallEdgeTriggered(pin)); else if (property == "clocks") { ClockSet clks = sta_->clocks(pin); return PropertyValue(&clks); From aec3a04ab9d5b74aab93c2821a9d16c85e1e4fcb Mon Sep 17 00:00:00 2001 From: Akash Levy Date: Mon, 10 Nov 2025 04:37:38 -0800 Subject: [PATCH 09/12] Remove isRiseEdgeTriggered and isFallEdgeTriggered fully --- include/sta/Network.hh | 2 -- 1 file changed, 2 deletions(-) diff --git a/include/sta/Network.hh b/include/sta/Network.hh index fd6d804f3..b4522bf0e 100644 --- a/include/sta/Network.hh +++ b/include/sta/Network.hh @@ -314,8 +314,6 @@ public: bool isDriver(const Pin *pin) const; bool isLoad(const Pin *pin) const; bool isClock(const Pin *pin) const; - bool isRiseEdgeTriggered(const Pin *pin) const; - bool isFallEdgeTriggered(const Pin *pin) const; // Has register/latch rise/fall edges from pin. bool isRegClkPin(const Pin *pin) const; // Pin clocks a timing check. From 68a95c1d2c322de28953c1585237f4c09b5fe084 Mon Sep 17 00:00:00 2001 From: Akash Levy Date: Mon, 10 Nov 2025 04:44:03 -0800 Subject: [PATCH 10/12] Remove unnecessary includes --- network/Network.cc | 3 --- 1 file changed, 3 deletions(-) diff --git a/network/Network.cc b/network/Network.cc index dccf7f6a2..34fe228ae 100644 --- a/network/Network.cc +++ b/network/Network.cc @@ -22,11 +22,8 @@ // // This notice may not be removed or altered from any source distribution. -#include #include "Network.hh" -#include "Sequential.hh" -#include "FuncExpr.hh" #include "StringUtil.hh" #include "PatternMatch.hh" From 63ae3b84c7d01060dcabd503f015ae8ec8976486 Mon Sep 17 00:00:00 2001 From: Akash Levy Date: Mon, 10 Nov 2025 18:11:36 -0800 Subject: [PATCH 11/12] Remove SWIG interfaces for properties in Liberty.i --- liberty/Liberty.i | 6 ------ 1 file changed, 6 deletions(-) diff --git a/liberty/Liberty.i b/liberty/Liberty.i index 9f3cc52a3..4dd5d7a87 100644 --- a/liberty/Liberty.i +++ b/liberty/Liberty.i @@ -265,15 +265,9 @@ default_operating_conditions() %extend LibertyCell { const char *name() { return self->name(); } -bool has_timing_model() { return self->hasTimingArcs(); } bool is_leaf() { return self->isLeaf(); } bool is_buffer() { return self->isBuffer(); } bool is_inverter() { return self->isInverter(); } -bool is_clock_gate() { return self->isClockGate(); } -bool is_integrated_clock_gating_cell() { return self->isClockGate(); } -bool is_memory() { return self->isMemory(); } -bool is_sequential() { return self->hasSequentials(); } -bool dont_use() { return self->dontUse(); } LibertyLibrary *liberty_library() { return self->libertyLibrary(); } Cell *cell() { return reinterpret_cast(self); } LibertyPort * From b3d4261c00dae13aec5ac11d625241720cb74e8e Mon Sep 17 00:00:00 2001 From: Akash Levy Date: Mon, 10 Nov 2025 18:20:21 -0800 Subject: [PATCH 12/12] Remove isClock from Network API --- include/sta/Network.hh | 1 - network/Network.cc | 7 ------- search/Property.cc | 6 ++++-- 3 files changed, 4 insertions(+), 10 deletions(-) diff --git a/include/sta/Network.hh b/include/sta/Network.hh index b4522bf0e..00566c10b 100644 --- a/include/sta/Network.hh +++ b/include/sta/Network.hh @@ -313,7 +313,6 @@ public: const Instance *hier_inst) const; bool isDriver(const Pin *pin) const; bool isLoad(const Pin *pin) const; - bool isClock(const Pin *pin) const; // Has register/latch rise/fall edges from pin. bool isRegClkPin(const Pin *pin) const; // Pin clocks a timing check. diff --git a/network/Network.cc b/network/Network.cc index 34fe228ae..578c06645 100644 --- a/network/Network.cc +++ b/network/Network.cc @@ -636,13 +636,6 @@ Network::isLoad(const Pin *pin) const || dir->isUnknown(); } -bool -Network::isClock(const Pin *pin) const -{ - const LibertyPort *port = libertyPort(pin); - return port && port->isClock(); -} - bool Network::isRegClkPin(const Pin *pin) const { diff --git a/search/Property.cc b/search/Property.cc index b703d4526..7066fb771 100644 --- a/search/Property.cc +++ b/search/Property.cc @@ -1014,8 +1014,10 @@ Properties::getProperty(const Pin *pin, return PropertyValue(network->isTopLevelPort(pin)); else if (property == "is_register_clock") return PropertyValue(network->isRegClkPin(pin)); - else if (property == "is_clock") - return PropertyValue(network->isClock(pin)); + else if (property == "is_clock") { + LibertyPort *liberty_port = network->libertyPort(pin); + return PropertyValue(liberty_port && liberty_port->isClock()); + } else if (property == "clocks") { ClockSet clks = sta_->clocks(pin); return PropertyValue(&clks);