blob: cb4e6eec340d587c123d60e0e7274c8e44f07c23 [file] [log] [blame]
# Copyright 2020 Efabless Corporation
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
proc check_assign_statements {args} {
set checker [count_matches assign $::env(synthesis_results).v]
if { $checker != 0 } {
puts_err "There are assign statements in the netlist"
flow_fail
} else {
puts_info "No assign statement in netlist"
}
}
proc check_synthesis_failure {args} {
set checker [catch {exec grep "\\\$" [index_file $::env(synthesis_reports)/2.stat.rpt]}]
if { ! $checker } {
puts_err "Synthesis failed"
flow_fail
}
}
proc check_timing_violations {args} {
if { [info exists ::env(LAST_TIMING_REPORT_TAG)] } {
set hold_report $::env(LAST_TIMING_REPORT_TAG).min.rpt
set setup_report $::env(LAST_TIMING_REPORT_TAG).max.rpt
set slew_report $::env(LAST_TIMING_REPORT_TAG).slew.rpt
foreach file [ list $hold_report $setup_report $slew_report] {
if {![file exist $file]} {
puts_err "File $file doesn't exist."
flow_fail
}
}
check_slew_violations -report_file $slew_report -corner "typical"
check_hold_violations -report_file $hold_report -corner "typical" -quit_on_vios [expr $::env(QUIT_ON_TIMING_VIOLATIONS) && $::env(QUIT_ON_HOLD_VIOLATIONS)]
check_setup_violations -report_file $setup_report -corner "typical" -quit_on_vios [expr $::env(QUIT_ON_TIMING_VIOLATIONS) && $::env(QUIT_ON_HOLD_VIOLATIONS)]
}
}
proc check_hold_violations {args} {
set options {
{-report_file required}
{-corner required}
{-quit_on_vios optional}
}
parse_key_args "check_hold_violations" args arg_values $options
set_if_unset arg_values(-quit_on_vios) 0
set report_file $arg_values(-report_file)
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 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'."
flow_fail
} else {
puts_warn "There are hold violations in the design at the $corner corner. Please refer to '$report_file_relative'."
}
} else {
puts_info "There are no hold violations in the design at the $corner corner."
}
}
proc check_setup_violations {args} {
set options {
{-report_file required}
{-corner required}
{-quit_on_vios optional}
}
parse_key_args "check_setup_violations" args arg_values $options
set_if_unset arg_values(-quit_on_vios) 0
set report_file $arg_values(-report_file)
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 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'."
flow_fail
} else {
puts_warn "There are setup violations in the design at the $corner corner. Please refer to '$report_file_relative'."
}
} else {
puts_info "There are no setup violations in the design at the $corner corner."
}
}
proc check_slew_violations {args} {
set options {
{-report_file required}
{-corner required}
{-quit_on_vios optional}
}
parse_key_args "check_slew_violations" args arg_values $options
set_if_unset arg_values(-quit_on_vios) 0
set report_file $arg_values(-report_file)
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 report_file_relative [relpath . $report_file]
if { $quit_on_vios } {
puts_err "There are max slew violations in the design at the $corner corner. Please refer to '$report_file_relative'."
flow_fail
} else {
puts_warn "There are max slew violations in the design at the $corner corner. Please refer to '$report_file_relative'."
}
} else {
puts_info "There are no max slew violations in the design at the $corner corner."
}
}
proc check_floorplan_missing_lef {args} {
set checker [catch {exec grep -E -o "module \[^\[:space:]]+ not found" [index_file $::env(floorplan_logs)/initial_fp.log]} missing_lefs]
if { ! $checker } {
puts_err "Floorplanning failed"
set lines [split $missing_lefs "\n"]
foreach line $lines {
puts_err "$line in $::env(MERGED_LEF)"
}
puts_err "Check whether EXTRA_LEFS is set appropriately"
flow_fail
}
}
proc check_floorplan_missing_pins {args} {
set checker [catch {exec grep -E -o "instance \[^\[:space:]]+ port \[^\[:space:]]+ not found" [index_file $::env(floorplan_logs)/openroad.log]} mismatches]
if { ! $checker } {
set lines [split $mismatches "\n"]
foreach line $lines {
puts_err "$line in $::env(MERGED_LEF)"
}
puts_err "Check whether EXTRA_LEFS is set appropriately and if they have the referenced pins."
flow_fail
}
}
proc check_cts_clock_nets {args} {
set checker [catch {exec grep -E -o "Error: No clock nets have been found." [index_file $::env(cts_logs)/cts.log]} error]
if { ! $checker } {
puts_err "Clock Tree Synthesis failed"
puts_err $error
puts_err "TritonCTS failed to find clock nets and/or sinks in the design; check whether the synthesized netlist contains flip-flops."
flow_fail
}
}
proc check_replace_divergence {args} {
set checker [catch {exec grep -E -o "RePlAce diverged. Please tune the parameters again" [index_file $::env(placement_logs)/global.log]} error]
if { ! $checker } {
puts_err "Global placement failed"
puts_err $error
flow_fail
}
}
proc check_macro_placer_num_solns {args} {
set checker [catch {exec grep -E -o "NumFinalSols = 0" [index_file $::env(placement_logs)/basic_mp.log]} error]
if { ! $checker } {
puts_err "Macro placement failed"
puts_err "$error; you may need to adjust the HALO"
flow_fail
}
}
proc quit_on_tr_drc {args} {
if { [info exists ::env(QUIT_ON_TR_DRC)] && $::env(QUIT_ON_TR_DRC) } {
set checker [count_matches violation $::env(routing_reports)/detailed.drc]
if { $checker != 0 } {
puts_err "There are violations in the design after detailed routing."
puts_err "Total Number of violations is $checker"
flow_fail
} else {
puts_info "No DRC violations after detailed routing."
}
}
}
proc quit_on_magic_drc {args} {
if { [info exists ::env(QUIT_ON_MAGIC_DRC)] && $::env(QUIT_ON_MAGIC_DRC) } {
set options {
{-log required}
}
parse_key_args "quit_on_magic_drc" args arg_values $options
set checker [count_matches violation $arg_values(-log)]
if { $checker != 0 } {
puts_err "There are violations in the design after Magic DRC."
puts_err "Total Number of violations is $checker"
flow_fail
} else {
puts_info "No DRC violations after GDS streaming out."
}
}
}
proc quit_on_lvs_error {args} {
if { [info exists ::env(QUIT_ON_LVS_ERROR)] && $::env(QUIT_ON_LVS_ERROR) } {
set options {
{-log required}
}
parse_key_args "quit_on_lvs_error" args arg_values $options
set checker [catch {exec grep -E -o "Total errors = 0" $arg_values(-log)} error]
if { $checker != 0 } {
set log_relative [relpath . $arg_values(-log)]
puts_err "There are LVS errors in the design: See '$log_relative' for details."
flow_fail
}
}
}
proc quit_on_illegal_overlaps {args} {
if { [info exists ::env(QUIT_ON_ILLEGAL_OVERLAPS)] && $::env(QUIT_ON_ILLEGAL_OVERLAPS) } {
set options {
{-log required}
}
parse_key_args "quit_on_illegal_overlaps" args arg_values $options
set checker [catch {exec grep -E -o "Illegal overlap" $arg_values(-log)} error]
if { ! $checker } {
puts_err "There are illegal overlaps (e.g., routes over obstructions) in your design."
puts_err "See $arg_values(-log) for more."
flow_fail
}
}
}
proc quit_on_unconnected_pdn_nodes {args} {
set log_file [index_file $::env(floorplan_logs)/pdn.log]
set checker [catch {exec grep -E "Unconnected PDN node" $log_file} error]
if { ! $checker } {
puts_err "PDN generation failed."
puts_err "You may need to adjust your macro placements or PDN \
offsets/pitches to power all standard cell rails (or other PDN stripes) \
in your design."
flow_fail
}
}
package provide openlane 0.9