Skip to content

Commit 56e4bd8

Browse files
Report power as JSON (The-OpenROAD-Project#342)
* fix power_json.tcl * get rid of the if/else statements throughout
1 parent 1bf9426 commit 56e4bd8

File tree

3 files changed

+125
-5
lines changed

3 files changed

+125
-5
lines changed

power/Power.tcl

Lines changed: 90 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -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

4041
proc_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+
107158
proc 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+
209294
proc 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 {

tcl/Util.tcl

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -185,6 +185,17 @@ proc define_hidden_cmd_args { cmd arglist } {
185185
namespace export $cmd
186186
}
187187

188+
# "Optional Upvar"
189+
# If $other_var is not empty, the upvar is executed.
190+
# Otherwise, $my_var is set to empty.
191+
proc upvar_opt { level other_var my_var } {
192+
if { $other_var != "" } {
193+
uplevel 1 "upvar $level $other_var $my_var"
194+
} else {
195+
uplevel 1 "set $my_var \"\""
196+
}
197+
}
198+
188199
################################################################
189200

190201
proc sta_warn { msg_id msg } {

test/power_json.tcl

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
# report_power reg1_asap7
2+
set sta_report_default_digits 4
3+
read_liberty ../examples/asap7_small.lib.gz
4+
read_verilog ../examples/reg1_asap7.v
5+
link_design top
6+
7+
create_clock -name clk1 -period 500 clk1
8+
create_clock -name clk2 -period 500 clk2
9+
create_clock -name clk3 -period 500 clk3
10+
11+
set_input_delay -clock clk1 1 {in1 in2}
12+
set_input_delay -clock clk2 1 {in1 in2}
13+
set_input_delay -clock clk3 1 {in1 in2}
14+
set_input_transition 10 {in1 in2 clk1 clk2 clk3}
15+
16+
set_propagated_clock {clk1 clk2 clk3}
17+
18+
read_spef ../examples/reg1_asap7.spef
19+
20+
set_power_activity -input -activity .1
21+
set_power_activity -input_port reset -activity 0
22+
23+
report_power -format json
24+
report_power -format json -instances "[get_cells -filter "name=~clkbuf*"]"

0 commit comments

Comments
 (0)