@@ -35,13 +35,14 @@ define_cmd_args "report_power" \
3535 [-highest_power_instances count]\
3636 [-corner corner]\
3737 [-digits digits]\
38+ [-format format]\
3839 [> filename] [>> filename] }
3940
4041proc_redirect report_power {
4142 global sta_report_default_digits
4243
4344 parse_key_args " report_power" args \
44- keys {-instances -highest_power_instances -corner -digits} flags {}
45+ keys {-instances -highest_power_instances -corner -digits -format } flags {}
4546
4647 check_argc_eq0 " report_power" $args
4748
@@ -56,16 +57,37 @@ proc_redirect report_power {
5657 }
5758 set corner [parse_corner keys]
5859
60+ if { [info exists keys(-format)] } {
61+ set format $keys(-format)
62+ if { $format != " text" && $format != " json" } {
63+ sta_error 311 " unknown power report -format $format "
64+ }
65+ } else {
66+ set format " text"
67+ }
68+
5969 if { [info exists keys(-instances)] } {
6070 set insts [get_instances_error " -instances" $keys(-instances) ]
61- report_power_insts $insts $corner $digits
71+ if { $format == " json" } {
72+ report_power_insts_json $insts $corner $digits
73+ } else {
74+ report_power_insts $insts $corner $digits
75+ }
6276 } elseif { [info exists keys(-highest_power_instances)] } {
6377 set count $keys(-highest_power_instances)
6478 check_positive_integer " -highest_power_instances" $count
6579 set insts [highest_power_instances $count $corner ]
66- report_power_insts $insts $corner $digits
80+ if { $format == " json" } {
81+ report_power_insts_json $insts $corner $digits
82+ } else {
83+ report_power_insts $insts $corner $digits
84+ }
6785 } else {
68- report_power_design $corner $digits
86+ if { $format == " json" } {
87+ report_power_design_json $corner $digits
88+ } else {
89+ report_power_design $corner $digits
90+ }
6991 }
7092}
7193
@@ -104,6 +126,35 @@ proc report_power_design { corner digits } {
104126 report_line " [ format %-20s {}] [ power_col_percent $design_internal $design_total $field_width ] [ power_col_percent $design_switching $design_total $field_width ] [ power_col_percent $design_leakage $design_total $field_width ] "
105127}
106128
129+ proc report_power_design_json { corner digits } {
130+ set power_result [design_power $corner ]
131+ set totals [lrange $power_result 0 3]
132+ set sequential [lrange $power_result 4 7]
133+ set combinational [lrange $power_result 8 11]
134+ set clock [lrange $power_result 12 15]
135+ set macro [lrange $power_result 16 19]
136+ set pad [lrange $power_result 20 end]
137+
138+ report_line " \{ "
139+ report_power_row_json " Sequential" $sequential $digits " ,"
140+ report_power_row_json " Combinational" $combinational $digits " ,"
141+ report_power_row_json " Clock" $clock $digits " ,"
142+ report_power_row_json " Macro" $macro $digits " ,"
143+ report_power_row_json " Pad" $pad $digits " ,"
144+ report_power_row_json " Total" $totals $digits " "
145+ report_line " \} "
146+ }
147+
148+ proc report_power_row_json { name row_result digits separator } {
149+ lassign $row_result internal switching leakage total
150+ report_line " \" $name \" : \{ "
151+ report_line " \" internal\" : [ format %.${digits} e $internal ] ,"
152+ report_line " \" switching\" : [ format %.${digits} e $switching ] ,"
153+ report_line " \" leakage\" : [ format %.${digits} e $leakage ] ,"
154+ report_line " \" total\" : [ format %.${digits} e $total ] "
155+ report_line " \} $separator "
156+ }
157+
107158proc max { x y } {
108159 if { $x >= $y } {
109160 return $x
@@ -206,6 +257,40 @@ proc report_power_insts { insts corner digits } {
206257 }
207258}
208259
260+ proc report_power_insts_json { insts corner digits } {
261+ set inst_pwrs {}
262+ foreach inst $insts {
263+ set power_result [instance_power $inst $corner ]
264+ lappend inst_pwrs [list $inst $power_result ]
265+ }
266+ set inst_pwrs [lsort -command inst_pwr_cmp $inst_pwrs ]
267+
268+ report_line " \[ "
269+ set first 1
270+ foreach inst_pwr $inst_pwrs {
271+ set inst [lindex $inst_pwr 0]
272+ set power [lindex $inst_pwr 1]
273+ if { !$first } {
274+ report_line " ,"
275+ }
276+ set first 0
277+ report_power_inst_json $inst $power $digits
278+ }
279+ report_line " \] "
280+ }
281+
282+ proc report_power_inst_json { inst power digits } {
283+ lassign $power internal switching leakage total
284+ set inst_name [get_full_name $inst ]
285+ report_line " \{ "
286+ report_line " \" name\" : \" $inst_name \" ,"
287+ report_line " \" internal\" : [ format %.${digits} e $internal ] ,"
288+ report_line " \" switching\" : [ format %.${digits} e $switching ] ,"
289+ report_line " \" leakage\" : [ format %.${digits} e $leakage ] ,"
290+ report_line " \" total\" : [ format %.${digits} e $total ] "
291+ report_line " \} "
292+ }
293+
209294proc inst_pwr_cmp { inst_pwr1 inst_pwr2 } {
210295 set pwr1 [lindex $inst_pwr1 1]
211296 set pwr2 [lindex $inst_pwr2 1]
@@ -287,7 +372,7 @@ proc set_power_activity { args } {
287372 if { [info exists keys(-input_ports)] } {
288373 set ports [get_ports_error " input_ports" $keys(-input_ports) ]
289374 foreach port $ports {
290- if { [get_property $port " direction" ] == " input" } {
375+ if { [get_property $port " direction" ] == " input" || [get_property $port " direction " ] == " in " } {
291376 if { [is_clock_src [sta::get_port_pin $port ]] } {
292377 sta_warn 310 " activity cannot be set on clock ports."
293378 } else {
0 commit comments