mirror of
https://github.com/The-OpenROAD-Project/OpenLane.git
synced 2026-05-29 00:23:55 +08:00
Integrate back OpenROAD STA (#1784)
+ add STA_MULTICORNER_READ_LIBS to pick between reading liberties vs reading verilog + spefs - undocumented + add reading CURRENT_SPEF in function `read` + add ability to not read EXTRA_LIBS in function `read_libs` + sta/multi_corner.tcl should now work with openroad + add -estimate_global and -estimate_placement to `run_sta` and used it whenever applicable: See https://github.com/The-OpenROAD-Project/OpenROAD/discussions/3287 + add -tool to run_sta to switch between openroad and opensta + use -pre_cts whenever applicable ~ fix a bug where EXTRA_SPEFS aren't properly loading. Fix is accomplished by passing PROCESS_CORNER to multi_corner.tcl script. + add verfied scl to verilator verified list. sky130_fd_sc_hs had verilator errors in its verilog models ~ fix wrong usage of FP_IO_HLENGTH. should be FP_IO_VLENGTH ~ restore `report_design_area` in STA. + add `report_design_area` in resizer scripts to see the impact of resizer, in terms of utilization
This commit is contained in:
@@ -30,6 +30,7 @@ set ::env(RSZ_USE_OLD_REMOVER) 0
|
||||
## STA
|
||||
set ::env(STA_REPORT_POWER) {1}
|
||||
set ::env(STA_WRITE_LIB) {1}
|
||||
set ::env(STA_MULTICORNER_READ_LIBS) 0
|
||||
|
||||
## Routing
|
||||
set ::env(RUN_DRT) 1
|
||||
|
||||
@@ -67,7 +67,7 @@ proc read_netlist {args} {
|
||||
proc read_libs {args} {
|
||||
sta::parse_key_args "read_libs" args \
|
||||
keys {-typical -slowest -fastest}\
|
||||
flags {-multi_corner_libs}
|
||||
flags {-no_extra}
|
||||
|
||||
if { ![info exists keys(-typical)] } {
|
||||
puts "read_libs -typical is required"
|
||||
@@ -86,9 +86,11 @@ proc read_libs {args} {
|
||||
foreach corner_name [array name corner] {
|
||||
puts "read_liberty -corner $corner_name $corner($corner_name)"
|
||||
read_liberty -corner $corner_name $corner($corner_name)
|
||||
if { [info exists ::env(EXTRA_LIBS) ] } {
|
||||
foreach lib $::env(EXTRA_LIBS) {
|
||||
read_liberty -corner $corner_name $lib
|
||||
if { [info exists flags(-no_extra)] } {
|
||||
if { [info exists ::env(EXTRA_LIBS) ] } {
|
||||
foreach lib $::env(EXTRA_LIBS) {
|
||||
read_liberty -corner $corner_name $lib
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -136,6 +138,12 @@ proc read {args} {
|
||||
exit 1
|
||||
}
|
||||
}
|
||||
if { [info exists ::env(CURRENT_SPEF)] } {
|
||||
if {[catch {read_spef $::env(CURRENT_SPEF)} errmsg]} {
|
||||
puts stderr $errmsg
|
||||
exit 1
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
proc write {args} {
|
||||
@@ -230,8 +238,6 @@ proc read_spefs {} {
|
||||
if { [info exists ::env(CURRENT_SPEF)] } {
|
||||
foreach corner $corners {
|
||||
read_spef -corner [$corner name] $::env(CURRENT_SPEF)
|
||||
read_spef -corner [$corner name] $::env(CURRENT_SPEF)
|
||||
read_spef -corner [$corner name] $::env(CURRENT_SPEF)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -243,9 +249,13 @@ proc read_spefs {} {
|
||||
puts "Matched [get_property $cell name] with $module_name"
|
||||
set matched 1
|
||||
foreach corner $corners {
|
||||
read_spef -path [get_property $cell name] -corner [$corner name] $spef_file_min
|
||||
read_spef -path [get_property $cell name] -corner [$corner name] $spef_file_nom
|
||||
read_spef -path [get_property $cell name] -corner [$corner name] $spef_file_max
|
||||
if { $::env(PROCESS_CORNER) eq "nom" } {
|
||||
read_spef -path [get_property $cell name] -corner [$corner name] $spef_file_nom
|
||||
} elseif { $::env(PROCESS_CORNER) eq "min" } {
|
||||
read_spef -path [get_property $cell name] -corner [$corner name] $spef_file_min
|
||||
} elseif { $::env(PROCESS_CORNER) eq "max" } {
|
||||
read_spef -path [get_property $cell name] -corner [$corner name] $spef_file_max
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -18,7 +18,7 @@ if { [info exists ::env(CONTEXTUAL_IO_FLAG)] } {
|
||||
read_lef $::env(placement_tmpfiles)/top_level.lef
|
||||
}
|
||||
|
||||
if {$::env(FP_IO_HLENGTH) != "" && $::env(FP_IO_HLENGTH) != ""} {
|
||||
if {$::env(FP_IO_HLENGTH) != "" && $::env(FP_IO_VLENGTH) != ""} {
|
||||
set_pin_length -hor_length $::env(FP_IO_HLENGTH) \
|
||||
-ver_length $::env(FP_IO_VLENGTH)
|
||||
}
|
||||
|
||||
@@ -76,3 +76,10 @@ write
|
||||
|
||||
# Run post design optimizations STA
|
||||
estimate_parasitics -placement
|
||||
|
||||
puts "area_report"
|
||||
puts "\n==========================================================================="
|
||||
puts "report_design_area"
|
||||
puts "============================================================================"
|
||||
report_design_area
|
||||
puts "area_report_end"
|
||||
|
||||
@@ -74,3 +74,10 @@ write
|
||||
|
||||
# Run post timing optimizations STA
|
||||
estimate_parasitics -global_routing
|
||||
|
||||
puts "area_report"
|
||||
puts "\n==========================================================================="
|
||||
puts "report_design_area"
|
||||
puts "============================================================================"
|
||||
report_design_area
|
||||
puts "area_report_end"
|
||||
|
||||
@@ -78,3 +78,10 @@ write
|
||||
|
||||
# Run post timing optimizations STA
|
||||
estimate_parasitics -global_routing
|
||||
|
||||
puts "area_report"
|
||||
puts "\n==========================================================================="
|
||||
puts "report_design_area"
|
||||
puts "============================================================================"
|
||||
report_design_area
|
||||
puts "area_report_end"
|
||||
|
||||
@@ -65,3 +65,10 @@ write
|
||||
|
||||
# Run post timing optimizations STA
|
||||
estimate_parasitics -placement
|
||||
|
||||
puts "area_report"
|
||||
puts "\n==========================================================================="
|
||||
puts "report_design_area"
|
||||
puts "============================================================================"
|
||||
report_design_area
|
||||
puts "area_report_end"
|
||||
|
||||
@@ -19,19 +19,43 @@ if { $::env(STA_MULTICORNER) } {
|
||||
lappend arg_list -fastest $::env(LIB_FASTEST)
|
||||
lappend arg_list -slowest $::env(LIB_SLOWEST)
|
||||
}
|
||||
read_libs {*}$arg_list
|
||||
|
||||
read_netlist -all
|
||||
read_spefs
|
||||
if { [file tail [info nameofexecutable]] == "sta" } {
|
||||
# OpenSTA
|
||||
if { $::env(STA_MULTICORNER_READ_LIBS) } {
|
||||
read_libs {*}$arg_list
|
||||
read_netlist ;# also reads sdc
|
||||
} else {
|
||||
read_libs -no_extra {*}$arg_list
|
||||
read_netlist -all ;# also reads sdc
|
||||
read_spefs
|
||||
}
|
||||
} else {
|
||||
# OpenROAD
|
||||
read ;# also reads sdc, spef and libs
|
||||
}
|
||||
|
||||
if { [info exists ::env(DEBUG)] && $::env(DEBUG) } {
|
||||
puts "sta_bin [file tail [info nameofexecutable]]"
|
||||
}
|
||||
|
||||
if { [info exists ::env(ESTIMATE_PARASITICS)]} {
|
||||
source $::env(SCRIPTS_DIR)/openroad/common/set_rc.tcl
|
||||
if { [info exists ::env(DEBUG)] && $::env(DEBUG) } {
|
||||
puts "estimating parasitics $::env(ESTIMATE_PARASITICS)"
|
||||
}
|
||||
estimate_parasitics {*}$::env(ESTIMATE_PARASITICS)
|
||||
}
|
||||
|
||||
if { $::env(STA_PRE_CTS) } {
|
||||
if { [info exists ::env(DEBUG)] && $::env(DEBUG) } {
|
||||
puts "sta pre cts"
|
||||
}
|
||||
unset_propagated_clock [all_clocks]
|
||||
}
|
||||
|
||||
set_cmd_units -time ns -capacitance pF -current mA -voltage V -resistance kOhm -distance um
|
||||
|
||||
if { $::env(STA_PRE_CTS) == 1 } {
|
||||
unset_propagated_clock [all_clocks]
|
||||
} else {
|
||||
set_propagated_clock [all_clocks]
|
||||
}
|
||||
|
||||
puts "min_report"
|
||||
puts "\n==========================================================================="
|
||||
@@ -149,5 +173,13 @@ puts "==========================================================================
|
||||
report_worst_slack -min
|
||||
puts "summary_report_end"
|
||||
|
||||
if { [file tail [info nameofexecutable]] == "openroad" } {
|
||||
puts "area_report"
|
||||
puts "\n==========================================================================="
|
||||
puts "report_design_area"
|
||||
puts "============================================================================"
|
||||
report_design_area
|
||||
puts "area_report_end"
|
||||
}
|
||||
|
||||
write -no_global_connect
|
||||
|
||||
@@ -48,7 +48,7 @@ proc run_cts {args} {
|
||||
scrot_klayout -layout $::env(CURRENT_DEF) -log $::env(cts_logs)/screenshot.log
|
||||
|
||||
if { [info exists ::env(CTS_REPORT_TIMING)] && $::env(CTS_REPORT_TIMING) } {
|
||||
run_sta -no_save $::env(cts_results) -log $::env(cts_logs)/cts_sta.log
|
||||
run_sta -estimate_placement -no_save $::env(cts_results) -log $::env(cts_logs)/cts_sta.log
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -32,7 +32,7 @@ proc global_placement_or {args} {
|
||||
TIMER::timer_stop
|
||||
exec echo "[TIMER::get_runtime]" | python3 $::env(SCRIPTS_DIR)/write_runtime.py "global placement - openroad"
|
||||
|
||||
run_sta -no_save -log $::env(placement_logs)/gpl_sta.log
|
||||
run_sta -pre_cts -estimate_placement -no_save -log $::env(placement_logs)/gpl_sta.log
|
||||
}
|
||||
|
||||
proc global_placement {args} {
|
||||
@@ -182,7 +182,7 @@ proc run_placement {args} {
|
||||
detailed_placement_or
|
||||
|
||||
scrot_klayout -layout $::env(CURRENT_DEF) -log $::env(placement_logs)/screenshot.log
|
||||
run_sta -no_save -log $::env(placement_logs)/dpl_sta.log
|
||||
run_sta -pre_cts -estimate_placement -no_save -log $::env(placement_logs)/dpl_sta.log
|
||||
}
|
||||
|
||||
proc run_resizer_design {args} {
|
||||
|
||||
@@ -451,7 +451,7 @@ proc run_resizer_design_routing {args} {
|
||||
|
||||
TIMER::timer_stop
|
||||
exec echo "[TIMER::get_runtime]" | python3 $::env(SCRIPTS_DIR)/write_runtime.py "resizer design optimizations - openroad"
|
||||
run_sta -no_save -log $::env(routing_logs)/rsz_design_sta.log
|
||||
run_sta -estimate_global -no_save -log $::env(routing_logs)/rsz_design_sta.log
|
||||
} else {
|
||||
puts_info "Skipping Global Routing Resizer Design Optimizations."
|
||||
}
|
||||
@@ -470,7 +470,7 @@ proc run_resizer_timing_routing {args} {
|
||||
|
||||
TIMER::timer_stop
|
||||
exec echo "[TIMER::get_runtime]" | python3 $::env(SCRIPTS_DIR)/write_runtime.py "resizer timing optimizations - openroad"
|
||||
run_sta -no_save -log $::env(routing_logs)/rsz_timing_sta.log
|
||||
run_sta -estimate_global -no_save -log $::env(routing_logs)/rsz_timing_sta.log
|
||||
} else {
|
||||
puts_info "Skipping Global Routing Resizer Timing Optimizations."
|
||||
}
|
||||
|
||||
@@ -22,6 +22,9 @@ proc run_sta {args} {
|
||||
{-log required}
|
||||
{-process_corner optional}
|
||||
{-save_to optional}
|
||||
{-tool optional}
|
||||
{-estimate_global optional}
|
||||
{-estimate_placement optional}
|
||||
}
|
||||
set flags {
|
||||
-multi_corner
|
||||
@@ -33,6 +36,7 @@ proc run_sta {args} {
|
||||
parse_key_args "run_sta" args arg_values $options flags_map $flags
|
||||
|
||||
set_if_unset arg_values(-save_to) "$::env(signoff_results)"
|
||||
set_if_unset arg_values(-tool) "openroad"
|
||||
|
||||
set multi_corner [info exists flags_map(-multi_corner)]
|
||||
set pre_cts [info exists flags_map(-pre_cts)]
|
||||
@@ -44,9 +48,11 @@ proc run_sta {args} {
|
||||
set corner_prefix "Multi-Corner"
|
||||
}
|
||||
|
||||
set ::env(PROCESS_CORNER) nom
|
||||
set process_corner_postfix ""
|
||||
if { [info exists arg_values(-process_corner)]} {
|
||||
set process_corner_postfix " at the $arg_values(-process_corner) process corner"
|
||||
set ::env(PROCESS_CORNER) $arg_values(-process_corner)
|
||||
}
|
||||
|
||||
increment_index
|
||||
@@ -68,6 +74,12 @@ proc run_sta {args} {
|
||||
if { [info exists flags_map(-netlist_in)] } {
|
||||
lappend arg_list -netlist_in
|
||||
}
|
||||
if { [info exists arg_values(-estimate_global)] && $::env(GRT_ESTIMATE_PARASITICS) } {
|
||||
set ::env(ESTIMATE_PARASITICS) -global
|
||||
}
|
||||
if { [info exists arg_values(-estimate_placement)] && $::env(PL_ESTIMATE_PARASITICS) } {
|
||||
set ::env(ESTIMATE_PARASITICS) -placement
|
||||
}
|
||||
|
||||
proc blackbox_modules_check {file_path} {
|
||||
set fp [open $file_path r]
|
||||
@@ -83,7 +95,7 @@ proc run_sta {args} {
|
||||
set ::env(STA_MULTICORNER) 0
|
||||
if { $multi_corner == 1 } {
|
||||
set ::env(STA_MULTICORNER) 1
|
||||
run_sta_script $::env(SCRIPTS_DIR)/openroad/sta/multi_corner.tcl \
|
||||
run_$arg_values(-tool)_script $::env(SCRIPTS_DIR)/openroad/sta/multi_corner.tcl \
|
||||
-no_update_current\
|
||||
{*}$arg_list
|
||||
|
||||
@@ -92,12 +104,13 @@ proc run_sta {args} {
|
||||
}
|
||||
unset ::env(SAVE_SDF)
|
||||
} else {
|
||||
run_sta_script $::env(SCRIPTS_DIR)/openroad/sta/multi_corner.tcl {*}$arg_list
|
||||
run_$arg_values(-tool)_script $::env(SCRIPTS_DIR)/openroad/sta/multi_corner.tcl {*}$arg_list
|
||||
if { [info exists flags_map(-blackbox_check)] } {
|
||||
blackbox_modules_check $log
|
||||
}
|
||||
}
|
||||
unset ::env(STA_MULTICORNER)
|
||||
unset -nocomplain ::env(ESTIMATE_PARASITICS)
|
||||
TIMER::timer_stop
|
||||
exec echo "[TIMER::get_runtime]" | python3 $::env(SCRIPTS_DIR)/write_runtime.py "sta - openroad"
|
||||
}
|
||||
@@ -153,14 +166,16 @@ proc run_parasitics_sta {args} {
|
||||
-log $log_name\
|
||||
-process_corner $process_corner\
|
||||
-multi_corner \
|
||||
-save_to $directory
|
||||
-save_to $directory \
|
||||
-tool sta
|
||||
|
||||
if { $process_corner == "nom" } {
|
||||
run_sta\
|
||||
-log $::env(signoff_logs)/rcx_sta.log\
|
||||
-process_corner $process_corner\
|
||||
-save_to $directory \
|
||||
-blackbox_check
|
||||
-blackbox_check \
|
||||
-tool sta
|
||||
|
||||
set ::env(LAST_TIMING_REPORT_TAG) [index_file $::env(signoff_reports)/rcx_sta]
|
||||
}
|
||||
|
||||
@@ -149,7 +149,8 @@ proc run_synthesis {args} {
|
||||
-log $::env(synthesis_logs)/sta.log \
|
||||
-netlist_in \
|
||||
-pre_cts \
|
||||
-save_to $::env(synthesis_results)
|
||||
-save_to $::env(synthesis_results) \
|
||||
-tool sta
|
||||
|
||||
set ::env(LAST_TIMING_REPORT_TAG) [index_file $::env(synthesis_reports)/syn_sta]
|
||||
|
||||
@@ -244,9 +245,11 @@ proc logic_equiv_check {args} {
|
||||
|
||||
proc run_verilator {} {
|
||||
set verilator_verified_pdks "sky130A sky130B"
|
||||
set verilator_verified_scl "sky130_fd_sc_hd"
|
||||
set includes ""
|
||||
if { [string match *$::env(PDK)* $verilator_verified_pdks] == 0 } {
|
||||
puts_warn "PDK '$::env(PDK)' will generate errors with instantiated stdcells in the design."
|
||||
if { [string match *$::env(PDK)* $verilator_verified_pdks] == 0 || \
|
||||
[string match *$::env(STD_CELL_LIBRARY)* $verilator_verified_scl] == 0} {
|
||||
puts_warn "PDK '$::env(PDK)', SCL '$::env(STD_CELL_LIBRARY)' will generate errors with instantiated stdcells in the design."
|
||||
puts_warn "Either disable QUIT_ON_VERILATOR_ERRORS or remove the instantiated cells."
|
||||
} else {
|
||||
set pdk_verilog_models [glob $::env(PDK_ROOT)/$::env(PDK)/libs.ref/$::env(STD_CELL_LIBRARY_OPT)/verilog/*.v]
|
||||
|
||||
Reference in New Issue
Block a user