Report power as JSON (#342)
* fix power_json.tcl * get rid of the if/else statements throughout
This commit is contained in:
parent
1bf9426e96
commit
56e4bd8ce1
|
|
@ -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
|
||||
|
||||
|
|
@ -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
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -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
|
||||
|
|
@ -206,6 +257,40 @@ 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 first 1
|
||||
foreach inst_pwr $inst_pwrs {
|
||||
set inst [lindex $inst_pwr 0]
|
||||
set power [lindex $inst_pwr 1]
|
||||
if { !$first } {
|
||||
report_line ","
|
||||
}
|
||||
set first 0
|
||||
report_power_inst_json $inst $power $digits
|
||||
}
|
||||
report_line "\]"
|
||||
}
|
||||
|
||||
proc report_power_inst_json { inst power digits } {
|
||||
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 "\}"
|
||||
}
|
||||
|
||||
proc inst_pwr_cmp { inst_pwr1 inst_pwr2 } {
|
||||
set pwr1 [lindex $inst_pwr1 1]
|
||||
set pwr2 [lindex $inst_pwr2 1]
|
||||
|
|
@ -287,7 +372,7 @@ proc set_power_activity { args } {
|
|||
if { [info exists keys(-input_ports)] } {
|
||||
set ports [get_ports_error "input_ports" $keys(-input_ports)]
|
||||
foreach port $ports {
|
||||
if { [get_property $port "direction"] == "input" } {
|
||||
if { [get_property $port "direction"] == "input" || [get_property $port "direction"] == "in" } {
|
||||
if { [is_clock_src [sta::get_port_pin $port]] } {
|
||||
sta_warn 310 "activity cannot be set on clock ports."
|
||||
} else {
|
||||
|
|
|
|||
11
tcl/Util.tcl
11
tcl/Util.tcl
|
|
@ -185,6 +185,17 @@ proc define_hidden_cmd_args { cmd arglist } {
|
|||
namespace export $cmd
|
||||
}
|
||||
|
||||
# "Optional Upvar"
|
||||
# If $other_var is not empty, the upvar is executed.
|
||||
# Otherwise, $my_var is set to empty.
|
||||
proc upvar_opt { level other_var my_var } {
|
||||
if { $other_var != "" } {
|
||||
uplevel 1 "upvar $level $other_var $my_var"
|
||||
} else {
|
||||
uplevel 1 "set $my_var \"\""
|
||||
}
|
||||
}
|
||||
|
||||
################################################################
|
||||
|
||||
proc sta_warn { msg_id msg } {
|
||||
|
|
|
|||
|
|
@ -0,0 +1,24 @@
|
|||
# report_power reg1_asap7
|
||||
set sta_report_default_digits 4
|
||||
read_liberty ../examples/asap7_small.lib.gz
|
||||
read_verilog ../examples/reg1_asap7.v
|
||||
link_design top
|
||||
|
||||
create_clock -name clk1 -period 500 clk1
|
||||
create_clock -name clk2 -period 500 clk2
|
||||
create_clock -name clk3 -period 500 clk3
|
||||
|
||||
set_input_delay -clock clk1 1 {in1 in2}
|
||||
set_input_delay -clock clk2 1 {in1 in2}
|
||||
set_input_delay -clock clk3 1 {in1 in2}
|
||||
set_input_transition 10 {in1 in2 clk1 clk2 clk3}
|
||||
|
||||
set_propagated_clock {clk1 clk2 clk3}
|
||||
|
||||
read_spef ../examples/reg1_asap7.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*"]"
|
||||
Loading…
Reference in New Issue