Skip to content

Commit 547e8c8

Browse files
committed
simplify floorplan_to_place.tcl script
Signed-off-by: Eder Monteiro <[email protected]>
1 parent 56420c0 commit 547e8c8

File tree

1 file changed

+12
-362
lines changed

1 file changed

+12
-362
lines changed
Lines changed: 12 additions & 362 deletions
Original file line numberDiff line numberDiff line change
@@ -1,382 +1,32 @@
1-
utl::set_metrics_stage "floorplan__{}"
2-
source $::env(SCRIPTS_DIR)/load.tcl
3-
load_design 1_synth.odb 1_synth.sdc
1+
# Enable keeping variables between stages
2+
set ::env(KEEP_VARS) 1
43

54
# Floorplan
6-
7-
proc report_unused_masters { } {
8-
set db [ord::get_db]
9-
set libs [$db getLibs]
10-
set masters ""
11-
foreach lib $libs {
12-
foreach master [$lib getMasters] {
13-
# filter out non-block masters, or you can remove this conditional to detect any unused master
14-
if { [$master getType] == "BLOCK" } {
15-
lappend masters $master
16-
}
17-
}
18-
}
19-
20-
set block [ord::get_db_block]
21-
set insts [$block getInsts]
22-
23-
foreach inst $insts {
24-
set inst_master [$inst getMaster]
25-
set masters [lsearch -all -not -inline $masters $inst_master]
26-
}
27-
28-
foreach master $masters {
29-
puts "Master [$master getName] is loaded but not used in the design"
30-
}
31-
}
32-
33-
report_unused_masters
34-
35-
#Run check_setup
36-
puts "\n=========================================================================="
37-
puts "Floorplan check_setup"
38-
puts "--------------------------------------------------------------------------"
39-
check_setup
40-
41-
set num_instances [llength [get_cells -hier *]]
42-
puts "number instances in verilog is $num_instances"
43-
44-
set additional_args ""
45-
append_env_var additional_args ADDITIONAL_SITES -additional_sites 1
46-
47-
# Check which floorplan initialization method is specified (mutually exclusive)
48-
set use_floorplan_def [env_var_exists_and_non_empty FLOORPLAN_DEF]
49-
set use_footprint [env_var_exists_and_non_empty FOOTPRINT]
50-
set use_die_and_core_area \
51-
[expr { [env_var_exists_and_non_empty DIE_AREA] && [env_var_exists_and_non_empty CORE_AREA] }]
52-
set use_core_utilization [env_var_exists_and_non_empty CORE_UTILIZATION]
53-
54-
# Enforce mutual exclusion - exactly one method must be specified
55-
set methods_defined \
56-
[expr { $use_floorplan_def + $use_footprint + $use_die_and_core_area + $use_core_utilization }]
57-
if { $methods_defined > 1 } {
58-
puts "Error: Floorplan initialization methods are mutually exclusive, pick one."
59-
exit 1
60-
}
61-
62-
# Method 1: Use existing DEF file with floorplan data
63-
if { $use_floorplan_def } {
64-
log_cmd read_def -floorplan_initialize $env(FLOORPLAN_DEF)
65-
# Method 2: Use ICeWall footprint file (platform-specific extension)
66-
} elseif { $use_footprint } {
67-
ICeWall load_footprint $env(FOOTPRINT)
68-
69-
initialize_floorplan \
70-
-die_area [ICeWall get_die_area] \
71-
-core_area [ICeWall get_core_area] \
72-
-site $::env(PLACE_SITE)
73-
74-
ICeWall init_footprint $env(SIG_MAP_FILE)
75-
# Method 3: Use explicit die and core area coordinates
76-
} elseif { $use_die_and_core_area } {
77-
initialize_floorplan -die_area $::env(DIE_AREA) \
78-
-core_area $::env(CORE_AREA) \
79-
-site $::env(PLACE_SITE) \
80-
{*}$additional_args
81-
# Method 4: Calculate core area from utilization, aspect ratio, and margins
82-
} elseif { $use_core_utilization } {
83-
initialize_floorplan -utilization $::env(CORE_UTILIZATION) \
84-
-aspect_ratio $::env(CORE_ASPECT_RATIO) \
85-
-core_space $::env(CORE_MARGIN) \
86-
-site $::env(PLACE_SITE) \
87-
{*}$additional_args
88-
} else {
89-
puts "Error: No floorplan initialization method specified"
90-
exit 1
91-
}
92-
93-
# Create routing tracks: MAKE_TRACKS script, platform make_tracks.tcl, or make_tracks command
94-
if { [env_var_exists_and_non_empty MAKE_TRACKS] } {
95-
log_cmd source $::env(MAKE_TRACKS)
96-
} elseif { [file exists $::env(PLATFORM_DIR)/make_tracks.tcl] } {
97-
log_cmd source $::env(PLATFORM_DIR)/make_tracks.tcl
98-
} else {
99-
make_tracks
100-
}
101-
102-
# Configure global routing: FASTROUTE_TCL script or
103-
# set_global_routing_layer_adjustment/set_routing_layers
104-
if { [env_var_exists_and_non_empty FASTROUTE_TCL] } {
105-
log_cmd source $::env(FASTROUTE_TCL)
106-
} else {
107-
log_cmd \
108-
set_global_routing_layer_adjustment \
109-
$::env(MIN_ROUTING_LAYER)-$::env(MAX_ROUTING_LAYER) $::env(ROUTING_LAYER_ADJUSTMENT)
110-
log_cmd set_routing_layers -signal $::env(MIN_ROUTING_LAYER)-$::env(MAX_ROUTING_LAYER)
111-
}
112-
113-
source_env_var_if_exists FOOTPRINT_TCL
114-
115-
if { ![env_var_equal SKIP_REPAIR_TIE_FANOUT 1] } {
116-
# This needs to come before any call to remove_buffers. You could have one
117-
# tie driving multiple buffers that drive multiple outputs.
118-
# Repair tie lo fanout
119-
puts "Repair tie lo fanout..."
120-
set tielo_cell_name [lindex $::env(TIELO_CELL_AND_PORT) 0]
121-
set tielo_lib_name [get_name [get_property [lindex [get_lib_cell $tielo_cell_name] 0] library]]
122-
set tielo_pin $tielo_lib_name/$tielo_cell_name/[lindex $::env(TIELO_CELL_AND_PORT) 1]
123-
repair_tie_fanout -separation $::env(TIE_SEPARATION) $tielo_pin
124-
125-
# Repair tie hi fanout
126-
puts "Repair tie hi fanout..."
127-
set tiehi_cell_name [lindex $::env(TIEHI_CELL_AND_PORT) 0]
128-
set tiehi_lib_name [get_name [get_property [lindex [get_lib_cell $tiehi_cell_name] 0] library]]
129-
set tiehi_pin $tiehi_lib_name/$tiehi_cell_name/[lindex $::env(TIEHI_CELL_AND_PORT) 1]
130-
repair_tie_fanout -separation $::env(TIE_SEPARATION) $tiehi_pin
131-
}
132-
133-
if { [env_var_exists_and_non_empty SWAP_ARITH_OPERATORS] } {
134-
estimate_parasitics -placement
135-
replace_arith_modules
136-
}
137-
138-
if { [env_var_equals REMOVE_ABC_BUFFERS 1] } {
139-
# remove buffers inserted by yosys/abc
140-
remove_buffers
141-
} else {
142-
# Skip clone & split
143-
set ::env(SETUP_MOVE_SEQUENCE) "unbuffer,sizeup,swap,buffer,vt_swap"
144-
set ::env(SKIP_LAST_GASP) 1
145-
set additional_args_repair_timing ""
146-
append_env_var additional_args_repair_timing MAX_REPAIR_TIMING_ITER -max_iterations 1
147-
repair_timing_helper -setup {*}$additional_args_repair_timing
148-
}
149-
150-
puts "Default units for flow"
151-
report_units
152-
report_units_metric
153-
report_metrics 2 "floorplan final" false false
154-
155-
source_env_var_if_exists POST_FLOORPLAN_TCL
156-
source_env_var_if_exists IO_CONSTRAINTS
157-
158-
write_db $::env(RESULTS_DIR)/2_1_floorplan.odb
159-
write_sdc -no_timestamp $::env(RESULTS_DIR)/2_1_floorplan.sdc
160-
5+
source $::env(SCRIPTS_DIR)/floorplan.tcl
1616

