Skip to content

Commit

Permalink
SDC Behavior Overhaul (The-OpenROAD-Project#1944)
Browse files Browse the repository at this point in the history
+ Add PNR_SDC_FILE
+ Warn when (PNR|SIGNOFF)_SDC_FILE are not overwritten by the user.
+ Add SDC_IN and DEFAULT_SDC_FILE to ignore list in CI
+ Add per corner max slew/fanout/cap count to sta report
+ Add per corner worst hold and setup value to sta report 
~ Rename RCX_SDC_FILE to SIGNOFF_SDC_FILE.
~ Always use PNR_SDC_FILE instead of CURRENT_SDC except during signoff stage, where SIGNOFF_SDC_FILE is used instead
~ Enable DIODE_ON_PORTS and RUN_HEURISTIC_DIODE_INSERTION for APU which fails after SDC updates.
~ Adjust timing checkers according to the new reported values
  • Loading branch information
kareefardi authored Sep 5, 2023
1 parent 2264b12 commit 5fb033c
Show file tree
Hide file tree
Showing 11 changed files with 80 additions and 50 deletions.
2 changes: 2 additions & 0 deletions .github/scripts/variables_documentation.py
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@
DEBUG
DESIGN_CONFIG
DESIGN_DIR
DEFAULT_SDC_FILE
ESTIMATE_PARASITICS
EXIT_ON_ERROR
EXT_NETLIST
Expand Down Expand Up @@ -89,6 +90,7 @@
SAVE_SPEF
SCRIPTS_DIR
SCRIPT_DIR
SDC_IN
START_TIME
STA_MULTICORNER
STA_PRE_CTS
Expand Down
6 changes: 6 additions & 0 deletions configuration/general.tcl
Original file line number Diff line number Diff line change
Expand Up @@ -80,3 +80,9 @@ set ::env(RUN_KLAYOUT_XOR) 1
set ::env(GENERATE_FINAL_SUMMARY_REPORT) {1}

set ::env(WRITE_VIEWS_NO_GLOBAL_CONNECT) 0


set ::env(BASE_SDC_FILE) $::env(SCRIPTS_DIR)/base.sdc
set ::env(DEFAULT_SDC_FILE) $::env(BASE_SDC_FILE)
set ::env(PNR_SDC_FILE) $:::env(BASE_SDC_FILE)
set ::env(SIGNOFF_SDC_FILE) $:::env(BASE_SDC_FILE)
2 changes: 0 additions & 2 deletions configuration/synthesis.tcl
Original file line number Diff line number Diff line change
Expand Up @@ -33,5 +33,3 @@ set ::env(SYNTH_FLAT_TOP) 0
set ::env(IO_PCT) 0.2
set ::env(SYNTH_EXTRA_MAPPING_FILE) ""

set ::env(BASE_SDC_FILE) $::env(SCRIPTS_DIR)/base.sdc

6 changes: 4 additions & 2 deletions docs/source/reference/configuration.md
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,8 @@ files you may be depending on, including headers, in `VERILOG_FILES`.
| `MERGED_LEF` <a id="MERGED_LEF"></a> | Points to `merged.lef`, which is a merger of various LEF files, including the technology lef, cells lef, any custom lefs, and IO lefs. |
| `NO_SYNTH_CELL_LIST` <a id="NO_SYNTH_CELL_LIST"></a> | Specifies the file that contains the don't-use-cell-list to be excluded from the liberty file during synthesis. If it's not defined, this path is searched `$::env(PDK_ROOT)/$::env(PDK)/libs.tech/openlane/$::env(STD_CELL_LIBRARY)/no_synth.cells` and if it's not found, then the original liberty will be used as is. |
| `DRC_EXCLUDE_CELL_LIST` <a id="DRC_EXCLUDE_CELL_LIST"></a> | Specifies the file that contains the don't-use-cell-list to be excluded from the liberty file during synthesis and timing optimizations. If it's not defined, this path is searched `$::env(PDK_ROOT)/$::env(PDK)/libs.tech/openlane/$::env(STD_CELL_LIBRARY)/drc_exclude.cells` and if it's not found, then the original liberty will be used as is. In other words, `DRC_EXCLUDE_CELL_LIST` contain the only excluded cell list in timing optimizations. |
| `BASE_SDC_FILE` <a id="BASE_SDC_FILE"></a> | Specifies the base SDC file using during the flow. It is the default SDC file used for `PNR_SDC_FILE` and `SIGNOFF_SDC_FILE` <br> (Default: `$::env(OPENLANE_ROOT)/scripts/base.SDC`) |
| `PNR_SDC_FILE` <a id="PNR_SDC_FILE"></a> | Specifies the SDC file used during all implementation (PnR) stages. It is used by tools in the flow and during STA done at these stages. It is *not* used during signoff stage. <br> (Default: `$::env(BASE_SDC_FILE)`) |

### Macros/Chip Integration

Expand Down Expand Up @@ -90,7 +92,6 @@ files you may be depending on, including headers, in `VERILOG_FILES`.
| `SYNTH_EXTRA_MAPPING_FILE` <a id="SYNTH_EXTRA_MAPPING_FILE"></a> | Points to extra techmap file for yosys that runs right after yosys `synth` before generic techmap. <br> (Default: `""`)|
| `SYNTH_PARAMETERS` <a id="SYNTH_PARAMETERS"></a> | Whitespace-delimited key value pairs to be `chparam`ed in Yosys. In the format `key1=value1 key2=value2` <br> (Default: None) |
| `SYNTH_ELABORATE_ONLY` <a id="SYNTH_ELABORATE_ONLY"></a> | "Elaborate" the design only without attempting any logic mapping. Useful when dealing with structural Verilog netlists. <br> (Default: `0`) |
| `BASE_SDC_FILE` <a id="BASE_SDC_FILE"></a> | Specifies the base sdc file to source before running Static Timing Analysis. <br> (Default: `$::env(OPENLANE_ROOT)/scripts/base.sdc`) |
| `VERILOG_INCLUDE_DIRS` <a id="VERILOG_INCLUDE_DIRS"></a> | Specifies the verilog includes directories. <br> Optional. |
| `SYNTH_FLAT_TOP` <a id="SYNTH_FLAT_TOP"></a> | Specifies whether or not the top level should be flattened during elaboration. 1 = True, 0= False <br> (Default: `0`)|
| `IO_PCT` <a id="IO_PCT"></a> | Specifies the percentage of the clock period used in the input/output delays. Ranges from 0 to 1.0. <br> (Default: `0.2`) |
Expand Down Expand Up @@ -303,7 +304,7 @@ These variables worked initially, but they were too sky130 specific and will be
| `RUN_SPEF_EXTRACTION` <a id="RUN_SPEF_EXTRACTION"></a> | Specifies whether or not to run SPEF extraction on the routed DEF. 1=enabled 0=disabled <br> (Default: `1`) |
| `SPEF_EXTRACTOR` <a id="SPEF_EXTRACTOR"></a> | Specifies which spef extractor to use. Values: `openrcx` or (**removed:** `def2spef`). <br> (Default: `openrcx`) |
| `RCX_MERGE_VIA_WIRE_RES` <a id="RCX_MERGE_VIA_WIRE_RES"></a> | Specifies whether to merge the via resistance with the wire resistance or separate it from the wire resistance. 1 = Merge via resistance, 0 = Separate via resistance <br> (Default: `1`)|
| `RCX_SDC_FILE` <a id="RCX_SDC_FILE"></a> | Specifies SDC file to be used for RCX-based STA, which can be different from the one used for implementation. <br> (Default: `BASE_SDC_FILE`) |
| `RCX_SDC_FILE` <a id="RCX_SDC_FILE"></a> | **Deprecated: Use `SIGNOFF_SDC_FILE`**: Specifies SDC file to be used for RCX-based STA, which can be different from the one used for implementation. <br> (Default: `BASE_SDC_FILE`) |
| `SPEF_WIRE_MODEL` <a id="SPEF_WIRE_MODEL"></a> | **Removed:** Specifies the wire model used in SPEF extraction. Options are `L` or `Pi` |
| `SPEF_EDGE_CAP_FACTOR` <a id="SPEF_EDGE_CAP_FACTOR"></a> | **Removed:** Specifies the edge capacitance factor used in SPEF extraction. Ranges from 0 to 1 |

Expand All @@ -322,6 +323,7 @@ These variables worked initially, but they were too sky130 specific and will be
| `PRIMARY_SIGNOFF_TOOL` <a id="PRIMARY_SIGNOFF_TOOL"></a> | Determines whether `magic` or `klayout` is the primary signoff tool. <br> (Default: `magic`) |
| `USE_ARC_ANTENNA_CHECK` <a id="USE_ARC_ANTENNA_CHECK"></a> | Specifies whether to use the openroad ARC antenna checker or magic antenna checker. 0=magic antenna checker, 1=ARC OR antenna checker <br> (Default: `1`)
| `RUN_CVC` <a id="RUN_CVC"></a> | Runs CVC on the output spice, which is a Circuit Validity Checker. Voltage aware ERC checker for CDL netlists. 1 = Enabled, 0 = Disabled. <br> (Default: `1`) |
| `SIGNOFF_SDC_FILE` <a id="SIGNOFF_SDC_FILE"></a> | Specifies SDC file used by multicorner STA during signoff stage, which can be different from the one used for implementation. <br> (Default: `BASE_SDC_FILE`) |

### Magic
|Variable|Description|
Expand Down
2 changes: 1 addition & 1 deletion docs/source/usage/hardening_macros.md
Original file line number Diff line number Diff line change
Expand Up @@ -72,7 +72,7 @@ Static Timing Analysis happens multiple times during the flow. However, they all

3. The IO delay percentage from the clock period `IO_PCT`. More about that [here](../reference/configuration.md).

4. You may want to write a custom SDC file to be used in STA and CTS. The default SDC file in the flow is as follows. However, you can change that by pointing to a new file with the environment variable `BASE_SDC_FILE`. More about that [here](../reference/configuration.md).
4. You may want to write a custom SDC file to be used in STA and CTS. The default SDC file in the flow is as follows. However, you can change that by pointing to a new file with the environment variable `IMPLEMENTATION_SDC_FILE`. More about that [here](../reference/configuration.md).

Other values are set based on the (PDK, STD_CELL_LIBRARY) used. You can read more about those configurations [here](../reference/configuration.md).

Expand Down
21 changes: 9 additions & 12 deletions scripts/openroad/common/io.tcl
Original file line number Diff line number Diff line change
Expand Up @@ -34,10 +34,11 @@ proc env_var_used {file var} {
return [string_in_file $file "\$::env($var)"]
}

proc read_current_sdc {} {
if { ![info exists ::env(CURRENT_SDC)]} {
puts "\[INFO] CURRENT_SDC not found. Not reading an SDC file."
return
proc read_sdc_wrapper {} {
if { [info exists ::env(STA_MULTICORNER)] && $::env(STA_MULTICORNER) == 1 } {
set sdc_in $::env(SIGNOFF_SDC_FILE)
} else {
set sdc_in $::env(PNR_SDC_FILE)
}

set ::env(SYNTH_MAX_FANOUT) $::env(MAX_FANOUT_CONSTRAINT)
Expand All @@ -46,8 +47,8 @@ proc read_current_sdc {} {
set ::env(SYNTH_MAX_TRAN) $::env(MAX_TRANSITION_CONSTRAINT)
}

puts "Reading design constraints file at '$::env(CURRENT_SDC)'…"
if {[catch {read_sdc $::env(CURRENT_SDC)} errmsg]} {
puts "Reading design constraints file at '$sdc_in'…"
if {[catch {read_sdc $sdc_in} errmsg]} {
puts stderr $errmsg
exit 1
}
Expand Down Expand Up @@ -90,9 +91,7 @@ proc read_netlist {args} {

link_design $::env(DESIGN_NAME)

if { [info exists ::env(CURRENT_SDC)] } {
read_current_sdc
}
read_sdc_wrapper

}

Expand Down Expand Up @@ -188,9 +187,7 @@ proc read {args} {

read_libs {*}$read_libs_args

if { [info exists ::env(CURRENT_SDC)] } {
read_current_sdc
}
read_sdc_wrapper

if { ![info exist flags(-no_spefs)] } {
if { [info exists ::env(CURRENT_SPEF)] } {
Expand Down
15 changes: 15 additions & 0 deletions scripts/openroad/sta/multi_corner.tcl
Original file line number Diff line number Diff line change
Expand Up @@ -62,7 +62,10 @@ foreach corner [sta::corners] {
puts "======================= [$corner name] Corner ===================================\n"
report_checks -sort_by_slack -path_delay min -fields {slew cap input nets fanout} -format full_clock_expanded -group_count 1000 -corner [$corner name]
puts ""
set ws [sta::format_time [sta::worst_slack_corner $corner "min"] 4]
puts "worst slack corner [$corner name]: $ws"
}

puts "min_report_end"


Expand All @@ -74,6 +77,8 @@ foreach corner [sta::corners] {
puts "======================= [$corner name] Corner ===================================\n"
report_checks -sort_by_slack -path_delay max -fields {slew cap input nets fanout} -format full_clock_expanded -group_count 1000 -corner [$corner name]
puts ""
set ws [sta::format_time [sta::worst_slack_corner $corner "max"] 4]
puts "worst slack corner [$corner name]: $ws"
}
puts "max_report_end"

Expand Down Expand Up @@ -105,6 +110,16 @@ foreach corner [sta::corners] {
puts "======================= [$corner name] Corner ===================================\n"
report_check_types -max_slew -max_capacitance -max_fanout -violators -corner [$corner name]
puts ""
set net "NULL"
set violators 1
set min_max "max"
set slew_pins [sta::check_slew_limits $net $violators $corner $min_max]
puts "max slew violations count [$corner name]: [llength $slew_pins]"
set fanout_pins [sta::check_fanout_limits $net $violators $min_max]
puts "max fanout violations count [$corner name]: [llength $fanout_pins]"
set cap_pins [sta::check_capacitance_limits $net $violators $corner $min_max]
puts "max cap violations count [$corner name]: [llength $cap_pins]"

}

puts "\n==========================================================================="
Expand Down
9 changes: 9 additions & 0 deletions scripts/tcl_commands/all.tcl
Original file line number Diff line number Diff line change
Expand Up @@ -637,6 +637,8 @@ proc prep {args} {
handle_deprecated_config LIB_RESIZER_OPT RSZ_LIB
handle_deprecated_config UNBUFFER_NETS RSZ_DONT_TOUCH_RX

handle_deprecated_config RCX_SDC_FILE SIGNOFF_SDC_FILE

### Checkers/Quitting
handle_deprecated_config CHECK_ASSIGN_STATEMENTS QUIT_ON_ASSIGN_STATEMENTS
handle_deprecated_config CHECK_UNMAPPED_CELLS QUIT_ON_UNMAPPED_CELLS
Expand Down Expand Up @@ -907,6 +909,13 @@ proc prep {args} {
}
}

if { $::env(PNR_SDC_FILE) == $::env(DEFAULT_SDC_FILE) } {
puts_warn "PNR_SDC_FILE is not set. It is recommended to write a custom SDC file for the design. Defaulting to BASE_SDC_FILE"
}
if { $::env(SIGNOFF_SDC_FILE) == $::env(DEFAULT_SDC_FILE) } {
puts_warn "SIGNOFF_SDC_FILE is not set. It is recommended to write a custom SDC file for the design. Defaulting to BASE_SDC_FILE"
}

TIMER::timer_stop
exec echo "[TIMER::get_runtime]" | python3 $::env(SCRIPTS_DIR)/write_runtime.py "openlane design prep"
return -code ok
Expand Down
30 changes: 20 additions & 10 deletions scripts/tcl_commands/checkers.tcl
Original file line number Diff line number Diff line change
Expand Up @@ -111,9 +111,9 @@ proc check_timing_violations {args} {

assert_files_exist "$hold_report $setup_report $misc_report"

check_misc_violations -report_file $misc_report -corner "typical"
check_hold_violations -report_file $hold_report -corner "typical" -quit_on_vios $arg_values(-quit_on_hold_vios)
check_setup_violations -report_file $setup_report -corner "typical" -quit_on_vios $arg_values(-quit_on_setup_vios)
check_misc_violations -report_file $misc_report -corner "Typical"
check_hold_violations -report_file $hold_report -corner "Typical" -quit_on_vios $arg_values(-quit_on_hold_vios)
check_setup_violations -report_file $setup_report -corner "Typical" -quit_on_vios $arg_values(-quit_on_setup_vios)
} else {
puts_warn "::env(LAST_TIMING_REPORT_TAG) not found."
}
Expand All @@ -131,8 +131,13 @@ proc check_hold_violations {args} {
set quit_on_vios $arg_values(-quit_on_vios)
set corner $arg_values(-corner)

set checker [catch {exec grep "VIOLATED" $report_file }]
if { ! $checker } {
set worst_slack [exec sed -n "s/worst slack corner $corner: \\(.*\\)/\\1/p" $report_file]
if { $worst_slack == "INF" } {
set checker 0
} else {
set checker [catch {exec python3 -c "if $worst_slack < 0: exit(1)"}]
}
if { $checker } {
set report_file_relative [relpath . $report_file]
if { $quit_on_vios } {
puts_err "There are hold violations in the design at the $corner corner. Please refer to '$report_file_relative'."
Expand All @@ -157,8 +162,13 @@ proc check_setup_violations {args} {
set quit_on_vios $arg_values(-quit_on_vios)
set corner $arg_values(-corner)

set checker [catch {exec grep "VIOLATED" $report_file }]
if { ! $checker } {
set worst_slack [exec sed -n "s/worst slack corner $corner: \\(.*\\)/\\1/p" $report_file]
if { $worst_slack == "INF" } {
set checker 0
} else {
set checker [catch {exec python3 -c "if $worst_slack < 0: exit(1)"}]
}
if { $checker } {
set report_file_relative [relpath . $report_file]
if { $quit_on_vios } {
puts_err "There are setup violations in the design at the $corner corner. Please refer to '$report_file_relative'."
Expand Down Expand Up @@ -188,7 +198,7 @@ proc check_misc_violations {args} {

set violated 0

set check_slew [catch {exec grep "slew violation count 0" $report_file}]
set check_slew [catch {exec grep "max slew violations count $corner: 0" $report_file}]
if { $check_slew } {
set violated 1
if { $quit_on_vios } {
Expand All @@ -198,7 +208,7 @@ proc check_misc_violations {args} {
}
}

set check_fanout [catch {exec grep "fanout violation count 0" $report_file}]
set check_fanout [catch {exec grep "max fanout violations count $corner: 0" $report_file}]
if { $check_fanout } {
set violated 1
if { $quit_on_vios } {
Expand All @@ -208,7 +218,7 @@ proc check_misc_violations {args} {
}
}

set check_capacitance [catch {exec grep "cap violation count 0" $report_file}]
set check_capacitance [catch {exec grep "max cap violations count $corner: 0" $report_file}]
if { $check_capacitance } {
set violated 1
if { $quit_on_vios } {
Expand Down
35 changes: 13 additions & 22 deletions scripts/tcl_commands/sta.tcl
Original file line number Diff line number Diff line change
Expand Up @@ -124,12 +124,6 @@ proc run_parasitics_sta {args} {
# * CURRENT_SPEF is the nom SPEF after the loop is done
# * CURRENT_LIB is the nom/nom LIB after the loop is done
# * CURRENT_SDF is the nom/nom SDF after the loop is done
if { ![info exists ::env(RCX_SDC_FILE)] } {
set ::env(RCX_SDC_FILE) $::env(CURRENT_SDC)
}

set backup_sdc_variable $::env(CURRENT_SDC)
set ::env(CURRENT_SDC) $::env(RCX_SDC_FILE)

set mca_results_dir "$arg_values(-out_directory)/mca"
set ::env(MC_SPEF_DIR) "$mca_results_dir/spef"
Expand Down Expand Up @@ -157,22 +151,21 @@ proc run_parasitics_sta {args} {

set log_name $::env(signoff_logs)/rcx_mcsta.$process_corner.log

run_sta\
-log $log_name\
-process_corner $process_corner\
-multi_corner \
-save_to $directory \
-tool sta
set sta_flags [list]
lappend sta_flags -log $log_name
lappend sta_flags -process_corner $process_corner
lappend sta_flags -multi_corner
lappend sta_flags -save_to $directory
lappend sta_flags -tool sta

if { $process_corner == "nom" } {
run_sta\
-log $::env(signoff_logs)/rcx_sta.log\
-process_corner $process_corner\
-save_to $directory \
-blackbox_check \
-tool sta

set ::env(LAST_TIMING_REPORT_TAG) [index_file $::env(signoff_reports)/rcx_sta]
lappend sta_flags -blackbox_check
}

run_sta {*}$sta_flags

if { $process_corner == "nom" } {
set ::env(LAST_TIMING_REPORT_TAG) "[index_file $::env(signoff_reports)/sta-rcx_$process_corner]/multi_corner_sta"
}

file mkdir $::env(MC_SPEF_DIR)
Expand All @@ -183,8 +176,6 @@ proc run_parasitics_sta {args} {
file copy -force {*}[glob $directory/$::env(DESIGN_NAME).*.sdf] $sdf_folder
}
}

set ::env(CURRENT_SDC) $backup_sdc_variable
}

package provide openlane 0.9
2 changes: 1 addition & 1 deletion scripts/utils/utils.tcl
Original file line number Diff line number Diff line change
Expand Up @@ -399,7 +399,7 @@ proc show_warnings {msg} {
set warnings_file [open $::env(RUN_DIR)/warnings.log "r"]
set warnings [read $warnings_file]
close $warnings_file
puts $warnings
puts "[color_text 3 "$warnings"]"
}
}

Expand Down

0 comments on commit 5fb033c

Please sign in to comment.