diff --git a/search/Property.cc b/search/Property.cc index f7d69fd9..6fc228f3 100644 --- a/search/Property.cc +++ b/search/Property.cc @@ -68,6 +68,35 @@ delayPropertyValue(Delay delay, //////////////////////////////////////////////////////////////// +class PropertyUnknown : public StaException +{ +public: + PropertyUnknown(const char *type, + const char *property); + virtual ~PropertyUnknown() THROW_DCL {} + virtual const char *what() const throw(); + +private: + const char *type_; + const char *property_; +}; + +PropertyUnknown::PropertyUnknown(const char *type, + const char *property) : + type_(type), + property_(property) +{ +} + +const char * +PropertyUnknown::what() const throw() +{ + return stringPrint("%s objects do not have a %s property.", + type_, property_); +} + +//////////////////////////////////////////////////////////////// + PropertyValue::PropertyValue() : type_(type_none) { @@ -109,6 +138,13 @@ PropertyValue::PropertyValue(LibertyCell *value) : liberty_cell_ = value; } +PropertyValue::PropertyValue(Library *value) : + type_(type_library) +{ + init(); + library_ = value; +} + PropertyValue::PropertyValue(Cell *value) : type_(type_cell) { @@ -195,6 +231,7 @@ PropertyValue::PropertyValue(const PropertyValue &value) : float_(value.float_), liberty_library_(value.liberty_library_), liberty_cell_(value.liberty_cell_), + library_(value.library_), cell_(value.cell_), inst_(value.inst_), pin_(value.pin_), @@ -239,6 +276,7 @@ PropertyValue::operator=(const PropertyValue &value) float_ = value.float_; liberty_library_ = value.liberty_library_; liberty_cell_ = value.liberty_cell_; + library_ = value.library_; cell_ = value.cell_; inst_ = value.inst_; pin_ = value.pin_; @@ -265,7 +303,7 @@ getProperty(const Library *lib, return PropertyValue(network->filename(lib)); #endif else - return PropertyValue(); + throw PropertyUnknown("library", property); } PropertyValue @@ -279,7 +317,7 @@ getProperty(const LibertyLibrary *lib, else if (stringEqual(property, "filename")) return PropertyValue(lib->filename()); else - return PropertyValue(); + throw PropertyUnknown("liberty library", property); } PropertyValue @@ -307,7 +345,7 @@ getProperty(const LibertyCell *cell, else if (stringEqual(property, "library")) return PropertyValue(cell->libertyLibrary()); else - return PropertyValue(); + throw PropertyUnknown("liberty cell", property); } PropertyValue @@ -330,10 +368,12 @@ getProperty(const Cell *cell, cell_name); return PropertyValue(full_name); } + else if (stringEqual(property, "library")) + return PropertyValue(network->library(cell)); else if (stringEqual(property, "filename")) return PropertyValue(network->filename(cell)); else - return PropertyValue(); + throw PropertyUnknown("cell", property); } //////////////////////////////////////////////////////////////// @@ -369,7 +409,7 @@ getProperty(const Port *port, return portSlackProperty(port, TransRiseFall::rise(), MinMax::max(), sta); else - return PropertyValue(); + throw PropertyUnknown("port", property); } static PropertyValue @@ -408,36 +448,7 @@ getProperty(const LibertyPort *port, else if (stringEqual(property, "direction")) return PropertyValue(port->direction()->name()); else - return PropertyValue(); -} - -//////////////////////////////////////////////////////////////// - -class PropertyError : public StaException -{ -public: - PropertyError(const char *type, - const char *property); - virtual const char *what() const throw(); - -protected: - const char *type_; - const char *property_; -}; - -PropertyError::PropertyError(const char *type, - const char *property) : - type_(type), - property_(property) -{ -} - -const char * -PropertyError::what() const throw() -{ - // leak - return stringPrint("%s objects do not have a %s property.", - type_, property_); + throw PropertyUnknown("liberty port", property); } //////////////////////////////////////////////////////////////// @@ -459,7 +470,7 @@ getProperty(const Instance *inst, else if (stringEqual(property, "cell")) return PropertyValue(network->cell(inst)); else - throw PropertyError("instance", property); + throw PropertyUnknown("instance", property); } //////////////////////////////////////////////////////////////// @@ -501,7 +512,7 @@ getProperty(const Pin *pin, return pinSlewProperty(pin, TransRiseFall::fall(), MinMax::min(), sta); else - throw PropertyError("pin", property); + throw PropertyUnknown("pin", property); } static PropertyValue @@ -548,7 +559,7 @@ getProperty(const Net *net, if (stringEqual(property, "full_name")) return PropertyValue(network->pathName(net)); else - throw PropertyError("net", property); + throw PropertyUnknown("net", property); } //////////////////////////////////////////////////////////////// @@ -580,7 +591,7 @@ getProperty(Edge *edge, else if (stringEqual(property, "to_pin")) return PropertyValue(edge->to(sta->graph())->pin()); else - throw PropertyError("edge", property); + throw PropertyUnknown("edge", property); } static PropertyValue @@ -631,7 +642,7 @@ getProperty(TimingArcSet *arc_set, return PropertyValue(name); } else - throw PropertyError("timing arc", property); + throw PropertyUnknown("timing arc", property); } //////////////////////////////////////////////////////////////// @@ -651,7 +662,7 @@ getProperty(Clock *clk, else if (stringEqual(property, "propagated")) return PropertyValue(clk->isPropagated() ? "1" : "0"); else - throw PropertyError("clock", property); + throw PropertyUnknown("clock", property); } //////////////////////////////////////////////////////////////// @@ -685,7 +696,7 @@ getProperty(PathEnd *end, return PropertyValue(&paths); } else - throw PropertyError("path end", property); + throw PropertyUnknown("path end", property); } PropertyValue @@ -702,7 +713,7 @@ getProperty(PathRef *path, else if (stringEqual(property, "slack")) return PropertyValue(delayPropertyValue(path->slack(sta), sta)); else - throw PropertyError("path", property); + throw PropertyUnknown("path", property); } static float diff --git a/search/Property.hh b/search/Property.hh index cde42d79..90e65601 100644 --- a/search/Property.hh +++ b/search/Property.hh @@ -33,7 +33,8 @@ class PropertyValue { public: enum Type { type_none, type_string, type_float, - type_liberty_library, type_liberty_cell, type_cell, + type_liberty_library, type_liberty_cell, + type_library, type_cell, type_instance, type_pin, type_pins, type_net, type_clock, type_clocks, type_path_refs }; PropertyValue(); @@ -43,6 +44,7 @@ public: PropertyValue(LibertyLibrary *value); PropertyValue(LibertyCell *value); PropertyValue(Cell *value); + PropertyValue(Library *value); PropertyValue(Instance *value); PropertyValue(Pin *value); PropertyValue(PinSeq *value); @@ -60,6 +62,7 @@ public: float floatValue() const { return float_; } LibertyLibrary *libertyLibrary() const { return liberty_library_; } LibertyCell *libertyCell() const { return liberty_cell_; } + Library *library() const { return library_; } Cell *cell() const { return cell_; } Instance *instance() const { return inst_; } Pin *pin() const { return pin_; } @@ -78,6 +81,7 @@ private: float float_; LibertyLibrary *liberty_library_; LibertyCell *liberty_cell_; + Library *library_; Cell *cell_; Instance *inst_; Pin *pin_; diff --git a/tcl/Cmds.tcl b/tcl/Cmds.tcl index fce22f69..433a86f0 100644 --- a/tcl/Cmds.tcl +++ b/tcl/Cmds.tcl @@ -1773,7 +1773,9 @@ proc get_property_cmd { cmd type_key cmd_args } { set quiet [info exists flags(-quiet)] check_argc_eq2 $cmd $cmd_args set object [lindex $cmd_args 0] - if { ![is_object $object] } { + if { $object == "" } { + sta_error "$cmd object is null." + } elseif { ![is_object $object] } { if [info exists keys($type_key)] { set object_type $keys($type_key) } else { diff --git a/tcl/Power.tcl b/tcl/Power.tcl index 0c01d0f0..cd86b201 100644 --- a/tcl/Power.tcl +++ b/tcl/Power.tcl @@ -42,9 +42,10 @@ proc_redirect report_power { set corner [parse_corner keys] if { [info exists keys(-instances)] } { - set insts [get_instance_error "-cell" $keys(-instances)] + set insts [get_instances_error "-instances" $keys(-instances)] foreach inst $insts { report_power_inst $inst $corner $digits + puts "" } } else { report_power_design $corner $digits @@ -107,16 +108,20 @@ proc report_power_col_percent { col_total total } { proc report_power_inst { inst corner digits } { puts "Instance: [get_full_name $inst]" - set cell [instance_property $inst "liberty_cell"] - puts "Cell: [get_name $cell]" - set library [liberty_cell_property $cell "library"] - puts "Liberty file: [liberty_library_property $library filename]" - set power_result [instance_power $inst $corner] - lassign $power_result internal switching leakage total - report_power_line "Internal power" $internal $digits - report_power_line "Switching power" $switching $digits - report_power_line "Leakage power" $leakage $digits - report_power_line "Total power" $total $digits + set cell [get_property $inst "liberty_cell"] + if { $cell != "NULL" } { + puts "Cell: [get_name $cell]" + set library [get_property $cell "library"] + puts "Library file: [get_property $library filename]" + set power_result [instance_power $inst $corner] + lassign $power_result internal switching leakage total + report_power_line "Internal power" $internal $digits + report_power_line "Switching power" $switching $digits + report_power_line "Leakage power" $leakage $digits + report_power_line "Total power" $total $digits + } else { + sta_error "[get_full_name $inst] is not a liberty cell instance." + } } proc report_power_line { type pwr digits } { diff --git a/tcl/StaTcl.i b/tcl/StaTcl.i index a949017b..7394d317 100644 --- a/tcl/StaTcl.i +++ b/tcl/StaTcl.i @@ -1578,6 +1578,12 @@ using namespace sta; Tcl_SetObjResult(interp, obj); } break; + case PropertyValue::Type::type_library: { + Tcl_Obj *obj = SWIG_NewInstanceObj(value.library(), + SWIGTYPE_p_Library, false); + Tcl_SetObjResult(interp, obj); + } + break; case PropertyValue::Type::type_cell: { Tcl_Obj *obj = SWIG_NewInstanceObj(value.cell(), SWIGTYPE_p_Cell, false);