blob: 19dd6a418cceb494c1a80f1f3effff3a83176221 [file] [log] [blame]
###############################################################################
# CADENCE COPYRIGHT NOTICE
# © 2008-2013 Cadence Design Systems, Inc. All rights reserved.
#------------------------------------------------------------------------------
#
# This Foundation Flow is provided as an example of how to perform specialized
# tasks.
#
# This work may not be copied, re-published, uploaded, or distributed in any way,
# in any medium, whether in whole or in part, without prior written permission
# from Cadence. Notwithstanding any restrictions herein, subject to compliance
# with the terms and conditions of the Cadence software license agreement under
# which this material was provided, this material may be copied and internally
# distributed solely for internal purposes for use with Cadence tools.
#
# This work is Cadence intellectual property and may under no circumstances be
# given to third parties, neither in original nor in modified versions, without
# explicit written permission from Cadence. The information contained herein is
# the proprietary and confidential information of Cadence or its licensors, and
# is supplied subject to, and may be used only by Cadence's current customers
# in accordance with, a previously executed license agreement between Cadence
# and its customer.
#
#------------------------------------------------------------------------------
# THIS MATERIAL IS PROVIDED BY CADENCE "AS IS" AND ANY EXPRESS OR IMPLIED
# WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
# MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
# IN NO EVENT SHALL CADENCE BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL
# OR CONSEQUENTIAL DAMAGES HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
# WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
# OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS MATERIAL, EVEN IF
# ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
###############################################################################
package provide foundation_flow 1.0
namespace eval FF_NOVUS:: {
###############################################################################
# Procedure to seed certain flow variables to a known default value as well
# as data variables required to seed the generic configuration file
###############################################################################
proc seed_variables {{force 0}} {
global vars
global rda_defaults
global udm
global env
global infos
global warnings
global errors
global fargs
global dargs
if {$force} {
if {[info exists vars(seed)]} {
unset vars(seed)
}
}
if {![info exists vars(seed)]} {
puts "<FF> Seeding variables ..."
if {![info exists vars(warning_count)]} {
set vars(warning_count) 0
}
if {![info exists vars(error_count)]} {
set vars(error_count) 0
}
if {![info exists vars(info_count)]} {
set vars(info_count) 0
}
###############################################################################
# Set vars(version) to "17.1.0" if not defined
###############################################################################
if {![info exists vars(version)]} {
if {[info exists fargs(version)]} {
# puts "<FF> INFO: Variable vars(version) not defined - setting to '$fargs(version)'"
set vars(version) $fargs(version)
} else {
set vars(version) $dargs(version)
}
set vars(flow) mmmc
} else {
if {([lsearch $FF::valid_versions $vars(version)] < 0)} {
set msg "Version '$vars(version)' not supported - setting to '17.1.0'"
puts "<FF> WARNING: $msg"
append commands "# $msg\n"
set warnings($vars(warning_count)) $msg
incr vars(warning_count)
set vars(flow) mmmc
set vars(version) "17.1.0"
} else {
if {[lindex [split $vars(version) "."] 0] > 10} {
set vars(flow) mmmc
}
}
}
if {[regexp "9.1" $vars(version)]} {
set vars(enable_ldb) FALSE
}
# if {[lindex [split $vars(version) "."] 0] > 14} {
# set vars(novus) true
# } else {
# set vars(novus) false
# }
if {[info exists fargs(novus)]} {
set vars(novus) $fargs(novus)
} else {
set vars(novus) $dargs(novus)
}
# Tool should always be innovus for 15.x as encounter is going away
if {![info exists vars(make_tool)]} {
if {[lindex [split $vars(version) "."] 0] > 14} {
set vars(make_tool) innovus
} else {
set vars(make_tool) encounter
}
}
if {[info exists vars(enable_ldb)] && $vars(enable_ldb)} {
if {[info exists vars(ran_compile)]} {
append commands [FF_NOVUS::run_compile]
}
}
###############################################################################
# Set vars(flow) to "mmmc" if not defined
###############################################################################
if {![info exists vars(flow)]} {
puts "<FF> INFO: Variable vars(flow) not defined - setting to 'mmmc'"
set vars(flow) mmmc
} else {
if {([lsearch [list "default" "pr_mmmc" "mmmc"] $vars(flow)] < 0)} {
puts "<FF> WARNING: Flow type '$vars(flow)' not supported - setting to 'mmmc'"
append commands "# WARNING: Flow type '$vars(flow)' not supported - setting to 'mmmc'\n"
set warnings($vars(warning_count)) "Flow type '$vars(flow)' not supported - setting to 'mmmc'"
incr vars(warning_count)
set vars(flow) mmmc
}
}
###############################################################################
# Make sure all scaling factors are either set or are 1.0 ... also
# support backwards compatibility of old names
###############################################################################
set map(pre_route_res_factor) def_res_factor
set map(pre_route_clk_res_factor) def_clk_res_factor
set map(pre_route_cap_factor) def_cap_factor
set map(pre_route_clk_cap_factor) def_clk_cap_factor
set map(post_route_res_factor) det_res_factor
set map(post_route_clk_res_factor) det_clk_res_factor
set map(post_route_cap_factor) det_cap_factor
set map(post_route_clk_cap_factor) det_clk_cap_factor
set map(post_route_xcap_factor) xcap_factor
if {[info exists vars(view_definition_tcl)] && ![info exists vars(parsed_view_definition_tcl)]} {
if {![file exists $vars(view_definition_tcl)]} {
puts "<FF> ERROR: View definition file $vars(view_definition_tcl) does not exist ... cannot continue"
exit
}
source $vars(script_path)/ETC/INNOVUS/overlay.tcl
puts "<FF> Parsing user view definition file ..."
set rc [catch {source $vars(view_definition_tcl)}]
# puts "-------------------------------------------------"
if {$vars(novus)} {
foreach var "library_sets rc_corners delay_corners timing_conditions setup_analysis_views hold_analysis_views power_domains" {
if {[info exists vars($var)]} {
set infos($vars(info_count)) "Variable vars($var) has been set to \"$vars($var)\""
incr vars(info_count)
}
}
} else {
foreach var "library_sets rc_corners delay_corners setup_analysis_views hold_analysis_views power_domains" {
if {[info exists vars($var)]} {
set infos($vars(info_count)) "Variable vars($var) has been set to \"$vars($var)\""
incr vars(info_count)
}
}
}
# puts $rc
# puts "-------------------------------------------------"
set vars(parsed_view_definition_tcl) true
}
# if {![info exists vars(view_definition_tcl)]} {
foreach rc_corner $vars(rc_corners) {
foreach option "pre_route_res_factor pre_route_clk_res_factor \
post_route_res_factor post_route_clk_res_factor \
pre_route_cap_factor pre_route_clk_cap_factor \
post_route_cap_factor post_route_clk_cap_factor \
post_route_xcap_factor" {
if {![info exists vars($rc_corner,$option)] && [info exists vars($rc_corner,$map($option))]} {
append commands "# INFO: Variable $map($option) has been changed to $option ... please update\n"
set infos($vars(info_count)) "Variable $map($option) has been changed to $option ... please update"
incr vars(info_count)
set vars($rc_corner,$option) $vars($rc_corner,$map($option))
}
}
}
###############################################################################
# The following will be used to seed the config file
###############################################################################
if {![FF::is_lp_flow]} {
set max_libs [list]
set min_libs [list]
set count 0
if {[info exists vars($vars($vars(default_setup_view),delay_corner),library_set)]} {
foreach lib $vars($vars($vars($vars(default_setup_view),delay_corner),library_set),timing) {
if {[lsearch $max_libs $lib] == -1} {
lappend max_libs $lib
incr count
}
}
} else {
if {[info exists vars($vars($vars(default_setup_view),delay_corner),late_library_set)]} {
foreach lib $vars($vars($vars($vars(default_setup_view),delay_corner),late_library_set),timing) {
if {[lsearch $max_libs $lib] == -1} {
lappend max_libs $lib
incr count
}
}
}
}
if {![info exists vars(timelib,max)]} {
set vars(timelib,max) $max_libs
}
if {[info exists vars($vars($vars(default_hold_view),delay_corner),library_set)]} {
foreach lib $vars($vars($vars($vars(default_hold_view),delay_corner),library_set),timing) {
if {[lsearch $min_libs $lib] == -1} {
lappend min_libs $lib
incr count
}
}
} else {
if {[info exists vars($vars($vars(default_hold_view),delay_corner),early_library_set)]} {
foreach lib $vars($vars($vars($vars(default_hold_view),delay_corner),early_library_set),timing) {
if {[lsearch $min_libs $lib] == -1} {
lappend min_libs $lib
incr count
}
}
}
}
if {![info exists vars(timelib,min)]} {
set vars(timelib,min) $min_libs
}
if {![info exists vars(timelib)]} {
set vars(timelib) ""
}
set vars(cdb_file) ""
set vars(cdb_file,min) ""
set vars(cdb_file,max) ""
if {[info exists vars($vars($vars(default_setup_view),delay_corner),library_set)]} {
if {[info exists vars($vars($vars($vars(default_setup_view),delay_corner),library_set),si)]} {
set vars(cdb_file,max) $vars($vars($vars($vars(default_setup_view),delay_corner),library_set),si)
}
} elseif {[info exists vars($vars($vars(default_setup_view),delay_corner),late_library_set)]} {
if {[info exists ars($vars($vars($vars(default_setup_view),delay_corner),late_library_set),si)]} {
set vars(cdb_file,max) $vars($vars($vars($vars(default_setup_view),delay_corner),late_library_set),si)
}
} else {
set vars(cdb_file,max) ""
}
if {[info exists vars($vars($vars(default_hold_view),delay_corner),library_set)]} {
if {[info exists vars($vars($vars($vars(default_hold_view),delay_corner),library_set),si)]} {
set vars(cdb_file,min) $vars($vars($vars($vars(default_hold_view),delay_corner),library_set),si)
}
} elseif {[info exists vars($vars($vars(default_hold_view),delay_corner),early_library_set)]} {
if {[info exists vars($vars($vars($vars(default_hold_view),delay_corner),early_library_set),si)]} {
set vars(cdb_file,min) $vars($vars($vars($vars(default_hold_view),delay_corner),early_library_set),si)
}
} else {
set vars(cdb_file,min) ""
}
if {[info exists vars($vars($vars(default_setup_view),constraint_mode),pre_cts_sdc)]} {
if {$vars(flow) != "mmmc"} {
set vars(timingcon_file) $vars($vars($vars(default_setup_view),constraint_mode),pre_cts_sdc)
}
set vars(pre_cts_sdc) $vars($vars($vars(default_setup_view),constraint_mode),pre_cts_sdc)
}
if {[info exists vars($vars($vars(default_setup_view),constraint_mode),pre_cts_ilm_sdc)]} {
if {$vars(flow) != "mmmc"} {
set vars(timingcon_file,full) $vars($vars($vars(default_setup_view),constraint_mode),pre_cts_ilm_sdc)
}
}
if {[info exists vars($vars($vars(default_setup_view),constraint_mode),incr_cts_sdc)]} {
set vars(incr_cts_sdc) $vars($vars($vars(default_setup_view),constraint_mode),incr_cts_sdc)
}
if {[info exists vars($vars($vars(default_setup_view),constraint_mode),post_cts_sdc)]} {
set vars(post_cts_sdc) $vars($vars($vars(default_setup_view),constraint_mode),post_cts_sdc)
}
if {[info exists vars($vars($vars($vars(default_hold_view),delay_corner),rc_corner),cap_table)] &&\
[info exists vars($vars($vars($vars(default_setup_view),delay_corner),rc_corner),cap_table)]} {
set vars(captbl_file) [concat \
"-best" $vars($vars($vars($vars(default_hold_view),delay_corner),rc_corner),cap_table) \
"-worst" $vars($vars($vars($vars(default_setup_view),delay_corner),rc_corner),cap_table) \
]
set vars(wc_cap_table) $vars($vars($vars($vars(default_setup_view),delay_corner),rc_corner),cap_table)
} else {
if {[info exists vars($vars($vars($vars(default_setup_view),delay_corner),rc_corner),cap_table)]} {
set vars(captbl_file) [concat \
"-best" $vars($vars($vars($vars(default_setup_view),delay_corner),rc_corner),cap_table) \
"-worst" $vars($vars($vars($vars(default_setup_view),delay_corner),rc_corner),cap_table) \
]
set vars(wc_cap_table) $vars($vars($vars($vars(default_setup_view),delay_corner),rc_corner),cap_table)
} else {
set vars(captbl_file) ""
}
}
} else {
set vars(timelib) ""
set vars(cdb_file) ""
set vars(timelib,max) ""
set vars(cdb_file,max) ""
set vars(timelib,min) ""
set vars(cdb_file,min) ""
set found_max 0
set found_min 0
if {[info exists vars(setup_analysis_views)] && [info exists vars(hold_analysis_views)]} {
foreach view $vars(setup_analysis_views) {
if {[info exists vars($vars($view,delay_corner),library_set)]} {
if {[info exists vars($vars($vars($view,delay_corner),library_set),timing)]} {
foreach file $vars($vars($vars($view,delay_corner),library_set),timing) {
if {[lsearch $vars(timelib,max) $file] == -1} {
lappend vars(timelib,max) $file
}
set found_max 1
}
} else {
puts "<FF> WARNING: Variable vars($vars($vars($view,delay_corner),library_set),timing) not defined"
set warnings($vars(warning_count)) "Variable vars($vars($vars($view,delay_corner),library_set),timing) not defined"
incr vars(warning_count)
}
} else {
if {![info exists vars($vars($view,delay_corner),early_library_set)]} {
puts "<FF> WARNING: Variable vars($vars($view,delay_corner),library_set) not defined"
set warnings($vars(warning_count)) "Variable vars($vars($view,delay_corner),library_set) not defined"
incr vars(warning_count)
}
}
}
foreach view $vars(hold_analysis_views) {
if {[info exists vars($vars($view,delay_corner),library_set)]} {
if {[info exists vars($vars($vars($view,delay_corner),library_set),timing)]} {
foreach file $vars($vars($vars($view,delay_corner),library_set),timing) {
if {[lsearch $vars(timelib,min) $file] == -1} {
lappend vars(timelib,min) $file
}
set found_min 1
}
} else {
puts "<FF> WARNING: vars($vars($vars($view,delay_corner),library_set),timing) not defined"
set warnings($vars(warning_count)) "Variable vars($vars($vars($view,delay_corner),library_set),timing) not defined"
incr vars(warning_count)
}
} else {
if {![info exists vars($vars($view,delay_corner),early_library_set)]} {
puts "<FF> WARNING: vars($vars($view,delay_corner),early_library_set) not defined"
set warnings($vars(warning_count)) "Variable vars($vars($view,delay_corner),early_library_set) not defined"
incr vars(warning_count)
}
}
}
if {[info exists vars(power_analysis_view)] && ($vars(power_analysis_view) != "")} {
set view $vars(power_analysis_view)
if {[info exists vars($vars($view,delay_corner),library_set)]} {
if {![info exists vars($vars($vars($view,delay_corner),library_set),timing)]} {
puts "<FF> WARNING: vars($vars($vars($view,delay_corner),library_set),timing) not defined"
set warnings($vars(warning_count)) "Variable vars($vars($vars($view,delay_corner),library_set),timing) not defined"
incr vars(warning_count)
}
} else {
if {![info exists vars($vars($view,delay_corner),early_library_set)]} {
puts "<FF> WARNING: vars($vars($view,delay_corner),early_library_set) not defined"
set warnings($vars(warning_count)) "Variable vars($vars($view,delay_corner),early_library_set) not defined"
incr vars(warning_count)
}
}
}
}
if {!$found_min || !$found_max} {
append commands "# WARNING: Either setup or hold analysis views inadequately defined"
set warnings($vars(warning_count)) "Either setup or hold analysis views inadequately defined"
incr vars(warning_count)
set vars(timelib,min) ""
set vars(timelib,max) ""
foreach library_set $vars(library_sets) {
if {[info exists vars($library_set,timing)]} {
set vars(timelib) [concat $vars(timelib) $vars($library_set,timing)]
}
if {[info exists vars($library_set,si)]} {
set vars(cdb_file) [concat $vars(cdb_file) $vars($library_set,si)]
}
}
}
set vars(captbl_file) ""
set vars(timingcon_file) ""
# set vars(pre_route_res_factor) 1.0
# set vars(post_route_res_factor) 1.0
# set vars(pre_route_cap_factor) 1.0
# set vars(post_route_cap_factor) 1.0
# set vars(pre_route_clk_res_factor) 1.0
# set vars(post_route_clk_res_factor) 1.0
# set vars(pre_route_clk_cap_factor) 1.0
# set vars(post_route_clk_cap_factor) 1.0
# set vars(post_route_xcap_factor) 1.0
# set vars(qxtech_file) ""
# set vars(qxconf_file) ""
# set vars(qxlib_file) ""
# set vars(qxlayermap_file) ""
}
set map(qx_tech_file) qxtech_file
set map(qx_conf_file) qxconf_file
set map(qx_lib_file) qxlib_file
foreach option "qx_tech_file qx_conf_file qx_lib_file" {
if {[info exists vars($vars($vars($vars(default_setup_view),delay_corner),rc_corner),$option)]} {
set vars($map($option)) $vars($vars($vars($vars(default_setup_view),delay_corner),rc_corner),$option)
} else {
set vars($map($option)) ""
}
}
if {![info exists vars(qx_layermap_file)]} {
if {[info exists vars(qrc_layer_map)]} {
set vars(qxlayermap_file) $vars(qrc_layer_map)
} else {
set vars(qxlayermap_file) ""
}
} else {
set vars(qxlayermap_file) $vars(qx_layermap_file)
set vars(qrc_layer_map) $vars(qx_layermap_file)
}
# }
###############################################################################
# Backwards compatibility
###############################################################################
if {[info exists vars(leakage_effort)] && ![info exists vars(leakage_power_effort)]} {
set vars(leakage_power_effort) $vars(leakage_effort)
}
if {[info exists vars(enable_cppr)] && (($vars(enable_cppr) == 0) || ($vars(enable_cppr) == false))} {
set vars(enable_cppr) none
}
if {[info exists vars(enable_cppr)] && (($vars(enable_cppr) == 1) || ($vars(enable_cppr) == true))} {
set vars(enable_cppr) both
}
if {[info exists vars(def_file)]} {
append commands "# WARNING: Variable def_file has been changed to def_files ... please update\n"
set warnings($vars(warning_count)) "Variable def_file has been changed to def_files ... please update"
incr vars(warning_count)
set vars(def_files) $vars(def_file)
}
###############################################################################
# Seed the rest of the config variables allowing user overrides ...
# Default values for all variables are in defaults.tcl
###############################################################################
if {![info exists vars(script_path)]} {
if {[info exists vars(script_root)]} {
set vars(script_path) $vars(script_root)
} else {
puts "<FF> ERROR: Variable vars(script_root) not defined"
exit 1
}
} else {
if {![info exists vars(script_root)]} {
set vars(script_root) $vars(script_path)
}
}
if {![info exists vars(setup_path)]} {
set vars(setup_path) "."
}
if {[info command FFF::get_tool] ne "" && [FFF::get_tool] eq "rc"} {
tcl_source $vars(script_path)/ETC/INNOVUS/rda_defaults.tcl
} else {
source $vars(script_path)/ETC/common_defaults.tcl
source $vars(script_path)/ETC/INNOVUS/defaults.tcl
source $vars(script_path)/ETC/INNOVUS/rda_defaults.tcl
}
if {$vars(novus)} {
FF_NOVUS::dump_novus_attributes
}
foreach option [array names rda_defaults] {
if {![info exists vars($option)]} {
set vars($option) $rda_defaults($option)
} else {
if {$vars($option) != $rda_defaults($option)} {
# puts "# <FF> INFO: User override of $option to $vars($option)"
}
}
}
if {![info exists vars(cpus_per_remote_host)] && [info exists vars(cpu_per_remote_host)]} {
puts "<FF> INFO: Setting 'vars(cpus_per_remote_host)' to 'vars(cpu_per_remote_host)'"
puts "<FF> INFO: ^"
puts "<FF> INFO: Please update your setup to cpus_per_remote ..."
set vars(cpus_per_remote_host) $vars(cpu_per_remote_host)
}
if {![info exists vars(flexmodel_art_based)]} {
if {[info exists vars(flexmodel_as_ptn)] && $vars(flexmodel_as_ptn)} {
set flow_defaults(flexmodel_art_based) 1
}
}
if {![info exists vars(high_timing_effort)]} {
set vars(high_timing_effort) $flow_defaults(high_timing_effort)
}
if {[info exists vars(clock_eco)] && ($vars(clock_eco) == "postcts")} {
set vars(clock_eco) "post_cts"
}
if {[info exists vars(clock_eco)] && ($vars(clock_eco) == "postroute")} {
set vars(clock_eco) "post_route"
}
if {[regexp "9.1" $vars(version)]} {
if {$vars(high_timing_effort)} {
if {[info exists vars(critical_range)] && ($vars(critical_range) != 1.0)} {
puts "<FF> High timing effort enabled but critical_range overridden by user settings"
}
if {[info exists vars(clock_eco)] && ($vars(clock_eco) != "post_cts")} {
puts "<FF> High timing effort enabled but clock_eco overridden by user settings"
}
if {[info exists vars(in_place_opt)] && !$vars(in_place_opt)} {
puts "<FF> High timing effort enabled but in_place_opt overridden by user settings"
}
}
}
if {[info exists vars(cts_engine)] && ([string tolower $vars(cts_engine)] == "cts")} {
set flow_defaults(update_io_latency) false
# set vars(cts,update_timing,skip) true
}
foreach option [array names flow_defaults] {
if {![info exists vars($option)]} {
set vars($option) $flow_defaults($option)
if {$vars(high_timing_effort) && [regexp "9.1" $vars(version)]} {
set vars(in_place_opt) true
set vars(critical_range) 1.0
# set vars(useful_skew) true
set vars(clock_eco) post_cts
}
} else {
set user($option) $vars($option)
}
}
# if {![info exists user(ccopt_effort)] && ($vars(cts_engine) == "ccopt")} {
# set vars(ccopt_effort) low
# }
if {![info exists flow_defaults(time_info_db)]} {
set flow_defaults(time_info_db) $flow_defaults(rpt_dir)/time_info.db
}
if {![info exists flow_defaults(time_info_full_rpt)]} {
set flow_defaults(time_info_full_rpt) $flow_defaults(rpt_dir)/time_info_full.rpt
}
if {![info exists flow_defaults(html_summary)]} {
set flow_defaults(html_summary) $flow_defaults(rpt_dir)/summary.html
}
if {![info exists vars(enable_si_aware)]} {
# if {[regsub "nm" $vars(process) ""] <= 65} {
# set vars(enable_si_aware) true
# } else {
set vars(enable_si_aware) false
# }
}
if {![info exists vars(dbs_format)]} {
if {[string compare -nocase $vars(netlist_type) "verilog"]>=0} {
set vars(dbs_format) fe
} else {
set vars(dbs_format) oa
}
}
if {![info exists vars(partition_dir)]} {
set vars(partition_dir) PARTITION
}
if {![info exists vars(partition_dir_pass2)]} {
if {$vars(enable_flexilm)} {
set vars(partition_dir_pass2) $vars(partition_dir)_PRECTS
} else {
set vars(partition_dir_pass2) $vars(partition_dir)_CTS
}
}
if {$vars(user_mode) == "hier"} {
FF_NOVUS::normalize_files
if {$vars(enable_flexilm)} {
# set vars(cts,starting_dbs) "\[glob *_post_eco.enc\]"
# # DLM is a two pass flow but user doesn't need to specify it
set vars(hier_flow_type) "2pass"
# set vars(place_opt_design) false
} else {
if {$vars(hier_flow_type) == "2pass"} {
set vars(postcts,starting_dbs) .
}
# }
}
if {[string compare -nocase $vars(dbs_format) "oa"]==0} {
if {![info exists vars(oa_abstract_name)]} { set vars(oa_abstract_name) abstract}
if {![info exists vars(oa_layout_name)]} { set vars(oa_layout_name) layout}
if {![info exists vars(oa_design_cell)]} { set vars(oa_design_cell) $vars(design)}
if {![info exists vars(oa_design_view)]} { set vars(oa_design_view) ""}
if {![info exists vars(oa_partition_lib)]} { set vars(oa_partition_lib) OA_PTN_LIB}
} else {
if {![info exists vars(oa_abstract_name)]} { set vars(oa_abstract_name) ""}
if {![info exists vars(oa_layout_name)]} { set vars(oa_layout_name) ""}
if {![info exists vars(oa_design_cell)]} { set vars(oa_design_cell) ""}
if {![info exists vars(oa_design_view)]} { set vars(oa_design_view) ""}
if {![info exists vars(oa_design_lib)]} { set vars(oa_design_lib) ""}
}
if {([string tolower $vars(fix_hold)] == "true") || ($vars(fix_hold) == 1)} {
set infos($vars(info_count)) "Changing vars(fix_hold) from $vars(fix_hold) to \"$flow_defaults(fix_hold)\""
incr vars(info_count)
set vars(fix_hold) $flow_defaults(fix_hold)
}
if {([string tolower $vars(enable_ocv)] == "true") || ($vars(enable_ocv) == 1)} {
set infos($vars(info_count)) "Changing vars(enable_ocv) from \"$vars(enable_ocv)\" to \"pre_place\""
incr vars(info_count)
set vars(enable_ocv) pre_place
} elseif {($vars(enable_ocv) == "none") || ($vars(enable_ocv) == 0)} {
set infos($vars(info_count)) "Changing vars(enable_ocv) from \"$vars(enable_ocv)\" to \"false\""
incr vars(info_count)
set vars(enable_ocv) false
}
if {[lindex [split $vars(version) "."] 0] > 11} {
if {[string tolower $vars(enable_ocv)] == "false"} {
if {[lindex [split $vars(version) "."] 0] < 15} {
set infos($vars(info_count)) "Changing vars(enable_ocv) from \"$vars(enable_ocv)\" to \"pre_postroute\""
incr vars(info_count)
set vars(enable_ocv) "pre_postroute"
} else {
set infos($vars(info_count)) "Changing vars(enable_ocv) from \"$vars(enable_ocv)\" to \"pre_cts\""
incr vars(info_count)
set vars(enable_ocv) "pre_place"
}
}
}
if {([string tolower $vars(enable_ss)] == "true") || ($vars(enable_ss) == 1)} {
set infos($vars(info_count)) "Changing vars(enable_ss) from $vars(enable_ss) to \"pre_postroute\""
incr vars(info_count)
set vars(enable_ss) pre_postroute
} elseif {($vars(enable_ss) == "none") || ($vars(enable_ss) == 0)} {
set infos($vars(info_count)) "Changing vars(enable_ss) from $vars(enable_ss) to \"false\""
incr vars(info_count)
set vars(enable_ss) false
}
if {([string tolower $vars(metalfill)] == "none") || ([string tolower $vars(metalfill)] == "false" && $vars(metalfill) != "false") || ($vars(metalfill) == 0)} {
set infos($vars(info_count)) "Changing vars(metalfill) from $vars(metalfill) to \"false\""
incr vars(info_count)
set vars(metalfill) false
}
if {[info exists vars(clock_eco)]} {
if {($vars(clock_eco) == "true") || ($vars(clock_eco) == 1)} {
set infos($vars(info_count)) "Changing vars(clock_eco) from $vars(clock_eco) to \"post_cts\""
incr vars(info_count)
set vars(clock_eco) post_cts
} elseif {($vars(clock_eco) == "false") || ($vars(clock_eco) == 0)} {
set infos($vars(info_count)) "Changing vars(clock_eco) from $vars(clock_eco) to \"none\""
incr vars(info_count)
set vars(clock_eco) none
} elseif {($vars(clock_eco) == "preroute") || ($vars(clock_eco) == "pre_route")} {
set infos($vars(info_count)) "Changing vars(clock_eco) from $vars(clock_eco) to \"post_cts\""
incr vars(info_count)
set vars(clock_eco) post_cts
} elseif {$vars(clock_eco) == "postroute"} {
set infos($vars(info_count)) "Changing vars(clock_eco) from $vars(clock_eco) to \"post_route\""
incr vars(info_count)
set vars(clock_eco) post_route
}
}
if {([string tolower $vars(flow_effort)] == "none") || ([string tolower $vars(flow_effort)] == "default")} {
append warnings($vars(warning_count)) "Changing vars(flow_effort) from '$vars(flow_effort)' to 'standard'"
incr vars(warning_count)
set vars(flow_effort) standard
}
if {([string tolower $vars(use_flexmodels)] == "true") || ($vars(use_flexmodels) == 1)} {
set vars(use_flexmodels) 1
} else {
set vars(use_flexmodels) 0
}
# if {$vars(use_flexmodels) && $vars(place_opt_design)} {
# set warnings($vars(warning_count)) "Setting vars(place_opt_design) to 'false' as vars(use_flexmodels) is true"
# incr vars(warning_count)
# set vars(place_opt_design) false
# }
if {([string tolower $vars(flexmodel_as_ptn)] == "true") || ($vars(flexmodel_as_ptn) == 1)} {
set vars(flexmodel_as_ptn) 1
} else {
set vars(flexmodel_as_ptn) 0
}
if {([string tolower $vars(placement_based_ptn)] == "true") || ($vars(placement_based_ptn) == 1)} {
set vars(placement_based_ptn) 1
} else {
set vars(placement_based_ptn) 0
}
if {([string tolower $vars(abutted_design)] == "true") || ($vars(abutted_design) == 1)} {
set vars(abutted_design) 1
} else {
set vars(abutted_design) 0
}
if {([string tolower $vars(insert_feedthrough)] == "true") || ($vars(insert_feedthrough) == 1)} {
set vars(insert_feedthrough) 1
} else {
set vars(insert_feedthrough) 0
}
if {![info exists vars(resize_shifter_and_iso_insts)] || $vars(resize_shifter_and_iso_insts) == ""} {
set vars(resize_shifter_and_iso_insts) true
}
if {![info exists vars(activity_file_format)] || $vars(activity_file_format) == ""} {
set vars(activity_file_format) TCF
}
if {![info exists vars(power_nets)]} {
if {[info exists vars(pwrnet)]} {
append commands "# INFO: Variable pwrnet has been changed to power_nets ... please update\n"
set infos($vars(info_count)) "Variable pwrnet has been changed to power_nets ... please update"
incr vars(info_count)
set vars(power_nets) $vars(pwrnet)
} else {
set vars(power_nets) ""
}
}
if {![info exists vars(ground_nets)]} {
if {[info exists vars(gndnet)]} {
append commands "# INFO: Variable gndnet has been changed to ground_nets ... please update\n"
set infos($vars(info_count)) "Variable gndnet has been changed to ground_nets ... please update"
incr vars(info_count)
set vars(ground_nets) $vars(gndnet)
} else {
set vars(ground_nets) ""
}
}
if {![info exists vars(superhosts)]} {
set vars(superhosts) 0
}
if {![info exists vars(superthreads)]} {
set vars(superthreads) 1
} else {
if {($vars(threads) > 1) && ($vars(superthreads) == 1)} {
set vars(superthreads) $vars(threads)
}
}
if {![info exists vars(makefile)]} {
set vars(makefile) 1
}
if {![info exists vars(flat)]} {
set vars(flat) none
}
if {![info exists vars(abort)]} {
set vars(abort) 0
}
if {![info exists vars(catch_errors)]} {
set vars(catch_errors) 1
}
if {![info exists vars(restore_design)]} {
set vars(restore_design) 1
}
if {$vars(catch_errors)} {
if {![info exists vars(save_on_catch)]} {
set vars(save_on_catch) 1
}
if {![info exists vars(exit_on_error)]} {
set vars(exit_on_error) 1
}
}
if {![info exists env(VPATH)]} {
set env(VPATH) $flow_defaults(vpath)
puts "<FF> INFO: Setting env(VPATH) to $flow_defaults(vpath)"
}
if {[info exists vars(cpf_file)]} {
if {![info exists vars(cpf_timing)]} {
set vars(cpf_timing) true
# set vars(flat) true
}
} else {
set vars(cpf_timing) false
}
if {!$vars(codegen)} {
if {[FF::is_lp_flow]} {
catch {alias ff_modify_power_domains FF_NOVUS::modify_power_domains}
catch {alias ff_add_power_switches FF_NOVUS::add_power_switches}
catch {alias ff_route_secondary_pg_nets FF_NOVUS::route_secondary_pg_nets}
catch {alias ff_get_power_domains FF_NOVUS::get_power_domains}
catch {alias ff_buffer_always_on_nets FF_NOVUS::buffer_always_on_nets}
catch {alias ff_insert_welltaps_endcaps FF_NOVUS::insert_welltaps_endcaps}
}
set flow_defaults(script_dir) "."
}
# Remember these for step based reporting ...
set vars(orig_rpt_dir) $vars(rpt_dir)
set vars(orig_log_dir) $vars(log_dir)
set vars(orig_dbs_dir) $vars(dbs_dir)
# Add these for get metric
if {![info exists vars(html_summary)]} {
set vars(html_summary) $vars(rpt_dir)/summary.html
}
if {![info exists vars(time_info_db)]} {
set vars(time_info_db) $vars(rpt_dir)/time_info.db
}
if {![info exists vars(time_info_rpt)]} {
set vars(time_info_rpt) $vars(rpt_dir)/time_info.rpt
}
if {[info command FFF::get_tool] ne "" && [FFF::get_tool] eq "rc"} {
tcl_source $vars(script_path)/ETC/INNOVUS/udm.tcl
} else {
source $vars(script_path)/ETC/INNOVUS/udm.tcl
}
if {!$vars(rc) || ($vars(rc) && ![info exists vars(rc_steps)])} {
set vars(seed) 1
}
}
# if {![info exists vars(view_definition_tcl)]} {
FF_NOVUS::normalize_constraints
# }
if {$vars(generate_flow_steps)} {
# set vars(skip_signoff_checks) true
FF_NOVUS::normalize_files
}
# if {[info exists vars(view_definition_tcl)]} {
# set vars(skip_signoff_checks) false
# }
# RC Stuff ...
# ------------------------------------------------------------------------------
if {$vars(rc)} {
if {![info exists vars(ovf_dir)]} { set vars(ovf_dir) OVF }
if {![info exists vars(lec_dir)]} { set vars(lec_dir) LEC }
if {![info exists vars(enable_rcp)]} { set vars(enable_rcp) 0 }
if {![info exists vars(enable_pam)]} { set vars(enable_pam) 0 }
set vars(syn_map,set_lib_attributes,skip) true
set vars(syn_map,set_misc_attributes,skip) true
set vars(syn_map,set_hdl_attributes,skip) true
set vars(syn_map,set_icg_attributes,skip) true
set vars(syn_map,set_dft_attributes,skip) true
set vars(syn_incr,set_opt_attributes,skip) true
###############################################################################
# Set netlist and def variables when RC / RCP enabled
###############################################################################
if {$vars(enable_rcp)} {
set vars(netlist) $vars(dbs_dir)/syn_place/syn_place.v.gz
# set vars(def_files) $vars(dbs_dir)/syn_place.def.gz
} else {
set vars(netlist) $vars(dbs_dir)/syn_incr/syn_incr.v.gz
# set vars(def_files) $vars(dbs_dir)/syn_incr/syn_incr.def.gz
}
}
if {$vars(novus)} {
#set vars(make_tool_args) "-nowin -64"
set vars(make_syn_tool_args) "-64"
set vars(generate_flow_steps) true
} else {
#set vars(make_tool_args) "-nowin -64"
set vars(make_syn_tool_args) "-64 -legacy_ui"
set vars(generate_flow_steps) true
}
}
###############################################################################
# Procedure to check the flow variables defined in the setup.tcl
###############################################################################
proc check_setup {} {
global vars
global tvars
global errors
global warnings
global infos
global check
if {[info exists vars(check_setup)] && !$vars(check_setup)} {
return
}
if {[info exists vars(warning_count)]} {
set warning_count $vars(warning_count)
} else {
set warning_count 0
}
if {[info exists vars(error_count)]} {
set error_count $vars(error_count)
} else {
set error_count 0
}
if {[info exists vars(info_count)]} {
set info_count $vars(info_count)
} else {
set info_count 0
}
if {$vars(place_opt_design) && $vars(enable_flexilm)} {
set warnings($warning_count) "Feature vars(place_opt_design) not support for top level implementation when vars(enable_flexilm) is true"
incr warning_count
}
if {[info exists vars(power_analysis_view)]} {
if {[lsearch [concat $vars(setup_analysis_views) $vars(hold_analysis_views)] $vars(power_analysis_view)] == -1} {
append commands "# ERROR: Power analysis view $vars(power_analysis_view) is not a defined view\n"
set errors($error_count) "Power analysis view $vars(power_analysis_view) is not a defined view"
incr error_count
}
}
set valid [list trial_ipo giga_opt proto_net_delay_model]
if {[lsearch $valid [string tolower $vars(budget_mode)]] == -1} {
append commands "# ERROR: Variable vars(budget_mode) has illegal value $vars(budget_mode)\n"
set errors($error_count) "Variable vars(budget_mode) has illegal value $vars(budget_mode)"
incr error_count
append commands "# Must be one of '$valid'\n"
}
if {[info exists vars(cts_engine)]} {
if {[string tolower $vars(cts_engine)] == "ccoptdesign"} {
set vars(cts_engine) ccopt
}
if {[string tolower $vars(cts_engine)] == "clockdesign"} {
set vars(cts_engine) cts
}
set valid [list ccopt ccopt_cts]
if {[lsearch $valid [string tolower $vars(cts_engine)]] == -1} {
append commands "# ERROR: Variable vars(cts_engine) has illegal value $vars(cts_engine)\n"
set errors($error_count) "Variable vars(cts_engine) has illegal value $vars(cts_engine)"
incr error_count
append commands "# Must be one of '$valid'\n"
}
}
if {[info exists vars(ccopt_integration)]} {
set valid {scripted native}
if {[lsearch $valid $vars(ccopt_integration)] == -1} {
append commands "# ERROR: Variable vars(cts_engine) has illegal value $vars(cts_engine)\n"
set errors($error_count) "Variable vars(cts_engine) has illegal value $vars(cts_engine)"
incr error_count
append commands "# Must be one of '$valid'\n"
}
} else {
# Default to native integration
set vars(ccopt_integration) "native"
}
if {[lindex [split $vars(version) "."] 0] > 10} {
foreach var [array names vars] {
set save_vars($var) $vars($var)
if {[info exists tvars($var)]} {
set vars($var) $tvars($var)
}
}
}
set commands ""
set check(files) [list]
set check(integers) [list]
if {![info exists vars(abort)]} {
set vars(abort) 0
}
if {[info exists vars(check_vars)] && $vars(check_vars)} {
source $vars(script_root)/ETC/INNOVUS/check_vars.tcl
}
append commands "# ==============================================\n"
append commands "# Required Variables\n"
append commands "# ==============================================\n"
set count 0
foreach required "fp_tcl_file fp_file def_files" {
# BCL: Note - This code removed as the RC Foundation Flow will set vars(def_files) when it
# isn't defined in the user's setup.tcl
#if {$vars(rc) && ![info exists vars(def_files)]} {
# set vars(def_files) $vars(dbs_dir)/$vars(design).syn_placed.def.gz
#}
if {!$vars(rc)} {
# BCL: Only check for vars(def_files) if not in RC mode
if {[info exists vars($required)] && ($vars($required) != "")} {
if {$required == "def_files"} {
set first 1
# BCL: Added subst around vars(def_files) to resolve vars(rundir)
foreach file [subst $vars(def_files)] {
if {$first == 1} {
append commands "# INFO: $required = $file\n"
set first 0
} else {
append commands "# INFO: $file"
}
if {!$vars(rc)} {
lappend check(files) $file
}
}
} else {
lappend check(files) $vars($required)
append commands "# INFO: $required = $vars($required)\n"
}
incr count
}
}
}
if {[info exists vars(fp_tcl_proc)]} {
append commands "# INFO: fp_tcl_proc = $vars(fp_tcl_proc)\n"
incr count
}
if {[info exists vars(oa_fp)]} {
if {[llength $vars(oa_fp)] == 3} {
append commands "# INFO: oa_fp = $vars(oa_fp)\n"
incr count
} else {
append commands "# ERROR: OA floorplan variable (oa_fp) should be 'lib cell view'"
set errors($error_count) "OA floorplan variable (oa_fp) should be 'lib cell view'"
incr error_count
}
} else {
if {$count == 0} {
append commands "# WARNING: Neither fp_file, def_files, fp_tcl_file, fp_tcl_proc are defined\n"
set warnings($warning_count) "Either fp_file, def_files, fp_tcl_file, fp_tcl_proc should be defined"
incr warning_count
}
}
if {[string compare -nocase $vars(netlist_type) "verilog"]>=0} {
# BCL: Note - This code removed as the RC Foundation Flow will set vars(def_netlist) when it
# isn't defined in the user's setup.tcl
#if {$vars(rc) && ![info exists vars(netlist)]} {
# set vars(netlist) $vars(dbs_dir)/$vars(design).syn_placed.v.gz
#}
if {!$vars(rc)} {
# BCL: Only check for vars(netlist) if not in RC mode
if {[info exists vars(netlist)]} {
# BCL: Added subst around vars(netlist)
foreach file [subst $vars(netlist)] {
if {!$vars(rc)} {
lappend check(files) $file
}
}
append commands "# INFO: netlist = $vars(netlist)\n"
} else {
if {($vars(netlist_type) == "Verilog")} {
append commands "# ERROR: A verilog netlist file must be defined\n"
set errors($error_count) "A verilog netlist file must be defined"
incr error_count
}
}
}
} elseif {[string compare -nocase $vars(netlist_type) "oa"]==0} {
append commands "# INFO: netlist_type = $vars(netlist_type)\n"
foreach required "oa_ref_lib oa_design_lib oa_design_cell oa_design_view" {
if {[info exists vars($required)] && ($vars($required) != "")} {
append commands "# INFO: $required = $vars($required)\n"
} else {
append commands "# ERROR: Variable $required must be defined when netlist_type is open access"
set errors($error_count) "Variable $required must be defined when netlist_type is open access"
incr error_count
}
}
}
if {[string compare -nocase $vars(dbs_format) "oa"]==0} {
append commands "# INFO: dbs_format = $vars(dbs_format)\n"
foreach required "oa_ref_lib oa_design_lib oa_abstract_name oa_layout_name" {
if {[info exists vars($required)] && ($vars($required) != "")} {
append commands "# INFO: $required = $vars($required)\n"
} else {
append commands "# ERROR: Variable $required must be defined when dbs_format is open access"
set errors($error_count) "Variable $required must be defined when dbs_format is open access"
incr error_count
}
}
}
if {[info exists vars(enable_lvs)] && $vars(enable_lvs)} {
if {[string compare -nocase $vars(dbs_format) "oa"]!=0} {
append commands "# WARNING: Variable enable_lvs is only allowed when dbs_format is open access"
set warnings($warning_count) "Variable enable_lvs is only allowed when dbs_format is open access"
incr warning_count
set vars(enable_lvs) false
}
}
# if {[info exists vars(netlist)]} {
# foreach file $vars(netlist) {
# lappend check(files) $file
# }
# } else {
# if {$vars(netlist_type) == "Verilog"} {
# append commands "# ERROR: A verilog netlist file must be defined\n"
# set errors($error_count) "A verilog netlist file must be defined"
# incr error_count
#
# }
# }
if {[info exists vars(cts_spec)] && ($vars(cts_engine) == "ccopt")} {
# append commands "# ERROR: Variable cts_spec defined and cts_engine is set to ccopt\n"
# set errors($error_count) "Variable cts_spec defined and cts_engine is set to ccopt"
# incr error_count
append commands "# WARNING: Variable cts_spec defined and cts_engine is set to ccopt\n"
set warnings($warning_count) "Variable cts_spec defined and cts_engine is set to ccopt"
incr warning_count
foreach file $vars(cts_spec) {
lappend check(files) $file
}
}
# if {[info exists vars(cpf_file)] && $vars(cpf_timing)} {
# set required_list "flow process library_sets rc_corners delay_corners"
# } else {
set required_list "flow process library_sets rc_corners delay_corners setup_analysis_views \
hold_analysis_views active_setup_views active_hold_views default_setup_view default_hold_view"
# }
foreach required $required_list {
if {[info exists vars($required)] && ($vars($required) != "")} {
append commands "# INFO: $required = $vars($required)\n"
if {$required == "flow"} {
if {([info exists vars(partition_list)] || ($vars(ilm_list) != "")) && ($vars(flow) != "mmmc")} {
append commands "# ERROR: Flow variable vars(flow) must be \"mmmc\" when ILMs are defined\n"
set errors($error_count) "# ERROR: Flow variable vars(flow) must be \"mmmc\" when ILMs are defined"
incr error_count
}
}
}
}
# if {![info exists vars(view_definition_tcl)]} {
append commands "# ==============================================\n"
append commands "# Library Sets\n"
append commands "# ==============================================\n"
foreach library_set $vars(library_sets) {
append commands "# INFO: $library_set:\n"
foreach required "timing" {
if {[info exists vars($library_set,$required)] && ($vars($library_set,$required) != "")} {
append commands "# INFO: $required = \n"
foreach lib $vars($library_set,$required) {
# lappend check(files) $lib
append commands "# INFO: $lib\n"
}
} else {
if {[FF::is_lp_flow]} {
append commands "# WARNING: Variable vars($library_set,$required) not defined\n"
set warnings($warning_count) "Variable vars($library_set,$required) not defined"
incr warning_count
} else {
append commands "# ERROR: Required variable vars($library_set,$required) not defined or empty\n"
set errors($error_count) "Required variable vars($library_set,$required) not defined or empty"
incr error_count
}
}
}
if {[info exists vars($library_set,aocv)]} {
foreach file $vars($library_set,aocv) {
if {![file exists $file]} {
append commands "# WARNING: AOCV table file does not exist ($file)\n"
set warnings($warning_count) "AOCV table file does not exist ($file)"
incr warning_count
}
}
} else {
if {$vars(enable_aocv)} {
append commands "# WARNING: AOCV enabled, but table not provided for $library_set\n"
set warnings($warning_count) "AOCV enabled, but table not provided for $library_set"
incr warning_count
}
}
if {[info exists vars($library_set,socv)]} {
foreach file $vars($library_set,socv) {
if {![file exists $file]} {
append commands "# WARNING: SOCV table file does not exist ($file)\n"
set warnings($warning_count) "SOCV table file does not exist ($file)"
incr warning_count
}
}
} else {
if {$vars(enable_socv)} {
append commands "# WARNING: SOCV enabled, but table not provided for $library_set\n"
set warnings($warning_count) "SOCV enabled, but table not provided for $library_set"
incr warning_count
}
}
if {[info exists vars($library_set,si)]} {
foreach file $vars($library_set,si) {
if {![file exists $file]} {
append commands "# WARNING: CDB file does not exist ($file)\n"
set warnings($warning_count) "CDB file does not exist ($file)"
incr warning_count
}
}
}
}
# }
append commands "# ==============================================\n"
append commands "# LEF Files\n"
append commands "# ==============================================\n"
if {[info exists vars(lef_files)]} {
foreach file $vars(lef_files) {
# lappend check(files) $file
append commands "# INFO: $file\n"
}
} else {
if {([string tolower $vars(netlist_type)] == "verilog") && (![info exists vars(oa_ref_lib)])} {
append commands "# ERROR: Required variable vars(lef_files) not defined\n"
set errors($error_count) "Required variable vars(lef_files) not defined"
incr error_count
}
}
if {[info exists vars(partition_list)]} {
append commands "# ==============================================\n"
append commands "# Hierarchical \n"
append commands "# ==============================================\n"
append commands "# INFO: partitions = $vars(partition_list)\n"
set cts_spec [FF::get_by_suffix vars ",cts_spec"]
if {$cts_spec != ""} {
append commands "# CTS Specs : \n"
foreach partition $cts_spec {
lappend check(files) $vars($partition,cts_spec)
append commands "# $partition -> $vars($partition,cts_spec)\n"
}
}
set latency_sdc [FF::get_by_suffix vars ",latency_sdc"]
if {$latency_sdc != ""} {
append commands "# Latency SDCs :\n"
foreach partition $latency_sdc {
lappend check(files) $vars($partition,latency_sdc)
if {[llength [split $partition ","]] == 1} {
append commands "# $partition -> $vars($partition,latency_sdc)\n"
} else {
append commands "# [lindex [split $partition ","] 0] ([lindex [split $partition ","] 1]) -> $vars($partition,latency_sdc)\n"
}
}
}
}
if {[info exists vars(enable_pac)] && $vars(enable_pac)} {
append commands "# WARNING: PAC is obsolete and will be removed in a future version. Consider using Sign-off ECO."
set warnings($warning_count) "PAC is obsolete and will be removed in a future version. Consider using Sign-off ECO."
incr warning_count
set pac_mode [FF::get_by_suffix vars ",pac_mode"]
if {$pac_mode != ""} {
set pac_list [list "read_only" "interface" "ilm" "all"]
foreach pac $pac_mode {
if {[lsearch $pac_list $vars($pac,pac_mode)] == -1} {
append commands "# ERROR: $pac pac_mode invalid value; must be one of \'$pac_list\'\n"
set errors($error_count) "$pac pac_mode invalid value; must be one of \'$pac_list\'"
incr error_count
}
}
}
}
if {[FF::is_lp_flow]} {
append commands "# ==============================================\n"
append commands "# Low Power \n"
append commands "# ==============================================\n"
if {[info exists vars(ieee1801_file)]} {
set warnings($warning_count) "Using vars(ieee1801_file) requires the following limited access feature : mvsSupportIEEE1801"
incr warning_count
}
set num_power_intent_files 0
foreach v {cpf_file ieee1801_file} {
if {[info exists vars($v)]} {
append commands "# INFO: $v = $vars($v)\n"
lappend check(files) $vars($v)
incr num_power_intent_files
}
}
if {$num_power_intent_files > 1} {
set errors($error_count) "vars(cpf_file) and vars(ieee1801_file) may not both be specified."
append commands "# ERROR: $errors($error_count)\n"
incr error_count
}
if {[info exists vars(power_domains)] && ($vars(power_domains) != "")} {
append commands "# INFO: power_domains = $vars(power_domains)\n"
foreach domain $vars(power_domains) {
set print($domain) 1
foreach optional "filler_cells tie_cells endcaps welltaps" {
if {[info exists vars($domain,$optional)] && ($vars($domain,$optional) != "")} {
if {$print($domain)} {
append commands "# INFO: $domain:\n"
set print($domain) 0
}
append commands "# INFO: $optional = $vars($domain,$optional)\n"
}
# if {$optional == "filler_cells} {
# set process [regsub "nm" $vars(process) ""]
# if {[expr $process <= 28)] && [info exists vars(filler_cells,min_gap)]} {
# append commands "# ERROR: For process node < 28nm, variable vars(filler_cells,min_gap) is required\n"
# set errors($error_count) "For process node < 28nm, variable vars(filler_cells,min_gap) is required"
# incr error_count
# }
# }
}
}
} else {
append commands "# WARNING: Recommended variable vars(power_domains) not defined\n"
set warnings($warning_count) "Recommended variable vars(power_domains) not defined"
incr warning_count
}
if {[info exists vars(power_analysis_view)] && ($vars(power_analysis_view) != "")} {
append commands "# INFO: power_analysis_view = $vars(power_analysis_view)\n"
} else {
append commands "# WARNING: Recommended variable vars(power_analysis_view) not defined\n"
append commands "# Will default to the default setup analysis view\n"
set warnings($warning_count) "Recommended variable vars(power_analysis_view) not defined"
incr warning_count
}
}
# if {![info exists vars(view_definition_tcl)]} {
append commands "# ==============================================\n"
append commands "# RC Corners\n"
append commands "# ==============================================\n"
set check(rc_corners) [list]
foreach rc_corner $vars(rc_corners) {
append commands "# INFO: $rc_corner:\n"
if {[info exists vars($rc_corner,cap_table)] && ($vars($rc_corner,cap_table) != "")} {
append commands "# INFO: cap_table = $vars($rc_corner,cap_table)\n"
lappend check(rc_corners) $vars($rc_corner,cap_table)
} else {
if {![info exists vars($rc_corner,qx_tech_file)]} {
append commands "# ERROR: Variable vars($rc_corner,cap_table) or vars($rc_corner,qx_tech_file) must be defined\n"
set errors($error_count) "Variable vars($rc_corner,cap_table) or vars($rc_corner,qx_tech_file) must be defined"
incr error_count
} else {
if {[lindex [split $vars(version) "."] 0] < 15} {
append commands "# INFO: Variable vars($rc_corner,cap_table) not defined\n"
set infos($info_count) "Variable vars($rc_corner,cap_table) not defined"
incr info_count
}
}
}
# if {$vars(cts_engine) != "cts"} {
# if {[info exists vars($rc_corner,atf_file)] && ($vars($rc_corner,atf_file) != "")} {
# append commands "# INFO: atf_file = $vars($rc_corner,atf_file)\n"
# lappend check(rc_corners) $vars($rc_corner,atf_file)
# } else {
# append commands "# WARNING: Recommended variable vars($rc_corner,atf_file) not defined\n"
# set warnings($warning_count) "Recommended variable vars($rc_corner,atf_file) not defined"
# incr warning_count
# }
# }
if {[info exists vars($rc_corner,T)] && ($vars($rc_corner,T) != "")} {
append commands "# INFO: temperature = $vars($rc_corner,T)\n"
set vars($rc_corner,temperature) $vars($rc_corner,T)
lappend check(integers) "$rc_corner,T"
} else {
append commands "# WARNING: Recommended variable vars($rc_corner,T) not defined\n"
set warnings($warning_count) "Recommended variable vars($rc_corner,T) not defined"
incr warning_count
}
if {[info exists vars($rc_corner,qx_tech_file)] && ($vars($rc_corner,qx_tech_file) != "")} {
append commands "# INFO: qx_tech_file = $vars($rc_corner,qx_tech_file)\n"
set vars($rc_corner,qrc_tech) $vars($rc_corner,qx_tech_file)
lappend check(rc_corners) $vars($rc_corner,qx_tech_file)
} else {
if {[info exists vars(postroute_extraction_effort)] && ($vars(postroute_extraction_effort) != "low")} {
append commands "# ERROR: qx_tech_file not defined for $rc_corner and postroute_extraction_effort is set to $vars(postroute_extraction_effort)\n"
set errors($error_count) "qx_tech_file not defined for $rc_corner and postroute_extraction_effort is set to $vars(postroute_extraction_effort)"
incr error_count
}
if {[info exists vars(signoff_extraction_effort)] && ($vars(signoff_extraction_effort) != "low")} {
append commands "# ERROR: qx_tech_file not defined for $rc_corner and signoff_extraction_effort is set to $vars(signoff_extraction_effort)\n"
set errors($error_count) "qx_tech_file not defined for $rc_corner and signoff_extraction_effort is set to $vars(signoff_extraction_effort)"
# set errors($error_count) "Required variable vars($rc_corner,cap_table) not defined"
incr error_count
}
}
}
if {[info exists vars(opconds)]} {
append commands "# ==============================================\n"
append commands "# Operating Conditions\n"
append commands "# ==============================================\n"
foreach opcond $vars(opconds) {
append commands "# INFO: $opcond:\n"
foreach required "P V T" {
if {[info exists vars($opcond,$required)] && ($vars($opcond,$required) != "")} {
append commands "# INFO: $required = $vars($opcond,$required)\n"
} else {
append commands "# ERROR: Required variable vars($opcond,$required) not defined\n"
set errors($error_count) "Required variable vars($opcond,$required) not defined"
incr error_count
}
}
}
}
append commands "# ==============================================\n"
append commands "# Timing Conditions\n"
append commands "# ==============================================\n"
if {[info exists vars(timing_conditions)]} {
foreach timing_condition $vars(timing_conditions) {
append commands "# INFO: $timing_condition:\n"
if {![FF::is_lp_flow]} {
if {[info exists vars($timing_condition,library_set)] && ($vars($timing_condition,library_set) != "")} {
append commands "# INFO: library_set = $vars($timing_condition,library_set)\n"
} else {
foreach additional "early_library_set late_library_set" {
if {[info exists vars($timing_condition,$additional)] && ($vars($timing_condition,$additional) != "")} {
append commands "# INFO: $additional = $vars($timing_condition,$additional)\n"
} else {
append commands "# ERROR: Required variable vars($timing_condition,library_set) and vars($timing_condition,$additional) not defined\n"
set errors($error_count) "Required variable vars($timing_condition,library_set) and vars($timing_condition,$additional) not defined\n"
incr error_count
}
}
}
}
foreach optional "opcond opcond_library early_opcond_library late_opcond_library" {
if {[info exists vars($timing_condition,$optional)] && ($vars($timing_condition,$optional) != "")} {
append commands "# INFO: $optional = $vars($timing_condition,$optional)\n"
}
}
}
} else {
foreach delay_corner $vars(delay_corners) {
append commands "# INFO: $delay_corner:\n"
if {![FF::is_lp_flow]} {
if {[info exists vars($delay_corner,library_set)] && ($vars($delay_corner,library_set) != "")} {
append commands "# INFO: library_set = $vars($delay_corner,library_set)\n"
} else {
foreach additional "early_library_set late_library_set" {
if {[info exists vars($delay_corner,$additional)] && ($vars($delay_corner,$additional) != "")} {
append commands "# INFO: $additional = $vars($delay_corner,$additional)\n"
} else {
append commands "# ERROR: Required variable vars($delay_corner,library_set) and vars($delay_corner,$additional) not defined\n"
set errors($error_count) "Required variable vars($delay_corner,library_set) and vars($delay_corner,$additional) not defined\n"
incr error_count
}
}
}
}
foreach optional "opcond opcond_library early_opcond_library late_opcond_library" {
if {[info exists vars($delay_corner,$optional)] && ($vars($delay_corner,$optional) != "")} {
append commands "# INFO: $optional = $vars($delay_corner,$optional)\n"
}
}
}
}
append commands "# ==============================================\n"
append commands "# Delay Corners\n"
append commands "# ==============================================\n"
set good_corners [list]
foreach delay_corner $vars(delay_corners) {
set args 0
append commands "# INFO: $delay_corner:\n"
if {[info exists vars($delay_corner,rc_corner)] && ($vars($delay_corner,rc_corner) != "")} {
append commands "# INFO: rc_corner = $vars($delay_corner,rc_corner)\n"
incr args
} else {
append commands "# ERROR: Required variable vars($delay_corner,rc_corner) not defined\n"
set errors($error_count) "Required variable vars($delay_corner,rc_corner) not defined"
incr error_count
}
if {(![FF::is_lp_flow]) || ([FF::is_lp_flow] && !$vars(cpf_timing))} {
if {[info exists vars(timing_conditions)]} { ; # Don't require this as we can construct ...
if {[info exists vars($delay_corner,timing_condition)] && ($vars($delay_corner,timing_condition) != "")} {
append commands "# INFO: timing_condition = $vars($delay_corner,timing_condition)\n"
incr args
} else {
foreach additional "early_timing_condition late_timing_condition" {
if {[info exists vars($delay_corner,$additional)] && ($vars($delay_corner,$additional) != "")} {
append commands "# INFO: $additional = $vars($delay_corner,$additional)\n"
incr args
} else {
append commands "# ERROR: Required variable vars($delay_corner,timing_condition) and vars($delay_corner,$additional) not defined\n"
set errors($error_count) "Required variable vars($delay_corner,timing_condition) and vars($delay_corner,$additional) not defined\n"
incr error_count
}
}
}
}
}
foreach optional "power_domains" {
if {[info exists vars($delay_corner,$optional)] && ($vars($delay_corner,$optional) != "")} {
append commands "# INFO: $optional = $vars($delay_corner,$optional)\n"
}
}
if {!$vars(cpf_timing) && ($args > 1)} {
lappend good_corners $delay_corner
} else {
if {$args > 0} {
lappend good_corners $delay_corner
}
}
}
set vars(good_corners) $good_corners
set check(constraint_modes) [list]
if {[FF::is_lp_flow]} {
append commands "# ==============================================\n"
append commands "# Constraint Modes\n"
append commands "# ==============================================\n"
if {[info exists vars(constraint_modes)]} {
foreach mode $vars(constraint_modes) {
append commands "# INFO: $mode:\n"
foreach other "pre_cts_sdc incr_cts_sdc post_cts_sdc" {
if {[info exists vars($mode,$other)] && ($vars($mode,$other) != "")} {
append commands "# INFO: $other = $vars($mode,$other)\n"
lappend check(constraint_modes) $vars($mode,$other)
} else {
if {!$vars(cpf_timing)} {
if {($other == "pre_cts_sdc") && $vars(rc)} {
set vars($mode,$other) $vars(dbs_dir)/$vars(design).syn_placed.$mode.sdc
} elseif {($other == "pre_cts_sdc") && !$vars(rc)} {
append commands "# ERROR: Variable vars($mode,$other) not defined\n"
set errors($error_count) "Variable vars($mode,$other) not defined"
incr error_count
} else {
if {($other == "pre_cts_sdc") || (($other == "post_cts_sdc") && ![info exists vars($mode,incr_cts_sdc)])} {
append commands "# INFO: Variable vars($mode,$other) not defined\n"
}
}
} else {
append commands "# INFO: Variable vars($mode,$other) not defined\n"
}
}
}
}
} else {
append commands "# INFO: No constraint mode information defined\n"
append commands "# Post CTS latency adjustment must be\n"
append commands "# managed by the user via plug-ins\n"
}
} else {
append commands "# ==============================================\n"
append commands "# Constraint Modes\n"
append commands "# ==============================================\n"
if {$vars(rc)} {
set required_list "synth_sdc pre_cts_sdc"
} else {
set required_list "pre_cts_sdc"
}
foreach mode $vars(constraint_modes) {
set found 0
append commands "# INFO: $mode:\n"
foreach required $required_list {
if {[info exists vars($mode,$required)] && ($vars($mode,$required) != "")} {
append commands "# INFO: $required = $vars($mode,$required)\n"
lappend check(constraint_modes) $vars($mode,$required)
incr found
} else {
if {[llength $required_list] == 1} {
append commands "# ERROR: Required variable vars($mode,$required) not defined\n"
set errors($error_count) "Required variable vars($mode,$required) not defined"
incr error_count
}
}
}
if {([llength $required_list] > 1) && ($found == 0)} {
append commands "# ERROR: One of the required variables ($required_list) not defined\n"
set errors($error_count) "One of the required variables ($required_list) not defined"
incr error_count
}
foreach other "post_cts_sdc incr_cts_sdc" {
if {$other == "post_cts_sdc" && ![info exists vars($other)]} {
if {![info exists vars($mode,$other)]} {
append commands "# INFO: Variable vars($mode,$other) not defined\n"
} else {
append commands "# INFO: $other = $vars($mode,$other)\n"
}
} else {
if {[info exists vars($mode,$other)] && ($vars($mode,$other) != "")} {
append commands "# INFO: $other = $vars($mode,$other)\n"
lappend check(constraint_modes) $vars($mode,$other)
} else {
append commands "# INFO: Variable vars($mode,$other) not defined\n"
}
}
}
}
}
if {![info exists vars(hold_analysis_views)]} {
set vars(hold_analysis_views) ""
}
if {![info exists vars(power_analysis_view)]} {
set vars(power_analysis_view) ""
}
append commands "# ==============================================\n"
append commands "# Analysis Views\n"
append commands "# ==============================================\n"
if {[FF::is_lp_flow]} {
foreach analysis_view [concat $vars(setup_analysis_views) $vars(hold_analysis_views) $vars(power_analysis_view)] {
append commands "# INFO: $analysis_view:\n"
foreach other "delay_corner constraint_mode" {
if {[info exists vars($analysis_view,$other)] && ($vars($analysis_view,$other) != "")} {
append commands "# INFO: $other = $vars($analysis_view,$other)\n"
lappend check(analysis_view) $vars($analysis_view,$other)
}
}
}
} else {
set check(analysis_views) [list]
foreach analysis_view [concat $vars(setup_analysis_views) $vars(hold_analysis_views) $vars(power_analysis_view)] {
append commands "# INFO: $analysis_view:\n"
foreach required "delay_corner constraint_mode" {
if {[info exists vars($analysis_view,$required)] && ($vars($analysis_view,$required) != "")} {
append commands "# INFO: $required = $vars($analysis_view,$required)\n"
lappend check(analysis_view) $vars($analysis_view,$required)
} else {
append commands "# ERROR: Required variable vars($analysis_view,$required) not defined\n"
set errors($error_count) "Required variable vars($analysis_view,$required) not defined"
incr error_count
}
}
}
}
# }
append commands "# ==============================================\n"
append commands "# Recommended Variables\n"
append commands "# ==============================================\n"
foreach recommended "scan_def gds_layer_map" {
if {[info exists vars($recommended)] && ($vars($recommended) != "")} {
lappend check(files) $vars($recommended)
append commands "# INFO: $recommended = $vars($recommended)\n"
}
}
if {[info exists vars(gds_files)] && ($vars(gds_files) != "")} {
append commands "# INFO: gds_files = $vars(gds_files)\n"
foreach file $vars(gds_files) {
lappend check(files) $file
}
}
foreach recommended "max_route_layer filler_cells tie_cells dont_use_list antenna_diode" {
if {[info exists vars($recommended)] && ($vars($recommended) != "")} {
append commands "# INFO: $recommended = $vars($recommended)\n"
if {$recommended == "tie_cells"} {
if {[llength $vars(tie_cells)] > 2} {
append commands "# ERROR: Recommended variable vars($recommended) has more than two cells\n"
set errors($error_count) "Recommended variable vars($recommended) has more than two cells"
incr error_count
}
}
if {$recommended == "antenna_diode"} {
if {[llength $vars(antenna_diode)] > 1} {
append commands "# ERROR: Recommended variable vars($recommended) has more than one cells\n"
set errors($error_count) "Recommended variable vars($recommended) has more than one cells"
incr error_count
}
}
if {$recommended == "max_route_layer"} {
lappend check(integers) "$recommended"
}
} else {
if {($recommended == "dont_use_list")} {
if {![info exists vars(dont_use_file)]} {
append commands "# WARNING: Recommended variables dont_use_list and dont_use_file not defined\n"
set warnings($warning_count) "Recommended variables dont_use_list and dont_use_file not defined"
incr warning_count
}
} else {
append commands "# WARNING: Recommended variable vars($recommended) not defined\n"
set warnings($warning_count) "Recommended variable vars($recommended) not defined"
incr warning_count
}
}
}
foreach optional "size_only_file dont_use_file" {
if {[info exists vars($optional)]} {
lappend check(files) $vars($optional)
}
}
append commands "# ==============================================\n"
append commands "# Other Variables\n"
append commands "# ==============================================\n"
foreach other "jtag_cells jtag_rows spare_cells" {
if {[info exists vars($other)] && ($vars($other) != "")} {
append commands "# INFO: $other = $vars($other)\n"
} else {
append commands "# INFO: Variable vars($other) not defined\n"
}
}
# if {![info exists vars(view_definition_tcl)]} {
append commands "# ==============================================\n"
append commands "# Scale Factors\n"
append commands "# ==============================================\n"
foreach rc_corner $vars(rc_corners) {
set i 0
append commands "# INFO: $rc_corner:\n"
if {[info exists vars($rc_corner,scale_tcl)]} {
if {[file exists $vars($rc_corner,scale_tcl)]} {
incr i
append commands "# INFO: scaling file = $vars($rc_corner,scale_tcl)\n"
} else {
puts "<FF> ERROR: Scaling file $vars($rc_corner,scale_tcl) for rc corner $rc_corner defined but does not exist"
set errors($error_count) "Scaling file $vars($rc_corner,scale_tcl) for rc corner $rc_corner defined but does not exist"
incr error_count
}
} else {
foreach other "pre_route_res_factor post_route_res_factor \
pre_route_cap_factor post_route_cap_factor \
pre_route_clk_res_factor post_route_clk_res_factor \
pre_route_clk_cap_factor post_route_clk_cap_factor \
post_route_xcap_factor" {
if {[info exists vars($rc_corner,$other)]} {
append commands "# INFO: $other = $vars($rc_corner,$other)\n"
incr i
}
}
}
if {$i == 0} {
append commands "# WARNING: No scale factors set for rc corner ($rc_corner)\n"
set warnings($warning_count) "No scale factors set for rc corner ($rc_corner)"
incr warning_count
}
}
append commands "# ==============================================\n"
append commands "# Derating Factors\n"
append commands "# ==============================================\n"
set i 0
if {[info exists vars(derate_tcl)]} {
append commands "# INFO: derate file = $vars(derate_tcl)\n"
lappend check(files) $vars(derate_tcl)
incr i
} else {
foreach delay_corner $vars(delay_corners) {
append commands "# INFO: $delay_corner:\n"
if {[info exists vars($delay_corner,derate_tcl)]} {
append commands "# INFO: derate file = $vars($delay_corner,derate_tcl)\n"
lappend check(files) $vars($delay_corner,derate_tcl)
incr i
} else {
if {[info exists vars(derate_tcl)]} {
append commands "# INFO: derate file = $vars(derate_tcl)\n"
lappend check(files) $vars(derate_tcl)
} else {
foreach other "early_data_cell early_clock_cell early_cell_check \
late_data_cell late_clock_cell late_cell_check \
data_cell_early clock_cell_early cell_check_early \
data_cell_late clock_cell_late cell_check_late" {
if {[info exists vars($delay_corner,$other)]} {
append commands "# INFO: $other = $vars($delay_corner,$other)\n"
incr i
}
}
}
}
if {$i == 0} {
append commands "# WARNING: No derating factors set for delay corner ($delay_corner)\n"
set warnings($warning_count) "No derating factors set for delay corner ($delay_corner)"
incr warning_count
}
}
}
# }
if {![regexp "9.1" $vars(version)]} {
set valid "TRUE FALSE true false auto"
if {[info exists vars(enable_si_aware)]} {
if {[lsearch $valid $vars(enable_si_aware)] == -1} {
append commands "# ERROR: Variable vars(enable_si_aware) has illegal value\n"
set errors($error_count) "Variable vars(enable_si_aware) has illegal value"
incr error_count
append commands "# Must be one of '$valid'\n"
}
}
}
set valid [list true false]
foreach var "fix_hold_ignore_ios fix_hold_allow_tns_degradation" {
if {![info exists vars($var)]} {
continue
}
if {[lsearch $valid [string tolower $vars($var)]] == -1} {
append commands "# ERROR: Variable vars($var) has illegal value $vars($var)\n"
set errors($error_count) "Variable vars($var) has illegal value $vars($var)"
incr error_count
append commands "# Must be one of '$valid'\n"
}
}
set valid "pre_place pre_prects pre_cts pre_postcts pre_postroute pre_postroute_si pre_signoff true false"
foreach option "metalfill enable_ocv enable_ss" {
if {[info exists vars($option)]} {
if {[lsearch $valid $vars($option)] == -1} {
append commands "# ERROR: Variable vars($option) has illegal value ($vars($option))\n"
set errors($error_count) "Variable vars($option) has illegal value ($vars($option))"
incr error_count
append commands "# Must be one of '$valid'\n"
}
}
}
set pacs [FF::get_by_suffix vars ",pac_mode"]
set valid "read_only interface all"
foreach pac $pacs {
if {[info exists vars(pac_mode)]} {
if {[lsearch $valid $vars(pac_mode)] == -1} {
append commands "# ERROR: Variable vars(pac_mode) has illegal value\n"
set errors($error_count) "Variable vars(pac_mode) has illegal value"
incr error_count
append commands "# Must be one of '$valid'\n"
}
}
}
set valid "default pessimistic"
if {[info exists vars(si_analysis_type)]} {
if {[lsearch $valid $vars(si_analysis_type)] == -1} {
append commands "# ERROR: Variable vars(si_analysis_type) has illegal value\n"
set errors($error_count) "Variable vars(si_analysis_type) has illegal value"
incr error_count
append commands "# Must be one of '$valid'\n"
}
}
set valid "post_cts post_route both none"
if {[info exists vars(clock_eco)]} {
if {[lsearch $valid $vars(clock_eco)] == -1} {
append commands "# ERROR: Variable vars(clock_eco) has illegal value\n"
set errors($error_count) "Variable vars(clock_eco) has illegal value"
incr error_count
append commands "# Must be one of '$valid'\n"
}
}
# if {$vars(enable_flexilm)} {
# set warnings($warning_count) "Using vars(enable_flexilm) requires the following limited access feature : encFlexILM"
# incr warning_count
# if {$vars(place_opt_design)} {
# set warnings($warning_count) "Setting vars(place_opt_design) to 'false' as vars(enable_flexilm) is true"
# incr warning_count
# set vars(place_opt_design) false
# }
# }
###############################################################################
# The rda_Input(ui_pg_connections) variable is a special case as depending
# on the value of this variable, other 'user defined' variables must be
# dynamically checked
###############################################################################
#if {[info exists vars(pg_connections)]} {
# foreach option $vars(pg_connections) {
# if {![info exists vars($option)]} {
# append commands "# ERROR: The p/g connection definition is incomplete"
# append commands " Please add 'set vars($option) <global_net>' to your setup.tcl"
# set errors($error_count) "The p/g connection definition is incomplete; variable vars($option) is required"
# incr error_count
# }
# }
#}
set check(plugins) [list]
if {[info exists vars(metalfill)] && ($vars(metalfill) != false)} {
set check(plugins) metalfill_tcl
}
append commands "# ==============================================\n"
append commands "# Plug-ins\n"
append commands "# ==============================================\n"
set rc_plugins "syn_init_tcl syn_load_rtl_tcl pre_syn_load_lib_tcl post_syn_load_lib_tcl \
pre_syn_elab_tcl post_syn_elab_tcl syn_dft_setup_tcl pre_syn_gen_tcl \
post_syn_gen_tcl pre_syn_map_tcl post_syn_map_tcl post_syn_dft_tcl \
pre_syn_incr_tcl post_syn_incr_tcl pre_syn_place_tcl postload_syn_place_tcl \
preexport_syn_place_tcl preannotation_syn_place_tcl post_syn_place_tcl pre_syn_exit_tcl"
set edi_plugins "always_source_tcl pre_init_tcl post_init_tcl \
pre_place_tcl place_tcl post_place_tcl pre_cts_tcl cts_tcl post_cts_tcl \
pre_prects_tcl post_prects_tcl pre_postcts_tcl post_postcts_tcl \
pre_postcts_hold_tcl post_postcts_hold_tcl pre_route_tcl post_route_tcl \
pre_postroute_tcl post_postroute_tcl pre_postroute_hold_tcl post_postroute_hold_tcl \
pre_postroute_si_tcl post_postroute_si_tcl pre_postroute_si_hold_tcl
post_postroute_si_hold_tcl pre_signoff_tcl post_signoff_tcl \
pre_rebudget_tcl post_rebudget_tcl pre_flexilm_tcl post_flexilm_tcl \
pre_assemble_tcl post_assemble_tcl pre_model_gen_tcl post_model_gen_tcl \
pre_partition_place_tcl post_partition_place_tcl pre_assemble_flex_ilm_tcl post_assemble_flexilm_tcl \
pre_partition_tcl post_partition_tcl"
set vars(rc_plugins) $rc_plugins
set vars(edi_plugins) $edi_plugins
if {$vars(rc)} {
set plugin_list [join [concat $rc_plugins $edi_plugins]]
} else {
set plugin_list $edi_plugins
}
foreach plugin $plugin_list {
if {[info exists vars($plugin)] && ($vars($plugin) != "")} {
append commands "# INFO: Plug-in $plugin = $vars($plugin)\n"
lappend check(plugins) $plugin
lappend vars(plugins_defined) $plugin
}
}
if {$vars(novus) && [info exists vars(plugins_defined)]} {
FF_NOVUS::convert_plugins
}
set dist(lsf) "queue resource args"
set dist(custom) "script"
set dist(rsh) "host_list"
set dist(local) ""
if {[info exists vars(distribute)]} {
if {[info exists dist($vars(distribute))]} {
append commands "# ==============================================\n"
append commands "# Distribution Setup\n"
append commands "# ==============================================\n"
append commands "# INFO: Mode = $vars(distribute)\n"
foreach option $dist($vars(distribute)) {
if {![info exists vars($vars(distribute),$option)]} {
append commands "# ERROR: Required variable vars($vars(distribute),$option) not defined\n"
set errors($error_count) "Required variable vars($vars(distribute),$option) not defined"
incr error_count
} else {
append commands "# INFO: $option = $vars($vars(distribute),$option)\n"
}
}
} else {
append commands "# ERROR: Distribution mode $vars(distribute) not supported\n"
set errors($error_count) "Distribution mode $vars(distribute) not supported"
incr error_count
}
} else {
if {[info exists vars(hosts)] && ($vars(hosts) > 1)} {
append commands "#WARNING: Variable vars(hosts) > 1 but vars(distribute) not defined\n"
set warnings($warning_count) "Variable vars(hosts) > 1 but vars(distribute) not defined"
incr warning_count
}
}
append commands "# ==============================================\n"
append commands "# Type Check\n"
append commands "# ==============================================\n"
foreach integer $check(integers) {
if {![string is integer -strict $vars($integer)]} {
append commands "# ERROR: Variables is not an integer ($integer) ...\n"
set errors($error_count) "Variables is not an integer ($integer) ..."
incr error_count
}
}
append commands "# ==============================================\n"
append commands "# File Check\n"
append commands "# ==============================================\n"
set files 0
append commands "# INFO: Checking design files ...\n"
foreach file $check(files) {
# append commands "# INFO: $file ...\n"
if {![file exists $file]} {
append commands "# ERROR: File does not exist ($file) ...\n"
set errors($error_count) "File does not exist ($file)"
incr error_count
} else {
incr files
}
}
append commands "# INFO: ... found $files files\n"
set files 0
append commands "# INFO: Checking LEF files ...\n"
if {[info exists vars(lef_files)]} {
foreach file $vars(lef_files) {
if {![file exists $file]} {
append commands "# ERROR: File does not exist ($file)\n"
set errors($error_count) "File does not exist ($file)"
incr error_count
} else {
incr files
}
}
append commands "# INFO: ... found ($files/[llength $vars(lef_files)]) lef files\n"
}
set files 0
set total 0
# if {![info exists vars(view_definition_tcl)]} {
# if {![info exists vars(cpf_file)]} {
append commands "# INFO: Checking library sets ...\n"
foreach library_set $vars(library_sets) {
if {[info exists vars(enable_ldb)] && $vars(enable_ldb)} {
set temp_list $vars($library_set,timing,orig)
} else {
set temp_list $vars($library_set,timing)
}
foreach file $temp_list {
incr total
if {![file exists $file]} {
append commands "# ERROR: File does not exist ($file)\n"
# set errors($error_count) "File does not exist ($file)"
# incr error_count
} else {
incr files
}
}
if {[info exists vars($library_set,si)]} {
foreach file $vars($library_set,si) {
incr total
if {![file exists $file]} {
append commands "# WARNING: CDB file does not exist ($file)\n"
# set warnings($warning_count) "CDB file does not exist ($file)"
# incr warning_count
} else {
incr files
}
}
} else {
if {!$vars(enable_si_aware)} {
append commands "# WARNING: CDB libraries not defined for $library_set library set\n"
set warnings($warning_count) "CDB libraries not defined for $library_set library set"
incr warning_count
}
}
}
append commands "# INFO: ... found ($files/$total) library files\n"
if {$total != $files} {
set errors($error_count) "[expr $total - $files] timing library files were not found "
incr error_count
}
set files 0
# }
append commands "# INFO: Checking rc corners ...\n"
foreach file $check(rc_corners) {
if {![file exists $file]} {
append commands "# ERROR: File does not exist ($file)\n"
set errors($error_count) "File does not exist ($file)"
incr error_count
} else {
incr files
}
}
append commands "# INFO: ... found $files files\n"
set files 0
append commands "# INFO: Checking constraint modes ...\n"
foreach file_list $check(constraint_modes) {
foreach file $file_list {
if {![file exists $file]} {
if {![info exists vars(cpf_file)] || ([info exists vars(cpf_file)] && !$vars(cpf_timing))} {
append commands "# ERROR: File does not exist ($file)\n"
set errors($error_count) "File does not exist ($file)"
incr error_count
}
} else {
incr files
}
}
}
# }
append commands "# INFO: ... found $files files\n"
set files 0
append commands "# INFO: Checking plugin files ...\n"
foreach plug $check(plugins) {
set file $vars($plug)
if {![file exists $file] && ![file exists $vars(plug_dir)/$file]} {
append commands "# WARNING: File does not exist ($file) ... continuing\n"
lappend vars(missing_plugins) $plug
} else {
lappend vars(plugins_found) $plug
incr files
if {!$vars(enable_celtic_steps)} {
if {[regexp "postroute_si" $plug]} {
append warnings($warning_count) "Plug-in $plug will be skipped for siAware flow"
incr warning_count
append commands "# WARNING: Plug-in $plug will be skipped for siAware flow\n"
append commands "# To enable celtic based SI flow, use vars(enable_celtic_steps)\n"
}
}
}
}
append commands "# INFO: ... found $files files\n"
append commands "# =====================================================\n"
append commands "# Flow Options\n"
append commands "# =====================================================\n"
if {[info exists vars(partition_list)]} {
set flow hierarchical
} else {
set flow flat
}
set valid [list none default standard express extreme]
if {[lsearch $valid [string tolower $vars(flow_effort)]] == -1} {
append commands "# ERROR: Variable vars(flow_effort) has illegal value $vars(flow_effort)\n"
set errors($error_count) "Variable vars(flow_effort) has illegal value $vars(flow_effort)"
incr error_count
append commands "# Must be one of '$valid'\n"
}
append commands "# Flow = $flow\n"
append commands "# Flavor = $vars(flow)\n"
append commands "# Effort = $vars(flow_effort)\n"
append commands "# -----------------------------------------------------\n"
append commands "# Placement Options\n"
append commands "# -----------------------------------------------------\n"
if {[info exists vars(place_opt_design)]} {
append commands "# Place Opt Design = $vars(place_opt_design)\n"
}
if {[info exists vars(in_place_opt)]} {
append commands "# In Place Opt = $vars(in_place_opt)\n"
}
if {[info exists vars(no_pre_place_opt)]} {
append commands "# No PrePlace Opt = $vars(no_pre_place_opt)\n"
}
if {[info exists vars(place_io_pins)]} {
append commands "# Place IO Pins = $vars(place_io_pins)\n"
}
if {[info exists vars(clock_gate_aware)]} {
append commands "# Clock Gate Aware = $vars(clock_gate_aware)\n"
}
if {[info exists vars(congestion_effort)]} {
if {$vars(congestion_effort) == "none"} {
unset vars(congestion_effort)
} else {
append commands "# Congestion Effort = $vars(congestion_effort)\n"
}
}
append commands "# -----------------------------------------------------\n"
append commands "# Clock Tree Options\n"
append commands "# -----------------------------------------------------\n"
append commands "# Route Clock Nets = $vars(route_clock_nets)\n"
if {[info exists vars(clock_eco)]} {
append commands "# Clock ECO = $vars(clock_eco)\n"
}
append commands "# -----------------------------------------------------\n"
append commands "# Optimization Options\n"
append commands "# -----------------------------------------------------\n"
if {[info exists vars(leakage_effort)]} {
append commands "# Leakage Effort = $vars(leakage_effort)\n"
}
if {[info exists vars(preserve_assertions)]} {
append commands "# Preserve Assertions = $vars(preserve_assertions)\n"
}
if {[info exists vars(useful_skew)]} {
append commands "# Useful Skew = $vars(useful_skew)\n"
}
if {[info exists vars(critical_range)]} {
append commands "# Critical Range = $vars(critical_range)\n"
}
if {[info exists vars(all_end_points)]} {
append commands "# All End Points = $vars(all_end_points)\n"
}
if {[info exists vars(size_only_file)]} {
append commands "# Size Only File = $vars(size_only_file)\n"
}
if {[info exists vars(dont_use_file)]} {
append commands "# Don't Use File = $vars(dont_use_file)\n"
}
if {[info exists vars(skew_buffers)]} {
append commands "# Skew Buffers = $vars(skew_buffers)\n"
}
if {[info exists vars(enable_pac)]} {
append commands "# Enable PAC = $vars(enable_pac)\n"
if {[info exists vars(partition_list)]} {
foreach pac $vars(partition_list) {
if {[info exists vars($pac,pac_mode)]} {
append commands "# $pac -> $vars($pac,pac_mode)\n"
}
}
}
}
append commands "# -----------------------------------------------------\n"
append commands "# Hold Fixing Options\n"
append commands "# -----------------------------------------------------\n"
append commands "# Fix Hold = $vars(fix_hold)\n"
if {[info exists vars(fix_hold_effort)]} {
append commands "# Fix Hold Effort = $vars(fix_hold_effort)\n"
}
if {[info exists vars(fix_hold_ignore_ios)]} {
append commands "# Ignore IOs = $vars(fix_hold_ignore_ios)\n"
}
if {[info exists vars(fix_hold_allow_tns_degradation)]} {
append commands "# Allow TNS Degradation = $vars(fix_hold_allow_tns_degradation)\n"
}
append commands "# -----------------------------------------------------\n"
append commands "# Timing Options\n"
append commands "# -----------------------------------------------------\n"
append commands "# Enable CPPR = $vars(enable_cppr)\n"
append commands "# Enable OCV = $vars(enable_ocv)\n"
append commands "# Enable AOCV = $vars(enable_aocv)\n"
append commands "# Enable SOCV = $vars(enable_socv)\n"
append commands "# Enable SS = $vars(enable_ss)\n"
append commands "# -----------------------------------------------------\n"
append commands "# Routing Options\n"
append commands "# -----------------------------------------------------\n"
if {[info exists vars(track_opt)]} {
append commands "# In Route Optimization = $vars(track_opt)\n"
# if {$vars(track_opt)} {
# set vars(enable_si_aware) true
# if {![info exists vars(tquantus_file)]} {
# set errors($error_count) "tQuantus file - vars(tquantus_file) - required when vars(track_opt) set to true"
# incr error_count
# }
# }
}
if {[info exists vars(multi_cut_effort)]} {
append commands "# Multi-Cut Effort = $vars(multi_cut_effort)\n"
}
if {[info exists vars(litho_driven_routing)]} {
append commands "# Litho Driven Routing = $vars(litho_driven_routing)\n"
}
if {[info exists vars(antenna_diode)] && ($vars(antenna_diode) != "")} {
append commands "# Antenna Diode = $vars(antenna_diode)\n"
}
if {[info exists vars(relative_c_thresh)] || \
[info exists vars(total_c_thresh)] || \
[info exists vars(coupling_c_thresh)] ||\
[info exists vars(postroute_extraction_effort)] ||\
[info exists vars(signoff_extraction_effort)]} {
append commands "# -----------------------------------------------------\n"
append commands "# Extraction Options\n"
append commands "# -----------------------------------------------------\n"
}
if {[info exists vars(relative_c_thresh)]} {
append commands "# Relative C Threshold = $vars(relative_c_thresh)\n"
}
if {[info exists vars(total_c_thresh)]} {
append commands "# Total C Threshold = $vars(total_c_thresh)\n"
}
if {[info exists vars(coupling_c_thresh)]} {
append commands "# Coupling C Threshold = $vars(coupling_c_thresh)\n"
}
if {[info exists vars(postroute_extraction_effort)]} {
append commands "# Postroute Effort Level = $vars(postroute_extraction_effort)\n"
}
if {[info exists vars(signoff_extraction_effort)]} {
append commands "# Signoff Effort Level = $vars(signoff_extraction_effort)\n"
}
append commands "# -----------------------------------------------------\n"
append commands "# DFM Options\n"
append commands "# -----------------------------------------------------\n"
set check_lpa_tech 0
set check_lpa_conf 0
if {[info exists vars(fix_litho)] && $vars(fix_litho)} {
append commands "# Fix Litho = $vars(fix_litho)\n"
set check_lpa_conf 1
set vars(verify_litho) true
}
if {[info exists vars(verify_litho)] && $vars(verify_litho)} {
append commands "# Verify Litho = $vars(verify_litho)\n"
set check_lpa_tech 1
}
if {[info exists vars(lpa_tech_file)]} {
append commands "# LPA Tech File = $vars(lpa_tech_file)\n"
}
if {$check_lpa_tech} {
if {![info exists vars(lpa_tech_file)]} {
set errors($error_count) "LPA tech file not defined ..."
incr error_count
}
}
if {[info exists vars(lpa_conf_file)]} {
append commands "# LPA Conf File = $vars(lpa_conf_file)\n"
}
if {$check_lpa_conf} {
if {![info exists vars(lpa_conf_file)]} {
set errors($error_count) "LPA conf file not defined ..."
incr error_count
}
}
append commands "# -----------------------------------------------------\n"
append commands "# Signal Integrity Options\n"
append commands "# -----------------------------------------------------\n"
append commands "# Process = $vars(process)\n"
if {[info exists vars(delta_delay_threshold)]} {
append commands "# Delta Delay Threshold = $vars(delta_delay_threshold)\n"
}
if {[info exists vars(celtic_settings)]} {
append commands "# Celtic Settings = $vars(celtic_settings)\n"
}
if {[info exists vars(si_analysis_type)]} {
append commands "# Analysis Type = $vars(si_analysis_type)\n"
}
if {[info exists vars(acceptable_wns)]} {
append commands "# Analysis Type = $vars(acceptable_wns)\n"
}
if {[info exists vars(distribute)]} {
if {[info exists dist($vars(distribute))]} {
append commands "# -----------------------------------------------------\n"
append commands "# Multiple CPUs\n"
append commands "# -----------------------------------------------------\n"
append commands "# Mode = $vars(distribute)\n"
if {[info exists vars(local_cpus)]} {
append commands "# CPUs On Local Host = $vars(local_cpus)\n"
}
if {[info exists vars(remote_hosts)]} {
append commands "# Number of Remote Hosts = $vars(remote_hosts)\n"
}
if {[info exists vars(cpus_per_remote_host)]} {
append commands "# CPUs Per Remote Host = $vars(cpus_per_remote_host)\n"
}
}
} else {
if {[info exists vars(local_cpus)]} {
append commands "# -----------------------------------------------------\n"
append commands "# Multiple CPUs\n"
append commands "# -----------------------------------------------------\n"
append commands "# CPUs On Local Host = $vars(local_cpus)\n"
}
}
if {$vars(high_timing_effort)} {
if {[lindex [split $vars(version) "."] 0] < 15} {
append commands "# -----------------------------------------------------\n"
append commands "# <<< HIGH EFFORT FLOW ENABLED >>>\n"
append commands "# -----------------------------------------------------\n"
} else {
append commands "# WARNING: Variable vars(high_timing_effort) not supported anymore. Please use vars(flow_effort).\n"
set warnings($warning_count) "Variable vars(high_timing_effort) not supported anymore. Please use vars(flow_effort)."
incr warning_count
}
}
append commands "# =====================================================\n"
append commands "# Abort on Setup Error = $vars(abort)\n"
append commands "# =====================================================\n"
if {[lindex [split $vars(version) "."] 0] > 10} {
foreach var [array names save_vars] {
set vars($var) $save_vars($var)
}
}
set command ""
set vars(info_count) $info_count
if {$info_count > 0} {
append command "# -----------------------------------------------------\n"
append command "# Info Summary\n"
append command "# -----------------------------------------------------\n"
for {set i 0} {$i<$info_count} {incr i} {
append command "# ([expr $i + 1]) $infos($i)\n"
}
append command "# -----------------------------------------------------\n"
append commands $command
}
set vars(warning_count) $warning_count
if {$warning_count > 0} {
append command "# -----------------------------------------------------\n"
append command "# Warning Summary\n"
append command "# -----------------------------------------------------\n"
for {set i 0} {$i<$warning_count} {incr i} {
append command "# ([expr $i + 1]) $warnings($i)\n"
}
append command "# -----------------------------------------------------\n"
append commands $command
}
set vars(error_count) $error_count
if {$error_count > 0} {
append command "# -----------------------------------------------------\n"
append command "# Error Summary\n"
append command "# -----------------------------------------------------\n"
for {set i 0} {$i<$error_count} {incr i} {
append command "# ([expr $i + 1]) $errors($i)\n"
}
append command "# -----------------------------------------------------\n"
append commands $command
} else {
append commands "# SETUP CHECK PASSED\n"
append commands "# =====================================================\n"
}
file mkdir $vars(script_dir)
set op [open $vars(script_dir)/check.rpt w]
# if {$vars(novus)} {
# FF_NOVUS::dump_novus_attributes
# }
puts $op $commands
close $op
if {$vars(abort) && ($error_count > 0)} {
puts "<FF> Aborting due to previous errors ..."
puts "<FF> See $vars(script_dir)/check.rpt for details"
puts ""
puts " Error Summary"
puts " -------------"
for {set i 0} {$i<$error_count} {incr i} {
puts " ([expr $i + 1]) $errors($i)"
}
puts "-------------------------------------------------"
exit -1
}
if {!$vars(codegen)} {
if {![FF::is_lp_flow]} {
return
}
set vars(required_procs) "get_clock_ports get_power_domains modify_power_domains add_power_switches \
route_secondary_pg_nets buffer_always_on_nets insert_welltaps_endcaps"
}
set vars(check_setup) 0
# Record errors for later processing
set vars(check_setup_errors) {}
for {set i 0} {$i<$error_count} {incr i} {
lappend vars(check_setup_errors) $errors($i)
}
}
###############################################################################
# Procedure to determine flow flavor, check for ilms, etc.
###############################################################################
proc check_flow {} {
global vars
set vars(ilm) 0
set vars(top) 0
if {![info exists vars(partition_list)] || ([info exists vars(partition_list)] && \
([file tail [file dirname [pwd]]] != "$vars(partition_dir)"))} {
if {![info exists vars(partition_list)]} {
set vars(flavor) flat
if {![info exists vars(mode)]} {
set vars(mode) "flat"
}
} else {
set vars(flavor) hier
if {![info exists vars(mode)]} {
set vars(mode) "top_down"
}
}
if {[info exists vars(partition_list)] && ($vars(mode) == "bottom_up")} {
set vars(ilm) 1
}
if {[info exists vars(ilm_list)] && ($vars(ilm_list) != "")} {
set vars(ilm) 1
} else {
set vars(ilm) 0
}
} else {
if {[info exists vars(partition_list)]} {
set ptn [file tail [pwd]]
set vars(ptn) $ptn
if {([file tail [file dirname [pwd]]] == "$vars(partition_dir)") &&
([lsearch $vars(partition_list) $ptn] == -1)} {
set vars(ilm) 1
set vars(top) 1
# FF_NOVUS::normalize_constraints
}
}
}
if {$vars(debug)} {
puts "<DEBUG> Flow -> $vars(flavor) : Step -> $vars(step) : ILM -> $vars(ilm)"
}
}
proc run_compile {} {
global vars
file mkdir $vars(script_dir)/INNOVUS
set op [open $vars(script_dir)/INNOVUS/run_compile.tcl w]
set commands ""
if {![info exists vars(ldb_dir)]} {
set vars(ldb_dir) LDB
}
file mkdir $vars(ldb_dir)
set done_list [list]
foreach set $vars(library_sets) {
set file_list [list]
foreach file $vars($set,timing) {
if {[lsearch $done_list $file] == -1} {
append commands "write_ldb -library $file -outfile $vars(ldb_dir)/[file tail $file.ldb]\n"
lappend done_list $file
}
lappend file_list $vars(ldb_dir)/[file tail $file].ldb
}
set vars($set,timing,orig) $vars($set,timing)
set vars($set,timing) $file_list
}
puts $op "$commands\nexit\n"
close $op
set vars(ran_compile) 1
}
# # Generate the command to verify geometry. This is verifyGeometry
# # for traditional processes, verify_drc for 20nm and below.
# proc verify_geometry_command {} {
# global vars
# set process [regsub "nm" $vars(process) ""]
# if {$process > 20} {
# return "verifyGeometry"
# } else {
# return "verify_drc"
# }
# }