From 8fa22a4aa5511952d2d8a21a22264949de929495 Mon Sep 17 00:00:00 2001 From: Minju Kim Date: Fri, 16 Oct 2026 11:30:01 +0900 Subject: [PATCH] place: add GPL_PLACE_IOS and configure IO pins with set_place_config Signed-off-by: Minju Kim --- docs/user/FlowVariables.md | 4 +++ flow/Makefile | 13 +++++++++- .../fakeram7_256x32/config.mk | 2 +- flow/designs/gf180/riscv32i/config.mk | 2 +- flow/designs/sky130hd/aes/config.mk | 2 +- flow/designs/sky130hs/riscv32i/config.mk | 2 +- flow/scripts/flow.tcl | 10 ++++--- flow/scripts/global_place.tcl | 26 ++++++++++++++++++- flow/scripts/io_placement.tcl | 6 ++--- flow/scripts/util.tcl | 8 ++++++ flow/scripts/variables.json | 13 ++++++++++ flow/scripts/variables.yaml | 11 ++++++++ flow/util/genMassive.py | 4 ++- tools/OpenROAD | 2 +- 14 files changed, 89 insertions(+), 16 deletions(-) diff --git a/docs/user/FlowVariables.md b/docs/user/FlowVariables.md index 4faa3cf80c9..6548b30d212 100644 --- a/docs/user/FlowVariables.md +++ b/docs/user/FlowVariables.md @@ -161,6 +161,7 @@ configuration file. | GLOBAL_ROUTE_USE_CUGR| Passed as -use_cugr to global_route. Uses CUGR as the global routing solver instead of the default FastRoute solver. NOTE: CUGR is not ready for production.| 0| | GND_NETS_VOLTAGES| Used for IR Drop calculation.| | | GPL_KEEP_OVERFLOW| Passed as -keep_resize_below_overflow to global_placement. Only used when GPL_TIMING_DRIVEN is enabled.| | +| GPL_PLACE_IOS| Place IO pins together with the cells in global placement (-place_ios).| 0| | GPL_RANDOM_SEED| Specifies a random seed for global placement. Useful for perturbation studies.| | | GPL_ROUTABILITY_DRIVEN| Specifies whether the placer should use routability driven placement.| 1| | GPL_TIMING_DRIVEN| Specifies whether the placer should use timing driven placement.| 1| @@ -278,6 +279,7 @@ configuration file. | SEC_CHECK| Perform a sequential equivalence check between the initial synthesis netlist and final netlist with the Kepler Formal PDR engine. If this fails, report an issue to OpenROAD.| 0| | SETUP_MOVE_SEQUENCE| Passed as -sequence to repair_timing. This should be a string of move keywords separated by commas.| | | SETUP_SLACK_MARGIN| Specifies a time margin for the slack when fixing setup violations. This option allows you to overfix or underfix(negative value, terminate retiming before 0 or positive slack). See HOLD_SLACK_MARGIN for more details.| 0| +| SET_PLACE_CONFIG_ARGS| Arguments to set_place_config| | | SKIP_ANTENNA_REPAIR| Skips antenna repair entirely.| 0| | SKIP_ANTENNA_REPAIR_POST_DRT| Skips antenna repair post-detailed routing.| 0| | SKIP_BUFFER_REMOVAL| Passed as -skip_buffer_removal to repair_timing. Do not remove buffers as a transform to fix timing violations (default: allow buffer removal).| | @@ -484,6 +486,7 @@ configuration file. - [FLOORPLAN_DEF](#FLOORPLAN_DEF) - [GLOBAL_PLACEMENT_ARGS](#GLOBAL_PLACEMENT_ARGS) - [GPL_KEEP_OVERFLOW](#GPL_KEEP_OVERFLOW) +- [GPL_PLACE_IOS](#GPL_PLACE_IOS) - [GPL_RANDOM_SEED](#GPL_RANDOM_SEED) - [GPL_ROUTABILITY_DRIVEN](#GPL_ROUTABILITY_DRIVEN) - [GPL_TIMING_DRIVEN](#GPL_TIMING_DRIVEN) @@ -509,6 +512,7 @@ configuration file. - [PRE_RESIZE_TCL](#PRE_RESIZE_TCL) - [REPORT_ENDPOINT_SLACK](#REPORT_ENDPOINT_SLACK) - [ROUTING_LAYER_ADJUSTMENT](#ROUTING_LAYER_ADJUSTMENT) +- [SET_PLACE_CONFIG_ARGS](#SET_PLACE_CONFIG_ARGS) - [SKIP_REPORT_METRICS](#SKIP_REPORT_METRICS) - [TNS_END_PERCENT](#TNS_END_PERCENT) diff --git a/flow/Makefile b/flow/Makefile index 759e13578d4..134ae0fd79e 100644 --- a/flow/Makefile +++ b/flow/Makefile @@ -515,7 +515,14 @@ $(eval $(call do-step,3_2_place_iop,$(RESULTS_DIR)/3_1_place_gp_skip_io.odb,io_p # STEP 3: Global placement with placed IOs, timing-driven, and routability-driven. #------------------------------------------------------------------------------- -$(eval $(call do-step,3_3_place_gp,$(RESULTS_DIR)/3_2_place_iop.odb $(RESULTS_DIR)/2_floorplan.sdc $(LIB_FILES),global_place)) +# -place_ios places the IO pins too, so steps 3_1 and 3_2 are skipped. +ifeq ($(GPL_PLACE_IOS),1) +GLOBAL_PLACE_INPUT_ODB = $(RESULTS_DIR)/2_floorplan.odb +else +GLOBAL_PLACE_INPUT_ODB = $(RESULTS_DIR)/3_2_place_iop.odb +endif + +$(eval $(call do-step,3_3_place_gp,$(GLOBAL_PLACE_INPUT_ODB) $(RESULTS_DIR)/2_floorplan.sdc $(LIB_FILES),global_place)) # STEP 4: Resizing & Buffering #------------------------------------------------------------------------------- @@ -537,7 +544,11 @@ $(RESULTS_DIR)/3_place.sdc: $(RESULTS_DIR)/3_5_place_dp.odb .PHONY: do-place do-place: +ifeq ($(GPL_PLACE_IOS),1) + $(UNSET_AND_MAKE) do-3_3_place_gp do-3_4_place_resized do-3_5_place_dp do-3_place +else $(UNSET_AND_MAKE) do-3_1_place_gp_skip_io do-3_2_place_iop do-3_3_place_gp do-3_4_place_resized do-3_5_place_dp do-3_place +endif # Clean Targets #------------------------------------------------------------------------------- diff --git a/flow/designs/asap7/riscv32i-mock-sram/fakeram7_256x32/config.mk b/flow/designs/asap7/riscv32i-mock-sram/fakeram7_256x32/config.mk index 331305f0d16..d743efcc3e5 100644 --- a/flow/designs/asap7/riscv32i-mock-sram/fakeram7_256x32/config.mk +++ b/flow/designs/asap7/riscv32i-mock-sram/fakeram7_256x32/config.mk @@ -13,7 +13,7 @@ export PLACE_DENSITY = 0.80 export MAX_ROUTING_LAYER = M4 export MIN_CLK_ROUTING_LAYER = M2 -export PLACE_PINS_ARGS = -min_distance 6 -min_distance_in_tracks +export SET_PLACE_CONFIG_ARGS = -io_pin_min_distance 6 -io_pin_min_distance_in_tracks export IO_CONSTRAINTS = $(DESIGN_HOME)/asap7/riscv32i-mock-sram/fakeram7_256x32/io.tcl export PDN_TCL = $(PLATFORM_DIR)/openRoad/pdn/BLOCK_grid_strategy.tcl diff --git a/flow/designs/gf180/riscv32i/config.mk b/flow/designs/gf180/riscv32i/config.mk index ce87ddef681..5a2b6b55b9a 100644 --- a/flow/designs/gf180/riscv32i/config.mk +++ b/flow/designs/gf180/riscv32i/config.mk @@ -9,7 +9,7 @@ export CORE_UTILIZATION = 55 export PLACE_DENSITY_LB_ADDON = 0.2 export TNS_END_PERCENT = 100 export SKIP_GATE_CLONING = 1 -export PLACE_PINS_ARGS = -min_distance 5 +export SET_PLACE_CONFIG_ARGS = -io_pin_min_distance 5 export IO_CONSTRAINTS = $(DESIGN_HOME)/$(PLATFORM)/$(DESIGN_NICKNAME)/io.tcl export SWAP_ARITH_OPERATORS = 1 diff --git a/flow/designs/sky130hd/aes/config.mk b/flow/designs/sky130hd/aes/config.mk index 3f095cd981f..971f5afab4c 100644 --- a/flow/designs/sky130hd/aes/config.mk +++ b/flow/designs/sky130hd/aes/config.mk @@ -5,7 +5,7 @@ export PLATFORM = sky130hd export VERILOG_FILES = $(sort $(wildcard $(DESIGN_HOME)/src/$(DESIGN_NICKNAME)/*.v)) export SDC_FILE = $(DESIGN_HOME)/$(PLATFORM)/$(DESIGN_NICKNAME)/constraint.sdc -export PLACE_PINS_ARGS = -min_distance 4 -min_distance_in_tracks +export SET_PLACE_CONFIG_ARGS = -io_pin_min_distance 4 -io_pin_min_distance_in_tracks export CORE_UTILIZATION = 35 export CORE_ASPECT_RATIO = 1 diff --git a/flow/designs/sky130hs/riscv32i/config.mk b/flow/designs/sky130hs/riscv32i/config.mk index 232ab3fbed2..23fe9f4f0f9 100644 --- a/flow/designs/sky130hs/riscv32i/config.mk +++ b/flow/designs/sky130hs/riscv32i/config.mk @@ -8,7 +8,7 @@ export SDC_FILE = $(DESIGN_HOME)/$(PLATFORM)/$(DESIGN_NICKNAME)/constraint. export CORE_UTILIZATION = 60 export PLACE_DENSITY_LB_ADDON = 0.1 # many east pins cause global routing congestion -export PLACE_PINS_ARGS=-min_distance 6 -min_distance_in_tracks +export SET_PLACE_CONFIG_ARGS=-io_pin_min_distance 6 -io_pin_min_distance_in_tracks export TNS_END_PERCENT = 100 export FASTROUTE_TCL = $(DESIGN_HOME)/$(PLATFORM)/$(DESIGN_NICKNAME)/fastroute.tcl diff --git a/flow/scripts/flow.tcl b/flow/scripts/flow.tcl index cd7f0a26bdf..ef384c873a3 100644 --- a/flow/scripts/flow.tcl +++ b/flow/scripts/flow.tcl @@ -59,10 +59,12 @@ flow_write_db 2_floorplan.odb flow_write_sdc 2_floorplan.sdc # Place -flow_source global_place_skip_io.tcl -flow_write_db 3_1_place_gp_skip_io.odb -flow_source io_placement.tcl -flow_write_db 3_2_place_iop.odb +if { ![env_var_equals GPL_PLACE_IOS 1] } { + flow_source global_place_skip_io.tcl + flow_write_db 3_1_place_gp_skip_io.odb + flow_source io_placement.tcl + flow_write_db 3_2_place_iop.odb +} flow_source global_place.tcl flow_write_db 3_3_place_gp.odb flow_source resize.tcl diff --git a/flow/scripts/global_place.tcl b/flow/scripts/global_place.tcl index 5822ef47c23..f375165499e 100644 --- a/flow/scripts/global_place.tcl +++ b/flow/scripts/global_place.tcl @@ -1,7 +1,18 @@ utl::set_metrics_stage "globalplace__{}" source $::env(SCRIPTS_DIR)/load.tcl erase_non_stage_variables place -load_design 3_2_place_iop.odb 2_floorplan.sdc +# Pins from a floorplan DEF or a footprint stay where they are. +set place_ios [expr { + [env_var_equals GPL_PLACE_IOS 1] + && ![env_var_exists_and_non_empty FLOORPLAN_DEF] + && ![env_var_exists_and_non_empty FOOTPRINT] + && ![env_var_exists_and_non_empty FOOTPRINT_TCL] +}] +if { [env_var_equals GPL_PLACE_IOS 1] } { + load_design 2_floorplan.odb 2_floorplan.sdc +} else { + load_design 3_2_place_iop.odb 2_floorplan.sdc +} source_step_tcl PRE GLOBAL_PLACE set_dont_use $::env(DONT_USE_CELLS) @@ -51,6 +62,15 @@ lappend global_placement_args -force_center_initial_place lappend global_placement_args -min_phi_coef $::env(MIN_PLACE_STEP_COEF) lappend global_placement_args -max_phi_coef $::env(MAX_PLACE_STEP_COEF) +if { $place_ios } { + if { [env_var_exists_and_non_empty PLACE_PINS_ARGS] } { + utl::warn FLW 25 "PLACE_PINS_ARGS is not used with GPL_PLACE_IOS;\ + put set_place_config options in SET_PLACE_CONFIG_ARGS." + } + set_io_place_config + lappend global_placement_args -place_ios +} + proc do_placement { global_placement_args } { set all_args [concat [list -density [place_density_with_lb_addon] \ -pad_left $::env(CELL_PAD_IN_SITES_GLOBAL_PLACEMENT) \ @@ -68,6 +88,10 @@ if { $result != 0 } { error $errMsg } +if { $place_ios } { + write_pin_placement $::env(RESULTS_DIR)/3_3_place_gp_pins.tcl +} + log_cmd estimate_parasitics -placement if { $::env(CLUSTER_FLOPS) } { diff --git a/flow/scripts/io_placement.tcl b/flow/scripts/io_placement.tcl index 5ad95bad51f..2dd76308d29 100644 --- a/flow/scripts/io_placement.tcl +++ b/flow/scripts/io_placement.tcl @@ -8,10 +8,8 @@ if { } { load_design 3_1_place_gp_skip_io.odb 2_floorplan.sdc source_step_tcl PRE IO_PLACEMENT - log_cmd place_pins \ - -hor_layers $::env(IO_PLACER_H) \ - -ver_layers $::env(IO_PLACER_V) \ - {*}[env_var_or_empty PLACE_PINS_ARGS] + set_io_place_config + log_cmd place_pins {*}[env_var_or_empty PLACE_PINS_ARGS] report_design_area orfs_write_db $::env(RESULTS_DIR)/3_2_place_iop.odb diff --git a/flow/scripts/util.tcl b/flow/scripts/util.tcl index 49ab5fd80fe..549efbbfb8b 100644 --- a/flow/scripts/util.tcl +++ b/flow/scripts/util.tcl @@ -152,6 +152,14 @@ proc env_var_or_empty { env_var } { return "" } +# place_pins and global_placement -place_ios both read these settings. +proc set_io_place_config { } { + set_place_config \ + -io_pin_hor_layers $::env(IO_PLACER_H) \ + -io_pin_ver_layers $::env(IO_PLACER_V) \ + {*}[env_var_or_empty SET_PLACE_CONFIG_ARGS] +} + proc find_macros { } { set macros "" diff --git a/flow/scripts/variables.json b/flow/scripts/variables.json index c79940855c2..7d8d25b9eb2 100644 --- a/flow/scripts/variables.json +++ b/flow/scripts/variables.json @@ -425,6 +425,13 @@ "place" ] }, + "GPL_PLACE_IOS": { + "default": 0, + "description": "Place IO pins together with the cells in global placement (-place_ios).\n", + "stages": [ + "place" + ] + }, "GPL_RANDOM_SEED": { "description": "Specifies a random seed for global placement. Useful for perturbation studies.\n", "stages": [ @@ -1163,6 +1170,12 @@ ], "tunable": 1 }, + "SET_PLACE_CONFIG_ARGS": { + "description": "Arguments to set_place_config\n", + "stages": [ + "place" + ] + }, "SKIP_ANTENNA_REPAIR": { "default": 0, "description": "Skips antenna repair entirely.\n", diff --git a/flow/scripts/variables.yaml b/flow/scripts/variables.yaml index ac913b71ad0..0793535c7b2 100644 --- a/flow/scripts/variables.yaml +++ b/flow/scripts/variables.yaml @@ -658,6 +658,11 @@ PLACE_PINS_ARGS: Arguments to place_pins stages: - place +SET_PLACE_CONFIG_ARGS: + description: | + Arguments to set_place_config + stages: + - place PLACE_DENSITY: description: > The desired average placement density of cells: 1.0 = dense, 0.0 = widely spread. @@ -719,6 +724,12 @@ GPL_ROUTABILITY_DRIVEN: stages: - place default: 1 +GPL_PLACE_IOS: + description: | + Place IO pins together with the cells in global placement (-place_ios). + stages: + - place + default: 0 GPL_KEEP_OVERFLOW: description: > Passed as -keep_resize_below_overflow to global_placement. diff --git a/flow/util/genMassive.py b/flow/util/genMassive.py index fc6c6bf13fe..68bbdbe349c 100644 --- a/flow/util/genMassive.py +++ b/flow/util/genMassive.py @@ -375,7 +375,9 @@ def writeConfigs(CurAttrs, CurChunkNum): if CurCoreDieMargin != "empty": fo.write("export CORE_MARGIN = %s\n" % CurCoreDieMargin) if CurPinsDistance != "empty": - fo.write("export PLACE_PINS_ARGS = -min_distance %s\n" % CurPinsDistance) + fo.write( + "export SET_PLACE_CONFIG_ARGS = -io_pin_min_distance %s\n" % CurPinsDistance + ) if CurGpPad != "empty": fo.write("export CELL_PAD_IN_SITES_GLOBAL_PLACEMENT = %s\n" % CurGpPad) if CurDpPad != "empty": diff --git a/tools/OpenROAD b/tools/OpenROAD index 91e5f5ff2f1..8da6ac250b0 160000 --- a/tools/OpenROAD +++ b/tools/OpenROAD @@ -1 +1 @@ -Subproject commit 91e5f5ff2f198fd130e8915c8ad4408b56987fa4 +Subproject commit 8da6ac250b0349c346d1abed7c2c43107f4ff6f7