diff --git a/CMakeLists.txt b/CMakeLists.txt index 2673c81b..d2f6f380 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1,14 +1,22 @@ -# Parallax Static Timing Analyzer +# OpenSTA, Static Timing Analyzer # Copyright (c) 2019, Parallax Software, Inc. -# All rights reserved. # -# No part of this document may be copied, transmitted or -# disclosed in any form or fashion without the express -# written consent of Parallax Software, Inc. +# This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program. If not, see . cmake_minimum_required (VERSION 3.9) -project(STA VERSION 2.0.11) +project(STA VERSION 2.0.12) set(CMAKE_VERBOSE_MAKEFILE ON) set(CMAKE_CXX_STANDARD 11) @@ -392,7 +400,6 @@ set(STA_TCL_FILES dcalc/DelayCalc.tcl parasitics/Parasitics.tcl sdf/Sdf.tcl - tcl/Compatibility.tcl verilog/Verilog.tcl ) diff --git a/liberty/TableModel.cc b/liberty/TableModel.cc index a8921242..7964862e 100644 --- a/liberty/TableModel.cc +++ b/liberty/TableModel.cc @@ -17,6 +17,7 @@ #include "Machine.hh" #include "Report.hh" #include "Error.hh" +#include "EnumNameMap.hh" #include "Units.hh" #include "Liberty.hh" #include "TableModel.hh" @@ -1335,82 +1336,37 @@ TableAxis::findAxisIndex(float value) const //////////////////////////////////////////////////////////////// +static EnumNameMap table_axis_variable_map = + {{TableAxisVariable::total_output_net_capacitance, "total_output_net_capacitance"}, + {TableAxisVariable::equal_or_opposite_output_net_capacitance, "equal_or_opposite_output_net_capacitance"}, + {TableAxisVariable::input_net_transition, "input_net_transition"}, + {TableAxisVariable::input_transition_time, "input_transition_time"}, + {TableAxisVariable::related_pin_transition, "related_pin_transition"}, + {TableAxisVariable::constrained_pin_transition, "constrained_pin_transition"}, + {TableAxisVariable::output_pin_transition, "output_pin_transition"}, + {TableAxisVariable::connect_delay, "connect_delay"}, + {TableAxisVariable::related_out_total_output_net_capacitance, "related_out_total_output_net_capacitance"}, + {TableAxisVariable::time, "time"}, + {TableAxisVariable::iv_output_voltage, "iv_output_voltage"}, + {TableAxisVariable::input_noise_width, "input_noise_width"}, + {TableAxisVariable::input_noise_height, "input_noise_height"}, + {TableAxisVariable::input_voltage, "input_voltage"}, + {TableAxisVariable::output_voltage, "output_voltage"}, + {TableAxisVariable::path_depth, "path_depth"}, + {TableAxisVariable::path_distance, "path_distance"}, + {TableAxisVariable::normalized_voltage, "normalized_voltage"} + }; + TableAxisVariable stringTableAxisVariable(const char *variable) { - if (stringEq(variable, "total_output_net_capacitance")) - return TableAxisVariable::total_output_net_capacitance; - if (stringEq(variable, "equal_or_opposite_output_net_capacitance")) - return TableAxisVariable::equal_or_opposite_output_net_capacitance; - else if (stringEq(variable, "input_net_transition")) - return TableAxisVariable::input_net_transition; - else if (stringEq(variable, "input_transition_time")) - return TableAxisVariable::input_transition_time; - else if (stringEq(variable, "related_pin_transition")) - return TableAxisVariable::related_pin_transition; - else if (stringEq(variable, "constrained_pin_transition")) - return TableAxisVariable::constrained_pin_transition; - else if (stringEq(variable, "output_pin_transition")) - return TableAxisVariable::output_pin_transition; - else if (stringEq(variable, "connect_delay")) - return TableAxisVariable::connect_delay; - else if (stringEq(variable,"related_out_total_output_net_capacitance")) - return TableAxisVariable::related_out_total_output_net_capacitance; - else if (stringEq(variable, "time")) - return TableAxisVariable::time; - else if (stringEq(variable, "iv_output_voltage")) - return TableAxisVariable::iv_output_voltage; - else if (stringEq(variable, "input_noise_width")) - return TableAxisVariable::input_noise_width; - else if (stringEq(variable, "input_noise_height")) - return TableAxisVariable::input_noise_height; - else if (stringEq(variable, "input_voltage")) - return TableAxisVariable::input_voltage; - else if (stringEq(variable, "output_voltage")) - return TableAxisVariable::output_voltage; - else if (stringEq(variable, "path_depth")) - return TableAxisVariable::path_depth; - else if (stringEq(variable, "path_distance")) - return TableAxisVariable::path_distance; - else if (stringEq(variable, "normalized_voltage")) - return TableAxisVariable::normalized_voltage; - else - return TableAxisVariable::unknown; + return table_axis_variable_map.find(variable, TableAxisVariable::unknown); } const char * tableVariableString(TableAxisVariable variable) { - switch (variable) { - case TableAxisVariable::total_output_net_capacitance: - return "total_output_net_capacitance"; - case TableAxisVariable::equal_or_opposite_output_net_capacitance: - return "equal_or_opposite_output_net_capacitance"; - case TableAxisVariable::input_net_transition: - return "input_net_transition"; - case TableAxisVariable::input_transition_time: - return "input_transition_time"; - case TableAxisVariable::related_pin_transition: - return "related_pin_transition"; - case TableAxisVariable::constrained_pin_transition: - return "constrained_pin_transition"; - case TableAxisVariable::output_pin_transition: - return "output_pin_transition"; - case TableAxisVariable::connect_delay: - return "connect_delay"; - case TableAxisVariable::related_out_total_output_net_capacitance: - return "related_out_total_output_net_capacitance"; - case TableAxisVariable::time: - return "time"; - case TableAxisVariable::iv_output_voltage: - return "iv_output_voltage"; - case TableAxisVariable::input_noise_width: - return "input_noise_width"; - case TableAxisVariable::input_noise_height: - return "input_noise_height"; - default: - return "unknown"; - } + return table_axis_variable_map.find(variable); } const Unit * diff --git a/tcl/Power.tcl b/tcl/Power.tcl index afa58473..28035766 100644 --- a/tcl/Power.tcl +++ b/tcl/Power.tcl @@ -58,24 +58,62 @@ proc report_power_design { corner digits } { set pad [lrange $power_result 16 end] lassign $totals design_internal design_switching design_leakage design_total - puts "Group Internal Switching Leakage Total" - puts " Power Power Power Power (mW)" - puts "-------------------------------------------------------------------" - report_power_row "Sequential" $sequential $design_total $digits - report_power_row "Combinational" $combinational $design_total $digits - report_power_row "Macro" $macro $design_total $digits - report_power_row "Pad" $pad $design_total $digits - puts "-------------------------------------------------------------------" - report_power_row "Total" $power_result $design_total $digits + set field_width [max [expr $digits + 6] 10] + report_power_title5 "Group" "Internal" "Switching" "Leakage" "Total" $field_width + report_power_title5 " " "Power" "Power" "Power" "Power" $field_width + report_title_dashes5 $field_width + report_power_row "Sequential" $sequential $design_total $field_width $digits + report_power_row "Combinational" $combinational $design_total $field_width $digits + report_power_row "Macro" $macro $design_total $field_width $digits + report_power_row "Pad" $pad $design_total $field_width $digits + report_title_dashes5 $field_width + report_power_row "Total" $power_result $design_total $field_width $digits - puts -nonewline " " - report_power_col_percent $design_internal $design_total - report_power_col_percent $design_switching $design_total - report_power_col_percent $design_leakage $design_total + puts -nonewline [format "%-20s" ""] + report_power_col_percent $design_internal $design_total $field_width + report_power_col_percent $design_switching $design_total $field_width + report_power_col_percent $design_leakage $design_total $field_width puts "" } -proc report_power_row { type row_result design_total digits } { +proc max { x y } { + if { $x >= $y } { + return $x + } else { + return $y + } +} + +proc report_power_title5 { title1 title2 title3 title4 title5 field_width } { + puts -nonewline [format "%-20s" $title1] + report_power_title4 $title2 $title3 $title4 $title5 $field_width +} + +proc report_power_title4 { title1 title2 title3 title4 field_width } { + puts -nonewline [format " %${field_width}s" $title1] + puts -nonewline [format " %${field_width}s" $title2] + puts -nonewline [format " %${field_width}s" $title3] + puts [format " %${field_width}s" $title4] +} + +proc report_title_dashes5 { field_width } { + set count [expr 20 + ($field_width + 1) * 4] + report_title_dashes $count +} + +proc report_title_dashes4 { field_width } { + set count [expr ($field_width + 1) * 4] + report_title_dashes $count +} + +proc report_title_dashes { count } { + for {set i 0} {$i < $count} {incr i} { + puts -nonewline "-" + } + puts "" +} + +proc report_power_row { type row_result design_total field_width digits } { lassign $row_result internal switching leakage total if { $design_total == 0.0 } { set percent 0.0 @@ -83,28 +121,28 @@ proc report_power_row { type row_result design_total digits } { set percent [expr $total / $design_total * 100] } puts -nonewline [format "%-20s" $type] - report_power_col $internal $digits - report_power_col $switching $digits - report_power_col $leakage $digits - report_power_col $total $digits + report_power_col $internal $field_width $digits + report_power_col $switching $field_width $digits + report_power_col $leakage $field_width $digits + report_power_col $total $field_width $digits puts [format " %5.1f%%" $percent] } -proc report_power_col { pwr digits } { - puts -nonewline [format "%10.${digits}f" [expr $pwr * 1e+3]] +proc report_power_col { pwr field_width digits } { + puts -nonewline [format " %$field_width.${digits}e" $pwr] } -proc report_power_col_percent { col_total total } { +proc report_power_col_percent { col_total total field_width } { if { $total == 0.0 } { set percent 0.0 } else { set percent [expr $col_total / $total * 100] } - puts -nonewline [format "%9.1f%%" $percent] + puts -nonewline [format "%$field_width.1f%%" $percent] } proc report_power_line { type pwr digits } { - puts [format "%-16s %.${digits}fmW" $type [expr $pwr * 1e+3]] + puts [format "%-16s %.${digits}e" $type $pwr] } proc report_power_insts { insts corner digits } { @@ -115,14 +153,16 @@ proc report_power_insts { insts corner digits } { } set inst_pwrs [lsort -command inst_pwr_cmp $inst_pwrs] - puts " Internal Switching Leakage Total Instance" - puts " Power Power Power Power (mW)" - puts "-------------------------------------------------------------------" + set field_width [max [expr $digits + 6] 10] + + report_power_title4 "Internal" "Switching" "Leakage" "Total" $field_width + report_power_title4 "Power" "Power" "Power" "Power" $field_width + report_title_dashes4 $field_width foreach inst_pwr $inst_pwrs { set inst [lindex $inst_pwr 0] set power [lindex $inst_pwr 1] - report_power_inst $inst $power $digits + report_power_inst $inst $power $field_width $digits } } @@ -140,12 +180,12 @@ proc inst_pwr_cmp { inst_pwr1 inst_pwr2 } { } } -proc report_power_inst { inst power_result digits } { +proc report_power_inst { inst power_result field_width digits } { lassign $power_result internal switching leakage total - report_power_col $internal $digits - report_power_col $switching $digits - report_power_col $leakage $digits - report_power_col $total $digits + report_power_col $internal $field_width $digits + report_power_col $switching $field_width $digits + report_power_col $leakage $field_width $digits + report_power_col $total $field_width $digits puts " [get_full_name $inst]" }