diff --git a/docs/user/FlowVariables.md b/docs/user/FlowVariables.md index d286aa2461..d6b532ea11 100644 --- a/docs/user/FlowVariables.md +++ b/docs/user/FlowVariables.md @@ -157,7 +157,6 @@ configuration file. | FOOTPRINT_TCL| Specifies a Tcl script with custom footprint-related commands for floorplan setup.| | | GDS_ALLOW_EMPTY| Single regular expression of module names of macros that have no .gds file| | | GDS_FILES| Path to platform GDS files.| | -| GENERATE_ARTIFACTS_ON_FAILURE| For instance Bazel needs artifacts (.odb and .rpt files) on a failure to allow the user to save hours on re-running the failed step locally, but when working with a Makefile flow, it is more natural to fail the step and leave the user to manually inspect the logs and artifacts directly via the file system. Set to 1 to change the behavior to generate artifacts upon failure to e.g. do a global route. The exit code will still be non-zero on all other failures that aren't covered by the "useful to inspect the artifacts on failure" use-case. Example: just like detailed routing, a global route that fails with congestion, is not a build failure(as in exit code non-zero), it is a successful(as in zero exit code) global route that produce reports detailing the problem. Detailed route will not proceed, if there is global routing congestion This allows build systems, such as bazel, to create artifacts for global and detailed route, even if the operation had problems, without having know about the semantics between global and detailed route. Considering that global and detailed route can run for a long time and use a lot of memory, this allows inspecting results on a laptop for a build that ran on a server.| 0| | GLOBAL_CONNECT_TCL| File path to the add_global_connection rules that connect the supply pins of the instances to the supply nets. Sourced at floorplan right after the netlist is loaded, before any step can mark an instance dont_touch; the rules are kept in the database. The platform's file by default; a design whose PDN_TCL names other supply nets sets its own. PDN_TCL defines the grids.| | | GLOBAL_PLACEMENT_ARGS| Use additional tuning parameters during global placement other than default args defined in global_place.tcl.| | | GLOBAL_ROUTE_ARGS| Replaces default arguments for global route. The -congestion_iterations default is set by the flow (30 for FastRoute, 10 for CUGR); add -congestion_iterations here to override it.| -congestion_report_iter_step 5 -verbose| @@ -681,7 +680,6 @@ configuration file. - [FILL_CONFIG](#FILL_CONFIG) - [FLOW_VARIANT](#FLOW_VARIANT) - [GDS_FILES](#GDS_FILES) -- [GENERATE_ARTIFACTS_ON_FAILURE](#GENERATE_ARTIFACTS_ON_FAILURE) - [GUI_TIMING](#GUI_TIMING) - [IR_DROP_LAYER](#IR_DROP_LAYER) - [KLAYOUT_TECH_FILE](#KLAYOUT_TECH_FILE) diff --git a/flow/scripts/detail_route.tcl b/flow/scripts/detail_route.tcl index 538e8476e0..4bdc0c10f4 100644 --- a/flow/scripts/detail_route.tcl +++ b/flow/scripts/detail_route.tcl @@ -2,10 +2,6 @@ utl::set_metrics_stage "detailedroute__{}" source $::env(SCRIPTS_DIR)/load.tcl load_design 5_1_grt.odb 5_1_grt.sdc source_step_tcl PRE DETAIL_ROUTE -if { ![grt::have_routes] } { - error "Global routing failed, run `make gui_grt` and load $::global_route_congestion_report \ - in DRC viewer to view congestion" -} if { !$::env(SKIP_DETAILED_ROUTE) } { erase_non_stage_variables route diff --git a/flow/scripts/global_route.tcl b/flow/scripts/global_route.tcl index c504826cc9..01ad91ba30 100644 --- a/flow/scripts/global_route.tcl +++ b/flow/scripts/global_route.tcl @@ -3,187 +3,158 @@ source $::env(SCRIPTS_DIR)/load.tcl erase_non_stage_variables grt load_design 4_cts.odb 4_cts.sdc -# This proc is here to allow us to use 'return' to return early from this -# file which is sourced -proc global_route_helper { } { - source_step_tcl PRE GLOBAL_ROUTE - - set res_aware "" - append_env_var res_aware ENABLE_RESISTANCE_AWARE -resistance_aware 0 - - set use_cugr "" - append_env_var use_cugr GLOBAL_ROUTE_USE_CUGR -use_cugr 0 - - # The flow's choice to accept congestion, from GLOBAL_ROUTE_ARGS, passed - # to every incremental reroute and to repair_antennas: each call decides - # for itself, and one without -allow_congestion reroutes a congested route - # harder and then fails on it. - set allow_congestion "" - if { [lsearch -exact $::env(GLOBAL_ROUTE_ARGS) -allow_congestion] >= 0 } { - set allow_congestion -allow_congestion +source_step_tcl PRE GLOBAL_ROUTE + +set res_aware "" +append_env_var res_aware ENABLE_RESISTANCE_AWARE -resistance_aware 0 + +set use_cugr "" +append_env_var use_cugr GLOBAL_ROUTE_USE_CUGR -use_cugr 0 + +# The flow's choice to accept congestion, from GLOBAL_ROUTE_ARGS, passed +# to every incremental reroute and to repair_antennas: each call decides +# for itself, and one without -allow_congestion reroutes a congested route +# harder and then fails on it. +set allow_congestion "" +if { [lsearch -exact $::env(GLOBAL_ROUTE_ARGS) -allow_congestion] >= 0 } { + set allow_congestion -allow_congestion +} + +proc set_grt_seed { } { + set seed_arg [env_var_or_empty GRT_SEED] + if { $seed_arg ne "" } { + log_cmd set_global_routing_random -seed $seed_arg } +} - proc set_grt_seed { } { - set seed_arg [env_var_or_empty GRT_SEED] - if { $seed_arg ne "" } { - log_cmd set_global_routing_random -seed $seed_arg - } +proc run_global_route_and_catch_failures { args } { + if { [catch { log_cmd global_route {*}$args } errMsg] } { + log_cmd write_db $::env(RESULTS_DIR)/5_1_grt-failed.odb + error $errMsg } +} - proc run_global_route_and_catch_failures { args } { - set result [catch { log_cmd global_route {*}$args } errMsg] - - if { $result != 0 } { - if { !$::env(GENERATE_ARTIFACTS_ON_FAILURE) } { - log_cmd write_db $::env(RESULTS_DIR)/5_1_grt-failed.odb - error $errMsg - } - orfs_write_sdc $::env(RESULTS_DIR)/5_1_grt.sdc - # A route that failed has no parasitics to time the endpoints with. - orfs_write_db $::env(RESULTS_DIR)/5_1_grt.odb 0 - return 0 - } - return 1 +proc do_global_route { res_aware use_cugr } { + set_grt_seed + # CUGR runs a full 3D maze pass per iteration; use a tighter default. + set cong_iters "-congestion_iterations 30" + if { $use_cugr ne "" } { + set cong_iters "-congestion_iterations 10" } + set all_args [concat [list \ + -congestion_report_file $::global_route_congestion_report] \ + $cong_iters $::env(GLOBAL_ROUTE_ARGS) {*}$res_aware {*}$use_cugr] - proc do_global_route { res_aware use_cugr } { - set_grt_seed - # CUGR runs a full 3D maze pass per iteration; use a tighter default. - set cong_iters "-congestion_iterations 30" - if { $use_cugr ne "" } { - set cong_iters "-congestion_iterations 10" - } - set all_args [concat [list \ - -congestion_report_file $::global_route_congestion_report] \ - $cong_iters $::env(GLOBAL_ROUTE_ARGS) {*}$res_aware {*}$use_cugr] + run_global_route_and_catch_failures {*}$all_args +} +set additional_args "" +append_env_var additional_args dbProcessNode -db_process_node 1 +append_env_var additional_args VIA_IN_PIN_MIN_LAYER -via_in_pin_bottom_layer 1 +append_env_var additional_args VIA_IN_PIN_MAX_LAYER -via_in_pin_top_layer 1 - return [run_global_route_and_catch_failures {*}$all_args] - } - set additional_args "" - append_env_var additional_args dbProcessNode -db_process_node 1 - append_env_var additional_args VIA_IN_PIN_MIN_LAYER -via_in_pin_bottom_layer 1 - append_env_var additional_args VIA_IN_PIN_MAX_LAYER -via_in_pin_top_layer 1 +log_cmd pin_access {*}$additional_args - log_cmd pin_access {*}$additional_args +do_global_route $res_aware $use_cugr - if { ![do_global_route $res_aware $use_cugr] } { - return - } +set_placement_padding -global \ + -left $::env(CELL_PAD_IN_SITES_DETAIL_PLACEMENT) \ + -right $::env(CELL_PAD_IN_SITES_DETAIL_PLACEMENT) - set_placement_padding -global \ - -left $::env(CELL_PAD_IN_SITES_DETAIL_PLACEMENT) \ - -right $::env(CELL_PAD_IN_SITES_DETAIL_PLACEMENT) +set_propagated_clock [all_clocks] +log_cmd estimate_parasitics - set_propagated_clock [all_clocks] - log_cmd estimate_parasitics +if { [env_var_exists_and_non_empty DONT_USE_CELLS] } { + set_dont_use $::env(DONT_USE_CELLS) +} - if { [env_var_exists_and_non_empty DONT_USE_CELLS] } { - set_dont_use $::env(DONT_USE_CELLS) +if { !$::env(SKIP_INCREMENTAL_REPAIR) } { + if { $::env(DETAILED_METRICS) } { + report_metrics 5 "global route pre repair design" } - if { !$::env(SKIP_INCREMENTAL_REPAIR) } { - if { $::env(DETAILED_METRICS) } { - report_metrics 5 "global route pre repair design" - } + # Repair design using global route parasitics + repair_design_helper + if { $::env(DETAILED_METRICS) } { + report_metrics 5 "global route post repair design" + } - # Repair design using global route parasitics - repair_design_helper - if { $::env(DETAILED_METRICS) } { - report_metrics 5 "global route post repair design" - } + # Running DPL to fix overlapped instances + # Run to get modified net by DPL + log_cmd global_route -start_incremental {*}$allow_congestion + detailed_placement_helper -quiet + # Route only the modified net by DPL + run_global_route_and_catch_failures -end_incremental {*}$res_aware \ + {*}$allow_congestion \ + -congestion_report_file $::env(REPORTS_DIR)/congestion_post_repair_design.rpt + + # Repair timing using global route parasitics + puts "Repair setup and hold violations..." + log_cmd estimate_parasitics - # Running DPL to fix overlapped instances - # Run to get modified net by DPL - log_cmd global_route -start_incremental {*}$allow_congestion - detailed_placement_helper -quiet - # Route only the modified net by DPL - if { - ![run_global_route_and_catch_failures -end_incremental {*}$res_aware \ - {*}$allow_congestion \ - -congestion_report_file $::env(REPORTS_DIR)/congestion_post_repair_design.rpt] - } { - return - } + repair_timing_helper - # Repair timing using global route parasitics - puts "Repair setup and hold violations..." - log_cmd estimate_parasitics + if { $::env(DETAILED_METRICS) } { + report_metrics 5 "global route post repair timing" + } - repair_timing_helper + log_cmd global_route -start_incremental {*}$allow_congestion + detailed_placement_helper -quiet + log_cmd check_placement -placeable -verbose + # Route only the modified net by DPL + run_global_route_and_catch_failures -end_incremental {*}$res_aware \ + {*}$allow_congestion \ + -congestion_report_file $::env(REPORTS_DIR)/congestion_post_repair_timing.rpt - if { $::env(DETAILED_METRICS) } { - report_metrics 5 "global route post repair timing" - } + log_cmd estimate_parasitics - log_cmd global_route -start_incremental {*}$allow_congestion - detailed_placement_helper -quiet - log_cmd check_placement -placeable -verbose - # Route only the modified net by DPL - if { - ![run_global_route_and_catch_failures -end_incremental {*}$res_aware \ - {*}$allow_congestion \ - -congestion_report_file $::env(REPORTS_DIR)/congestion_post_repair_timing.rpt] - } { - return + if { $::env(OPT_POST_GRT_WNS) } { + set repair_timing_args \ + [list -setup -sequence "vt_swap reroute" -skip_last_gasp -repair_tns 0 -verbose] + if { [env_var_exists_and_non_empty MATCH_CELL_FOOTPRINT] } { + lappend repair_timing_args -match_cell_footprint } - - log_cmd estimate_parasitics - - if { $::env(OPT_POST_GRT_WNS) } { - set repair_timing_args \ - [list -setup -sequence "vt_swap reroute" -skip_last_gasp -repair_tns 0 -verbose] - if { [env_var_exists_and_non_empty MATCH_CELL_FOOTPRINT] } { - lappend repair_timing_args -match_cell_footprint - } - if { $::env(SETUP_SLACK_MARGIN) != 0 } { - lappend repair_timing_args -setup_margin $::env(SETUP_SLACK_MARGIN) - } - log_cmd repair_timing {*}$repair_timing_args - - if { $::env(DETAILED_METRICS) } { - report_metrics 5 "global route post repair timing_opt_wns" - } + if { $::env(SETUP_SLACK_MARGIN) != 0 } { + lappend repair_timing_args -setup_margin $::env(SETUP_SLACK_MARGIN) } - } + log_cmd repair_timing {*}$repair_timing_args - if { !$::env(OPT_POST_GRT_WNS) } { - log_cmd global_route -start_incremental {*}$allow_congestion - recover_power_helper - # Route the modified nets by rsz journal restore - if { - ![run_global_route_and_catch_failures -end_incremental {*}$res_aware \ - {*}$allow_congestion \ - -congestion_report_file $::env(REPORTS_DIR)/congestion_post_recover_power.rpt] - } { - return + if { $::env(DETAILED_METRICS) } { + report_metrics 5 "global route post repair timing_opt_wns" } } +} - if { - !$::env(SKIP_ANTENNA_REPAIR) && - [env_var_exists_and_non_empty MAX_REPAIR_ANTENNAS_ITER_GRT] - } { - puts "Repair antennas..." - repair_antennas -iterations $::env(MAX_REPAIR_ANTENNAS_ITER_GRT) \ - {*}$allow_congestion - # repair antennas calls DPL internally - log_cmd check_placement -placeable -verbose - check_antennas -report_file $::env(REPORTS_DIR)/grt_antennas.log - } +if { !$::env(OPT_POST_GRT_WNS) } { + log_cmd global_route -start_incremental {*}$allow_congestion + recover_power_helper + # Route the modified nets by rsz journal restore + run_global_route_and_catch_failures -end_incremental {*}$res_aware \ + {*}$allow_congestion \ + -congestion_report_file $::env(REPORTS_DIR)/congestion_post_recover_power.rpt +} - puts "Estimate parasitics..." - log_cmd estimate_parasitics +if { + !$::env(SKIP_ANTENNA_REPAIR) && + [env_var_exists_and_non_empty MAX_REPAIR_ANTENNAS_ITER_GRT] +} { + puts "Repair antennas..." + repair_antennas -iterations $::env(MAX_REPAIR_ANTENNAS_ITER_GRT) \ + {*}$allow_congestion + # repair antennas calls DPL internally + log_cmd check_placement -placeable -verbose + check_antennas -report_file $::env(REPORTS_DIR)/grt_antennas.log +} - report_metrics 5 "global route" +puts "Estimate parasitics..." +log_cmd estimate_parasitics - # Write SDC to results with updated clock periods that are just failing. - # Use make target update_sdc_clock to install the updated sdc. - source [file join $::env(SCRIPTS_DIR) "write_ref_sdc.tcl"] +report_metrics 5 "global route" - write_guides $::env(RESULTS_DIR)/route.guide - source_step_tcl POST GLOBAL_ROUTE - orfs_write_db $::env(RESULTS_DIR)/5_1_grt.odb - orfs_write_sdc $::env(RESULTS_DIR)/5_1_grt.sdc -} +# Write SDC to results with updated clock periods that are just failing. +# Use make target update_sdc_clock to install the updated sdc. +source [file join $::env(SCRIPTS_DIR) "write_ref_sdc.tcl"] -global_route_helper +write_guides $::env(RESULTS_DIR)/route.guide +source_step_tcl POST GLOBAL_ROUTE +orfs_write_db $::env(RESULTS_DIR)/5_1_grt.odb +orfs_write_sdc $::env(RESULTS_DIR)/5_1_grt.sdc diff --git a/flow/scripts/variables.json b/flow/scripts/variables.json index 245c4b2457..37fbdc9740 100644 --- a/flow/scripts/variables.json +++ b/flow/scripts/variables.json @@ -402,10 +402,6 @@ "GDS_FILES": { "description": "Path to platform GDS files.\n" }, - "GENERATE_ARTIFACTS_ON_FAILURE": { - "default": 0, - "description": "For instance Bazel needs artifacts (.odb and .rpt files) on a failure to allow the user to save hours on re-running the failed step locally, but when working with a Makefile flow, it is more natural to fail the step and leave the user to manually inspect the logs and artifacts directly via the file system. Set to 1 to change the behavior to generate artifacts upon failure to e.g. do a global route. The exit code will still be non-zero on all other failures that aren't covered by the \"useful to inspect the artifacts on failure\" use-case. Example: just like detailed routing, a global route that fails with congestion, is not a build failure(as in exit code non-zero), it is a successful(as in zero exit code) global route that produce reports detailing the problem. Detailed route will not proceed, if there is global routing congestion This allows build systems, such as bazel, to create artifacts for global and detailed route, even if the operation had problems, without having know about the semantics between global and detailed route. Considering that global and detailed route can run for a long time and use a lot of memory, this allows inspecting results on a laptop for a build that ran on a server.\n" - }, "GLOBAL_CONNECT_TCL": { "description": "File path to the add_global_connection rules that connect the supply pins of the instances to the supply nets. Sourced at floorplan right after the netlist is loaded, before any step can mark an instance dont_touch; the rules are kept in the database. The platform's file by default; a design whose PDN_TCL names other supply nets sets its own. PDN_TCL defines the grids.\n", "stages": [ diff --git a/flow/scripts/variables.yaml b/flow/scripts/variables.yaml index 5ece219886..5dfc4ea737 100644 --- a/flow/scripts/variables.yaml +++ b/flow/scripts/variables.yaml @@ -1,27 +1,4 @@ --- -GENERATE_ARTIFACTS_ON_FAILURE: - description: > - For instance Bazel needs artifacts (.odb and .rpt files) on a failure to - allow the user to save hours on re-running the failed step locally, but when - working with a Makefile flow, it is more natural to fail the step and leave - the user to manually inspect the logs and artifacts directly via the file - system. - Set to 1 to change the behavior to generate artifacts upon failure to e.g. - do a global route. The exit code will still be non-zero on all other - failures that aren't covered by the "useful to inspect the artifacts on - failure" use-case. - Example: just like detailed routing, a global route that fails with - congestion, is not a build failure(as in exit code non-zero), it is a - successful(as in zero exit code) global route that produce reports - detailing the problem. - Detailed route will not proceed, if there is global routing congestion - This allows build systems, such as bazel, to create artifacts for global and - detailed route, even if the operation had problems, without having know - about the semantics between global and detailed route. - Considering that global and detailed route can run for a long time and use a - lot of memory, this allows inspecting results on a laptop for a build that - ran on a server. - default: 0 TNS_END_PERCENT: description: > Default TNS_END_PERCENT value for post CTS timing repair. Try fixing all