diff --git a/openlane/scripts/openroad/common/io.tcl b/openlane/scripts/openroad/common/io.tcl index cc73bf9bf..af2bedded 100644 --- a/openlane/scripts/openroad/common/io.tcl +++ b/openlane/scripts/openroad/common/io.tcl @@ -347,12 +347,11 @@ set ::metrics_file "" if { [info exists ::env(OPENSTA)] && $::env(OPENSTA) } { proc write_metric_num {metric value} { if { $value == 1e30 } { - write_metric_str $metric Infinity + set value inf } elseif { $value == -1e30 } { - write_metric_str $metric -Infinity - } else { - puts "%OL_METRIC_F $metric $value" + set value -inf } + puts "%OL_METRIC_F $metric $value" } proc write_metric_int {metric value} { puts "%OL_METRIC_I $metric $value" diff --git a/openlane/scripts/openroad/sta/corner.tcl b/openlane/scripts/openroad/sta/corner.tcl index 344c69d66..e8d1a0987 100644 --- a/openlane/scripts/openroad/sta/corner.tcl +++ b/openlane/scripts/openroad/sta/corner.tcl @@ -193,12 +193,9 @@ puts "%OL_CREATE_REPORT tns.max.rpt" puts "\n===========================================================================" puts "Total Negative Slack (Setup)" puts "============================================================================" -set tns_design 0 -foreach corner [sta::corners] { - set tns [sta::format_time [sta::total_negative_slack_corner_cmd $corner "max"] $sta_report_default_digits] - write_metric_num "timing__setup__tns__corner:[$corner name]" $tns - puts "[$corner name]: $tns" -} +set tns [sta::format_time [sta::total_negative_slack_corner_cmd $corner "max"] $sta_report_default_digits] +write_metric_num "timing__setup__tns__corner:[$corner name]" $tns +puts "[$corner name]: $tns" puts "%OL_END_REPORT" puts "%OL_CREATE_REPORT wns.min.rpt" @@ -248,6 +245,7 @@ set total_setup_vios 0 set r2r_setup_vios 0 set hold_timing_paths [find_timing_paths -unique_paths_to_endpoint -path_delay min -sort_by_slack -group_count 999999999 -slack_max 0] +set worst_r2r_hold_slack 1e30 foreach path $hold_timing_paths { set from "reg" set to "reg" @@ -265,6 +263,12 @@ foreach path $hold_timing_paths { incr total_hold_vios if { "$kind" == "reg-reg" } { + set slack [get_property $path slack] + + if { $slack < $worst_r2r_hold_slack } { + set worst_r2r_hold_slack $slack + } + incr r2r_hold_vios } @@ -272,6 +276,7 @@ foreach path $hold_timing_paths { } set setup_timing_paths [find_timing_paths -unique_paths_to_endpoint -path_delay max -sort_by_slack -group_count 999999999 -slack_max 0] +set worst_r2r_setup_slack 1e30 foreach path $setup_timing_paths { set from "reg" set to "reg" @@ -290,6 +295,13 @@ foreach path $setup_timing_paths { incr total_setup_vios if { "$kind" == "reg-reg" } { + set slack [get_property $path slack] + puts $slack + + if { $slack < $worst_r2r_setup_slack } { + set worst_r2r_setup_slack $slack + } + incr r2r_setup_vios } @@ -297,8 +309,10 @@ foreach path $setup_timing_paths { } write_metric_int "timing__hold_vio__count__corner:[$corner name]" $total_hold_vios +write_metric_num "timing__hold_r2r__ws__corner:[$corner name]" $worst_r2r_hold_slack write_metric_int "timing__hold_r2r_vio__count__corner:[$corner name]" $r2r_hold_vios write_metric_int "timing__setup_vio__count__corner:[$corner name]" $total_setup_vios +write_metric_num "timing__setup_r2r__ws__corner:[$corner name]" $worst_r2r_setup_slack write_metric_int "timing__setup_r2r_vio__count__corner:[$corner name]" $r2r_setup_vios puts "%OL_END_REPORT" diff --git a/openlane/steps/openroad.py b/openlane/steps/openroad.py index 2871cbe85..27db5b99a 100644 --- a/openlane/steps/openroad.py +++ b/openlane/steps/openroad.py @@ -92,7 +92,9 @@ "clock__skew__worst_hold": (-inf, max), "clock__skew__worst_setup": (-inf, max), "timing__hold__ws": (inf, min), + "timing__hold_r2r__ws": (inf, min), "timing__setup__ws": (inf, min), + "timing__setup_r2r__ws": (inf, min), "timing__hold__wns": (inf, min), "timing__setup__wns": (inf, min), "timing__hold__tns": (0, lambda x: sum(x)), @@ -580,18 +582,25 @@ def format_count(count: Optional[Union[int, float, Decimal]]) -> str: def format_slack(slack: Optional[Union[int, float, Decimal]]) -> str: if slack is None: return "[gray]?" + if slack == float(inf): + return "[gray]N/A" slack = round(float(slack), 4) - if slack <= 0: - return f"[red]{slack}" + formatted_slack = f"{slack:.4f}" + if slack < 0: + return f"[red]{formatted_slack}" else: - return f"[green]{slack}" + return f"[green]{formatted_slack}" table = rich.table.Table() table.add_column("Corner/Group") table.add_column("Hold Worst Slack") + table.add_column("reg-to-reg") + table.add_column("Hold TNS") table.add_column("Hold Violations") table.add_column("of which reg-to-reg") table.add_column("Setup Worst Slack") + table.add_column("reg-to-reg") + table.add_column("Setup TNS") table.add_column("Setup Violations") table.add_column("of which reg-to-reg") table.add_column("Max Cap Violations") @@ -603,9 +612,13 @@ def format_slack(slack: Optional[Union[int, float, Decimal]]) -> str: row = [corner] for metric in [ "timing__hold__ws", + "timing__hold_r2r__ws", + "timing__hold__tns", "timing__hold_vio__count", "timing__hold_r2r_vio__count", "timing__setup__ws", + "timing__setup_r2r__ws", + "timing__setup__tns", "timing__setup_vio__count", "timing__setup_r2r_vio__count", "design__max_cap_violation__count",