From f1a52748ad8e5e6a50b25dfe3fe8d96cc1954bf7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C3=98yvind=20Harboe?= Date: Thu, 29 Oct 2026 14:51:43 +0100 Subject: [PATCH] metrics: report what is free unconditionally MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit With SKIP_REPORT_METRICS=1, report_metrics reported nothing at all, so a flow that skips it for speed also lost design area, instance counts and utilization, though those are a walk over the instances that needs no timer. Report them unconditionally, before the skip. SKIP_REPORT_METRICS now skips only what costs time: the timing update behind setup and hold WS and TNS, fmax, the max slew/cap/fanout checks and clock skew; the power analysis; and the reports/_*.rpt text reports. The calls that take measurable time even on asap7/gcd, 5 to 200 ms each on a few hundred cells, run under log_cmd, so on a large design the log names any that takes five seconds or more. The four register path searches go through `log_cmd eval { ... }`, so the log prints the command rather than the expanded register list. On asap7/gcd, metrics on (DETAILED_METRICS=1) and off give byte-identical .odb files at every stage; with SKIP_REPORT_METRICS=1 every stage's metrics .json has the design area and no timing. Co-Authored-By: Claude Opus 5.5 Signed-off-by: Øyvind Harboe --- docs/user/FlowVariables.md | 2 +- flow/scripts/report_metrics.tcl | 30 +++++++++++++++++------------- flow/scripts/variables.json | 2 +- flow/scripts/variables.yaml | 9 +++++++-- 4 files changed, 26 insertions(+), 17 deletions(-) diff --git a/docs/user/FlowVariables.md b/docs/user/FlowVariables.md index 5e47afd713..f12e1f4a02 100644 --- a/docs/user/FlowVariables.md +++ b/docs/user/FlowVariables.md @@ -291,7 +291,7 @@ configuration file. | SKIP_LAST_GASP| Do not use last gasp optimization to fix timing violations (default: use gate last gasp).| | | SKIP_PIN_SWAP| Do not use pin swapping as a transform to fix timing violations (default: use pin swapping).| | | SKIP_REPAIR_TIE_FANOUT| Skip repair_tie_fanout at floorplan step.| 0| -| SKIP_REPORT_METRICS| If set to 1, then metrics, report_metrics does nothing. Useful to speed up builds.| 0| +| SKIP_REPORT_METRICS| If set to 1, report_metrics writes only the metrics that cost no analysis: design area, instance counts and utilization. Timing, power, clock skew, the max slew/cap/fanout checks and the `reports/_*.rpt` text reports are skipped; they need a timing update and a power analysis at every stage that calls it. The counters the tools record as they run (placement, legalization, routing, repair, warnings) are written either way.| 0| | SKIP_VT_SWAP| Do not perform VT swap to improve QoR (default: do VT swap).| | | SLEW_MARGIN| Specifies a slew margin when fixing max slew violations. This option allows you to overfix.| | | SWAP_ARITH_OPERATORS| Improve timing QoR by swapping ALU and MULT arithmetic operators.| 0| diff --git a/flow/scripts/report_metrics.tcl b/flow/scripts/report_metrics.tcl index 5accb72a34..d59c0fd3f5 100644 --- a/flow/scripts/report_metrics.tcl +++ b/flow/scripts/report_metrics.tcl @@ -7,6 +7,7 @@ proc report_puts { out } { } proc report_metrics { stage when { include_erc true } { include_clock_skew true } } { + report_design_area_metrics if { $::env(SKIP_REPORT_METRICS) } { return } @@ -17,7 +18,7 @@ proc report_metrics { stage when { include_erc true } { include_clock_skew true report_puts "\n==========================================================================" report_puts "$when report_tns" report_puts "--------------------------------------------------------------------------" - report_tns >> $filename + log_cmd report_tns >> $filename report_tns_metric report_tns_metric -hold @@ -36,7 +37,7 @@ proc report_metrics { stage when { include_erc true } { include_clock_skew true report_puts "\n==========================================================================" report_puts "$when report_clock_min_period" report_puts "--------------------------------------------------------------------------" - report_clock_min_period -include_port_paths >> $filename + log_cmd report_clock_min_period -include_port_paths >> $filename report_fmax_metric if { $include_clock_skew && $::env(REPORT_CLOCK_SKEW) } { @@ -70,9 +71,9 @@ proc report_metrics { stage when { include_erc true } { include_clock_skew true report_puts "\n==========================================================================" report_puts "$when report_check_types -max_slew -max_cap -max_fanout -violators" report_puts "--------------------------------------------------------------------------" - report_check_types -max_slew -max_capacitance -max_fanout -violators >> $filename + log_cmd report_check_types -max_slew -max_capacitance -max_fanout -violators >> $filename - report_erc_metrics + log_cmd report_erc_metrics report_puts "\n==========================================================================" report_puts "$when max_slew_check_slack" @@ -163,16 +164,18 @@ proc report_metrics { stage when { include_erc true } { include_clock_skew true report_puts "\n==========================================================================" report_puts "$when report_checks -path_delay max reg to reg" report_puts "--------------------------------------------------------------------------" - report_checks -path_delay max -from [all_registers] -to [all_registers] \ - -format full_clock_expanded >> $filename + log_cmd eval { report_checks -path_delay max -from [all_registers] -to [all_registers] \ + -format full_clock_expanded >> $filename } report_puts "\n==========================================================================" report_puts "$when report_checks -path_delay min reg to reg" report_puts "--------------------------------------------------------------------------" - report_checks -path_delay min -from [all_registers] -to [all_registers] \ - -format full_clock_expanded >> $filename + log_cmd eval { report_checks -path_delay min -from [all_registers] -to [all_registers] \ + -format full_clock_expanded >> $filename } set inp_to_reg_critical_path \ - [lindex [find_timing_paths -path_delay max -from [all_inputs] -to [all_registers]] 0] + [lindex [log_cmd eval { + find_timing_paths -path_delay max -from [all_inputs] -to [all_registers] + }] 0] if { $inp_to_reg_critical_path != "" } { set target_clock_latency_max \ [sta::format_time [$inp_to_reg_critical_path target_clk_delay] 4] @@ -182,7 +185,9 @@ proc report_metrics { stage when { include_erc true } { include_clock_skew true set inp_to_reg_critical_path [lindex \ - [find_timing_paths -path_delay min -from [all_inputs] -to [all_registers]] 0] + [log_cmd eval { + find_timing_paths -path_delay min -from [all_inputs] -to [all_registers] + }] 0] if { $inp_to_reg_critical_path != "" } { set target_clock_latency_min \ [sta::format_time [$inp_to_reg_critical_path target_clk_delay] 4] @@ -237,12 +242,12 @@ proc report_metrics { stage when { include_erc true } { include_clock_skew true if { [env_var_exists_and_non_empty CORNERS] } { foreach corner $::env(CORNERS) { report_puts "Corner: $corner" - report_power -corner $corner >> $filename + log_cmd report_power -corner $corner >> $filename report_power_metric -corner $corner } unset corner } else { - report_power >> $filename + log_cmd report_power >> $filename report_power_metric } @@ -251,5 +256,4 @@ proc report_metrics { stage when { include_erc true } { include_clock_skew true puts "$when report_design_area" puts "--------------------------------------------------------------------------" report_design_area - report_design_area_metrics } diff --git a/flow/scripts/variables.json b/flow/scripts/variables.json index f5c5c00c26..959c80a8c9 100644 --- a/flow/scripts/variables.json +++ b/flow/scripts/variables.json @@ -1264,7 +1264,7 @@ }, "SKIP_REPORT_METRICS": { "default": 0, - "description": "If set to 1, then metrics, report_metrics does nothing. Useful to speed up builds.\n", + "description": "If set to 1, report_metrics writes only the metrics that cost no analysis: design area, instance counts and utilization. Timing, power, clock skew, the max slew/cap/fanout checks and the `reports/_*.rpt` text reports are skipped; they need a timing update and a power analysis at every stage that calls it. The counters the tools record as they run (placement, legalization, routing, repair, warnings) are written either way.\n", "stages": [ "synth", "floorplan", diff --git a/flow/scripts/variables.yaml b/flow/scripts/variables.yaml index d0634da90d..77fd6aeaf3 100644 --- a/flow/scripts/variables.yaml +++ b/flow/scripts/variables.yaml @@ -128,8 +128,13 @@ REPORT_ENDPOINT_SLACK: default: 0 SKIP_REPORT_METRICS: description: > - If set to 1, then metrics, report_metrics does nothing. Useful to speed up - builds. + If set to 1, report_metrics writes only the metrics that cost no + analysis: design area, instance counts and utilization. Timing, power, + clock skew, the max slew/cap/fanout checks and the + `reports/_*.rpt` text reports are skipped; they need a timing + update and a power analysis at every stage that calls it. The + counters the tools record as they run (placement, legalization, + routing, repair, warnings) are written either way. stages: - synth - floorplan