Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
95 changes: 91 additions & 4 deletions power/Power.tcl
Original file line number Diff line number Diff line change
Expand Up @@ -35,13 +35,14 @@ define_cmd_args "report_power" \
[-highest_power_instances count]\
[-corner corner]\
[-digits digits]\
[-format format]\
[> filename] [>> filename] }

proc_redirect report_power {
global sta_report_default_digits

parse_key_args "report_power" args \
keys {-instances -highest_power_instances -corner -digits} flags {}
keys {-instances -highest_power_instances -corner -digits -format} flags {}

check_argc_eq0 "report_power" $args

Expand All @@ -56,16 +57,37 @@ proc_redirect report_power {
}
set corner [parse_corner keys]

if { [info exists keys(-format)] } {
set format $keys(-format)
if { $format != "text" && $format != "json" } {
sta_error 311 "unknown power report -format $format"
}
} else {
set format "text"
}

if { [info exists keys(-instances)] } {
set insts [get_instances_error "-instances" $keys(-instances)]
report_power_insts $insts $corner $digits
if { $format == "json" } {
report_power_insts_json $insts $corner $digits
} else {
report_power_insts $insts $corner $digits
}
} elseif { [info exists keys(-highest_power_instances)] } {
set count $keys(-highest_power_instances)
check_positive_integer "-highest_power_instances" $count
set insts [highest_power_instances $count $corner]
report_power_insts $insts $corner $digits
if { $format == "json" } {
report_power_insts_json $insts $corner $digits
} else {
report_power_insts $insts $corner $digits
}
} else {
report_power_design $corner $digits
if { $format == "json" } {
report_power_design_json $corner $digits
} else {
report_power_design $corner $digits
}
}
}

Expand Down Expand Up @@ -104,6 +126,35 @@ proc report_power_design { corner digits } {
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]"
}

proc report_power_design_json { corner digits } {
set power_result [design_power $corner]
set totals [lrange $power_result 0 3]
set sequential [lrange $power_result 4 7]
set combinational [lrange $power_result 8 11]
set clock [lrange $power_result 12 15]
set macro [lrange $power_result 16 19]
set pad [lrange $power_result 20 end]

report_line "\{"
report_power_row_json "Sequential" $sequential $digits ","
report_power_row_json "Combinational" $combinational $digits ","
report_power_row_json "Clock" $clock $digits ","
report_power_row_json "Macro" $macro $digits ","
report_power_row_json "Pad" $pad $digits ","
report_power_row_json "Total" $totals $digits ""
report_line "\}"
}

proc report_power_row_json { name row_result digits separator } {
lassign $row_result internal switching leakage total
report_line " \"$name\": \{"
report_line " \"internal\": [format %.${digits}e $internal],"
report_line " \"switching\": [format %.${digits}e $switching],"
report_line " \"leakage\": [format %.${digits}e $leakage],"
report_line " \"total\": [format %.${digits}e $total]"
report_line " \}$separator"
}

proc max { x y } {
if { $x >= $y } {
return $x
Expand Down Expand Up @@ -206,6 +257,42 @@ proc report_power_insts { insts corner digits } {
}
}

proc report_power_insts_json { insts corner digits } {
set inst_pwrs {}
foreach inst $insts {
set power_result [instance_power $inst $corner]
lappend inst_pwrs [list $inst $power_result]
}
set inst_pwrs [lsort -command inst_pwr_cmp $inst_pwrs]

report_line "\["
set count [llength $inst_pwrs]
set index 0
foreach inst_pwr $inst_pwrs {
set inst [lindex $inst_pwr 0]
set power [lindex $inst_pwr 1]
incr index
if { $index < $count } {
report_power_inst_json $inst $power $digits ","
} else {
report_power_inst_json $inst $power $digits ""
}
}
report_line "\]"
}

proc report_power_inst_json { inst power digits separator } {
lassign $power internal switching leakage total
set inst_name [get_full_name $inst]
report_line "\{"
report_line " \"name\": \"$inst_name\","
report_line " \"internal\": [format %.${digits}e $internal],"
report_line " \"switching\": [format %.${digits}e $switching],"
report_line " \"leakage\": [format %.${digits}e $leakage],"
report_line " \"total\": [format %.${digits}e $total]"
report_line "\}$separator"
}

proc inst_pwr_cmp { inst_pwr1 inst_pwr2 } {
set pwr1 [lindex $inst_pwr1 1]
set pwr2 [lindex $inst_pwr2 1]
Expand Down
76 changes: 76 additions & 0 deletions test/power_json.ok
Original file line number Diff line number Diff line change
@@ -0,0 +1,76 @@
Warning: ../examples/gcd_sky130hd.v line 527, module sky130_fd_sc_hd__tapvpwrvgnd_1 not found. Creating black box for TAP_11.
{
"Sequential": {
"internal": 3.0660e-04,
"switching": 4.7564e-05,
"leakage": 2.9607e-10,
"total": 3.5417e-04
},
"Combinational": {
"internal": 1.5871e-04,
"switching": 2.0511e-04,
"leakage": 6.8590e-10,
"total": 3.6381e-04
},
"Clock": {
"internal": 4.6828e-05,
"switching": 1.2049e-04,
"leakage": 2.3004e-11,
"total": 1.6732e-04
},
"Macro": {
"internal": 0.0000e+00,
"switching": 0.0000e+00,
"leakage": 0.0000e+00,
"total": 0.0000e+00
},
"Pad": {
"internal": 0.0000e+00,
"switching": 0.0000e+00,
"leakage": 0.0000e+00,
"total": 0.0000e+00
},
"Total": {
"internal": 5.1214e-04,
"switching": 3.7316e-04,
"leakage": 1.0050e-09,
"total": 8.8530e-04
}
}
[
{
"name": "clkbuf_2_3__f_clk",
"internal": 9.3880e-06,
"switching": 2.5721e-05,
"leakage": 4.6007e-12,
"total": 3.5109e-05
},
{
"name": "clkbuf_2_0__f_clk",
"internal": 9.3814e-06,
"switching": 2.5163e-05,
"leakage": 4.6007e-12,
"total": 3.4544e-05
},
{
"name": "clkbuf_2_1__f_clk",
"internal": 9.3672e-06,
"switching": 2.3965e-05,
"leakage": 4.6007e-12,
"total": 3.3332e-05
},
{
"name": "clkbuf_2_2__f_clk",
"internal": 9.3592e-06,
"switching": 2.3293e-05,
"leakage": 4.6007e-12,
"total": 3.2652e-05
},
{
"name": "clkbuf_0_clk",
"internal": 9.3319e-06,
"switching": 2.2346e-05,
"leakage": 4.6007e-12,
"total": 3.1678e-05
}
]
14 changes: 14 additions & 0 deletions test/power_json.tcl
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
# report_power gcd
set sta_report_default_digits 4
read_liberty ../examples/sky130hd_tt.lib.gz
read_verilog ../examples/gcd_sky130hd.v
link_design gcd

read_sdc ../examples/gcd_sky130hd.sdc
set_propagated_clock clk
read_spef ../examples/gcd_sky130hd.spef
set_power_activity -input -activity .1
set_power_activity -input_port reset -activity 0

report_power -format json
report_power -format json -instances "[get_cells -filter "name=~clkbuf*"]"
1 change: 1 addition & 0 deletions test/regression_vars.tcl
Original file line number Diff line number Diff line change
Expand Up @@ -155,6 +155,7 @@ record_sta_tests {
path_group_names
prima3
report_checks_sorted
power_json
report_checks_src_attr
report_json1
report_json2
Expand Down