1627
# Macro placement
163-
source $::env(SCRIPTS_DIR)/macro_place_util.tcl
164-
165-
write_db $::env(RESULTS_DIR)/2_2_floorplan_macro.odb
166-
write_macro_placement $::env(RESULTS_DIR)/2_2_floorplan_macro.tcl
167-
8+
source $::env(SCRIPTS_DIR)/macro_place.tcl
1689

16910
# Tapcell insertion
170-
if { [env_var_exists_and_non_empty TAPCELL_TCL] } {
171-
source $::env(TAPCELL_TCL)
172-
} else {
173-
cut_rows
174-
}
175-
176-
write_db $::env(RESULTS_DIR)/2_3_floorplan_tapcell.odb
11+
source $::env(SCRIPTS_DIR)/tapcell.tcl
17712

17813
# PDN
179-
source $::env(PDN_TCL)
180-
pdngen
181-
182-
source_env_var_if_exists POST_PDN_TCL
183-
184-
# Check all supply nets
185-
set block [ord::get_db_block]
186-
foreach net [$block getNets] {
187-
set type [$net getSigType]
188-
if { $type == "POWER" || $type == "GROUND" } {
189-
# Temporarily disable due to CI issues
190-
# puts "Check supply: [$net getName]"
191-
# check_power_grid -net [$net getName]
192-
}
193-
}
194-
195-
write_db $::env(RESULTS_DIR)/2_4_floorplan_pdn.odb
14+
source $::env(SCRIPTS_DIR)/pdn.tcl
19615

