mirror of
https://github.com/The-OpenROAD-Project/OpenROAD.git
synced 2026-06-02 01:08:34 +08:00
300 lines
9.4 KiB
Tcl
300 lines
9.4 KiB
Tcl
## SPDX-License-Identifier: BSD-3-Clause
|
|
## Copyright (c) 2019-2026, The OpenROAD Authors
|
|
|
|
# Assumes flow_helpers.tcl has been read.
|
|
read_libraries
|
|
read_verilog $synth_verilog
|
|
link_design $top_module
|
|
read_sdc $sdc_file
|
|
|
|
set_thread_count [cpu_count]
|
|
# Temporarily disable sta's threading due to random failures
|
|
sta::set_thread_count 1
|
|
|
|
utl::metric "IFP::ord_version" [ord::openroad_git_describe]
|
|
# Note that sta::network_instance_count is not valid after tapcells are added.
|
|
utl::metric "IFP::instance_count" [sta::network_instance_count]
|
|
|
|
initialize_floorplan -site $site \
|
|
-die_area $die_area \
|
|
-core_area $core_area
|
|
|
|
source $tracks_file
|
|
|
|
# remove buffers inserted by synthesis
|
|
remove_buffers
|
|
|
|
if { $pre_placed_macros_file != "" } {
|
|
source $pre_placed_macros_file
|
|
}
|
|
|
|
################################################################
|
|
# Macro Placement
|
|
if { [have_macros] } {
|
|
lassign $macro_place_halo halo_x halo_y
|
|
set report_dir [make_result_file ${design}_${platform}_rtlmp]
|
|
rtl_macro_placer -halo_width $halo_x -halo_height $halo_y \
|
|
-report_directory $report_dir
|
|
}
|
|
|
|
################################################################
|
|
# Tapcell insertion
|
|
eval tapcell $tapcell_args ;# tclint-disable command-args
|
|
|
|
################################################################
|
|
# Power distribution network insertion
|
|
source $pdn_cfg
|
|
pdngen
|
|
|
|
################################################################
|
|
# Global placement
|
|
|
|
foreach layer_adjustment $global_routing_layer_adjustments {
|
|
lassign $layer_adjustment layer adjustment
|
|
set_global_routing_layer_adjustment $layer $adjustment
|
|
}
|
|
set_routing_layers -signal $global_routing_layers \
|
|
-clock $global_routing_clock_layers
|
|
set_macro_extension 2
|
|
|
|
# Global placement skip IOs
|
|
global_placement -density $global_place_density \
|
|
-pad_left $global_place_pad -pad_right $global_place_pad -skip_io
|
|
|
|
# IO Placement
|
|
place_pins -hor_layers $io_placer_hor_layer -ver_layers $io_placer_ver_layer
|
|
|
|
# Global placement with placed IOs and routability-driven
|
|
global_placement -routability_driven -density $global_place_density \
|
|
-pad_left $global_place_pad -pad_right $global_place_pad
|
|
|
|
# checkpoint
|
|
set global_place_db [make_result_file ${design}_${platform}_global_place.db]
|
|
write_db $global_place_db
|
|
|
|
################################################################
|
|
# Repair max slew/cap/fanout violations and normalize slews
|
|
source $layer_rc_file
|
|
set_wire_rc -signal -layer $wire_rc_layer
|
|
set_wire_rc -clock -layer $wire_rc_layer_clk
|
|
set_dont_use $dont_use
|
|
|
|
estimate_parasitics -placement
|
|
|
|
repair_design -slew_margin $slew_margin -cap_margin $cap_margin
|
|
|
|
repair_tie_fanout -separation $tie_separation $tielo_port
|
|
repair_tie_fanout -separation $tie_separation $tiehi_port
|
|
|
|
set_placement_padding -global -left $detail_place_pad -right $detail_place_pad
|
|
detailed_placement
|
|
|
|
# post resize timing report (ideal clocks)
|
|
report_worst_slack -min -digits 3
|
|
report_worst_slack -max -digits 3
|
|
report_tns -digits 3
|
|
# Check slew repair
|
|
report_check_types -max_slew -max_capacitance -max_fanout -violators
|
|
|
|
utl::metric "RSZ::repair_design_buffer_count" [rsz::repair_design_buffer_count]
|
|
utl::metric "RSZ::max_slew_slack" [expr [sta::max_slew_check_slack_limit] * 100]
|
|
utl::metric "RSZ::max_fanout_slack" [expr [sta::max_fanout_check_slack_limit] * 100]
|
|
utl::metric "RSZ::max_capacitance_slack" [expr [sta::max_capacitance_check_slack_limit] * 100]
|
|
|
|
################################################################
|
|
# Clock Tree Synthesis
|
|
|
|
# Clone clock tree inverters next to register loads
|
|
# so cts does not try to buffer the inverted clocks.
|
|
repair_clock_inverters
|
|
|
|
clock_tree_synthesis -root_buf $cts_buffer -buf_list $cts_buffer \
|
|
-sink_clustering_enable \
|
|
-sink_clustering_max_diameter $cts_cluster_diameter
|
|
|
|
# CTS leaves a long wire from the pad to the clock tree root.
|
|
repair_clock_nets
|
|
|
|
# place clock buffers
|
|
detailed_placement
|
|
|
|
# checkpoint
|
|
set cts_db [make_result_file ${design}_${platform}_cts.db]
|
|
write_db $cts_db
|
|
|
|
################################################################
|
|
# Setup/hold timing repair
|
|
|
|
set_propagated_clock [all_clocks]
|
|
|
|
# Global routing is fast enough for the flow regressions.
|
|
# It is NOT FAST ENOUGH FOR PRODUCTION USE.
|
|
set repair_timing_use_grt_parasitics 0
|
|
if { $repair_timing_use_grt_parasitics } {
|
|
# Global route for parasitics - no guide file requied
|
|
global_route -congestion_iterations 100
|
|
estimate_parasitics -global_routing
|
|
} else {
|
|
estimate_parasitics -placement
|
|
}
|
|
|
|
repair_timing -skip_gate_cloning
|
|
|
|
# Post timing repair.
|
|
report_worst_slack -min -digits 3
|
|
report_worst_slack -max -digits 3
|
|
report_tns -digits 3
|
|
report_check_types -max_slew -max_capacitance -max_fanout -violators -digits 3
|
|
|
|
utl::metric "RSZ::worst_slack_min" [sta::worst_slack -min]
|
|
utl::metric "RSZ::worst_slack_max" [sta::worst_slack -max]
|
|
utl::metric "RSZ::tns_max" [sta::total_negative_slack -max]
|
|
utl::metric "RSZ::hold_buffer_count" [rsz::hold_buffer_count]
|
|
|
|
################################################################
|
|
# Detailed Placement
|
|
|
|
detailed_placement
|
|
|
|
# Capture utilization before fillers make it 100%
|
|
utl::metric "DPL::utilization" [format %.1f [expr [rsz::utilization] * 100]]
|
|
utl::metric "DPL::design_area" [sta::format_area [rsz::design_area] 0]
|
|
|
|
# checkpoint
|
|
set dpl_db [make_result_file ${design}_${platform}_dpl.db]
|
|
write_db $dpl_db
|
|
|
|
set verilog_file [make_result_file ${design}_${platform}.v]
|
|
write_verilog $verilog_file
|
|
|
|
################################################################
|
|
# Global routing
|
|
|
|
pin_access
|
|
|
|
set route_guide [make_result_file ${design}_${platform}.route_guide]
|
|
global_route -guide_file $route_guide \
|
|
-congestion_iterations 100 -verbose
|
|
|
|
set verilog_file [make_result_file ${design}_${platform}.v]
|
|
write_verilog -remove_cells $filler_cells $verilog_file
|
|
|
|
################################################################
|
|
# Repair antennas post-GRT
|
|
|
|
utl::set_metrics_stage "grt__{}"
|
|
repair_antennas -iterations 5
|
|
|
|
check_antennas
|
|
utl::clear_metrics_stage
|
|
utl::metric "GRT::ANT::errors" [ant::antenna_violation_count]
|
|
|
|
################################################################
|
|
# Detailed routing
|
|
|
|
# Run pin access again after inserting diodes and moving cells
|
|
# pin_access
|
|
|
|
detailed_route -output_drc [make_result_file "${design}_${platform}_route_drc.rpt"] \
|
|
-output_maze [make_result_file "${design}_${platform}_maze.log"] \
|
|
-no_pin_access \
|
|
-verbose 0
|
|
|
|
write_guides [make_result_file "${design}_${platform}_output_guide.mod"]
|
|
set drv_count [detailed_route_num_drvs]
|
|
utl::metric "DRT::drv" $drv_count
|
|
|
|
set routed_db [make_result_file ${design}_${platform}_route.db]
|
|
write_db $routed_db
|
|
|
|
set routed_def [make_result_file ${design}_${platform}_route.def]
|
|
write_def $routed_def
|
|
|
|
################################################################
|
|
# Repair antennas post-DRT
|
|
|
|
set repair_antennas_iters 0
|
|
utl::set_metrics_stage "drt__repair_antennas__pre_repair__{}"
|
|
while { [check_antennas] && $repair_antennas_iters < 5 } {
|
|
utl::set_metrics_stage "drt__repair_antennas__iter_${repair_antennas_iters}__{}"
|
|
|
|
repair_antennas
|
|
|
|
detailed_route -output_drc [make_result_file "${design}_${platform}_ant_fix_drc.rpt"] \
|
|
-output_maze [make_result_file "${design}_${platform}_ant_fix_maze.log"] \
|
|
-no_pin_access \
|
|
-verbose 0
|
|
|
|
incr repair_antennas_iters
|
|
}
|
|
|
|
utl::set_metrics_stage "drt__{}"
|
|
check_antennas
|
|
|
|
utl::clear_metrics_stage
|
|
utl::metric "DRT::ANT::errors" [ant::antenna_violation_count]
|
|
|
|
if { ![design_is_routed] } {
|
|
error "Design has unrouted nets."
|
|
}
|
|
|
|
set repair_antennas_db [make_result_file ${design}_${platform}_repaired_route.odb]
|
|
write_db $repair_antennas_db
|
|
|
|
################################################################
|
|
# Filler placement
|
|
|
|
filler_placement $filler_cells
|
|
check_placement -verbose
|
|
|
|
# checkpoint
|
|
set fill_db [make_result_file ${design}_${platform}_fill.db]
|
|
write_db $fill_db
|
|
|
|
################################################################
|
|
# Extraction
|
|
|
|
if { $rcx_rules_file != "" } {
|
|
define_process_corner -ext_model_index 0 X
|
|
extract_parasitics -ext_model_file $rcx_rules_file
|
|
|
|
set spef_file [make_result_file ${design}_${platform}.spef]
|
|
write_spef $spef_file
|
|
|
|
read_spef $spef_file
|
|
} else {
|
|
# Use global routing based parasitics inlieu of rc extraction
|
|
estimate_parasitics -global_routing
|
|
}
|
|
|
|
################################################################
|
|
# Final Report
|
|
|
|
report_checks -path_delay min_max -format full_clock_expanded \
|
|
-fields {input_pin slew capacitance} -digits 3
|
|
report_worst_slack -min -digits 3
|
|
report_worst_slack -max -digits 3
|
|
report_tns -digits 3
|
|
report_check_types -max_slew -max_capacitance -max_fanout -violators -digits 3
|
|
report_clock_skew -digits 3
|
|
report_power -corner $power_corner
|
|
|
|
report_floating_nets -verbose
|
|
report_design_area
|
|
|
|
utl::metric "DRT::worst_slack_min" [sta::worst_slack -min]
|
|
utl::metric "DRT::worst_slack_max" [sta::worst_slack -max]
|
|
utl::metric "DRT::tns_max" [sta::total_negative_slack -max]
|
|
utl::metric "DRT::clock_skew" [expr abs([sta::worst_clock_skew -setup])]
|
|
|
|
# slew/cap/fanout slack/limit
|
|
utl::metric "DRT::max_slew_slack" [expr [sta::max_slew_check_slack_limit] * 100]
|
|
utl::metric "DRT::max_fanout_slack" [expr [sta::max_fanout_check_slack_limit] * 100]
|
|
utl::metric "DRT::max_capacitance_slack" [expr [sta::max_capacitance_check_slack_limit] * 100]
|
|
# report clock period as a metric for updating limits
|
|
utl::metric "DRT::clock_period" [get_property [lindex [all_clocks] 0] period]
|
|
|
|
# not really useful without pad locations
|
|
#set_pdnsim_net_voltage -net $vdd_net_name -voltage $vdd_voltage
|
|
#analyze_power_grid -net $vdd_net_name
|