diff --git a/CMakeLists.txt b/CMakeLists.txt index 620f9cbb..3043c6ab 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -424,6 +424,7 @@ set(SWIG_FILES ${STA_HOME}/power/Power.i ${STA_HOME}/sdc/Sdc.i ${STA_HOME}/sdf/Sdf.i + ${STA_HOME}/search/Property.i ${STA_HOME}/search/Search.i ${STA_HOME}/spice/WriteSpice.i ${STA_HOME}/tcl/Exception.i diff --git a/doc/ChangeLog.txt b/doc/ChangeLog.txt index f074ed8a..65ce152a 100644 --- a/doc/ChangeLog.txt +++ b/doc/ChangeLog.txt @@ -12,12 +12,6 @@ build directory instead of `app/`. The set_max_delay and set_min_delay commands now support the -probe option. With -probe these commands do not break paths at internal (non-startpoint) pins. -The set_property command is used to annotate a user defined property -on an object. It does not change the value of built in properties. If -property names a built-in property it has no effect. - - set_property [-object_type type] object property value - Release 2.6.1 2025/03/30 ------------------------- diff --git a/doc/OpenSTA.odt b/doc/OpenSTA.odt index d459ca03..495ea6fb 100644 Binary files a/doc/OpenSTA.odt and b/doc/OpenSTA.odt differ diff --git a/doc/OpenSTA.pdf b/doc/OpenSTA.pdf index 5270fd8d..f20e6fea 100644 Binary files a/doc/OpenSTA.pdf and b/doc/OpenSTA.pdf differ diff --git a/include/sta/Property.hh b/include/sta/Property.hh index 561354ce..93b34e32 100644 --- a/include/sta/Property.hh +++ b/include/sta/Property.hh @@ -38,80 +38,54 @@ namespace sta { class Sta; class PropertyValue; +class Sta; +class PropertyValue; + template class PropertyRegistry { public: - PropertyValue getProperty(TYPE inst, - const std::string property); - void setProperty(TYPE inst, - const std::string property, - PropertyValue value); + void defineProperty(const std::string property, + std::function handler); + PropertyValue getProperty(TYPE object, + const std::string property, + const char *type_name, + Sta *sta); private: - std::map, PropertyValue> registry_; + std::map> registry_; }; class Properties { public: Properties(Sta *sta); + virtual ~Properties() {} PropertyValue getProperty(const Library *lib, const std::string property); - void setProperty(const Library *lib, - const std::string property, - PropertyValue value); PropertyValue getProperty(const LibertyLibrary *lib, const std::string property); - void setProperty(const LibertyLibrary *lib, - const std::string property, - PropertyValue value); PropertyValue getProperty(const Cell *cell, const std::string property); - void setProperty(const Cell *cell, - const std::string property, - PropertyValue value); PropertyValue getProperty(const LibertyCell *cell, const std::string property); - void setProperty(const LibertyCell *cell, - const std::string property, - PropertyValue value); PropertyValue getProperty(const Port *port, const std::string property); - void setProperty(const Port *port, - const std::string property, - PropertyValue value); PropertyValue getProperty(const LibertyPort *port, const std::string property); - void setProperty(const LibertyPort *port, - const std::string property, - PropertyValue value); PropertyValue getProperty(const Instance *inst, const std::string property); - void setProperty(const Instance *inst, - const std::string property, - PropertyValue value); PropertyValue getProperty(const Pin *pin, const std::string property); - void setProperty(const Pin *pin, - const std::string property, - PropertyValue value); PropertyValue getProperty(const Net *net, const std::string property); - void setProperty(const Net *net, - const std::string property, - PropertyValue value); PropertyValue getProperty(Edge *edge, const std::string property); - void setProperty(Edge *edge, - const std::string property, - PropertyValue value); PropertyValue getProperty(const Clock *clk, const std::string property); - void setProperty(const Clock *clk, - const std::string property, - PropertyValue value); PropertyValue getProperty(PathEnd *end, const std::string property); PropertyValue getProperty(Path *path, @@ -119,7 +93,40 @@ public: PropertyValue getProperty(TimingArcSet *arc_set, const std::string property); -private: + // Define handler for external property. + // proerties->defineProperty("foo", + // [] (const Instance *, Sta *) -> PropertyValue { + // return PropertyValue("bar"); + // }); + void defineProperty(std::string property, + std::function handler); + void defineProperty(std::string property, + std::function handler); + void defineProperty(std::string property, + std::function handler); + void defineProperty(std::string property, + std::function handler); + void defineProperty(std::string property, + std::function handler); + void defineProperty(std::string property, + std::function handler); + void defineProperty(std::string property, + std::function handler); + void defineProperty(std::string property, + std::function handler); + void defineProperty(std::string property, + std::function handler); + +protected: PropertyValue portSlew(const Port *port, const MinMax *min_max); PropertyValue portSlew(const Port *port, @@ -152,18 +159,16 @@ private: const RiseFall *rf, const MinMax *min_max); - // set_property user definied properties. - PropertyRegistry registry_lib_; - PropertyRegistry registry_liberty_lib_; + PropertyRegistry registry_library_; + PropertyRegistry registry_liberty_library_; PropertyRegistry registry_cell_; PropertyRegistry registry_liberty_cell_; PropertyRegistry registry_port_; PropertyRegistry registry_liberty_port_; - PropertyRegistry registry_inst_; + PropertyRegistry registry_instance_; PropertyRegistry registry_pin_; PropertyRegistry registry_net_; - PropertyRegistry registry_edge_; - PropertyRegistry registry_clk_; + Sta *sta_; }; diff --git a/search/Property.cc b/search/Property.cc index ae5c5485..49956330 100644 --- a/search/Property.cc +++ b/search/Property.cc @@ -635,43 +635,11 @@ PropertyValue::boolValue() const //////////////////////////////////////////////////////////////// -template -PropertyValue -PropertyRegistry::getProperty(TYPE object, - const std::string property) - -{ - auto itr = registry_.find({object, property}); - if (itr != registry_.end()) - return itr->second; - else - return PropertyValue(); -} - -template -void -PropertyRegistry::setProperty(TYPE object, - const std::string property, - PropertyValue value) -{ - registry_[{object, property}] = value; -} - -//////////////////////////////////////////////////////////////// - Properties::Properties(Sta *sta) : sta_(sta) { } -void -Properties::setProperty(const Library *lib, - const string property, - PropertyValue value) -{ - registry_lib_.setProperty(lib, property, value); -} - PropertyValue Properties::getProperty(const Library *lib, const std::string property) @@ -681,7 +649,8 @@ Properties::getProperty(const Library *lib, || property == "full_name") return PropertyValue(network->name(lib)); else { - PropertyValue value = registry_lib_.getProperty(lib, property); + PropertyValue value = registry_library_.getProperty(lib, property, + "library", sta_); if (value.type() != PropertyValue::Type::type_none) return value; else @@ -691,14 +660,6 @@ Properties::getProperty(const Library *lib, //////////////////////////////////////////////////////////////// -void -Properties::setProperty(const LibertyLibrary *lib, - const string property, - PropertyValue value) -{ - registry_liberty_lib_.setProperty(lib, property, value); -} - PropertyValue Properties::getProperty(const LibertyLibrary *lib, const std::string property) @@ -709,7 +670,9 @@ Properties::getProperty(const LibertyLibrary *lib, else if (property == "filename") return PropertyValue(lib->filename()); else { - PropertyValue value = registry_liberty_lib_.getProperty(lib, property); + PropertyValue value = registry_liberty_library_.getProperty(lib, property, + "liberty_library", + sta_); if (value.type() != PropertyValue::Type::type_none) return value; else @@ -719,14 +682,37 @@ Properties::getProperty(const LibertyLibrary *lib, //////////////////////////////////////////////////////////////// -void -Properties::setProperty(const LibertyCell *cell, - const string property, - PropertyValue value) +PropertyValue +Properties::getProperty(const Cell *cell, + const std::string property) { - registry_liberty_cell_.setProperty(cell, property, value); + Network *network = sta_->cmdNetwork(); + if (property == "name" + || property == "base_name") + return PropertyValue(network->name(cell)); + else if (property == "full_name") { + Library *lib = network->library(cell); + string lib_name = network->name(lib); + string cell_name = network->name(cell); + string full_name = lib_name + network->pathDivider() + cell_name; + return PropertyValue(full_name); + } + else if (property == "library") + return PropertyValue(network->library(cell)); + else if (property == "filename") + return PropertyValue(network->filename(cell)); + else { + PropertyValue value = registry_cell_.getProperty(cell, property, + "cell", sta_); + if (value.type() != PropertyValue::Type::type_none) + return value; + else + throw PropertyUnknown("cell", property); + } } +//////////////////////////////////////////////////////////////// + PropertyValue Properties::getProperty(const LibertyCell *cell, const std::string property) @@ -757,7 +743,8 @@ Properties::getProperty(const LibertyCell *cell, else if (property == "area") return PropertyValue(cell->area(), sta_->units()->scalarUnit()); else { - PropertyValue value = registry_liberty_cell_.getProperty(cell, property); + PropertyValue value = registry_liberty_cell_.getProperty(cell, property, + "liberty_cell", sta_); if (value.type() != PropertyValue::Type::type_none) return value; else @@ -767,52 +754,6 @@ Properties::getProperty(const LibertyCell *cell, //////////////////////////////////////////////////////////////// -void -Properties::setProperty(const Cell *cell, - const string property, - PropertyValue value) -{ - registry_cell_.setProperty(cell, property, value); -} - -PropertyValue -Properties::getProperty(const Cell *cell, - const std::string property) -{ - Network *network = sta_->cmdNetwork(); - if (property == "name" - || property == "base_name") - return PropertyValue(network->name(cell)); - else if (property == "full_name") { - Library *lib = network->library(cell); - string lib_name = network->name(lib); - string cell_name = network->name(cell); - string full_name = lib_name + network->pathDivider() + cell_name; - return PropertyValue(full_name); - } - else if (property == "library") - return PropertyValue(network->library(cell)); - else if (property == "filename") - return PropertyValue(network->filename(cell)); - else { - PropertyValue value = registry_cell_.getProperty(cell, property); - if (value.type() != PropertyValue::Type::type_none) - return value; - else - throw PropertyUnknown("cell", property); - } -} - -//////////////////////////////////////////////////////////////// - -void -Properties::setProperty(const Port *port, - const string property, - PropertyValue value) -{ - registry_port_.setProperty(port, property, value); -} - PropertyValue Properties::getProperty(const Port *port, const std::string property) @@ -861,7 +802,8 @@ Properties::getProperty(const Port *port, return portSlew(port, RiseFall::fall(), MinMax::min()); else { - PropertyValue value = registry_port_.getProperty(port, property); + PropertyValue value = registry_port_.getProperty(port, property, + "port", sta_); if (value.type() != PropertyValue::Type::type_none) return value; else @@ -913,14 +855,6 @@ Properties::portSlack(const Port *port, //////////////////////////////////////////////////////////////// -void -Properties::setProperty(const LibertyPort *port, - const string property, - PropertyValue value) -{ - registry_liberty_port_.setProperty(port, property, value); -} - PropertyValue Properties::getProperty(const LibertyPort *port, const std::string property) @@ -987,7 +921,8 @@ Properties::getProperty(const LibertyPort *port, return delayPropertyValue(delay); } else { - PropertyValue value = registry_liberty_port_.getProperty(port, property); + PropertyValue value = registry_liberty_port_.getProperty(port, property, + "liberty_port", sta_); if (value.type() != PropertyValue::Type::type_none) return value; else @@ -997,14 +932,6 @@ Properties::getProperty(const LibertyPort *port, //////////////////////////////////////////////////////////////// -void -Properties::setProperty(const Instance *inst, - const string property, - PropertyValue value) -{ - registry_inst_.setProperty(inst, property, value); -} - PropertyValue Properties::getProperty(const Instance *inst, const string property) @@ -1034,7 +961,8 @@ Properties::getProperty(const Instance *inst, else if (property == "is_memory") return PropertyValue(liberty_cell && liberty_cell->isMemory()); else { - PropertyValue value = registry_inst_.getProperty(inst, property); + PropertyValue value = registry_instance_.getProperty(inst, property, + "instance", sta_); if (value.type() != PropertyValue::Type::type_none) return value; else @@ -1044,14 +972,6 @@ Properties::getProperty(const Instance *inst, //////////////////////////////////////////////////////////////// -void -Properties::setProperty(const Pin *pin, - const string property, - PropertyValue value) -{ - registry_pin_.setProperty(pin, property, value); -} - PropertyValue Properties::getProperty(const Pin *pin, const std::string property) @@ -1122,7 +1042,7 @@ Properties::getProperty(const Pin *pin, return pinSlew(pin, RiseFall::fall(), MinMax::min()); else { - PropertyValue value = registry_pin_.getProperty(pin, property); + PropertyValue value = registry_pin_.getProperty(pin, property, "pin", sta_); if (value.type() != PropertyValue::Type::type_none) return value; else @@ -1201,14 +1121,6 @@ Properties::pinSlew(const Pin *pin, //////////////////////////////////////////////////////////////// -void -Properties::setProperty(const Net *net, - const string property, - PropertyValue value) -{ - registry_net_.setProperty(net, property, value); -} - PropertyValue Properties::getProperty(const Net *net, const std::string property) @@ -1219,7 +1131,7 @@ Properties::getProperty(const Net *net, else if (property == "full_name") return PropertyValue(network->pathName(net)); else { - PropertyValue value = registry_net_.getProperty(net, property); + PropertyValue value = registry_net_.getProperty(net, property, "net", sta_); if (value.type() != PropertyValue::Type::type_none) return value; else @@ -1229,14 +1141,6 @@ Properties::getProperty(const Net *net, //////////////////////////////////////////////////////////////// -void -Properties::setProperty(Edge *edge, - const string property, - PropertyValue value) -{ - registry_edge_.setProperty(edge, property, value); -} - PropertyValue Properties::getProperty(Edge *edge, const std::string property) @@ -1259,13 +1163,8 @@ Properties::getProperty(Edge *edge, return PropertyValue(edge->from(sta_->graph())->pin()); else if (property == "to_pin") return PropertyValue(edge->to(sta_->graph())->pin()); - else { - PropertyValue value = registry_edge_.getProperty(edge, property); - if (value.type() != PropertyValue::Type::type_none) - return value; - else + else throw PropertyUnknown("edge", property); - } } PropertyValue @@ -1319,14 +1218,6 @@ Properties::getProperty(TimingArcSet *arc_set, //////////////////////////////////////////////////////////////// -void -Properties::setProperty(const Clock *clk, - const string property, - PropertyValue value) -{ - registry_clk_.setProperty(clk, property, value); -} - PropertyValue Properties::getProperty(const Clock *clk, const std::string property) @@ -1344,13 +1235,8 @@ Properties::getProperty(const Clock *clk, return PropertyValue(clk->isVirtual()); else if (property == "is_propagated") return PropertyValue(clk->isPropagated()); - else { - PropertyValue value = registry_clk_.getProperty(clk, property); - if (value.type() != PropertyValue::Type::type_none) - return value; - else - throw PropertyUnknown("clock", property); - } + else + throw PropertyUnknown("clock", property); } //////////////////////////////////////////////////////////////// @@ -1420,4 +1306,104 @@ Properties::capacitancePropertyValue(float cap) return PropertyValue(cap, sta_->units()->capacitanceUnit()); } +//////////////////////////////////////////////////////////////// + +void +Properties::defineProperty(std::string property, + std::function handler) +{ + registry_library_.defineProperty(property, handler); +} + +void +Properties::defineProperty(std::string property, + std::function handler) +{ + registry_liberty_library_.defineProperty(property, handler); +} + +void +Properties::defineProperty(std::string property, + std::function handler) +{ + registry_cell_.defineProperty(property, handler); +} + +void +Properties::defineProperty(std::string property, + std::function handler) +{ + registry_liberty_cell_.defineProperty(property, handler); +} + +void +Properties::defineProperty(std::string property, + std::function handler) +{ + registry_port_.defineProperty(property, handler); +} + +void +Properties::defineProperty(std::string property, + std::function handler) +{ + registry_liberty_port_.defineProperty(property, handler); +} + +void +Properties::defineProperty(std::string property, + std::function handler) +{ + registry_instance_.defineProperty(property, handler); +} + +void +Properties::defineProperty(std::string property, + std::function handler) +{ + registry_pin_.defineProperty(property, handler); +} + +void +Properties::defineProperty(std::string property, + std::function handler) +{ + registry_net_.defineProperty(property, handler); +} + +//////////////////////////////////////////////////////////////// + +template +PropertyValue +PropertyRegistry::getProperty(TYPE object, + const std::string property, + const char *type_name, + Sta *sta) + +{ + auto itr = registry_.find({property}); + if (itr != registry_.end()) + return itr->second(object, sta); + else + throw PropertyUnknown(type_name, property); +} + +template +void +PropertyRegistry::defineProperty(const std::string property, + std::function handler) +{ + registry_[property] = handler; +} + } // namespace diff --git a/search/Property.i b/search/Property.i index edad5f1b..bb3853b2 100644 --- a/search/Property.i +++ b/search/Property.i @@ -43,15 +43,6 @@ library_property(const Library *lib, return properties.getProperty(lib, property); } -void -set_library_property(const Library *lib, - const char *property, - PropertyValue value) -{ - Properties &properties = Sta::sta()->properties(); - properties.setProperty(lib, property, value); -} - PropertyValue liberty_library_property(const LibertyLibrary *lib, const char *property) @@ -60,15 +51,6 @@ liberty_library_property(const LibertyLibrary *lib, return properties.getProperty(lib, property); } -void -set_liberty_library_property(const LibertyLibrary *lib, - const char *property, - PropertyValue value) -{ - Properties &properties = Sta::sta()->properties(); - properties.setProperty(lib, property, value); -} - PropertyValue cell_property(const Cell *cell, const char *property) @@ -77,15 +59,6 @@ cell_property(const Cell *cell, return properties.getProperty(cell, property); } -void -set_cell_property(const Cell *cell, - const char *property, - PropertyValue value) -{ - Properties &properties = Sta::sta()->properties(); - properties.setProperty(cell, property, value); -} - PropertyValue liberty_cell_property(const LibertyCell *cell, const char *property) @@ -94,15 +67,6 @@ liberty_cell_property(const LibertyCell *cell, return properties.getProperty(cell, property); } -void -set_liberty_cell_property(const LibertyCell *cell, - const char *property, - PropertyValue value) -{ - Properties &properties = Sta::sta()->properties(); - properties.setProperty(cell, property, value); -} - PropertyValue port_property(const Port *port, const char *property) @@ -111,15 +75,6 @@ port_property(const Port *port, return properties.getProperty(port, property); } -void -set_port_property(const Port *port, - const char *property, - PropertyValue value) -{ - Properties &properties = Sta::sta()->properties(); - properties.setProperty(port, property, value); -} - PropertyValue liberty_port_property(const LibertyPort *port, const char *property) @@ -128,15 +83,6 @@ liberty_port_property(const LibertyPort *port, return properties.getProperty(port, property); } -void -set_liberty_port_property(const LibertyPort *port, - const char *property, - PropertyValue value) -{ - Properties &properties = Sta::sta()->properties(); - properties.setProperty(port, property, value); -} - PropertyValue instance_property(const Instance *inst, const char *property) @@ -145,15 +91,6 @@ instance_property(const Instance *inst, return properties.getProperty(inst, property); } -void -set_instance_property(const Instance *inst, - const char *property, - PropertyValue value) -{ - Properties &properties = Sta::sta()->properties(); - properties.setProperty(inst, property, value); -} - PropertyValue pin_property(const Pin *pin, const char *property) @@ -162,15 +99,6 @@ pin_property(const Pin *pin, return properties.getProperty(pin, property); } -void -set_pin_property(const Pin *pin, - const char *property, - PropertyValue value) -{ - Properties &properties = Sta::sta()->properties(); - properties.setProperty(pin, property, value); -} - PropertyValue net_property(const Net *net, const char *property) @@ -179,15 +107,6 @@ net_property(const Net *net, return properties.getProperty(net, property); } -void -set_net_property(const Net *net, - const char *property, - PropertyValue value) -{ - Properties &properties = Sta::sta()->properties(); - properties.setProperty(net, property, value); -} - PropertyValue edge_property(Edge *edge, const char *property) @@ -196,15 +115,6 @@ edge_property(Edge *edge, return properties.getProperty(edge, property); } -void -set_edge_property(Edge *edge, - const char *property, - PropertyValue value) -{ - Properties &properties = Sta::sta()->properties(); - properties.setProperty(edge, property, value); -} - PropertyValue clock_property(Clock *clk, const char *property) @@ -213,15 +123,6 @@ clock_property(Clock *clk, return properties.getProperty(clk, property); } -void -set_clock_property(const Clock *clk, - const char *property, - PropertyValue value) -{ - Properties &properties = Sta::sta()->properties(); - properties.setProperty(clk, property, value); -} - PropertyValue path_end_property(PathEnd *end, const char *property) @@ -239,8 +140,8 @@ path_property(Path *path, } PropertyValue -timing_arc_set_property(TimingArcSet *arc_set, - const char *property) +timing_arc_property(TimingArcSet *arc_set, + const char *property) { Properties &properties = Sta::sta()->properties(); return properties.getProperty(arc_set, property); diff --git a/tcl/Property.tcl b/tcl/Property.tcl index 7466ec99..ed291091 100644 --- a/tcl/Property.tcl +++ b/tcl/Property.tcl @@ -76,7 +76,7 @@ proc get_object_property { object prop } { } elseif { $object_type == "Path" } { return [path_property $object $prop] } elseif { $object_type == "TimingArcSet" } { - return [timing_arc_set_property $object $prop] + return [timing_arc_property $object $prop] } else { sta_error 2203 "get_property unsupported object type $object_type." } @@ -116,65 +116,5 @@ proc get_property_object_type { object_type object_name quiet } { return [lindex $object 0] } -define_cmd_args "set_property" \ - {[-object_type library|liberty_library|cell|liberty_cell|instance|pin|net|port|clock|timing_arc] object property value} - -proc set_property { args } { - return [get_property_cmd "set_property" "-object_type" $args] -} - -proc set_property { args } { - parse_key_args "set_property" args keys {-object_type} flags {-quiet} - check_argc_eq3 "set_property" $args - set quiet [info exists flags(-quiet)] - set object [lindex $args 0] - if { $object == "" } { - sta_error 2207 "set_property object is null." - } elseif { ![is_object $object] } { - if [info exists keys(-object_type)] { - set object_type $keys(-object_type) - } else { - sta_error 2208 "set_property -object_type must be specified with object name argument." - } - set object [get_property_object_type $object_type $object $quiet] - } - set prop [lindex $args 1] - set value [lindex $args 2] - set_object_property $object $prop $value -} - -proc set_object_property { object prop value } { - if { [is_object $object] } { - set object_type [object_type $object] - if { $object_type == "Instance" } { - set_instance_property $object $prop $value - } elseif { $object_type == "Pin" } { - set_pin_property $object $prop $value - } elseif { $object_type == "Net" } { - set_net_property $object $prop $value - } elseif { $object_type == "Clock" } { - set_clock_property $object $prop $value - } elseif { $object_type == "Port" } { - set_port_property $object $prop $value - } elseif { $object_type == "LibertyPort" } { - set_liberty_port_property $object $prop $value - } elseif { $object_type == "LibertyCell" } { - set_liberty_cell_property $object $prop $value - } elseif { $object_type == "Cell" } { - set_cell_property $object $prop $value - } elseif { $object_type == "Library" } { - set_library_property $object $prop $value - } elseif { $object_type == "LibertyLibrary" } { - set_liberty_library_property $object $prop $value - } elseif { $object_type == "Edge" } { - set_edge_property $object $prop $value - } else { - sta_error 2209 "get_property unsupported object type $object_type." - } - } else { - sta_error 2210 "get_property $object is not an object." - } -} - # sta namespace end. }