Skip to content

Commit cd42b5b

Browse files
authored
Merge pull request #3592 from eder-matheus/flow_single_run
add target to run floorplan to place in a single openroad run
2 parents 9951dfd + 98aeea0 commit cd42b5b

File tree

3 files changed

+389
-1
lines changed

3 files changed

+389
-1
lines changed

flow/Makefile

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -392,6 +392,17 @@ do-$(1)$(if $(4),$(4),):
392392
cp $(RESULTS_DIR)/$(2) $(RESULTS_DIR)/$(1)$(if $(4),$(4),.odb)
393393
endef
394394

395+
# ==============================================================================
396+
397+
# Custom target to go from synthesis to placement in a single OpenROAD run
398+
$(eval $(call do-step,1_3_floorplan_to_place, $(RESULTS_DIR)/1_synth.v $(RESULTS_DIR)/1_synth.sdc,floorplan_to_place))
399+
400+
.PHONY: floorplan_to_place
401+
floorplan_to_place: $(RESULTS_DIR)/1_synth.v $(RESULTS_DIR)/1_synth.sdc
402+
$(UNSET_AND_MAKE) do-1_3_floorplan_to_place
403+
404+
# ==============================================================================
405+
395406
$(eval $(call do-step,1_3_synth,$(RESULTS_DIR)/1_synth.v $(RESULTS_DIR)/1_synth.sdc,synth_odb))
396407