19716
# Global placement skipping IOs
198-
if { [env_var_exists_and_non_empty FLOORPLAN_DEF] } {
199-
puts "FLOORPLAN_DEF is set. Skipping global placement without IOs"
200-
} elseif { [all_pins_placed] } {
201-
puts "All pins are placed. Skipping global placement without IOs"
202-
} else {
203-
log_cmd global_placement -skip_io -density [place_density_with_lb_addon] \
204-
-pad_left $::env(CELL_PAD_IN_SITES_GLOBAL_PLACEMENT) \
205-
-pad_right $::env(CELL_PAD_IN_SITES_GLOBAL_PLACEMENT) \
206-
{*}[env_var_or_empty GLOBAL_PLACEMENT_ARGS]
207-
}
208-
209-
write_db $::env(RESULTS_DIR)/3_1_place_gp_skip_io.odb
17+
source $::env(SCRIPTS_DIR)/global_place_skip_io.tcl
21018

21119
# IO placement
212-
if {
213-
![env_var_exists_and_non_empty FLOORPLAN_DEF] &&
214-
![env_var_exists_and_non_empty FOOTPRINT] &&
215-
![env_var_exists_and_non_empty FOOTPRINT_TCL]
216-
} {
217-
# load_design 3_1_place_gp_skip_io.odb 2_floorplan.sdc
218-
log_cmd place_pins \
219-
-hor_layers $::env(IO_PLACER_H) \
220-
-ver_layers $::env(IO_PLACER_V) \
221-
{*}[env_var_or_empty PLACE_PINS_ARGS]
222-
write_db $::env(RESULTS_DIR)/3_2_place_iop.odb
223-
write_pin_placement $::env(RESULTS_DIR)/3_2_place_iop.tcl
224-
} else {
225-
log_cmd exec cp $::env(RESULTS_DIR)/3_1_place_gp_skip_io.odb $::env(RESULTS_DIR)/3_2_place_iop.odb
226-
}
20+
source $::env(SCRIPTS_DIR)/io_placement.tcl
22721

22822
# Global placement
229-
utl::set_metrics_stage "globalplace__{}"
230-
set_dont_use $::env(DONT_USE_CELLS)
231-
232-
if { $::env(GPL_TIMING_DRIVEN) } {
233-
remove_buffers
234-
}
235-
236-
# Do not buffer chip-level designs
237-
# by default, IO ports will be buffered
238-
# to not buffer IO ports, set environment variable
239-
# DONT_BUFFER_PORT = 1
240-
if { ![env_var_exists_and_non_empty FOOTPRINT] } {
241-
if { ![env_var_equals DONT_BUFFER_PORTS 1] } {
242-
puts "Perform port buffering..."
243-
buffer_ports {*}[env_var_or_empty BUFFER_PORTS_ARGS]
244-
}
245-
}
246-
247-
set global_placement_args {}
248-
249-
# Parameters for routability mode in global placement
250-
append_env_var global_placement_args GPL_ROUTABILITY_DRIVEN -routability_driven 0
251-
252-
# Parameters for timing driven mode in global placement
253-
if { $::env(GPL_TIMING_DRIVEN) } {
254-
lappend global_placement_args {-timing_driven}
255-
if { [info exists ::env(GPL_KEEP_OVERFLOW)] } {
256-
lappend global_placement_args -keep_resize_below_overflow $::env(GPL_KEEP_OVERFLOW)
257-
}
258-
}
259-
260-
proc do_placement { global_placement_args } {
261-
set all_args [concat [list -density [place_density_with_lb_addon] \
262-
-pad_left $::env(CELL_PAD_IN_SITES_GLOBAL_PLACEMENT) \
263-
-pad_right $::env(CELL_PAD_IN_SITES_GLOBAL_PLACEMENT)] \
264-
$global_placement_args]
265-
266-
lappend all_args {*}[env_var_or_empty GLOBAL_PLACEMENT_ARGS]
267-
268-
log_cmd global_placement {*}$all_args
269-
}
270-
271-
set result [catch { do_placement $global_placement_args } errMsg]
272-
if { $result != 0 } {
273-
write_db $::env(RESULTS_DIR)/3_3_place_gp-failed.odb
274-
error $errMsg
275-
}
276-
277-
estimate_parasitics -placement
278-
279-
if { [env_var_equals CLUSTER_FLOPS 1] } {
280-
cluster_flops
281-
estimate_parasitics -placement
282-
}
283-
284-
report_metrics 3 "global place" false false
285-
286-
write_db $::env(RESULTS_DIR)/3_3_place_gp.odb
23+
source $::env(SCRIPTS_DIR)/global_place.tcl
28724

