blob: e1152601eb1ef5ff05733a42f8e9649228ded850 [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 FFMM:: {
set validModes [list "flat" "hier" "top_down" "bottom_up" "user"]
set missingFiles "<FF> ERROR: Could not find Foundation Flow script files in directory \"%s\""
set missingSetupFile "<FF> ERROR: Could not find setup.tcl in directory \"%s\""
set missingRC "<FF> ERROR: Could not find 'rc' executable"
set noMode "<FF> ERROR: \"-m\" option specified without a runtime mode"
set noFlat "<FF> ERROR: \"-f\" option specified without a valid option"
set noVersion "<FF> ERROR: \"-v\" option specified without a valid option"
set noPath "<FF> ERROR: \"-d\" option specified without a directory path"
set noStyle "<FF> ERROR: \"-y\" option specified without a style option \[date|increment\]"
set noRundir "<FF> ERROR: \"-u\" option specified without a directory path"
set noSetupPath "<FF> ERROR: \"-s\" option specified without a directory path"
set noAppletPath "<FF> ERROR: \"-a\" option specified without a directory path"
set nosynth_flow "<FF> WARNING: \"-r\" option specified without a synthesis flow"
set noSuchPath "<FF> ERROR: Directory path \"%s\" not found."
set unknownMode "<FF> ERROR: Unknown runtime mode specified \"%s\" "
set unknownOption "<FF> ERROR: Unrecognized option \"%s\" "
set usage "
Usage: tclsh <path_to>/SCRIPTS/gen_flow.tcl <options> step ?step? ... ?step?
The \"step\" is the portion of the flow that you want to execute. To find
the valid list of steps for a given mode, simply omit the step from the
command-line invocation. You can also specify step as either of the two
forms:
a-b : Execute all steps between step a and b, inclusive
a- : Execute all steps in the flow from step a, inclusive
Obviously, \"a\" and \"b\" should be valid steps for the specific mode.
Options may be one or more of the following:
-h | --help : Print this message
-H | --Help : Print step help
-m | --mode : Set the script mode. The default is \"flat\".
Valid modes are: $validModes
-d | --dir : Output directory for generated scripts.
-f | --flat : Level of unrolling ... full, partial, none
-n | --nomake : Skip Makefile generation
-y | --style : Rundir naming style \[date|increment\]
-r | --rtl : Enable RTL Script Generation
-N | --Novus : Enable novus_ui flowkit generation
-s | --setup : Provide the directory containing the setup.tcl setup file
-u | --rundir : Directory to execute the flow
requried to run the Foundation Flow.
-v | --version : Target version (17.1.0, 16.2.0, 16.1.0, 15.2.0, 15.1.0, ...)
-V | --Verbose : Verbose mode
Examples:
---------
tclsh SCRIPTS/gen_innovus_flow.tcl all
tclsh SCRIPTS/gen_innovus_flow.tcl -m top_down all
tclsh SCRIPTS/gen_innovus_flow.tcl -d prects_scripts init-prects
tclsh SCRIPTS/gen_innovus_flow.tcl -u work/run -y date -r default_synthesis_flow_3step all
"
}
namespace eval FF:: {
variable valid_versions {
17.1.0
16.2.0 16.1.0
15.2.0 15.1.0
14.2.0 14.1.0
13.2.0 13.1.0
12.1.0
11.1.3 11.1.2 11.1.1 11.1.0
10.1.3 10.1.2 10.1.1 10.1.0
9.1.3 9.1.2
}
proc wrap_command {tag command} {
global vars
global env
global errors
# if {$vars(debug)} {
# puts "<FF> Wrapping command: $command in step $vars(step) ..."
# }
if {![info exists vars(tags,verbose)]} {
set verbose FALSE
} else {
set verbose $vars(tags,verbose)
}
if {![info exists vars(tags,verbosity_level)]} {
set verbosity_level LOW
} else {
switch [string toupper $vars(tags,verbosity_level)] {
"LOW" {
set verbosity_level LOW
}
"HIGH" {
set verbosity_level HIGH
}
default {
set verbosity_level LOW
}
}
}
if {[info exists vars($tag,pre_tcl)] || \
[info exists vars($tag,post_tcl)] || \
[info exists vars($tag,skip)] || \
[info exists vars($tag,replace_tcl)]} {
if {![info exists vars(tagged)]} {
set vars(tagged) [list]
}
}
if {$verbosity_level == "HIGH"} {
set commands "# <BEGIN TAG> $tag\n"
} else {
set commands ""
}
# set commands ""
if {[info exists vars($tag,skip)] && $vars($tag,skip)} {
lappend vars(tagged) $tag,skip
regsub -all "\\\n" "\n\n$command\n" "\n# " skip
# append skip "\n"
if {$verbose} {
append commands "\n# <begin tag $tag,skip>"
}
append commands $skip
if {$verbose} {
append commands "<end tag $tag,skip>\n\n"
}
append commands "\n"
if {$verbose} {
return $commands
} else {
return
}
}
if {[info exists vars($tag,pre_tcl)]} {
if {[file exists $vars($tag,pre_tcl)]} {
lappend vars(tagged) $tag,pre_tcl
if {$vars(flat) == "full"} {
set ip [open $vars($tag,pre_tcl) r]
if {$verbose} {
append commands "\n# <begin tag $tag,pre_tcl>\n"
}
while {[gets $ip line]>=0} {
append commands "$line\n"
}
close $ip
if {$verbose} {
append commands "# <end tag $tag,pre_tcl>\n\n"
}
} else {
append commands "source $vars($tag,pre_tcl)\n"
}
} else {
puts "<FF> ERROR: $tag pre_tcl file ($vars($tag,pre_tcl)) not found"
set errors($vars(error_count)) "$tag pre_tcl file ($vars($tag,pre_tcl)) not found"
incr vars(error_count)
if {$verbose} {
append commands "# <end tag $tag,pre_tcl>\n\n"
}
}
}
if {[info exists vars($tag,replace_tcl)]} {
if {[file exists $vars($tag,replace_tcl)]} {
lappend vars(tagged) $tag,replace_tcl
set ip [open $vars($tag,replace_tcl) r]
if {$verbose} {
append commands "\n# <begin tag $tag,replace_tcl>\n"
}
while {[gets $ip line]>=0} {
append commands "$line\n"
}
close $ip
} else {
puts "<FF> ERROR: $tag replace_tcl file ($vars($tag,replace_tcl)) not found"
set errors($vars(error_count)) "$tag replace_tcl file ($vars($tag,replace_tcl)) not found"
incr vars(error_count)
}
if {$verbose} {
append commands "# <end tag $tag,replace_tcl>\n\n"
}
} else {
# Insert original command here
append commands $command
}
if {[info exists vars($tag,post_tcl)]} {
if {[file exists $vars($tag,post_tcl)]} {
lappend vars(tagged) $tag,post_tcl
if {$verbose} {
append commands "\n# <begin tag $tag,post_tcl>\n"
}
if {$vars(flat) == "full"} {
set ip [open $vars($tag,post_tcl) r]
while {[gets $ip line]>=0} {
append commands "$line\n"
}
close $ip
# if {$verbose} {
# append commands "#<<<\n"
# }
} else {
append commands "source $vars($tag,post_tcl)\n"
}
} else {
puts "<FF> ERROR: $tag post_tcl file ($vars($tag,post_tcl)) not found"
set errors($vars(error_count)) "$tag post_tcl file ($vars($tag,post_tcl)) not found"
incr vars(error_count)
}
if {$verbose} {
append commands "# <end tag $tag,post_tcl>\n\n"
}
}
if {$verbosity_level == "HIGH"} {
append commands "\n# <END TAG> $tag\n"
}
return $commands
}
proc get_line_match {pattern file} {
set ip [open $file r]
while {[gets $ip line]>=0} {
if {[regexp "$pattern" $line]>0} {
set match $line
}
}
return $match
}
proc singular {val {false "s"} {true ""}} {
if {$val==1} { return $true } else { return $false }
}
proc size {val {suffix "byte"}} {
set level 0
set prefixes [list "" kilo mega giga tera peta]
while {$val>1024} {
set val [expr $val/1024.0]
incr level
}
set val [expr int($val+0.5)]
return "$val [lindex $prefixes $level]$suffix[singular $val]"
}
proc system_info {} {
global vars
set uname [exec uname]
if {[lsearch "Linux" $uname] != -1} {
set inFile "$vars(script_root)/ETC/status.dat"
if {![file exists $inFile]} {
return
}
set upId [open "/proc/uptime" r]
set info(uptime) [lindex [split [gets $upId] .] 0]
close $upId
foreach {var val} {mon 2592000 wks 604800 day 86400 hrs 3600 min 60 sec 1} {
set info(uptime.${var}) [expr $info(uptime)/${val}]
set info(uptime) [expr $info(uptime)-($info(uptime.${var})*${val})]
}
set info(host.fqdn) [info hostname]
set info(host.name) [lindex [split $info(host.fqdn) .] 0]
set info(host.domain) [string range $info(host.fqdn) [expr [string length $info(host.name)]+1] end]
set info(host.os) $::tcl_platform(os)
set info(host.osver) $::tcl_platform(osVersion)
set info(host.machine) $::tcl_platform(machine)
if {$info(host.os)=="Linux"} {
if {[file exists /etc/slackware-version]} { set info(host.distribution) "Slackware" }
if {[file exists /etc/redhat-release]} { set info(host.distribution) "RedHat" }
if {[file exists /etc/mandrake-release]} { set info(host.distribution) "Mandrake" }
if {![info exists info(host.distribution)]} { set info(host.distribution) "Unknown" }
} else {
return
}
set cpuId [open "/proc/cpuinfo" r]
set info(cpu.total) 0
set info(cpu.cpucores) 1
while {![eof $cpuId]} {
gets $cpuId ln
set ln [split $ln :]
set item [string trim [lindex $ln 0]]
set value [string trim [lindex $ln 1]]
set info(cpu.[lindex $item 0][lindex $item 1]) $value
if {[lindex $item 0] == "processor"} {incr info(cpu.total)}
}
close $cpuId
set memId [open "/proc/meminfo" r]
set info(mem.free) 0
while {![eof $memId]} {
gets $memId ln
set ln [split $ln :]
set item [string trim [lindex $ln 0]]
catch { set value [expr [string trim [lindex [lindex $ln 1] 0]]*1024] }
switch -- "$item" {
MemTotal { set info(mem.total) $value }
SwapTotal { set info(mem.swap.total) $value }
SwapFree { set info(mem.swap.free) $value }
MemFree { incr info(mem.free) $value }
Cached { incr info(mem.free) $value }
Buffers { incr info(mem.free) $value }
}
}
set parseId [open $inFile r]
while 1 {
gets $parseId ln
if {[eof $parseId]} { break }
catch { puts [subst $ln] } err
}
close $parseId
}
}
############################################################################
# This routine iterates over variables that maintain lists of files. If
# any element of the list is a wildcard, that entry is replaced with the
# Tcl command that will expand the name at runtime
############################################################################
proc process_file_lists {} {
global vars
if {![info exists vars(globbed)]} {
set vars(globbed) false
}
if {$vars(globbed)} {
return
}
set vars(globbed) true
if {[regexp "^11" $vars(version)]} {
return
}
# BCL: Removed def_files from this list
set var_indices [list "cts_spec" "lef_files" \
"timing" "si" "ecsm" "cts_sdc"]
# BCL: Add def_files to list only if it doesn't have [subst] in the name (other wise we need to keep [subst... unexpanded)
if {[info exists vars(def_files)] && ![regexp {\[subst \$vars} $vars(def_files)]} {lappend var_indices def_files}
foreach index $var_indices {
set all_names [array names vars -glob "*$index"]
foreach name $all_names {
set expanded_files ""
# BCL: Added subst around final variable to resolve vars(rundir) references
foreach file [subst $vars($name)] {
if {([string first "*" $file] != -1) ||
([string first "?" $file] != -1)} {
if {![catch {set files [glob $file]}]} {
lappend expanded_files $files
}
} else {
lappend expanded_files $file
}
}
set vars($name) $expanded_files
}
}
}
proc get_required_procs {file} {
#
# Given a list of required procedures, return the lines that represent
# those procedures from the utils.tcl file
#
global vars
global errors
#
# Read the file and gather all of the contents
#
set all_lines ""
set length 0
set ip [open $file]
while {[gets $ip line]>=0} {
if {[info exists vars(novus)] && $vars(novus)} {
set utils_lines($length) [regsub "Puts" $line "puts"]
} else {
set utils_lines($length) $line
}
incr length
}
close $ip
#
# Iterate across each line and pull out relevant procedures
#
set lines ""
set i 0
while {$i < $length} {
set line $utils_lines($i)
foreach proc $vars(required_procs) {
if {[regexp "proc $proc" $line] > 0} {
append lines " $line\n"
incr i
while {$i < $length} {
set line $utils_lines($i)
if {[regexp "proc " $line] > 0} {
incr i -1
break
}
if {![regexp "^#" [string trimleft $line] ] && ($i != [expr $length-1])} {
append lines "$line\n"
}
incr i
}
break
}
}
incr i
}
set lines [string trimright $lines]
return "$lines\n"
}
proc source_plug {plugin {abort 1}} {
global vars
global env
global warnings
global plugin_error
global errorInfo
global return_code
# Added for ETS/EPS
if {![info exists vars(flat)]} {
set vars(flat) full
}
if {[info exists vars(codegen)] && !$vars(codegen)} {
set vars(flat) full
}
set flat $vars(flat)
if {$vars(generate_flow_steps)} {
#set vars(flat) full
}
if {[info exists vars(verbose)] && $vars(verbose)} {
set verbose true
} else {
set verbose false
}
set commands "puts \"<FF> Plugin -> $plugin\"\n"
set no_comments ""
if {[info exists vars($plugin)]} {
if {![info exists vars(plugins)]} {
set vars(plugins) [list]
}
if {[lsearch $vars(plugins) $plugin] == -1} {
set suffix [lindex [split $plugin ","] 1]
if {($suffix != "derate_tcl") && ($suffix != "scale_tcl")} {
lappend vars(plugins) $plugin
}
}
set found 0
set plug_list []
foreach plug_file $vars($plugin) {
if {[file exists $plug_file]} {
set found 1
lappend plug_list $plug_file
continue
} elseif {[file exists $vars(plug_dir)/$plug_file]} {
set found 1
# lappend plug_list $plug_file
lappend plug_list $vars(plug_dir)/$plug_file
continue
} else {
if {[file exists $vars(cwd)/$plug_file]} {
set found 1
lappend plug_list $vars(cwd)/$plug_file
continue
}
}
}
if {!$found} {
if {![info exists vars(missing_plugins)]} {
set vars(missing_plugins) [list]
}
if {[lsearch $vars(missing_plugins) $plugin] == -1} {
lappend vars(missing_plugins) $plugin
set warnings($vars(warning_count)) "Plug-in $plugin defined but file(s) not found"
incr vars(warning_count)
}
}
if {$vars(flat) == "partial"} {
foreach plug_file $plug_file {
if {[file exists $plug_file]} {
append commands "puts \"<FF> LOADING \'$plug_file\' PLUG-IN FILE(s) \"\n"
append commands "if { \[ catch { source $plug_file } plugin_error \] } {\n"
append commands " puts \"<FF> ============= PLUG-IN ERROR ==================\"\n"
append commands " puts \"<FF> \$errorInfo\"\n"
append commands " puts \"<FF> \$plugin_error\"\n"
append commands " puts \"<FF> ==============================================\"\n"
append commands " set return_code 99\n"
if {$abort} {
append commands " exit \$return_code\n"
}
append commands "}\n"
}
}
} elseif {$vars(flat) == "full"} {
if {!$found} {
append commands "ff_procs::source_plug $plugin\n"
} else {
if {$verbose && ![regexp "," $plugin]} {
set commands "\n# <begin plug-in $plugin>\n"
}
if {![info exists vars(plug_files)]} {
set vars(plug_files) [list]
}
foreach plug_file $plug_list {
if {[file exists $plug_file]} {
# if {$verbose} {
# append commands "#>>>\n"
# }
append commands "# <begin $plug_file>\n"
if {[info exists vars(old_plugins)] && $vars(old_plugins) && ([lsearch $vars(edi_plugins) $plugin] != -1)} {
append commands "eval_enc \{\n"
}
if {[lsearch $vars(plug_files) $plugin] == -1} {
set suffix [lindex [split $plugin ","] 1]
if {($suffix != "derate_tcl") && ($suffix != "scale_tcl")} {
lappend vars(plug_files) "$plugin"
}
}
set ip [open $plug_file r]
while {[gets $ip line]>=0} {
# if {![regexp "^$" $line]} {
if {$vars(generate_flow_steps)} {
append commands " $line\n"
} else {
append commands "$line\n"
}
if {![regexp "^#" $line]} {
append no_comments " $line\n"
}
# }
}
close $ip
append commands "# <end $plug_file>\n"
if {[info exists vars(old_plugins)] && $vars(old_plugins) && ([lsearch $vars(edi_plugins) $plugin] != -1)} {
append commands "\}\n"
}
# if {$verbose} {
# append commands "#<<<\n"
# }
} elseif {[file exists $vars(plug_dir)/$plug_file]} {
# if {$verbose} {
# append commands "#>>>\n"
# }
if {[lsearch $vars(plug_files) $plugin] == -1} {
set suffix [lindex [split $plugin ","] 1]
if {($suffix != "derate_tcl") && ($suffix != "scale_tcl")} {
lappend vars(plug_files) "$plugin"
}
}
set ip [open $vars(plug_dir)/$plug_file r]
while {[gets $ip line]>=0} {
if {![regexp "^$" $line]} {
append commands "$line\n"
}
if {![regexp "^#" $line]} {
append no_comments " $line\n"
}
}
close $ip
# if {$verbose} {
# append commands "#<<<\n"
# }
}
}
if {$verbose && ![regexp "," $plugin]} {
append commands "# <end plug-in $plugin>\n\n"
}
}
} else {
append commands "ff_procs::source_plug $plugin\n"
}
}
set vars(flat) $flat
if {$vars(generate_flow_steps) && ($no_comments != "") && ![regexp ff_procs $commands] && ![regexp derate_tcl $plugin]} {
if {$no_comments == ""} {
set commands ""
}
if {[lindex [split $vars(version) "."] 0] > 14} {
if {![file exists $vars(cwd)/.plugins]} {
set op [open $vars(cwd)/.plugins w]
} else {
set op [open $vars(cwd)/.plugins a]
}
if {[regexp "^pre_$vars(step)" $plugin] && ($vars(step) != "partition_place")} {
set type begin_tcl
} else {
if {[regexp "^post_$vars(step)" $plugin] && ($vars(step) != "partition_place")} {
set type end_tcl
} else {
if {[regexp "^syn" $plugin] || [regexp "^always" $plugin] || [regexp "^final_always" $plugin] || [regexp "^pre_syn" $plugin]} {
set type import
} else {
if {$vars(step) != "partition_place"} {
set type skip
} else {
set type import
}
}
}
}
set step_plug [format %s_%s $vars(step) $plugin]
if {![info exists vars(processed_plugins)]} {
set vars(processed_plugins) [list]
lappend vars(processed_plugins) $step_plug
} else {
# puts "$vars(processed_plugins) : $step_plug"
if {[lsearch $vars(processed_plugins) $step_plug] == -1} {
lappend vars(processed_plugins) $step_plug
} else {
if {($vars(step) != "partition_place") && ![regexp "always" $plugin]} {
set type skip
}
}
}
if {$type != "skip"} {
# if {$type == "import"} {
# set ip [open $plug_file r]
# while {[gets $ip line]>=0} {
# if {![regexp "^$" $line]} {
# append commands " $line\n"
# if {![regexp "^#" $line]} {
# append no_comments " $line\n"
# }
# }
# }
# close $ip
return $commands
} else {
if {[info exists vars(old_plugins)] && ![regexp syn_ $vars(step)]} {
set temp "set_db flow_step:$vars(step) .$type { eval_enc {\n"
append temp $no_comments
append temp "}}\n"
puts $op $temp
} else {
set temp "set_db flow_step:$vars(step) .$type {\n"
append temp $no_comments
append temp "}\n"
puts $op $temp
}
}
} else {
puts "Skipping plugin $plugin as it cannot be (or already has been) tied to a flow_step attribute"
}
close $op
} else {
return $commands
}
} else {
return $commands
}
}
namespace export get_tool
proc get_tool {} {
set tool_name ""
set path_to_exe [info nameofexecutable]
if {[regexp {/rc(64)?(-\w)?$} $path_to_exe]} {
set tool_name "rc"
} elseif {[regexp {/genus(64)?(-\w)?$} $path_to_exe]} {
set tool_name "rc"
} elseif {[regexp {.*\/(LEC|lec)} $path_to_exe]} {
set tool_name "lec"
} elseif {[regexp {.*\/verify} $path_to_exe]} {
set tool_name "clp"
} elseif {[regexp {.*\/CCD} $path_to_exe]} {
set tool_name "ccd"
} elseif {[regexp {.*\/ctos} $path_to_exe]} {
set tool_name "ctos"
} elseif {[regexp {.*\/tclsh} $path_to_exe]} {
set tool_name "tclsh"
} elseif {[regexp {.*\/innovus} $path_to_exe]} {
set tool_name "edi"
} elseif {[regexp {.*\/encounter} $path_to_exe]} {
set tool_name "edi"
} elseif {[regexp {.*\/velocity} $path_to_exe]} {
set tool_name "edi"
} elseif {[regexp {.*\/ncsim} $path_to_exe]} {
set tool_name "ies"
}
return $tool_name
}
proc source_file {file {abort 1}} {
global vars
global source_error
global errorInfo
global return_code
# puts "<FF> LOADING '$file' FILE"
if {[file exists $file]} {
if {[info command FF::get_tool] ne "" && [FF::get_tool] eq "rc" } {
set sourceResult [catch { uplevel tcl_source $file } source_error ]
} else {
set sourceResult [catch { uplevel source $file } source_error ]
}
if { $sourceResult } {
puts "<FF> =============== TCL ERROR ===================="
puts "<FF> Error loading $file file"
puts "<FF> $errorInfo"
puts "<FF> $source_error"
puts "<FF> =============================================="
set return_code 99
if {$abort} {
exit $return_code
}
}
}
}
proc get_by_suffix {passed_array {suffix ""}} {
#
# Get the list of array indices that have a suffix of the
# passed string sequence
#
upvar $passed_array the_array
#
# If there is no suffix, return every name
#
if {[string length $suffix] == 0} {
return array names the_array
}
#
# If there is a suffix, find the matching names and return
# the list of those names (without the suffix attached to it).
# This is most helpful when looking for "multi-dimensional array
# indices" (in quotes because Tcl doesn't support multiple
# dimensions for array indices)
#
set suffix_length [string length $suffix]
set all_names [array names the_array -glob "*$suffix"]
set names [list]
foreach name $all_names {
set length [string length $name]
set index [string range $name 0 [expr $length - $suffix_length - 1]]
lappend names $index
}
return $names
}
###########################################################################
# Utility procedures on lists
###########################################################################
proc lintersection {lista listb} {
#
# Return the intersection of lista and listb, removing any duplicates
#
set intersect [list]
foreach a $lista {
if {([lsearch $listb $a] != -1) && \
([lsearch $intersect $a] == -1)} {
lappend intersect $a
}
}
return $intersect
}
proc lunion {lista listb} {
#
# Return the union of lista and listb, removing any duplicates
#
set union [list]
foreach a $lista {
if {[lsearch $union $a] == -1} {
lappend union $a
}
}
foreach b $listb {
if {[lsearch $union $b] == -1} {
lappend union $b
}
}
return $union
}
###########################################################################
# Utilities to handle different control structure output (if-then-else,
# foreach, etc.)
###########################################################################
proc for_each {var var_list code_block} {
#
# Return a string for a Tcl foreach block
#
set code ""
if {![llength $code_block]} {
return $code
}
set code "foreach $var $var_list \{\n"
foreach line [getLines $code_block] {
append code " $line"
}
append code "\}\n"
return $code
}
proc get_lines {code_block} {
#
# Return a list of lines from the strings in code_block
#
set block [list]
while {[llength $code_block]} {
set index [string first "\n" $code_block]
if {$index == -1} {
set index [string length $code_block]
}
set line [string range $code_block 0 $index]
set code_block [string range $code_block [expr $index + 1] end]
if {[string index $line end] != "\n"} {
append line "\n"
}
lappend block $line
}
return $block
}
proc if_else {cond then_block {else_block ""}} {
#
# Output a Tcl if-then-else block with the passed data.
#
set command "if \{$cond\} \{\n"
foreach line [get_lines $then_block] {
append command " $line"
}
if {[llength $else_block]} {
append command "\} else \{\n"
foreach line [get_lines $else_block] {
append command " $line"
}
}
append command "\}\n"
return $command
}
proc pretty_print_lists {line debug} {
#
# If there is an explicit Tcl list in the line, we may want to
# separate it out into multiple lines. It will turn a list from
# [list a b c]
# into
# [list a \
# b \
# c]
# That may not look like much, but for lists that have really *big*
# text entries, it makes it look a lot nicer
#
# If there is no list in the line, do nothing
#
set endChar [string index $line end]
set line [string trimright $line]
if {$endChar == "\n"} {
append line "\n"
}
set listPos [string first "\[list " $line]
if {$listPos == -1} {
return $line
}
set original $line
#
# Initialize the line with the contents of the line up to and including
# the "[list " text. Also determine the amount of indentation in the
# line so that we know what to do for subsequent lines
#
incr listPos 5
set nextLine [string range $line 0 $listPos]
set indent [string repeat " " [string length $nextLine]]
set line [string trimleft [string range $line $listPos end]]
#
# Make sure that there is no space between the close brace in the list
# and the last text in the list. This will help with processing (below)
#
set line [string trimright $line]
if {[string index $line end] != "\]"} {
return $original
}
set line [string range $line 0 [expr [string length $line] - 2]]
set line [string trimright $line]
append line "\]\n"
#
# Parse each element in the list
#
set printString ""
while {[string length $line]} {
#
# Get the next item in the list
#
set space [string first " " $line]
if {$space == -1} {
set space [string length $line]
}
set arg [string range $line 0 $space]
append nextLine $arg
#
# Remove that item from the line
#
set line [string range $line [expr $space + 1] end]
set line [string trimleft $line]
if {[string length $line]} {
if {[string length $nextLine] > 80} {
append printString "$nextLine\\\n"
set nextLine $indent
}
}
}
append printString $nextLine
return $printString
}
proc pretty_print {commands format_options {debug 0}} {
global vars
#
# Pretty print the lines, one by one. The following will be done:
# o If the line is greater than 80 columns, we will break it up
# along the options (-option) and indent
# o Fix any indentation
#
if {[info exists vars(catch_errors)] && $vars(catch_errors)} {
set indent 3
} else {
set indent 0
}
set lines ""
set len [string length $commands]
while {$len > 0} {
#
# Handle the simple case. If the leading character is a carriage
# return, append a blank line to the pretty-printed lines and
# continue on
#
set cr [string first "\n" $commands]
if {!$cr} {
set commands [string range $commands 1 end]
incr len -1
append lines "\n"
continue
}
#
# If we didn't find a carriage return in the string, the entire thing
# is a single line. Otherwise, remove the next line from the set of
# lines. If it still ends up being a blank line, append the blank
# line to the pretty-printed string and continue on
#
if {$cr == -1} {
set line $commands
set commands ""
set len 0
} else {
set line [string range $commands 0 $cr]
set commands [string range $commands [incr cr] end]
set len [expr $len - $cr]
}
set line [string trimright $line]
if {![string length $line]} {
append lines "\n"
continue
}
#
# We have a real line with real text. If there is no quote in the
# string, compress multiple blank spaces to a single blank space
#
set line [string trimleft $line]
if {[string first "\"" $line] == -1} {
set line [regsub -all {\s+} $line " "]
}
#
# Apply the proper amount of indentation
#
set isPut [string equal -nocase -length 5 $line "puts "]
set firstChar [string index $line 0]
if {$firstChar == "\}"} {
incr indent -3
}
set blanks [string repeat " " $indent]
set line "${blanks}${line}"
if {[string index $line end] == "\{"} {
incr indent 3
}
#
# If the first character is a dash, we have already broken the line
# up for pretty printing.
#
if {$firstChar == "-"} {
append lines " $line\n"
continue
}
#
# Don't bother formatting comments or short lines. Also, if the
# routine has been told not to format the command line options, just
# output the line
#
set lineLen [string length $line]
if {$isPut || ($firstChar == "\#") ||
($lineLen < 80) || !$format_options} {
append lines "$line\n"
continue
}
#
# The line length is over 80, and it's a real Innovus command, and it's
# not a print (puts) statement. Start indenting on the -option
# options. The first "-option" should be on the same line as the
# command. All subsequent options should be on their own line,
# slightly indented from the basic command
#
set firstDash [string first " -" $line]
if {$firstDash == -1} {
append lines "$line\n"
continue
}
set dash [string first " -" $line [incr firstDash]]
set leading ""
while {$dash != -1} {
set fragment [string range $line 0 [expr $dash - 1]]
append lines \
[pretty_print_lists "${leading}${fragment} \\\n" $debug]
set leading "$blanks "
set line [string range $line [expr $dash + 1] end]
set line [string trimleft $line]
set dash [string first " -" $line]
}
append lines [pretty_print_lists "${leading}${line}\n" $debug]
}
return $lines
}
proc strip_lines {commands markers} {
#
# This routine strips out lines from $commands when they start with
# any of the list elements in $markers
#
set lines ""
while {[string length $commands] > 0} {
#
# Get the next line from the set of commands
#
set cr [string first "\n" $commands]
if {$cr == -1} {
set line $commands
set commands ""
} else {
set line [string range $commands 0 $cr]
set commands [string range $commands [incr cr] end]
}
#
# If the line starts with a marker, ignore the line
#
set trimmed [string trimleft $line]
set matched false
foreach marker $markers {
set len [string length $marker]
if {[string equal -nocase -length $len $marker $trimmed]} {
set matched true
break
}
}
if {$matched} {
continue
}
append lines $line
}
return $lines
}
proc gen_makefile {steps type} {
global vars
global desc
global env
global errors
if {!$vars(makefile)} {
return
}
set desc(syn_map) "Technology Mapping"
set desc(syn_incr) "Incremental Synthesis"
set desc(syn_place) "Placement/Physical Synthesis"
set desc(init) "Design Import / Initialization"
if {$vars(rc)} {
set desc(place) "Legalization"
} else {
set desc(place) "Cell Placement"
}
set desc(prects) "PreCTS Optimization"
set desc(cts) "Clock Tree Synthesis"
set desc(postcts) "PostCTS Optimization"
set desc(postcts_hold) "PostCTS Hold Fixing"
set desc(route) "Global/Detail Route"
set desc(postroute) "PostRoute Optimization"
set desc(postroute_hold) "PostRoute Hold Fixing"
set desc(postroute_si_hold) "SI Hold Fixing"
set desc(postroute_si) "SI Optimization"
set desc(signoff) "Signoff Timing / Verify"
if {$vars(debug)} {
puts "<DEBUG> Generating $type makefile in [exec pwd] for steps $steps ..."
# if {[info exists vars(partition_dir)]} {
# puts "vars(partition_dir) -> $vars(partition_dir)"
# puts "[file tail [file dirname [exec pwd]]] == $vars(partition_dir)"
# puts "[file dirname [exec pwd]] == [file normalize $vars(partition_dir)]"
# }
}
puts "-------------------------------------------------"
puts "<FF> Generating $type Makefile for [llength $steps] steps"
puts "<FF> Directory: [pwd]"
puts "<FF> Steps: $steps"
# puts "-------------------------------------------------"
# BCL: Note - the Makefile needs to be fixed to the rundir here, as it will be dumped in the final exported
# vars.tcl
if {$vars(make) == "all"} {
if {([file tail [file dirname [exec pwd]]] == $vars(partition_dir)) || \
([file tail [file dirname [exec pwd]]] == $vars(partition_dir_pass2))} {
set vars(makefile_name) "Makefile"
} else {
set vars(makefile_name) "\$vars(rundir)/Makefile"
}
} else {
if {[file tail [file dirname [exec pwd]]] == $vars(partition_dir)} {
set vars(makefile_name) "Makefile.$vars(argv)"
} else {
set vars(makefile_name) "\$vars(rundir)/Makefile.$vars(argv)"
}
}
regsub -all " " $vars(makefile_name) "_" vars(makefile_name)
set op [open [subst $vars(makefile_name)] w]
# if {$vars(debug)} {
# puts "<DEBUG> Opening file: $vars(makefile_name) in [exec pwd] -> $op"
# }
# set stop signoff
set stop [lindex $vars(steps) [expr [llength $vars(steps)]-1]]
if {$vars(rc) && [info exists vars(rc_steps)]} {
set start [lindex $vars(rc_steps) 0]
} else {
set start [lindex $vars(steps) 0]
}
if {$type == "hier"} {
set type top_down
if {$vars(hier_flow_type) == "2pass"} {
set type 2pass
if {$vars(enable_flexilm)} {
set type flexilm
}
}
}
if {$type == "user"} { set type flat }
switch $type {
"flat" {
set execute_string [join $vars(execute_string)]
puts $op "VERSION=17.10-p003_1"
puts $op "VPATH=$env(VPATH)"
puts $op "TCLSH=[lindex $execute_string 0]"
puts $op "GEN_FLOW=[::FF::relPathTo [file normalize [subst [lindex $execute_string 1]]] [file normalize [subst $vars(rundir)]]]"
puts $op "SETUP_PATH=[relPathTo [file normalize [subst $vars(setup_path)]] [file normalize [subst $vars(rundir)]]]"
puts $op "TOOL=$vars(make_tool)"
puts $op "ARGS=$vars(make_tool_args)"
puts $op "FSTEPS=$steps"
if {$vars(rc)} {
puts $op "SYN_TOOL=$vars(make_syn_tool)"
puts $op "SYN_ARGS=$vars(make_syn_tool_args)"
if {[info exists vars(syn_log_dir)]} {
puts $op "SYN_LOG=[relPathTo [file normalize [subst $vars(syn_log_dir)]] [file normalize $vars(rundir)]]"
}
}
if {[regexp $vars(partition_dir) [file tail [file dirname [pwd]]]]} {
puts $op "SCRIPTS=$vars(script_dir)"
puts $op "LOG=$vars(log_dir)"
} else {
# BCL: Added the following in order to fix the difference in location between the rundir and scripts location
puts $op "SCRIPTS=[relPathTo [file normalize $vars(script_dir)] [file normalize $vars(rundir)]]"
# BCL: Added subst to resolve vars(rundir)
# BCL: Then modified to make relative to the rundir
puts $op "LOG=[relPathTo [file normalize [subst $vars(log_dir)]] [file normalize $vars(rundir)]]"
}
puts $op "BROWSER=$vars(make_browser)"
if {[info exists vars(make_update)]} {
puts $op "UPDATE=$vars(make_update)"
} elseif {[file tail [file dirname [pwd]]] != "$vars(partition_dir)"} {
puts $op "UPDATE=yes"
}
puts $op ""
puts $op "STEPS = [format "version setup %s do_cleanup" $steps]"
puts $op "FF_START = $start"
puts $op "FF_STOP = $stop"
puts $op ""
puts $op [format "all: version setup %s do_cleanup" $steps]
puts $op ""
puts $op "version:"
puts $op "\t@echo \"\# Foundation Flows Version \$(VERSION)\""
puts $op ""
puts $op "help:"
puts $op "\t@echo \"===================================================\""
puts $op "\t@echo \" \$(VERSION) Foundation Flows\""
puts $op "\t@echo \"===================================================\""
puts $op "\t@echo \" Makefile Targets\""
puts $op "\t@echo \"===================================================\""
puts $op "\t@echo \" setup : Setup Run Directory\""
if {$vars(rc) && [info exists vars(rc_steps)]} {
foreach step $vars(rc_steps) {
puts $op "\t@echo \" $step : $desc($step)\""
}
}
foreach step $steps {
# puts $op "\t@echo \" $step : $desc($step)\""
if {![info exists desc($step)]} {
set desc($step) "No information for this step"
}
set temp [format "%+21s : %-45s" $step $desc($step)]
puts $op "\t@echo $temp"
}
puts $op "\t@echo \"---------------------------------------------------\""
puts $op "\t@echo \" all : All design steps\""
puts $op "\t@echo \" simple : Single script (all steps in a single session) - no stop/start\""
puts $op "\t@echo \" single : Single script (all steps in a single session)\""
puts $op "\t@echo \"===================================================\""
puts $op "\t@echo \" Makefile Options\""
puts $op "\t@echo \"===================================================\""
puts $op "\t@echo \" VPATH : Make directory (default make)\""
if {$vars(novus)} {
puts $op "\t@echo \" TOOL : INNOVUS executable (default innovus)\""
puts $op "\t@echo \" ARGS : INNOVUS arguments (default -nowin -64)\""
} else {
puts $op "\t@echo \" TOOL : INNOVUS executable (default innovus)\""
puts $op "\t@echo \" ARGS : INNOVUS arguments (default -nowin -64)\""
}
if {$vars(rc)} {
puts $op "\t@echo \"SYN_TOOL : GENUS executable (default genus)\""
puts $op "\t@echo \"SYN_ARGS : GENUS arguments (default -64)\""
puts $op "\t@echo \"SYN_LOG : GENUS log dir (default RC/logs/<stage>.log)\""
}
if {[file tail [file dirname [pwd]]] != "$vars(partition_dir)"} {
puts $op "\t@echo \" UPDATE : Update scripts (default yes)\""
}
puts $op "\t@echo \" SCRIPTS : Script directory (default $vars(script_dir))\""
puts $op "\t@echo \" LOG : Logfile directory (default [subst $vars(log_dir))]\""
puts $op "\t@echo \"===================================================\""
puts $op ""
# if {[file tail [file dirname [pwd]]] != "$vars(partition_dir)"} {
# if {[info exists vars(plug_files)]} {
# puts $op "flow: $vars(config_files) $vars(plug_files)"
# } else {
# puts $op "flow: $vars(config_files)"
# }
# puts $op "\t@if \[ \$(UPDATE) == yes ] ; then \\"
# puts $op "\t\t[lindex $execute_string 0] [lindex $execute_string 1] -m flat all ; \\"
# puts $op "\t\t/bin/touch \$(VPATH)/\$@ ; \\"
# puts $op "\telse \\"
# puts $op "\t\techo 'SKIPPING FLOW UPDATE ...' ; \\"
# puts $op "\tfi"
# } else {
# puts $op "flow:"
# }
puts $op "\nsimple: setup"
if {$vars(step_arg) == "all"} {
puts $op "\tFF_STOP=\$(FF_STOP); VPATH=\$(VPATH); export VPATH; \$(TOOL) -init \$(SCRIPTS)/INNOVUS/run_simple.tcl -log \$(LOG)/simple.log \$(ARGS)"
} else {
puts $op "\tFF_STOP=\$(FF_STOP); VPATH=\$(VPATH); export VPATH; \$(TOOL) -init \$(SCRIPTS)/INNOVUS/run_simple.$vars(step_arg).tcl -log \$(LOG)/simple.$vars(step_arg).log \$(ARGS)"
}
puts $op ""
puts $op "\nsingle: setup"
puts $op "\tFF_STOP=\$(FF_STOP); VPATH=\$(VPATH); export VPATH; \$(TOOL) -init \$(SCRIPTS)/INNOVUS/run_all.tcl -log \$(LOG)/single.log \$(ARGS)"
puts $op ""
puts $op "setup:"
puts $op "\t@/bin/mkdir -p \$(VPATH) \$(LOG)"
puts $op "\t@/bin/touch \$(VPATH)/\$@"
if {[info exists vars(enable_ldb)] && $vars(enable_ldb)} {
puts $op "\t\$(TOOL) -init \$(SCRIPTS)/INNOVUS/run_compile.tcl -log \$(LOG)/compile.log -win \$(ARGS)"
}
puts $op ""
set prior_step "setup"
set arg_list "-n "
# if {$vars(novus)} {
# append arg_list "-N "
# }
if {$vars(verbose)} {
append arg_list "-V "
}
if {$vars(edi)} {
append arg_list "-e "
}
if {$vars(rc)} {
append arg_list "-r "
}
# RC Steps, if any, always go first
if {[info exists vars(rc_steps)] && $vars(rc_steps) ne ""} {
foreach step $vars(rc_steps) {
puts $op "$step: $prior_step"
puts $op "\t@mkdir -p \$(SYN_LOG);"
if {![regexp $vars(partition_dir) [file tail [file dirname [pwd]]]]} {
puts $op "\t@if \[ \"\$(UPDATE)\" = \"yes\" ] ; then \\"
if {[file normalize .] ne [file normalize $vars(rundir)]} {
puts $op "\t\tcd [relPathTo [file normalize .] [file normalize $vars(rundir)]]; [lindex $execute_string 0] [::FF::relPathTo [file normalize [subst [lindex $execute_string 1]]] [file normalize [subst $vars(rundir)]]] -m flat -d [relPathTo [file normalize $vars(script_dir)] [file normalize $vars(rundir)]] -v $vars(version) -s [relPathTo [file normalize [subst $vars(setup_path)]] [file normalize [subst $vars(rundir)]]] -y none -u [relPathTo [file normalize $vars(rundir)] [file normalize .]] $arg_list $step ; \\"
} else {
puts $op "\t\t[lindex $execute_string 0] [::FF::relPathTo [file normalize [subst [lindex $execute_string 1]]] [file normalize [subst $vars(rundir)]]] -m flat -d [relPathTo [file normalize $vars(script_dir)] [file normalize $vars(rundir)]] -v $vars(version) -s [relPathTo [file normalize [subst $vars(setup_path)]] [file normalize [subst $vars(rundir)]]] -y none $arg_list $step ; \\"
}
puts $op "\tfi"
}
puts $op "\tVPATH=\$(VPATH); export VPATH; \$(SYN_TOOL) -f \$(SCRIPTS)/GENUS/$step.tcl -logfile \$(SYN_LOG)/$step.log -cmdfile \$(SYN_LOG)/$step.cmd \$(SYN_ARGS)"
set prior_step $step
}
}
foreach step $steps {
# These steps should not also be rc_steps:
if {![info exists vars(rc_steps)] || [lsearch $vars(rc_steps) $step] == "-1"} {
puts $op "$step: $prior_step"
puts $op "\t@mkdir -p \$(LOG);"
# puts $op "\t@\$(MAKE) -f Makefile flow"
if {![regexp $vars(partition_dir) [file tail [file dirname [pwd]]]]} {
puts $op "\t@if \[ \"\$(UPDATE)\" = \"yes\" ] ; then \\"
# cd to ff_exe_dir here only if vars(rundir) ne vars(ff_exe_dir)
if {[file normalize .] ne [file normalize $vars(rundir)]} {
puts $op "\t\tcd [relPathTo [file normalize .] [file normalize $vars(rundir)]]; [lindex $execute_string 0] [::FF::relPathTo [file normalize [subst [lindex $execute_string 1]]] [file normalize [subst $vars(rundir)]]] -m $vars(mode) -d [relPathTo [file normalize $vars(script_dir)] [file normalize $vars(rundir)]] -v $vars(version) -s [relPathTo [file normalize [subst $vars(setup_path)]] [file normalize [subst $vars(rundir)]]] -y none -u [relPathTo [file normalize $vars(rundir)] [file normalize .]] $arg_list $step ; \\"
} else {
puts $op "\t\t[lindex $execute_string 0] [::FF::relPathTo [file normalize [subst [lindex $execute_string 1]]] [file normalize [subst $vars(rundir)]]] -m $vars(mode) -d [relPathTo [file normalize $vars(script_dir)] [file normalize $vars(rundir)]] -v $vars(version) -s [relPathTo [file normalize [subst $vars(setup_path)]] [file normalize [subst $vars(rundir)]]] -y none $arg_list $step ; \\"
}
# Need to add code to cd back to rundir here
puts $op "\tfi"
}
if {[regexp "^syn" $step]} {
puts $op "\tVPATH=\$(VPATH); export VPATH; \$(SYN_TOOL) -f \$(SCRIPTS)/GENUS/run_$step.tcl -logfile \$(LOG)/$step.log -cmdfile \$(LOG)/$step.cmd \$(SYN_ARGS)"
} else {
puts $op "\tVPATH=\$(VPATH); export VPATH; \$(TOOL) -init \$(SCRIPTS)/INNOVUS/run_$step.tcl -log \$(LOG)/$step.log -overwrite \$(ARGS)"
}
# puts $op "\t/bin/touch \$(VPATH)/$step\n"
set prior_step $step
}
}
# puts $op "html:"
# puts $op "\tFFVARS=$vars(script_dir)/vars.tcl; export FFVARS; /usr/bin/tclsh \$(SCRIPTS)/INNOVUS/gen_html.tcl .; cd $vars(html_dir); \$(BROWSER) file:`pwd`/index.html"
# puts $op ""
puts $op "debug_%:"
puts $op "\tVPATH=\$(VPATH); export STEP=\$* ; export VPATH; \$(TOOL) -init \$(SCRIPTS)/INNOVUS/run_debug.tcl -log \$(LOG)/\$@.log -win \$(ARGS:-nowin=)"
puts $op ""
puts $op "lec_%:"
puts $op "\texport STEP=\$* ; lec -64 -xl -Dofile \$(SCRIPTS)/INNOVUS/run_lec.tcl -NOGui -LOGfile \$(LOG)/\$@.log"
puts $op ""
puts $op "help_%:"
puts $op "\t[lindex $execute_string 0] \$(GEN_FLOW) -H \$*"
puts $op ""
# puts $op ".PHONY: clean html"
puts $op ".PHONY: clean"
puts $op ""
puts $op "clean:"
puts $op "\t/bin/mv *.rpt $vars(rpt_dir) ;\\"
puts $op "\t/bin/rm -fr extLogDir* __qrc.log *cts_trace *.rpt.old *delete* placementReports* *.rguide *_mmmc \\\n\t*_constr.pt .constr* .FE* .routing* .timing_file* .tdrlog*"
puts $op ""
puts $op "do_cleanup: signoff"
puts $op "\t\$(MAKE) clean"
puts $op "\t/bin/touch \$(VPATH)/\$@"
puts $op ""
puts $op "reset : version"
puts $op "\t/bin/rm -fr \$(VPATH)/* extLogDir* __qrc.log *cts_trace *.rpt.old *delete* placementReports* *.rguide *_mmmc"
puts $op "\t@for file in \$(STEPS) ; \\"
puts $op "\tdo \\"
puts $op "\t\tif \[ -r \$(VPATH)/\$\$file \] ; then \\"
puts $op "\t\t\t/bin/rm \$(VPATH)/\$\$file ; \\"
puts $op "\t\tfi \\"
puts $op "\tdone"
puts $op ""
puts $op "block_%: setup"
puts $op "\t@if \[ \"x\$*\" = \"xsingle\" \] ; then \\"
puts $op "\t\tff_stop=\$(FF_STOP); \\"
puts $op "\t\ttarget=\"\$@ (from: \$(FF_START) to: \$(FF_STOP))\"; \\"
puts $op "\telse \\"
puts $op "\t\tff_stop=\$* ; \\"
puts $op "\t\ttarget=\$@; \\"
puts $op "\tfi; \\"
puts $op "\tif \[ -r \$(VPATH)/.RUNNING \] ; then \\"
puts $op "\t\techo \"INFO: A build seems to be running already... check \$(VPATH)/.RUNNING file and remove that file if the process is dead\" ; \\"
puts $op "\t\t/bin/head -1 \$(VPATH)/.RUNNING ; \\"
puts $op "\t\texit -1 ; \\"
puts $op "\telse \\"
puts $op "\t\t/bin/rm -f \$(VPATH)/block_\$\$\{ff_stop\}.DONE \$(VPATH)/block_\$\$\{ff_stop\}.FAILED \$(VPATH)/block_\$\$\{ff_stop\}.PASS ; \\"
puts $op "\t\t(echo \"# Started building \$\$\{target\} at \"`/bin/date`\" on \"`/bin/hostname`\" PID: \$\$\$\$\" ; \$(MAKE) \$(TARGET) ) &>\$(VPATH)/.RUNNING ; \\"
puts $op "\t\tif \[ -r \$(VPATH)/\$\$\{ff_stop\} \] ; then \\"
puts $op "\t\t\tif \[ -r \$(VPATH)/.RUNNING \] ; then \\"
puts $op "\t\t\t\t/bin/mv \$(VPATH)/.RUNNING \$(VPATH)/block_\$\$\{ff_stop\}.PASS ; \\"
puts $op "\t\t\t\t/bin/touch \$(VPATH)/block_\$\$\{ff_stop\} ; \\"
puts $op "\t\t\t\t/bin/touch \$(VPATH)/block_\$\$\{ff_stop\}.DONE ; \\"
puts $op "\t\t\telse \\"
puts $op "\t\t\t\techo \"# Something did not work properly\" > \$(VPATH)/block_\$\$\{ff_stop\}.FAILED ; \\"
puts $op "\t\t\t\t/bin/touch \$(VPATH)/block_\$\$\{ff_stop\}.DONE ; \\"
puts $op "\t\t\t\texit -1; \\"
puts $op "\t\t\tfi ; \\"
puts $op "\t\telse \\"
puts $op "\t\t\tif \[ -r \$(VPATH)/.RUNNING \] ; then \\"
puts $op "\t\t\t\t/bin/mv \$(VPATH)/.RUNNING \$(VPATH)/block_\$\$\{ff_stop\}.FAILED ; \\"
puts $op "\t\t\telse \\"
puts $op "\t\t\t\techo \"# Something did not work properly\" > \$(VPATH)/block_\$\$\{ff_stop\}.FAILED ; \\"
puts $op "\t\t\tfi ; \\"
puts $op "\t\t\t/bin/touch \$(VPATH)/block_\$\$\{ff_stop\}.DONE ; \\"
puts $op "\t\t\texit -1 ; \\"
puts $op "\t\tfi ; \\"
puts $op "\tfi"
if {$vars(generate_flow_steps) && [info exists vars(flow_steps)]} {
if {[info exists vars(flow_steps,flat)]} {
set fp1 [open $vars(script_dir)/flow_config.tcl w]
set fp2 [open $vars(script_dir)/flow_steps.tcl w]
puts $fp1 "set_db flow_database_directory $vars(dbs_dir)"
puts $fp1 "set_db flow_report_directory $vars(rpt_dir)"
puts $fp1 "set_db flow_log_directory $vars(log_dir)"
puts $fp2 [regsub "create_flow_step -name init " $vars(flow_steps,flat) "create_flow_step -name init_design "]
puts $fp1 "\nset_db flow_mail_to [exec whoami]"
puts $fp1 "set_db flow_mail_on_error true\n"
if {$vars(top)} {
set vars(flow_name) top
} else {
set vars(flow_name) block
}
if {[file exists $vars(cwd)/.plugins]} {
set ip [open $vars(cwd)/.plugins r]
while {[gets $ip line]>=0} {
puts $fp1 $line
}
close $ip
# file delete $vars(cwd)/.plugins
}
close $fp1
puts $fp2 "create_flow_step -name init_floorplan { }"
close $fp2
if {[info exists vars(partition_list)]} {
if {($vars(design) == [lindex $vars(partition_list) 0]) || $vars(top)} {
set hp [open $vars(script_dir)/.hiersteps.tcl w]
if {$vars(top)} {
set temp [regsub -all "create_flow_step -name init" $vars(flow_steps,flat) "create_flow_step -name top_init"]
set temp2 [regsub -all "create_flow_step -name prects" $temp "create_flow_step -name top_prects"]
set temp3 [regsub -all "create_flow_step -name place" $temp2 "create_flow_step -name top_place"]
set temp4 [regsub -all "create_flow_step -name cts" $temp3 "create_flow_step -name top_cts"]
set vars(flow_steps,flat) [regsub -all "create_flow_step -name signoff" $temp4 "create_flow_step -name top_signoff"]
}
puts $hp $vars(flow_steps,flat)
close $hp
}
}
unset vars(flow_steps)
}
}
if {$vars(generate_flow_steps)} {
if {[lsearch $steps "assemble"] != -1} {
set steps [lreplace $steps end end]
}
set fp [open run_flow.tcl w]
puts $fp "source $vars(script_dir)/flow_steps.tcl"
puts $fp "if \{\[file exists $vars(script_dir)/plug_steps.tcl\]\} \{"
puts $fp " source $vars(script_dir)/plug_steps.tcl"
puts $fp "\}"
if {[file tail [pwd]] == $vars(top_cell)} {
if {[file tail [file dirname [pwd]]] == "$vars(partition_dir)"} {
set vars(flow_name) "top"
} else {
set vars(flow_name) "top_pass2"
}
set top_steps " $steps"
foreach s "init place prects cts signoff" {
set temp [regsub " $s" $top_steps " top_$s"]
set top_steps $temp
}
puts $fp "create_flow \\\n -name $vars(flow_name)\\\n -tool $vars(make_tool)\\\n -tool_options {-log $vars(flow_name).log}\\\n \[list $top_steps\]\n"
} else {
set dir [file tail [pwd]]
set pdir [file tail [file tail $dir]]
if {[info exists vars(partition_list)]} {
if {([file tail [pwd]] == [lindex $vars(partition_list) 0])} {
if {[file tail [file dirname [pwd]]] == "$vars(partition_dir)"} {
set vars(flow_name) "block"
} else {
set vars(flow_name) "block_pass2"
}
puts $fp "create_flow \\\n -name $vars(flow_name)\\\n -tool $vars(make_tool)\\\n -tool_options {-log $vars(flow_name).log}\\\n \[list $steps\]\n"
}
} else {
if {!$vars(rc)} {
set vars(flow_name) "innovus"
puts $fp "source $vars(script_dir)/flow_config.tcl"
puts $fp "create_flow \\\n -name $vars(flow_name)\\\n -tool $vars(make_tool)\\\n -tool_options {-log $vars(flow_name).log}\\\n \[list $steps\]\n"
} else {
set rc_steps [list]
set edi_steps [list]
foreach s $steps {
if {[regexp syn_ $s]} {
lappend rc_steps $s
} else {
lappend edi_steps $s
}
}
set vars(flow_name) "genus"
# puts $fp "source $vars(script_dir)/flow_steps.tcl"
puts $fp "source $vars(script_dir)/flow_config.tcl"
puts $fp "create_flow \\\n -name $vars(flow_name)\\\n -tool $vars(make_syn_tool)\\\n -tool_options {-log $vars(flow_name).log}\\\n \[list $rc_steps\]\n"
set vars(flow_name) "innovus"
puts $fp "create_flow \\\n -name $vars(flow_name)\\\n -tool $vars(make_tool)\\\n -tool_options {-log $vars(flow_name).log}\\\n \[list $edi_steps\]\n"
}
}
}
close $fp
}
}
"bottom_up" {
puts $op "VERSION=17.10-p003_1"
puts $op "VPATH=$env(VPATH)"
puts $op "TOOL=$vars(make_tool)"
puts $op "SCRIPTS=$vars(script_dir)"
puts $op "LOG=$vars(log_dir)"
puts $op "BROWSER=$vars(make_browser)"
if {[info exists vars(make_update)]} {
puts $op "UPDATE=$vars(make_update)"
} elseif {[file tail [file dirname [pwd]]] != "$vars(partition_dir)"} {
puts $op "UPDATE=yes"
}
puts $op ""
puts $op "ARGS=$vars(make_tool_args)"
puts $op "STEPS = [format "version setup %s do_cleanup" $steps]"
puts $op "FF_STOP = signoff"
puts $op "FF_START = init"
puts $op ""
puts $op [format "all: version setup %s do_cleanup" $steps]
puts $op ""
puts $op "version:"
puts $op "\t@echo \"\# Foundation Flows Version \$(VERSION)\""
puts $op ""
puts $op "help:"
puts $op "\t@echo \"===================================================\""
puts $op "\t@echo \" \$(VERSION) Foundation Flows\""
puts $op "\t@echo \"===================================================\""
puts $op "\t@echo \" Makefile Targets\""
puts $op "\t@echo \"===================================================\""
puts $op "\t@echo \" setup : Setup Run Directory\""
puts $op "\t@echo \" init : Create Initial Database\""
puts $op "\t@echo \" place : Cell Placement\""
puts $op "\t@echo \" prects : PreCTS Optimization\""
puts $op "\t@echo \" cts : Clock Tree Synthesis\""
puts $op "\t@echo \" postcts : PostCTS Optimization\""
puts $op "\t@echo \" postcts_hold : PostCTS Oold Fixing\""
puts $op "\t@echo \" route : Global/Detail Route\""
puts $op "\t@echo \" postroute : PostRoute Optimization\""
puts $op "\t@echo \" postroute_hold : PostRoute Hold Fixing\""
puts $op "\t@echo \" postroute_si_hold : SI Hold Fixing\""
puts $op "\t@echo \" postroute_si : SI Optimization\""
puts $op "\t@echo \" signoff : Signoff Timing / Verify\""
puts $op "\t@echo \" assemble : Design Assembly / Verify\""
puts $op "\t@echo \"---------------------------------------------------\""
puts $op "\t@echo \" all : All design steps\""
puts $op "\t@echo \" simple : Single script (all steps in a single session) - no stop/start\""
puts $op "\t@echo \" single : Single script (all steps in a single session)\""
puts $op "\t@echo \"===================================================\""
puts $op "\t@echo \" Makefile Options\""
puts $op "\t@echo \"===================================================\""
puts $op "\t@echo \" VPATH : Make directory (default make)\""
if {$vars(novus)} {
puts $op "\t@echo \" TOOL : INNOVUS executable (default innovus)\""
puts $op "\t@echo \" ARGS : INNOVUS arguments (default -nowin -64)\""
} else {
puts $op "\t@echo \" TOOL : INNOVUS executable (default innovus)\""
puts $op "\t@echo \" ARGS : INNOVUS arguments (default -nowin -64)\""
}
if {[file tail [file dirname [pwd]]] != "$vars(partition_dir)"} {
puts $op "\t@echo \" UPDATE : Update scripts (default yes)\""
}
# puts $op "\t@echo \" BROWSER : HTML browser (default netscape)\""
puts $op "\t@echo \" SCRIPTS : Script directory (default $vars(script_dir))\""
puts $op "\t@echo \" LOG : Logfile directory (default $vars(log_dir))\""
puts $op "\t@echo \"===================================================\""
puts $op ""
# if {[file tail [file dirname [pwd]]] != "$vars(partition_dir)"} {
# if {[info exists vars(plug_files)]} {
# puts $op "flow: $vars(config_files) $vars(plug_files)"
# } else {
# puts $op "flow: $vars(config_files)"
# }
# puts $op "\t@if \[ \$(UPDATE) == yes ] ; then \\"
# puts $op "\t\t[lindex $execute_string 0] [lindex $execute_string 1] -m flat all ; \\"
# puts $op "\t\t/bin/touch \$(VPATH)/\$@ ; \\"
# puts $op "\telse \\"
# puts $op "\t\techo 'SKIPPING FLOW UPDATE ...' ; \\"
# puts $op "\tfi"
# } else {
# puts $op "flow:"
# }
puts $op "\nsimple: setup"
if {$vars(step_arg) == "all"} {
puts $op "\tFF_STOP=\$(FF_STOP); VPATH=\$(VPATH); export VPATH; \$(TOOL) -init \$(SCRIPTS)/INNOVUS/run_simple.tcl -log \$(LOG)/simple.log \$(ARGS)"
} else {
puts $op "\tFF_STOP=\$(FF_STOP); VPATH=\$(VPATH); export VPATH; \$(TOOL) -init \$(SCRIPTS)/INNOVUS/run_simple.$vars(step_arg).tcl -log \$(LOG)/simple.$vars(step_arg).log \$(ARGS)"
}
puts $op ""
puts $op "\nsingle: setup"
puts $op "\tFF_STOP=\$(FF_STOP); VPATH=\$(VPATH); export VPATH; \$(TOOL) -init \$(SCRIPTS)/INNOVUS/run_all.tcl -log \$(LOG)/single.log \$(ARGS)"
puts $op ""
puts $op "setup:"
puts $op "\t@/bin/mkdir -p \$(VPATH) \$(LOG)"
puts $op "\t@/bin/touch \$(VPATH)/\$@"
if {[info exists vars(enable_ldb)] && $vars(enable_ldb)} {
puts $op "\t\$(TOOL) -init \$(SCRIPTS)/INNOVUS/run_compile.tcl -log \$(LOG)/compile.log -win \$(ARGS)"
}
puts $op ""
set prior_step "setup"
foreach step $steps {
puts $op "$step: $prior_step"
# puts $op "\t@\$(MAKE) -f Makefile flow"
if {[file dirname [pwd]] != "$vars(partition_dir)"} {
puts $op "\t@if \[ \$(UPDATE) == yes ] ; then \\"
puts $op "\t\t[lindex $execute_string 0] [lindex $execute_string 1] -n -m bottom_up $step ; \\"
puts $op "\tfi"
}
puts $op "\tVPATH=\$(VPATH); export VPATH; \$(TOOL) -init \$(SCRIPTS)/INNOVUS/run_$step.tcl -log \$(LOG)/$step.log -overwrite \$(ARGS)"
puts $op "\t/bin/touch \$(VPATH)/$step\n"
set prior_step $step
}
# puts $op "html:"
# puts $op "\tFFSTEPS=\$(STEPS); export FFSTEPS; FFLOGDIR=\$(LOG); export FFLOGDIR; /usr/bin/tclsh \$(SCRIPTS)/INNOVUS/gen_html.tcl .; cd HTML; \$(BROWSER) file:`pwd`/index.html"
# puts $op ""
puts $op "debug_%:"
puts $op "\tVPATH=\$(VPATH); export STEP=\$* ; export VPATH; \$(TOOL) -init \$(SCRIPTS)/INNOVUS/run_debug.tcl -log \$(LOG)/\$@.log -win \$(ARGS:-nowin=)"
puts $op ""
puts $op "lec_%:"
puts $op "\texport STEP=\$* ; lec -64 -xl -Dofile \$(SCRIPTS)/INNOVUS/run_lec.tcl -NOGui -LOGfile \$(LOG)/\$@.log"
puts $op ""
# puts $op ".PHONY: clean html"
puts $op ".PHONY: clean"
puts $op ""
puts $op "clean:"
puts $op "\t/bin/mv *.rpt $vars(rpt_dir) ;\\"
puts $op "\t/bin/rm -fr extLogDir* __qrc.log *cts_trace *.rpt.old *delete* placementReports* *.rguide *_mmmc \\\n\t*_constr.pt .constr* .FE* .routing* .timing_file* .tdrlog*"
puts $op ""
puts $op "do_cleanup: signoff"
puts $op "\t\$(MAKE) clean"
puts $op "\t/bin/touch \$(VPATH)/\$@"
puts $op ""
puts $op "reset : version"
puts $op "\t/bin/rm -fr \$(VPATH)/* extLogDir* __qrc.log *cts_trace *.rpt.old *delete* placementReports* *.rguide *_mmmc"
puts $op "\t@for file in \$(STEPS) ; \\"
puts $op "\tdo \\"
puts $op "\t\tif \[ -r \$(VPATH)/\$\$file \] ; then \\"
puts $op "\t\t\t/bin/rm \$(VPATH)/\$\$file ; \\"
puts $op "\t\tfi \\"
puts $op "\tdone"
puts $op ""
puts $op "block_%: setup"
puts $op "\t@if \[ \"x\$*\" = \"xsingle\" \] ; then \\"
puts $op "\t\tff_stop=\$(FF_STOP); \\"
puts $op "\t\ttarget=\"\$@ (from: \$(FF_START) to: \$(FF_STOP))\"; \\"
puts $op "\telse \\"
puts $op "\t\tff_stop=\$* ; \\"
puts $op "\t\ttarget=\$@; \\"
puts $op "\tfi; \\"
puts $op "\tif \[ -r \$(VPATH)/.RUNNING \] ; then \\"
puts $op "\t\techo \"INFO: A build seems to be running already... check \$(VPATH)/.RUNNING file and remove that file if the process is dead\" ; \\"
puts $op "\t\t/bin/head -1 \$(VPATH)/.RUNNING ; \\"
puts $op "\t\texit -1 ; \\"
puts $op "\telse \\"
puts $op "\t\t/bin/rm -f \$(VPATH)/block_\$\$\{ff_stop\}.DONE \$(VPATH)/block_\$\$\{ff_stop\}.FAILED \$(VPATH)/block_\$\$\{ff_stop\}.PASS ; \\"
puts $op "\t\t(echo \"# Started building \$\$\{target\} at \"`/bin/date`\" on \"`/bin/hostname`\" PID: \$\$\$\$\" ; \$(MAKE) \$(TARGET) ) &>\$(VPATH)/.RUNNING ; \\"
puts $op "\t\tif \[ -r \$(VPATH)/\$\$\{ff_stop\} \] ; then \\"
puts $op "\t\t\tif \[ -r \$(VPATH)/.RUNNING \] ; then \\"
puts $op "\t\t\t\t/bin/mv \$(VPATH)/.RUNNING \$(VPATH)/block_\$\$\{ff_stop\}.PASS ; \\"
puts $op "\t\t\t\t/bin/touch \$(VPATH)/block_\$\$\{ff_stop\} ; \\"
puts $op "\t\t\t\t/bin/touch \$(VPATH)/block_\$\$\{ff_stop\}.DONE ; \\"
puts $op "\t\t\telse \\"
puts $op "\t\t\t\techo \"# Something did not work properly\" > \$(VPATH)/block_\$\$\{ff_stop\}.FAILED ; \\"
puts $op "\t\t\t\t/bin/touch \$(VPATH)/block_\$\$\{ff_stop\}.DONE ; \\"
puts $op "\t\t\t\texit -1; \\"
puts $op "\t\t\tfi ; \\"
puts $op "\t\telse \\"
puts $op "\t\t\tif \[ -r \$(VPATH)/.RUNNING \] ; then \\"
puts $op "\t\t\t\t/bin/mv \$(VPATH)/.RUNNING \$(VPATH)/block_\$\$\{ff_stop\}.FAILED ; \\"
puts $op "\t\t\telse \\"
puts $op "\t\t\t\techo \"# Something did not work properly\" > \$(VPATH)/block_\$\$\{ff_stop\}.FAILED ; \\"
puts $op "\t\t\tfi ; \\"
puts $op "\t\t\t/bin/touch \$(VPATH)/block_\$\$\{ff_stop\}.DONE ; \\"
puts $op "\t\t\texit -1 ; \\"
puts $op "\t\tfi ; \\"
puts $op "\tfi"
if {$vars(generate_flow_steps) && [info exists vars(flow_steps)]} {
if {[info exists vars(flow_steps,flat)]} {
set fp1 [open $vars(script_dir)/flow_config.tcl w]
set fp2 [open $vars(script_dir)/flow_steps.tcl w]
puts $fp1 "set_db flow_database_directory $vars(dbs_dir)"
puts $fp1 "set_db flow_report_directory $vars(rpt_dir)"
puts $fp1 "set_db flow_log_directory $vars(log_dir)"
puts $fp2 $vars(flow_steps,flat)
puts $fp1 "\nset_db flow_mail_to [exec whoami]"
puts $fp1 "set_db flow_mail_on_error true\n"
if {$vars(top)} {
set vars(flow_name) top
} else {
set vars(flow_name) block
}
# puts $fp "create_flow \\\n -name $vars(flow_name)\\\n -tool $vars(make_tool)\\\n -tool_options {-log $vars(flow_name).log}\\\n \[list [FF::adjust_steps]\]\n"
# puts $hp "create_flow \\\n -name $vars(flow_name)\\\n -tool $vars(make_tool)\\\n -tool_options {-log $vars(flow_name).log}\\\n \[list $steps\]\n"
# puts $fp "run_flow -flow $vars(flow_name)"
if {[file exists $vars(cwd)/.plugins]} {
set ip [open $vars(cwd)/.plugins r]
while {[gets $ip line]>=0} {
puts $fp1 $line
}
close $ip
file delete $vars(cwd)/.plugins
}
close $fp1
close $fp2
if {[info exists vars(partition_list)]} {
if {($vars(design) == [lindex $vars(partition_list) 0]) || $vars(top)} {
set hp [open $vars(script_dir)/.hiersteps.tcl w]
if {$vars(top)} {
set temp [regsub -all "create_flow_step -name init" $vars(flow_steps,flat) "create_flow_step -name top_init"]
set temp2 [regsub -all "create_flow_step -name cts" $temp "create_flow_step -name top_cts"]
set vars(flow_steps,flat) [regsub -all "create_flow_step -name signoff" $temp2 "create_flow_step -name top_signoff"]
}
puts $hp $vars(flow_steps,flat)
if {$vars(top)} {
set top_steps " $steps"
foreach s " init prects cts signoff" {
set temp [regsub " $s" $top_steps " top_$s"]
set top_steps $temp
}
## set temp [regsub "init" [FF::adjust_steps] "top_init"]
# set temp [regsub "init" $steps "top_init"]
# set temp2 [regsub " prects " $temp " top_prects "]
# set temp3 [regsub " cts " $temp2 " top_cts "]
# set top_steps [regsub "signoff" $temp3 "top_signoff"]
puts $hp "create_flow \\\n -name $vars(flow_name)\\\n -tool $vars(make_tool)\\\n -tool_options {-log $vars(flow_name).log}\\\n \[list $top_steps\]\n"
} else {
# puts $hp "create_flow \\\n -name $vars(flow_name)\\\n -tool $vars(make_tool)\\\n -tool_options {-log $vars(flow_name).log}\\\n \[list [FF::adjust_steps]\]\n"
puts $hp "create_flow \\\n -name $vars(flow_name)\\\n -tool $vars(make_tool)\\\n -tool_options {-log $vars(flow_name).log}\\\n \[list $steps\]\n"
}
close $hp
}
}
unset vars(flow_steps)
}
}
}
"top_down" {
puts $op "VERSION=17.10-p003_1"
puts $op "VPATH=./make"
puts $op "TOOL=$vars(make_tool)"
puts $op "SCRIPTS=$vars(script_dir)"
puts $op "LOG=$vars(log_dir)"
puts $op "ARGS=$vars(make_tool_args)"
puts $op "PARALLEL=-j2"
puts $op "SUBMIT=\"\""
puts $op "TARGET=signoff"
puts $op "FF_STOP=signoff"
puts $op "STEPS = [format "version setup %s do_cleanup" $steps]"
puts $op ""
# puts $op "TOP=`/bin/grep \"^set vars(design)\" $vars(setup_tcl) | /bin/awk ' { printf(\"%s\\n\",\$\$3) } '`"
puts $op "TOP=$vars(design)"
puts $op ""
if {[info exists vars(use_flexmodels)] && $vars(use_flexmodels)} {
if {[info exists vars(flexmodel_prototype)] && $vars(flexmodel_prototype)} {
puts $op "all: setup model_gen prototype partition_place assign_pin partition blocks.\$(TARGET) top.\$(TARGET) assemble"
} else {
puts $op "all: setup model_gen partition_place assign_pin partition blocks.\$(TARGET) top.\$(TARGET) assemble"
}
} else {
puts $op "all: setup partition_place assign_pin partition blocks.\$(TARGET) top.\$(TARGET) assemble"
}
puts $op ""
puts $op "help:"
puts $op "\t@echo \"===================================================\""
puts $op "\t@echo \" \$(VERSION) Foundation Flows\""
puts $op "\t@echo \"===================================================\""
puts $op "\t@echo \" Makefile Targets\""
puts $op "\t@echo \"===================================================\""
puts $op "\t@echo \" all : Run complete flow (default)\""
if {[info exists vars(use_flexmodels)] && $vars(use_flexmodels)} {
puts $op "\t@echo \" model_gen : Generate flexmodels\""
if {[info exists vars(flexmodel_prototype)] && $vars(flexmodel_prototype)} {
puts $op "\t@echo \" prototype : Flexmodel prototype\""
}
}
puts $op "\t@echo \" partition_place : Initial placement & feedthrough\""
puts $op "\t@echo \" assign_pin : Pin assignment\""
puts $op "\t@echo \" partition : Partition design\""
puts $op "\t@echo \" blocks.<target> : Implement blocks\""
puts $op "\t@echo \" assemble : Assemble design\""
puts $op "\t@echo \"===================================================\""
puts $op "\t@echo \" Makefile Options\""
puts $op "\t@echo \"===================================================\""
puts $op "\t@echo \" VPATH : Make directory (default make)\""
puts $op "\t@echo \" SUBMIT : LSF launch command (default '')\""
puts $op "\t@echo \" PARALLEL : Number of machines (default -j2)\""
if {$vars(novus)} {
puts $op "\t@echo \" TOOL : INNOVUS executable (default innovus)\""
puts $op "\t@echo \" ARGS : INNOVUS arguments (default -nowin -64)\""
} else {
puts $op "\t@echo \" TOOL : INNOVUS executable (default innovus)\""
puts $op "\t@echo \" ARGS : INNOVUS arguments (default -nowin -64)\""
}
puts $op "\t@echo \" SCRIPTS : Script directory (default $vars(script_dir))\""
puts $op "\t@echo \" LOG : Logfile directory (default $vars(log_dir))\""
puts $op "\t@echo \"===================================================\""
puts $op ""
# puts $op "flow: $vars(config_files)"
# puts $op "\texecute_string"
# puts $op "\t@/bin/touch \$(VPATH)/\$@"
puts $op "assemble: top.\$(TARGET)"
puts $op "\tVPATH=\$(VPATH); export VPATH; \$(TOOL) \$(ARGS) -init \$(SCRIPTS)/INNOVUS/run_assemble.tcl -log \$(LOG)/assemble.log -overwrite"
puts $op "\t/bin/touch \$(VPATH)/assemble"
puts $op ""
puts $op "top.\$(TARGET) : blocks.\$(TARGET)"
puts $op "\tcd $vars(partition_dir)/\$(TOP); \$(MAKE) -f Makefile FF_STOP=\$(FF_STOP) \$(TARGET) "
puts $op "\t/bin/touch \$(VPATH)/\$@"
puts $op ""
puts $op "blocks.\$(TARGET) : partition"
puts $op "\tcd $vars(partition_dir); VPATH=\$(VPATH); export VPATH; \$(MAKE) \$(PARALLEL) blocks FF_STOP=\$(FF_STOP) TARGET=\$(TARGET)"
puts $op "\t/bin/touch \$(VPATH)/\$@"
puts $op ""
if {[info exists vars(use_flexmodels)] && $vars(use_flexmodels)} {
puts $op "model_gen : setup"
puts $op "\tVPATH=\$(VPATH); export VPATH; \$(TOOL) \$(ARGS) -init \$(SCRIPTS)/INNOVUS/run_model_gen.tcl -log \$(LOG)/model_gen.log -overwrite"
puts $op "\t/bin/touch \$(VPATH)/model_gen"
puts $op ""
if {[info exists vars(flexmodel_prototype)] && $vars(flexmodel_prototype)} {
puts $op "prototype : model_gen"
puts $op "\tVPATH=\$(VPATH); export VPATH; \$(TOOL) \$(ARGS) -init \$(SCRIPTS)/INNOVUS/run_prototype.tcl -log \$(LOG)/prototype.log -overwrite"
puts $op "\t/bin/touch \$(VPATH)/prototype"
puts $op ""
puts $op "partition_place : prototype"
} else {
puts $op "partition_place : model_gen"
}
} else {
puts $op "partition_place : setup"
}
puts $op "\tVPATH=\$(VPATH); export VPATH; \$(TOOL) \$(ARGS) -init \$(SCRIPTS)/INNOVUS/run_partition_place.tcl -log \$(LOG)/partition_place.log -overwrite"
puts $op "\t/bin/touch \$(VPATH)/partition_place"
puts $op ""
puts $op "assign_pin : partition_place"
puts $op "\tVPATH=\$(VPATH); export VPATH; \$(TOOL) \$(ARGS) -init \$(SCRIPTS)/INNOVUS/run_assign_pin.tcl -log \$(LOG)/assign_pin.log -overwrite"
puts $op "\t/bin/touch \$(VPATH)/assign_pin"
puts $op ""
puts $op "partition : assign_pin"
puts $op "\tVPATH=\$(VPATH); export VPATH; \$(TOOL) \$(ARGS) -init \$(SCRIPTS)/INNOVUS/run_partition.tcl -log \$(LOG)/partition.log -overwrite"
puts $op "\t/bin/touch \$(VPATH)/partition"
puts $op ""
puts $op "single:"
puts $op "\t@\$(MAKE) TARGET=single FF_STOP=\$(FF_STOP)"
puts $op ""
puts $op "debug_%:"
puts $op "\texport STEP=\$* ; VPATH=\$(VPATH); export VPATH; \$(TOOL) -init \$(SCRIPTS)/INNOVUS/run_debug.tcl -log \$(LOG)/\$@.log -win \$(ARGS:-nowin=)"
puts $op ""
puts $op "reset:"
puts $op "\t@/bin/rm -f \$(VPATH)/* $vars(partition_dir)/*/\$(VPATH)/* $vars(partition_dir)/*/\$(VPATH)/.RUNNING"
puts $op ""
puts $op "setup:"
puts $op "#\t/bin/rm -fr $vars(partition_dir) \$(VPATH) LOG"
puts $op "\t/bin/mkdir -p \$(VPATH) LOG"
puts $op "\t/bin/touch \$(VPATH)/setup"
if {$vars(generate_flow_steps) && [info exists vars(flow_steps)]} {
set fp [open run_flow.tcl w]
# puts $fp "source $vars(script_dir)/flow_steps.tcl"
set fp1 [open $vars(script_dir)/flow_config.tcl w]
set fp2 [open $vars(script_dir)/flow_steps.tcl w]
# puts $fp1 "set_db flow_step:assemble .skip_db true"
# puts $fp1 "set_db flow_step:partition .skip_db true"
puts $fp1 "set_db flow_database_directory $vars(dbs_dir)"
puts $fp1 "set_db flow_report_directory $vars(rpt_dir)"
puts $fp1 "set_db flow_log_directory $vars(log_dir)"
puts $fp1 "\nset_db flow_mail_to [exec whoami]"
puts $fp1 "set_db flow_mail_on_error true\n"
foreach p [concat $vars(partition_list) $vars(design)] {
# set vars(flow_name) $p
if {[file exists $vars(partition_dir)/$p/$vars(script_dir)/.hiersteps.tcl]} {
puts $fp2 "#-------------------------- $p --------------------------"
set ip [open $vars(partition_dir)/$p/$vars(script_dir)/.hiersteps.tcl r]
if {$p != $vars(design)} {
while {[gets $ip line]>=0} {
puts $fp2 $line
}
} else {
while {[gets $ip line]>=0} {
if {[regexp "create_flow_step -name top_" $line]} {
puts $fp2 $line
while {[gets $ip line]>=0} {
if {[regexp "^\}" $line]} {
puts $fp2 $line
break
} else {
puts $fp2 $line
}
}
}
}
}
}
if {[file exists $vars(partition_dir)/$p/run_flow.tcl]} {
set ip [open $vars(partition_dir)/$p/run_flow.tcl r]
while {[gets $ip line]>=0} {
puts $fp $line
}
}
if {[info exists vars(partition_dir_pass2)] && [file exists $vars(partition_dir_pass2)/$p/run_flow.tcl]} {
set ip [open $vars(partition_dir_pass2)/$p/run_flow.tcl r]
while {[gets $ip line]>=0} {
puts $fp $line
}
}
}
puts $fp2 "#-------------------------- HIER STEPS --------------------------"
puts $fp2 $vars(flow_steps,hier)
set asteps [FF::adjust_steps]
# set vars(flow_name) $vars(design)
# puts $fp "create_flow \\\n -name $vars(flow_name)\\\n -tool $vars(make_tool)\\\n -tool_options {-log $vars(flow_name).log}\\\n \[list $asteps\]\n"
set psteps [list]
set bsteps [list]
foreach s $asteps {
if {([lsearch $vars(fsteps) $s] != -1) && ($s != "assemble")} {
lappend bsteps $s
} else {
if {$s != "assemble"} {
lappend psteps $s
}
}
}
set vars(flow_name) final_assembly
puts $fp "create_flow \\\n -name $vars(flow_name)\\\n -tool $vars(make_tool)\\\n -tool_options {-log $vars(flow_name).log}\\\n \[list assemble\]\n"
set vars(flow_name) partitioning
puts $fp "create_flow \\\n -name $vars(flow_name)\\\n -tool $vars(make_tool)\\\n -tool_options {-log $vars(flow_name).log}\\\n \[list $psteps\]\n"
unset vars(flow_steps)
# set vars(flow_name) $vars(design)
# puts $fp "create_flow \\\n -name $vars(flow_name)\\\n -tool $vars(make_tool)\\\n -tool_options {-log $vars(flow_name).log}\\\n \[list $bsteps\]\n"
if {[file exists $vars(cwd)/.plugins]} {
set ip [open $vars(cwd)/.plugins r]
while {[gets $ip line]>=0} {
puts $fp1 $line
}
close $ip
file delete $vars(cwd)/.plugins
}
if {![info exists vars(run_flow)]} {
puts $fp "source $vars(script_dir)/flow_config.tcl"
set vars(run_flow) DONE
}
close $fp
close $fp1
close $fp2
}
}
"2pass" {
set op1 [open Makefile.pass1 w]
puts $op1 "VERSION=17.10-p003_1"
puts $op1 "VPATH=./make"
puts $op1 "TOOL=$vars(make_tool)"
puts $op1 "SCRIPTS=$vars(script_dir)"
puts $op1 "LOG=$vars(log_dir)"
puts $op1 "ARGS=$vars(make_tool_args)"
puts $op1 "PARALLEL=-j2"
puts $op1 "SUBMIT=\"\""
puts $op1 "TARGET=cts"
puts $op1 "FF_STOP=cts"
puts $op1 "STEPS = [format "version setup %s do_cleanup" $steps]"
puts $op1 ""
# puts $op1 "TOP=`/bin/grep \"^set vars(design)\" $vars(setup_tcl) | /bin/awk ' { printf(\"%s\\n\",\$\$3) } '`"
puts $op1 "TOP=$vars(design)"
puts $op1 ""
if {[info exists vars(use_flexmodels)] && $vars(use_flexmodels)} {
if {[info exists vars(flexmodel_prototype)] && $vars(flexmodel_prototype)} {
puts $op1 "all: setup prototype model_gen partition_place assign_pin partition blocks.\$(TARGET) top.\$(TARGET)"
} else {
puts $op1 "all: setup model_gen partition_place assign_pin partition blocks.\$(TARGET) top.\$(TARGET)"
}
} else {
puts $op1 "all: setup partition_place assign_pin partition blocks.\$(TARGET) top.\$(TARGET)"
}
puts $op1 "\t@echo \" Makefile Targets\""
puts $op1 "\t@echo \"===================================================\""
puts $op1 "\t@echo \" all : Run complete flow (default)\""
if {[info exists vars(use_flexmodels)] && $vars(use_flexmodels)} {
if {[info exists vars(flexmodel_prototype)] && $vars(flexmodel_prototype)} {
puts $op "\t@echo \" prototype : Flexmodel prototype\""
}
puts $op "\t@echo \" model_gen : Generate flexmodels\""
}
puts $op1 "\t@echo \" partition_place : Initial placement & feedthrough\""
puts $op1 "\t@echo \" assign_pin : Pin assignment\""
puts $op1 "\t@echo \" partition : Partition design\""
puts $op1 "\t@echo \" blocks.<target> : Implement blocks\""
if {$vars(enable_flexilm)} {
puts $op1 "\t@echo \" flexilm : PreCTS DLM flow\""
} else {
puts $op1 "\t@echo \" rebudget : Rebudget constraints\""
}
puts $op1 "\t@echo \"===================================================\""
puts $op1 "\t@echo \" Makefile Options\""
puts $op1 "\t@echo \"===================================================\""
puts $op1 "\t@echo \" VPATH : Make directory (default make)\""
puts $op1 "\t@echo \" SUBMIT : LSF launch command (default '')\""
puts $op1 "\t@echo \" PARALLEL : Number of machines (default -j2)\""
if {$vars(novus)} {
puts $op1 "\t@echo \" TOOL : INNOVUS executable (default innovus)\""
puts $op1 "\t@echo \" ARGS : INNOVUS arguments (default -novus_ui -64)\""
} else {
puts $op1 "\t@echo \" TOOL : INNOVUS executable (default innovus)\""
puts $op1 "\t@echo \" ARGS : INNOVUS arguments (default -nowin -64)\""
}
puts $op1 "\t@echo \" SCRIPTS : Script directory (default $vars(script_dir))\""
puts $op1 "\t@echo \" LOG : Logfile directory (default $vars(log_dir))\""
puts $op1 "\t@echo \"===================================================\""
puts $op1 ""
# puts $op1 "flow: $vars(config_files)"
# puts $op1 "\texecute_string"
# puts $op1 "\t@/bin/touch \$(VPATH)/\$@"
puts $op1 "top.\$(TARGET) : blocks.\$(TARGET)"
puts $op1 "\tcd $vars(partition_dir)/\$(TOP); \$(MAKE) -f Makefile FF_STOP=\$(FF_STOP) \$(TARGET) "
puts $op1 "\t/bin/touch \$(VPATH)/\$@"
puts $op1 ""
puts $op1 "blocks.\$(TARGET) : partition"
puts $op1 "\tcd $vars(partition_dir); VPATH=\$(VPATH); export VPATH; \$(MAKE) \$(PARALLEL) blocks FF_STOP=\$(FF_STOP) TARGET=\$(TARGET)"
puts $op1 "\t/bin/touch \$(VPATH)/\$@"
if {[info exists vars(use_flexmodels)] && $vars(use_flexmodels)} {
if {[info exists vars(flexmodel_prototype)] && $vars(flexmodel_prototype)} {
puts $op1 "prototype : setup"
puts $op1 "\tVPATH=\$(VPATH); export VPATH; \$(TOOL) \$(ARGS) -init \$(SCRIPTS)/INNOVUS/run_prototype.tcl -log \$(LOG)/prototype.log -overwrite"
puts $op1 "\t/bin/touch \$(VPATH)/prototype"
puts $op1 ""
puts $op1 "model_gen : prototype"
} else {
puts $op1 "model_gen : setup"
}
puts $op1 "\tVPATH=\$(VPATH); export VPATH; \$(TOOL) \$(ARGS) -init \$(SCRIPTS)/INNOVUS/run_model_gen.tcl -log \$(LOG)/model_gen.log -overwrite"
puts $op1 "\t/bin/touch \$(VPATH)/model_gen"
puts $op1 ""
puts $op1 "partition_place : model_gen"
} else {
puts $op1 "partition_place : setup"
}
puts $op1 "\tVPATH=\$(VPATH); export VPATH; \$(TOOL) \$(ARGS) -init \$(SCRIPTS)/INNOVUS/run_partition_place.tcl -log \$(LOG)/partition_place.log -overwrite"
puts $op1 "\t/bin/touch \$(VPATH)/partition_place"
puts $op1 ""
puts $op1 "assign_pin : partition_place"
puts $op1 "\tVPATH=\$(VPATH); export VPATH; \$(TOOL) \$(ARGS) -init \$(SCRIPTS)/INNOVUS/run_assign_pin.tcl -log \$(LOG)/assign_pin.log -overwrite"
puts $op1 "\t/bin/touch \$(VPATH)/assign_pin"
puts $op1 ""
puts $op1 "partition : assign_pin"
puts $op1 "\tVPATH=\$(VPATH); export VPATH; \$(TOOL) \$(ARGS) -init \$(SCRIPTS)/INNOVUS/run_partition.tcl -log \$(LOG)/partition.log -overwrite"
puts $op1 "\t/bin/touch \$(VPATH)/partition"
puts $op1 ""
puts $op1 "single:"
puts $op1 "\t@\$(MAKE) TARGET=single FF_STOP=\$(FF_STOP)"
puts $op1 ""
puts $op1 "debug_%:"
puts $op1 "\texport STEP=\$* ; VPATH=\$(VPATH); export VPATH; \$(TOOL) -init \$(SCRIPTS)/INNOVUS/run_debug.tcl -log \$(LOG)/\$@.log -win \$(ARGS:-nowin=)"
puts $op1 ""
puts $op1 "reset:"
puts $op1 "\t@/bin/rm -f \$(VPATH)/* $vars(partition_dir)/*/\$(VPATH)/* $vars(partition_dir)/*/\$(VPATH)/.RUNNING"
puts $op1 ""
puts $op1 "setup:"
puts $op1 "#\t/bin/rm -fr $vars(partition_dir) \$(VPATH) LOG"
puts $op1 "\t/bin/mkdir -p \$(VPATH) LOG"
puts $op1 "\t/bin/touch \$(VPATH)/setup"
close $op1
set op2 [open Makefile.pass2 w]
puts $op2 "VERSION=17.10-p003_1"
puts $op2 "VPATH=./make"
puts $op2 "TOOL=$vars(make_tool)"
puts $op2 "SCRIPTS=$vars(script_dir)"
puts $op2 "LOG=$vars(log_dir)"
puts $op2 "ARGS=$vars(make_tool_args)"
puts $op2 "PARALLEL=-j2"
puts $op2 "SUBMIT=\"\""
puts $op2 "TARGET=signoff"
puts $op2 "FF_STOP=signoff"
puts $op2 "STEPS = [format "version setup %s do_cleanup" $steps]"
puts $op2 ""
# puts $op2 "TOP=`/bin/grep \"^set vars(design)\" $vars(setup_tcl) | /bin/awk ' { printf(\"%s\\n\",\$\$3) } '`"
puts $op2 "TOP=$vars(design)"
puts $op2 ""
if {$vars(enable_flexilm)} {
puts $op2 "all: setup rebudget blocks.\$(TARGET) top.\$(TARGET) assemble"
} else {
puts $op2 "all: setup rebudget blocks.\$(TARGET) top.\$(TARGET) assemble"
}
puts $op2 ""
puts $op2 "help:"
puts $op2 "\t@echo \"===================================================\""
puts $op2 "\t@echo \" \$(VERSION) Foundation Flows\""
puts $op2 "\t@echo \"===================================================\""
puts $op2 "\t@echo \" Makefile Targets\""
puts $op2 "\t@echo \"===================================================\""
puts $op2 "\t@echo \" all : Run complete flow (default)\""
if {$vars(enable_flexilm)} {
puts $op2 "\t@echo \" rebudget : Rebudget design\""
}
puts $op2 "\t@echo \" blocks.<target> : Implement blocks\""
puts $op2 "\t@echo \" assemble : Assemble design\""
puts $op2 "\t@echo \"===================================================\""
puts $op2 "\t@echo \" Makefile Options\""
puts $op2 "\t@echo \"===================================================\""
puts $op2 "\t@echo \" VPATH : Make directory (default make)\""
puts $op2 "\t@echo \" SUBMIT : LSF launch command (default '')\""
puts $op2 "\t@echo \" PARALLEL : Number of machines (default -j2)\""
if {$vars(novus)} {
puts $op2 "\t@echo \" TOOL : INNOVUS executable (default innovus)\""
puts $op2 "\t@echo \" ARGS : INNOVUS arguments (default -novus_ui -64)\""
} else {
puts $op2 "\t@echo \" TOOL : INNOVUS executable (default innovus)\""
puts $op2 "\t@echo \" ARGS : INNOVUS arguments (default -nowin -64)\""
}
puts $op2 "\t@echo \" SCRIPTS : Script directory (default $vars(script_dir))\""
puts $op2 "\t@echo \" LOG : Logfile directory (default $vars(log_dir))\""
puts $op2 "\t@echo \"===================================================\""
puts $op2 ""
# puts $op2 "flow: $vars(config_files)"
# puts $op2 "\texecute_string"
# puts $op2 "\t@/bin/touch \$(VPATH)/\$@"
puts $op2 "assemble: top.\$(TARGET)"
puts $op2 "\tVPATH=\$(VPATH); export VPATH; \$(TOOL) \$(ARGS) -init \$(SCRIPTS)/INNOVUS/run_assemble.tcl -log \$(LOG)/assemble.log -overwrite"
puts $op2 "\t/bin/touch \$(VPATH)/assemble"
puts $op2 ""
puts $op2 "top.\$(TARGET) : blocks.\$(TARGET)"
puts $op2 "\tcd $vars(partition_dir_pass2)/\$(TOP); \$(MAKE) -f Makefile FF_STOP=\$(FF_STOP) \$(TARGET) "
puts $op2 "\t/bin/touch \$(VPATH)/\$@"
puts $op2 ""
puts $op2 "blocks.\$(TARGET) : rebudget"
puts $op2 "\tcd $vars(partition_dir_pass2); VPATH=\$(VPATH); export VPATH; \$(MAKE) \$(PARALLEL) blocks FF_STOP=\$(FF_STOP) TARGET=\$(TARGET)"
puts $op2 "\t/bin/touch \$(VPATH)/\$@"
puts $op2 ""
puts $op1 "rebudget : top.cts"
puts $op1 "\tVPATH=\$(VPATH); export VPATH; \$(TOOL) \$(ARGS) -init \$(SCRIPTS)/INNOVUS/run_rebudget.tcl -log \$(LOG)/rebudget.log -overwrite"
puts $op1 "\t/bin/touch \$(VPATH)/rebudget"
puts $op1 ""
puts $op2 "single:"
puts $op2 "\t@\$(MAKE) TARGET=single FF_STOP=\$(FF_STOP)"
puts $op2 ""
puts $op2 "debug_%:"
puts $op2 "\texport STEP=\$* ; VPATH=\$(VPATH); export VPATH; \$(TOOL) -init \$(SCRIPTS)/INNOVUS/run_debug.tcl -log \$(LOG)/\$@.log -win \$(ARGS:-nowin=)"
puts $op2 ""
puts $op2 "reset:"
puts $op2 "\t@/bin/rm -f \$(VPATH)/* $vars(partition_dir_pass2)/*/\$(VPATH)/* $vars(partition_dir_pass2)/*/\$(VPATH)/.RUNNING"
puts $op2 ""
puts $op2 "setup:"
puts $op2 "#\t/bin/rm -fr $vars(partition_dir_pass2) \$(VPATH) LOG"
puts $op2 "\t/bin/mkdir -p \$(VPATH) LOG"
close $op2
puts $op "include Makefile.pass1"
puts $op "include Makefile.pass2"
if {$vars(generate_flow_steps) && [info exists vars(flow_steps)]} {
set fp1 [open $vars(script_dir)/flow_config.tcl w]
set fp2 [open $vars(script_dir)/flow_steps.tcl w]
puts $fp1 "set_db flow_database_directory $vars(dbs_dir)"
puts $fp1 "set_db flow_report_directory $vars(rpt_dir)"
puts $fp1 "set_db flow_log_directory $vars(log_dir)"
puts $fp1 "\nset_db flow_mail_to [exec whoami]"
puts $fp1 "set_db flow_mail_on_error true\n"
# puts $fp $vars(flow_steps)
foreach p [concat $vars(partition_list) $vars(design)] {
# set vars(flow_name) $p
if {[file exists $vars(partition_dir)/$p/$vars(script_dir)/.hiersteps.tcl]} {
# puts $fp2 "#-------------------------- $p --------------------------"
set ip [open $vars(partition_dir)/$p/$vars(script_dir)/.hiersteps.tcl r]
if {$p != $vars(design)} {
while {[gets $ip line]>=0} {
puts $fp2 $line
}
} else {
while {[gets $ip line]>=0} {
if {[regexp "create_flow_step -name top_" $line]} {
puts $fp2 $line
while {[gets $ip line]>=0} {
if {[regexp "^\}" $line]} {
puts $fp2 $line
break
} else {
puts $fp2 $line
}
}
}
}
}
}
if {[file exists $vars(partition_dir)/$p/run_flow.tcl]} {
set ip [open $vars(partition_dir)/$p/run_flow.tcl r]
while {[gets $ip line]>=0} {
puts $fp $line
}
}
if {[info exists vars(partition_dir_pass2)] && [file exists $vars(partition_dir_pass2)/$p/run_flow.tcl]} {
set ip [open $vars(partition_dir_pass2)/$p/run_flow.tcl r]
while {[gets $ip line]>=0} {
puts $fp $line
}
}
}
puts $fp2 "#-------------------------- HIER STEPS --------------------------"
puts $fp2 $vars(flow_steps,hier)
set vars(flow_name) $vars(design)
set asteps [FF::adjust_steps]
# puts $fp "create_flow \\\n -name $vars(flow_name)\\\n -tool $vars(make_tool)\\\n -tool_options {-log $vars(flow_name).log}\\\n \[list $asteps\]\n"
set psteps [list]
set bsteps [list]
foreach s $asteps {
if {([lsearch $vars(fsteps) $s] != -1) && ($s != "assemble")} {
lappend bsteps $s
} else {
if {$s != "assemble"} {
lappend psteps $s
}
}
}
set vars(flow_name) final_assembly
puts $fp "create_flow \\\n -name $vars(flow_name)\\\n -tool $vars(make_tool)\\\n -tool_options {-log $vars(flow_name).log}\\\n \[list assemble\]\n"
set vars(flow_name) partitioning
puts $fp "create_flow \\\n -name $vars(flow_name)\\\n -tool $vars(make_tool)\\\n -tool_options {-log $vars(flow_name).log}\\\n \[list $psteps\]\n"
# puts $fp "run_flow -flow $vars(flow_name)"
unset vars(flow_steps)
# set vars(flow_name) $vars(design)
# puts $fp "create_flow \\\n -name $vars(flow_name)\\\n -tool $vars(make_tool)\\\n -tool_options {-log $vars(flow_name).log}\\\n \[list $bsteps\]\n"
if {[file exists $vars(cwd)/.plugins]} {
set ip [open $vars(cwd)/.plugins r]
while {[gets $ip line]>=0} {
puts $fp1 $line
}
close $ip
file delete $vars(cwd)/.plugins
}
close $fp
close $fp1
close $fp2
}
}
"flexilm" {
puts $op "VERSION=17.10-p003_1"
puts $op "VPATH=./make"
puts $op "TOOL=$vars(make_tool)"
puts $op "SCRIPTS=FF"
puts $op "LOG=LOG"
puts $op "ARGS=$vars(make_tool_args)"
puts $op "PARALLEL=-j2"
puts $op "SUBMIT=\"\""
puts $op "TARGET=assemble"
puts $op "FF_STOP=assemble"
puts $op "STEPS = version setup do_cleanup"
puts $op ""
# puts $op "TOP=`/bin/grep \"^set vars(design)\" $vars(setup_tcl) | /bin/awk ' { printf(\"%s\\n\",\$\$3) } '`"
puts $op "TOP=$vars(design)"
puts $op ""
if {[info exists vars(use_flexmodels)] && $vars(use_flexmodels)} {
if {[info exists vars(flexmodel_prototype)] && $vars(flexmodel_prototype)} {
puts $op "all: setup prototype model_gen partition_place assign_pin partition blocks.prects top.prects assemble_flexilm blocks.signoff top.signoff assemble"
} else {
puts $op "all: setup model_gen partition_place assign_pin partition blocks.prects top.prects assemble_flexilm blocks.signoff top.signoff assemble"
}
} else {
puts $op "all: setup partition_place assign_pin partition blocks.prects top.prects assemble_flexilm blocks.signoff top.signoff assemble"
}
puts $op ""
puts $op "help:"
puts $op "\t@echo \"===================================================\""
puts $op "\t@echo \" \$(VERSION) Foundation Flows\""
puts $op "\t@echo \"===================================================\""
puts $op "\t@echo \" Makefile Targets\""
puts $op "\t@echo \"===================================================\""
puts $op "\t@echo \" all : Run complete flow (default)\""
if {[info exists vars(use_flexmodels)] && $vars(use_flexmodels)} {
if {[info exists vars(flexmodel_prototype)] && $vars(flexmodel_prototype)} {
puts $op "\t@echo \" prototype : Flexmodel prototype\""
}
puts $op "\t@echo \" model_gen : Generate flexmodels\""
}
puts $op "\t@echo \" partition_place : Initial placement & feedthrough\""
puts $op "\t@echo \" assign_pin : Pin assignment\""
puts $op "\t@echo \" partition : Partition design\""
puts $op "\t@echo \" block.prects : Implement blocks to preCTS and generate flexIlm\""
puts $op "\t@echo \" top.prects : flexIlm prects optimization and flexIlm ECO\""
puts $op "\t@echo \" assemble_flexilm : Check assembled preCTS timing\""
puts $op "\t@echo \" block.signoff : implement blocks\""
puts $op "\t@echo \" top.signoff : implement top\""
puts $op "\t@echo \" assemble : final chip assembly\""
puts $op "\t@echo \"===================================================\""
puts $op "\t@echo \" Makefile Options\""
puts $op "\t@echo \"===================================================\""
puts $op "\t@echo \" VPATH : Make directory (default make)\""
puts $op "\t@echo \" SUBMIT : LSF launch command (default '')\""
puts $op "\t@echo \" PARALLEL : Number of machines (default -j2)\""
if {$vars(novus)} {
puts $op "\t@echo \" TOOL : INNOVUS executable (default innovus)\""
puts $op "\t@echo \" ARGS : INNOVUS arguments (default -novus_ui -64)\""
} else {
puts $op "\t@echo \" TOOL : INNOVUS executable (default innovus)\""
puts $op "\t@echo \" ARGS : INNOVUS arguments (default -nowin -64)\""
}
puts $op "\t@echo \" SCRIPTS : Script directory (default FF)\""
puts $op "\t@echo \" LOG : Logfile directory (default LOG)\""
puts $op "\t@echo \"===================================================\""
puts $op "assemble: top.signoff"
puts $op "\tVPATH=\$(VPATH); export VPATH; \$(TOOL) \$(ARGS) -init \$(SCRIPTS)/INNOVUS/run_assemble.tcl -log \$(LOG)/assemble.log -overwrite"
puts $op "\t/bin/touch \$(VPATH)/assemble"
puts $op ""
puts $op "top.signoff : blocks.signoff"
puts $op "\tcd PARTITION_PRECTS/\$(TOP); \$(MAKE) -f Makefile FF_STOP=signoff signoff"
puts $op " /bin/touch \$(VPATH)/\$@"
puts $op ""
puts $op "blocks.signoff : assemble_flexilm"
puts $op "\tcd PARTITION_PRECTS; VPATH=\$(VPATH); export VPATH; \$(MAKE) \$(PARALLEL) blocks FF_STOP=signoff TARGET=signoff"
puts $op " /bin/touch \$(VPATH)/\$@"
puts $op ""
puts $op "assemble_flexilm : top.prects"
puts $op "\tVPATH=\$(VPATH); export VPATH; \$(TOOL) \$(ARGS) -init \$(SCRIPTS)/INNOVUS/run_assemble_flexilm.tcl -log \$(LOG)/assemble_flexilm.log -overwrite"
puts $op "\t/bin/touch \$(VPATH)/assemble_flexilm"
puts $op ""
puts $op "top.prects : blocks.prects"
if {$vars(place_opt_design)} {
puts $op "\tcd PARTITION/\$(TOP); \$(MAKE) -f Makefile FF_STOP=place place "
} else {
puts $op "\tcd PARTITION/\$(TOP); \$(MAKE) -f Makefile FF_STOP=prects prects "
}
puts $op "\t/bin/touch \$(VPATH)/\$@"
puts $op "\t/bin/cp -rf PARTITION_FLEXILM/* PARTITION_PRECTS"
puts $op "\t/bin/rm -rf PARTITION_FLEXILM"
puts $op ""
puts $op "blocks.prects : partition"
if {$vars(place_opt_design)} {
puts $op "\tcd PARTITION; VPATH=\$(VPATH); export VPATH; \$(MAKE) \$(PARALLEL) blocks FF_STOP=place TARGET=place"
} else {
puts $op "\tcd PARTITION; VPATH=\$(VPATH); export VPATH; \$(MAKE) \$(PARALLEL) blocks FF_STOP=prects TARGET=prects"
}
puts $op "\t/bin/touch \$(VPATH)/\$@"
if {[info exists vars(use_flexmodels)] && $vars(use_flexmodels)} {
if {[info exists vars(flexmodel_prototype)] && $vars(flexmodel_prototype)} {
puts $op "prototype : setup"
puts $op "\tVPATH=\$(VPATH); export VPATH; \$(TOOL) \$(ARGS) -init \$(SCRIPTS)/INNOVUS/run_prototype.tcl -log \$(LOG)/prototype.log -overwrite"
puts $op "\t/bin/touch \$(VPATH)/prototype"
puts $op ""
puts $op "model_gen : prototype"
} else {
puts $op "model_gen : setup"
}
puts $op "\tVPATH=\$(VPATH); export VPATH; \$(TOOL) \$(ARGS) -init \$(SCRIPTS)/INNOVUS/run_model_gen.tcl -log \$(LOG)/model_gen.log -overwrite"
puts $op "\t/bin/touch \$(VPATH)/model_gen"
puts $op ""
puts $op "partition_place : model_gen"
} else {
puts $op "partition_place : setup"
}
puts $op "\tVPATH=\$(VPATH); export VPATH; \$(TOOL) \$(ARGS) -init \$(SCRIPTS)/INNOVUS/run_partition_place.tcl -log \$(LOG)/partition_place.log -overwrite"
puts $op "\t/bin/touch \$(VPATH)/partition_place"
puts $op ""
puts $op "assign_pin : partition_place"
puts $op " VPATH=\$(VPATH); export VPATH; \$(TOOL) \$(ARGS) -init \$(SCRIPTS)/INNOVUS/run_assign_pin.tcl -log \$(LOG)/assign_pin.log -overwrite"
puts $op " /bin/touch \$(VPATH)/assign_pin"
puts $op ""
puts $op "partition : assign_pin"
puts $op "\tVPATH=\$(VPATH); export VPATH; \$(TOOL) \$(ARGS) -init \$(SCRIPTS)/INNOVUS/run_partition.tcl -log \$(LOG)/partition.log -overwrite"
puts $op " /bin/touch \$(VPATH)/partition"
puts $op ""
puts $op "single:"
puts $op "\t@\$(MAKE) TARGET=single FF_STOP=signoff"
puts $op ""
puts $op "debug_%:"
puts $op "\texport STEP=\$* ; VPATH=\$(VPATH); export VPATH; \$(TOOL) -init \$(SCRIPTS)/INNOVUS/run_debug.tcl -log \$(LOG)/\$@.log -win \$(ARGS:-nowin=)"
puts $op ""
puts $op "reset:"
puts $op "\t@/bin/rm -f \$(VPATH)/* PARTITION/*/\$(VPATH)/* PARTITION/*/\$(VPATH)/.RUNNING"
puts $op "\t@/bin/rm -f \$(VPATH)/* PARTITION_PRECTS/*/\$(VPATH)/* PARTITION_PRECTS/*/\$(VPATH)/.RUNNING"
puts $op ""
puts $op "setup:"
puts $op "#\t/bin/rm -fr PARTITION \$(VPATH) LOG"
puts $op "\t/bin/mkdir -p \$(VPATH) LOG"
puts $op "\t/bin/touch \$(VPATH)/setup"
if {$vars(generate_flow_steps) && [info exists vars(flow_steps)]} {
set fp [open run_flow.tcl w]
if {![info exists vars(run_flow)]} {
# puts $fp "source $vars(script_dir)/flow_steps.tcl"
puts $fp "source $vars(script_dir)/flow_config.tcl"
set vars(run_flow) DONE
}
set fp1 [open $vars(script_dir)/flow_config.tcl w]
set fp2 [open $vars(script_dir)/flow_steps.tcl w]
puts $fp1 "set_db flow_database_directory $vars(dbs_dir)"
puts $fp1 "set_db flow_report_directory $vars(rpt_dir)"
puts $fp1 "set_db flow_log_directory $vars(log_dir)"
puts $fp1 "\nset_db flow_mail_to [exec whoami]"
puts $fp1 "set_db flow_mail_on_error true\n"
# puts $fp $vars(flow_steps)
foreach p [concat $vars(partition_list) $vars(design)] {
# set vars(flow_name) $p
if {[file exists $vars(partition_dir)/$p/$vars(script_dir)/.hiersteps.tcl]} {
# puts $fp2 "#-------------------------- $p --------------------------"
set ip [open $vars(partition_dir)/$p/$vars(script_dir)/.hiersteps.tcl r]
if {$p != $vars(design)} {
while {[gets $ip line]>=0} {
puts $fp2 $line
}
} else {
while {[gets $ip line]>=0} {
if {[regexp "create_flow_step -name top_" $line]} {
puts $fp2 $line
while {[gets $ip line]>=0} {
if {[regexp "^\}" $line]} {
puts $fp2 $line
break
} else {
puts $fp2 $line
}
}
}
}
}
}
if {[file exists $vars(partition_dir)/$p/run_flow.tcl]} {
set ip [open $vars(partition_dir)/$p/run_flow.tcl r]
while {[gets $ip line]>=0} {
puts $fp $line
}
}
if {[info exists vars(partition_dir_pass2)] && [file exists $vars(partition_dir_pass2)/$p/run_flow.tcl]} {
set ip [open $vars(partition_dir_pass2)/$p/run_flow.tcl r]
while {[gets $ip line]>=0} {
puts $fp $line
}
}
}
puts $fp2 "#-------------------------- HIER STEPS --------------------------"
puts $fp2 $vars(flow_steps,hier)
set vars(flow_name) $vars(design)
set asteps [FF::adjust_steps]
# puts $fp "create_flow \\\n -name $vars(flow_name)\\\n -tool $vars(make_tool)\\\n -tool_options {-log $vars(flow_name).log}\\\n \[list $asteps\]\n"
set psteps [list]
set bsteps [list]
foreach s $asteps {
if {([lsearch $vars(fsteps) $s] != -1) && ($s != "assemble")} {
lappend bsteps $s
} else {
if {![regexp "^assemble" $s]} {
lappend psteps $s
}
}
}
set vars(flow_name) intermediate_assembly
puts $fp "create_flow \\\n -name $vars(flow_name)\\\n -tool $vars(make_tool)\\\n -tool_options {-log $vars(flow_name).log}\\\n \[list assemble_flexilm\]\n"
set vars(flow_name) final_assembly
puts $fp "create_flow \\\n -name $vars(flow_name)\\\n -tool $vars(make_tool)\\\n -tool_options {-log $vars(flow_name).log}\\\n \[list assemble\]\n"
set vars(flow_name) partitioning
puts $fp "create_flow \\\n -name $vars(flow_name)\\\n -tool $vars(make_tool)\\\n -tool_options {-log $vars(flow_name).log}\\\n \[list $psteps\]\n"
# puts $fp "run_flow -flow $vars(flow_name)"
unset vars(flow_steps)
# set vars(flow_name) $vars(design)
# puts $fp "create_flow \\\n -name $vars(flow_name)\\\n -tool $vars(make_tool)\\\n -tool_options {-log $vars(flow_name).log}\\\n \[list $bsteps\]\n"
if {[file exists $vars(cwd)/.plugins]} {
set ip [open $vars(cwd)/.plugins r]
while {[gets $ip line]>=0} {
puts $fp1 $line
}
close $ip
file delete $vars(cwd)/.plugins
}
close $fp
close $fp1
close $fp2
}
}
}