397408
$(eval $(call do-step,2_1_floorplan,$(RESULTS_DIR)/1_synth.v $(RESULTS_DIR)/1_synth.sdc $(TECH_LEF) $(SC_LEF) $(ADDITIONAL_LEFS) $(FOOTPRINT) $(SIG_MAP_FILE) $(FOOTPRINT_TCL) $(LIB_FILES) $(IO_CONSTRAINTS),floorplan))
Lines changed: 377 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,377 @@
1+
utl::set_metrics_stage "floorplan__{}"
2+
source $::env(SCRIPTS_DIR)/load.tcl
3+
load_design 1_synth.v 1_synth.sdc
4+
5+
# 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+
repair_timing_helper -setup
146+
}
147+
148+
puts "Default units for flow"
149+
report_units
150+
report_units_metric
151+
report_metrics 2 "floorplan final" false false
152+
153+
source_env_var_if_exists POST_FLOORPLAN_TCL
154+
source_env_var_if_exists IO_CONSTRAINTS
155+
156+
write_db $::env(RESULTS_DIR)/2_1_floorplan.odb
157+
write_sdc -no_timestamp $::env(RESULTS_DIR)/2_1_floorplan.sdc
158+
159+
160+
# Macro placement
161+
source $::env(SCRIPTS_DIR)/macro_place_util.tcl
162+
163+
write_db $::env(RESULTS_DIR)/2_2_floorplan_macro.odb
164+
write_macro_placement $::env(RESULTS_DIR)/2_2_floorplan_macro.tcl
165+
166+
167+
# Tapcell insertion
168+
if { [env_var_exists_and_non_empty TAPCELL_TCL] } {
169+
source $::env(TAPCELL_TCL)
170+
} else {
171+
cut_rows
172+
}
173+
174+
write_db $::env(RESULTS_DIR)/2_3_floorplan_tapcell.odb
175+
176+
# PDN
177+
source $::env(PDN_TCL)
178+
pdngen
179+
180+
source_env_var_if_exists POST_PDN_TCL
181+
182+
# Check all supply nets
183+
set block [ord::get_db_block]
184+
foreach net [$block getNets] {
185+
set type [$net getSigType]
186+
if { $type == "POWER" || $type == "GROUND" } {
187+
# Temporarily disable due to CI issues
188+
# puts "Check supply: [$net getName]"
189+
# check_power_grid -net [$net getName]
190+
}
191+
}
192+
193+
write_db $::env(RESULTS_DIR)/2_4_floorplan_pdn.odb
194+
195+
# Global placement skipping IOs
196+
if { [env_var_exists_and_non_empty FLOORPLAN_DEF] } {
197+
puts "FLOORPLAN_DEF is set. Skipping global placement without IOs"
198+
} elseif { [all_pins_placed] } {
199+
puts "All pins are placed. Skipping global placement without IOs"
200+
} else {
201+
log_cmd global_placement -skip_io -density [place_density_with_lb_addon] \
202+
-pad_left $::env(CELL_PAD_IN_SITES_GLOBAL_PLACEMENT) \
203+
-pad_right $::env(CELL_PAD_IN_SITES_GLOBAL_PLACEMENT) \
204+
{*}[env_var_or_empty GLOBAL_PLACEMENT_ARGS]
205+
}
206+
207+
write_db $::env(RESULTS_DIR)/3_1_place_gp_skip_io.odb
208+
209+
# IO placement
210+
if {
211+
![env_var_exists_and_non_empty FLOORPLAN_DEF] &&
212+
![env_var_exists_and_non_empty FOOTPRINT] &&
213+
![env_var_exists_and_non_empty FOOTPRINT_TCL]
214+
} {
215+
# load_design 3_1_place_gp_skip_io.odb 2_floorplan.sdc
216+
log_cmd place_pins \
217+
-hor_layers $::env(IO_PLACER_H) \
218+
-ver_layers $::env(IO_PLACER_V) \
219+
{*}[env_var_or_empty PLACE_PINS_ARGS]
220+
write_db $::env(RESULTS_DIR)/3_2_place_iop.odb
221+
write_pin_placement $::env(RESULTS_DIR)/3_2_place_iop.tcl
222+
} else {
223+
log_cmd exec cp $::env(RESULTS_DIR)/3_1_place_gp_skip_io.odb $::env(RESULTS_DIR)/3_2_place_iop.odb
224+
}
225+
226+
# Global placement
227+
utl::set_metrics_stage "globalplace__{}"
228+
set_dont_use $::env(DONT_USE_CELLS)
229+
230+
if { $::env(GPL_TIMING_DRIVEN) } {
231+
remove_buffers
232+
}
233+
234+
# Do not buffer chip-level designs
235+
# by default, IO ports will be buffered
236+
# to not buffer IO ports, set environment variable
237+
# DONT_BUFFER_PORT = 1
238+
if { ![env_var_exists_and_non_empty FOOTPRINT] } {
239+
if { ![env_var_equals DONT_BUFFER_PORTS 1] } {
240+
puts "Perform port buffering..."
241+
buffer_ports
242+
}
243+
}
244+
245+
set global_placement_args {}
246+
247+
# Parameters for routability mode in global placement
248+
append_env_var global_placement_args GPL_ROUTABILITY_DRIVEN -routability_driven 0
249+
250+
# Parameters for timing driven mode in global placement
251+
if { $::env(GPL_TIMING_DRIVEN) } {
252+
lappend global_placement_args {-timing_driven}
253+
if { [info exists ::env(GPL_KEEP_OVERFLOW)] } {
254+
lappend global_placement_args -keep_resize_below_overflow $::env(GPL_KEEP_OVERFLOW)
255+
}
256+
}
257+
258+
proc do_placement { global_placement_args } {
259+
set all_args [concat [list -density [place_density_with_lb_addon] \
260+
-pad_left $::env(CELL_PAD_IN_SITES_GLOBAL_PLACEMENT) \
261+
-pad_right $::env(CELL_PAD_IN_SITES_GLOBAL_PLACEMENT)] \
262+
$global_placement_args]
263+
264+
lappend all_args {*}[env_var_or_empty GLOBAL_PLACEMENT_ARGS]
265+
266+
log_cmd global_placement {*}$all_args
267+
}
268+
269+
set result [catch { do_placement $global_placement_args } errMsg]
270+
if { $result != 0 } {
271+
write_db $::env(RESULTS_DIR)/3_3_place_gp-failed.odb
272+
error $errMsg
273+
}
274+
275+
estimate_parasitics -placement
276+
277+
if { [env_var_equals CLUSTER_FLOPS 1] } {
278+
cluster_flops
279+
estimate_parasitics -placement
280+
}
281+
282+
report_metrics 3 "global place" false false
283+
284+
write_db $::env(RESULTS_DIR)/3_3_place_gp.odb
285+
286+
# Resizing
287+
utl::set_metrics_stage "placeopt__{}"
288+
estimate_parasitics -placement
289+
290+
set instance_count_before [sta::network_leaf_instance_count]
291+
set pin_count_before [sta::network_leaf_pin_count]
292+
293+
set_dont_use $::env(DONT_USE_CELLS)
294+
295+
if { [env_var_exists_and_non_empty EARLY_SIZING_CAP_RATIO] } {
296+
log_cmd set_opt_config -set_early_sizing_cap_ratio $env(EARLY_SIZING_CAP_RATIO)
297+
}
298+
299+
if { [env_var_exists_and_non_empty SWAP_ARITH_OPERATORS] } {
300+
replace_arith_modules
301+
}
302+
303+
repair_design_helper
304+
305+
# hold violations are not repaired until after CTS
306+
307+
# post report
308+
309+
puts "Floating nets: "
310+
report_floating_nets
311+
312+
report_metrics 3 "resizer" true false
313+
314+
puts "Instance count before $instance_count_before, after [sta::network_leaf_instance_count]"
315+
puts "Pin count before $pin_count_before, after [sta::network_leaf_pin_count]"
316+
317+
write_db $::env(RESULTS_DIR)/3_4_place_resized.odb
318+
319+
# Detailed placement
320+
utl::set_metrics_stage "detailedplace__{}"
321+
322+
source $::env(PLATFORM_DIR)/setRC.tcl
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
358+
359+
# 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+
log_cmd repair_timing -repair_tns $::env(TNS_END_PERCENT)
369+
370+
# Legalize placement after timing repair
371+
detailed_placement
372+
373+
puts "Estimate parasitics"
374+
estimate_parasitics -placement
375+
report_metrics 3 "place repair timing" true false
376+
377+
write_db $::env(RESULTS_DIR)/3_6_place_repair_timing.odb

0 commit comments

Comments
 (0)