28825
# Resizing
289-
utl::set_metrics_stage "placeopt__{}"
290-
estimate_parasitics -placement
291-
292-
set instance_count_before [sta::network_leaf_instance_count]
293-
set pin_count_before [sta::network_leaf_pin_count]
294-
295-
set_dont_use $::env(DONT_USE_CELLS)
296-
297-
if { [env_var_exists_and_non_empty EARLY_SIZING_CAP_RATIO] } {
298-
log_cmd set_opt_config -set_early_sizing_cap_ratio $env(EARLY_SIZING_CAP_RATIO)
299-
}
300-
301-
if { [env_var_exists_and_non_empty SWAP_ARITH_OPERATORS] } {
302-
replace_arith_modules
303-
}
304-
305-
repair_design_helper
306-
307-
# hold violations are not repaired until after CTS
308-
309-
# post report
310-
311-
puts "Floating nets: "
312-
report_floating_nets
313-
314-
report_metrics 3 "resizer" true false
315-
316-
puts "Instance count before $instance_count_before, after [sta::network_leaf_instance_count]"
317-
puts "Pin count before $pin_count_before, after [sta::network_leaf_pin_count]"
318-
319-
write_db $::env(RESULTS_DIR)/3_4_place_resized.odb
26+
source $::env(SCRIPTS_DIR)/resize.tcl
32027

32128
# Detailed placement
322-
utl::set_metrics_stage "detailedplace__{}"
323-
324-
proc do_dpl { } {
325-
# Only for use with hybrid rows
326-
if { [env_var_equals BALANCE_ROWS 1] } {
327-
balance_row_usage
328-
}
329-
330-
set_placement_padding -global \
331-
-left $::env(CELL_PAD_IN_SITES_DETAIL_PLACEMENT) \
332-
-right $::env(CELL_PAD_IN_SITES_DETAIL_PLACEMENT)
333-
detailed_placement
334-
335-
if { [env_var_equals ENABLE_DPO 1] } {
336-
if { [env_var_exists_and_non_empty DPO_MAX_DISPLACEMENT] } {
337-
improve_placement -max_displacement $::env(DPO_MAX_DISPLACEMENT)
338-
} else {
339-
improve_placement
340-
}
341-
}
342-
optimize_mirroring
343-
344-
utl::info FLW 12 "Placement violations [check_placement -verbose]."
345-
346-
estimate_parasitics -placement
347-
}
348-
349-
set result [catch { do_dpl } errMsg]
350-
if { $result != 0 } {
351-
write_db $::env(RESULTS_DIR)/3_5_place_dp-failed.odb
352-
error $errMsg
353-
}
354-
355-
report_metrics 3 "detailed place" true false
356-
357-
write_db $::env(RESULTS_DIR)/3_5_place_dp.odb
29+
source $::env(SCRIPTS_DIR)/detail_place.tcl
35830

35931
# Repair timing after placement
360-
utl::set_metrics_stage "place_repair_timing__{}"
361-
362-
set_placement_padding -global \
363-
-left $::env(CELL_PAD_IN_SITES_DETAIL_PLACEMENT) \
364-
-right $::env(CELL_PAD_IN_SITES_DETAIL_PLACEMENT)
365-
366-
puts "Repair setup and hold violations"
367-
estimate_parasitics -placement
368-
369-
set additional_args_repair_timing ""
370-
append_env_var additional_args_repair_timing MAX_REPAIR_TIMING_ITER -max_iterations 1
371-
372-
log_cmd repair_timing -repair_tns $::env(TNS_END_PERCENT) \
373-
{*}$additional_args_repair_timing
374-
375-
# Legalize placement after timing repair
376-
detailed_placement
377-
378-
puts "Estimate parasitics"
379-
estimate_parasitics -placement
380-
report_metrics 3 "place repair timing" true false
381-
382-
write_db $::env(RESULTS_DIR)/3_6_place_repair_timing.odb
32+
source $::env(SCRIPTS_DIR)/repair_timing_post_place.tcl

0 commit comments

Comments
 (0)