pluto_hdl_adi/projects/scripts/adi_fmc_constr_generator.tcl

353 lines
16 KiB
Tcl
Executable File

# To use this script you can source it in any tcl shell or simply
# run it e.g. tclsh ../../scripts/adi_fmc_constr_generator.tcl fmc0
proc gen_fmc_constr {{fmc_index1 fmc} {fmc_index2 {}}} {
variable col0_max 0
variable col1_max 0
variable col2_max 0
variable col3_max 0
variable io_standard_max 0
set platform [expr [regexp {a10gx|a10soc|s10soc} [file tail [pwd]]] ? "{intel}" : "{xilinx}"]
if {[string match $platform xilinx]} {
set constr_file [open fmc_constr.xdc w+]
if {[string length $fmc_index2] == 0} {
gen_xilinx_fmc $fmc_index1 fmc $constr_file
} else {
gen_xilinx_fmc $fmc_index1 fmc1 $constr_file
gen_xilinx_fmc $fmc_index2 fmc2 $constr_file
}
close $constr_file
if {![catch {[string length [get_property NAME [current_project]]]} errmsg]} {
add_files -fileset constrs_1 -norecurse fmc_constr.xdc
}
} else {
set constr_file [open fmc_constr.tcl w+]
if {[string length $fmc_index2] == 0} {
gen_intel_fmc $fmc_index1 fmc $constr_file
} else {
gen_intel_fmc $fmc_index1 fmc1 $constr_file
gen_intel_fmc $fmc_index2 fmc2 $constr_file
}
close $constr_file
}
}
proc gen_xilinx_fmc {fmc_index fmc_file constr_file} {
set cwd [pwd]
set carrier [file tail $cwd]
set eval_board [file tail [file dirname $cwd]]
global col0_max
global col1_max
global col2_max
global col3_max
global io_standard_max
variable last_gbt_pin 0
variable gbt_exist_flag 0
variable edit_flag 0
set carrier_path [glob ../../common/$carrier/$carrier\_$fmc_index*.txt]
set carrier_file [open $carrier_path r]
set carrier_data [read $carrier_file]
close $carrier_file
set line_c [split $carrier_data \n]
set carrierType [expr [string match *$carrier* vck190vmk180] ? 2 : [string match *u* $carrier] || [string match v* $carrier]]
set eval_board_path [glob ../common/*_$fmc_file*.txt]
set eval_board_file [open $eval_board_path r]
set eval_board_data [read $eval_board_file]
close $eval_board_file
set line_e [split $eval_board_data \n]
for {set i 1} {$i < [llength $line_e]} {incr i} {
if {[string match [lindex $line_e $i] ""] || [string match " *" [lindex $line_e $i]]} {continue}
if {[string match #* [lindex $line_e $i]]} {continue}
set col_e [join [lindex $line_e $i] " "]
if {[string match $carrier vcu118] && [string match $fmc_index fmcp] && [string match *[lindex $col_e 0]* D4D5B20B21]} {
set last_gbt_pin [lindex $col_e 0]
set gbt_exist_flag 1
}
if {![string match [lindex $col_e 4] #N/A]} {
if {!$carrierType} {
if {[string match [lindex $col_e 4] LVDS] || [string match [lindex $col_e 4] LVDS15]} {set col_e [lreplace $col_e 4 4 LVDS_25]}
if {[string match [lindex $col_e 4] LVCMOS18] || [string match [lindex $col_e 4] LVCMOS15]} {set col_e [lreplace $col_e 4 4 LVCMOS25]}
}
if {$carrierType == 1} {
if {[string match [lindex $col_e 4] LVDS_25] || [string match [lindex $col_e 4] LVDS15]} {set col_e [lreplace $col_e 4 4 LVDS]}
if {[string match [lindex $col_e 4] LVCMOS25] || [string match [lindex $col_e 4] LVCMOS15]} {set col_e [lreplace $col_e 4 4 LVCMOS18]}
}
if {$carrierType == 2} {
if {[string match [lindex $col_e 4] LVDS_25] || [string match [lindex $col_e 4] LVDS]} {set col_e [lreplace $col_e 4 4 LVDS15]}
if {[string match [lindex $col_e 4] LVCMOS25] || [string match [lindex $col_e 4] LVCMOS18]} {set col_e [lreplace $col_e 4 4 LVCMOS15]}
}
set io_standard [lindex $col_e 4]
} else {set io_standard ""}
if {![string match [lindex $col_e 5] #N/A]} {
for {set k 5} {$k < [llength $col_e]} {incr k} {
append io_standard " [lindex $col_e $k]"
}
}
if {[string length $io_standard] > $io_standard_max} {
set io_standard_max [string length $io_standard]
}
for {set j 1} {$j < [llength $line_c]} {incr j} {
set col_c [join [lindex $line_c $j] " "]
if {[string match [lindex $col_e 0] [lindex $col_c 0]]} {
if {![string match [lindex $col_c 2] #N/A]} {
if {[string length [lindex $col_c 0]] > $col0_max} {
set col0_max [string length [lindex $col_c 0]]
}
if {[string length [lindex $col_c 1]] > $col1_max} {
set col1_max [string length [lindex $col_c 1]]
}
if {[string length [lindex $col_c 2]] > $col2_max} {
set col2_max [string length [lindex $col_c 2]]
}
}
if {[string length [lindex $col_e 3]] > $col3_max} {
set col3_max [string length [lindex $col_e 3]]
}
}
}
}
if {[string match $carrier vcu118] && [string match $fmc_index fmcp] && $gbt_exist_flag} {set edit_flag 1}
for {set i 1} {$i < [llength $line_e]} {incr i} {
if {[string match [lindex $line_e $i] ""] || [string match " *" [lindex $line_e $i]]} {
puts $constr_file ""
continue
}
if {[string match #* [lindex $line_e $i]]} {
puts $constr_file [lindex $line_e $i]
continue
}
if {$edit_flag} {
puts $constr_file "#----------------------------------------------------------THIS SECTION NEEDS MANUAL EDITING----------------------------------------------------------"
set edit_flag 0
}
set col_e [join [lindex $line_e $i] " "]
for {set j 1} {$j < [llength $line_c]} {incr j} {
set col_c [join [lindex $line_c $j] " "]
if {[string match [lindex $col_e 0] [lindex $col_c 0]]} {
if {![string match [lindex $col_c 2] #N/A]} {
set spaces_0 ""
set spaces_1 ""
set spaces_2 ""
set spaces_3 ""
for {set k 0} {$k < [expr $col0_max - [string length [lindex $col_c 0]]]} {incr k} {append spaces_0 " "}
for {set k 0} {$k < [expr $col1_max - [string length [lindex $col_c 1]]]} {incr k} {append spaces_1 " "}
for {set k 0} {$k < [expr $col2_max - [string length [lindex $col_c 2]]]} {incr k} {append spaces_2 " "}
for {set k 0} {$k < [expr $col3_max - [string length [lindex $col_e 3]]]} {incr k} {append spaces_3 " "}
if {![string match [lindex $col_e 4] #N/A]} {
if {!$carrierType} {
if {[string match [lindex $col_e 4] LVDS] || [string match [lindex $col_e 4] LVDS15]} {set col_e [lreplace $col_e 4 4 LVDS_25]}
if {[string match [lindex $col_e 4] LVCMOS18] || [string match [lindex $col_e 4] LVCMOS15]} {set col_e [lreplace $col_e 4 4 LVCMOS25]}
}
if {$carrierType == 1} {
if {[string match [lindex $col_e 4] LVDS_25] || [string match [lindex $col_e 4] LVDS15]} {set col_e [lreplace $col_e 4 4 LVDS]}
if {[string match [lindex $col_e 4] LVCMOS25] || [string match [lindex $col_e 4] LVCMOS15]} {set col_e [lreplace $col_e 4 4 LVCMOS18]}
}
if {$carrierType == 2} {
if {[string match [lindex $col_e 4] LVDS_25] || [string match [lindex $col_e 4] LVDS]} {set col_e [lreplace $col_e 4 4 LVDS15]}
if {[string match [lindex $col_e 4] LVCMOS25] || [string match [lindex $col_e 4] LVCMOS18]} {set col_e [lreplace $col_e 4 4 LVCMOS15]}
}
set io_standard "$spaces_2 IOSTANDARD [lindex $col_e 4]"
} else {
set io_standard ""
}
if {![string match [lindex $col_e 5] #N/A]} {
if {![string length $io_standard]} {set io_standard $spaces_2}
for {set k 5} {$k < [llength $col_e]} {incr k} {
append io_standard " [lindex $col_e $k]"
}
}
if {[string length $io_standard] > 0} {
for {set k 0} {$k < [expr $io_standard_max + [string length $spaces_2] + 12 - [string length $io_standard]]} {incr k} {append spaces_3 " "}
puts $constr_file "set_property -dict \{PACKAGE_PIN [lindex $col_c 2]$io_standard\} \[get_ports [lindex $col_e 3]\]$spaces_3 ; ## [lindex $col_c 0]$spaces_0 [lindex $col_c 1] $spaces_1 [lindex $col_c 3]"
} else {
for {set k 0} {$k < [expr $io_standard_max + 12 - [string length $io_standard]]} {incr k} {append spaces_3 " "}
puts $constr_file "set_property -dict \{PACKAGE_PIN [lindex $col_c 2]\}$spaces_2 \[get_ports [lindex $col_e 3]\]$spaces_3 ; ## [lindex $col_c 0]$spaces_0 [lindex $col_c 1] $spaces_1 [lindex $col_c 3]"
}
if {[string match $carrier vcu118] && [string match $fmc_index fmcp] && [string match [lindex $col_c 0] $last_gbt_pin] && ![string match $last_gbt_pin* [lindex $line_c [expr $j+2]] ] && [string match [lindex $col_e 0] $last_gbt_pin] && ![string match $last_gbt_pin* [lindex $line_e [expr $i+2]]]} {
puts $constr_file #-----------------------------------------------------------------------------------------------------------------------------------------------------
}
}
}
}
}
}
proc gen_intel_fmc {fmc_index fmc_file constr_file} {
set cwd [pwd]
set carrier [file tail $cwd]
global col0_max
global col1_max
global col2_max
global col3_max
variable current_index 1
variable spaceFlag 0
variable serialFlag 0
variable xcvrCount 0
set xcvrType "xcvr_\$\{i\}"
set carrier_path [glob ../../common/$carrier/$carrier\_$fmc_index*.txt]
set carrier_file [open $carrier_path r]
set carrier_data [read $carrier_file]
close $carrier_file
set line_c [split $carrier_data \n]
set eval_board_path [glob ../common/*_$fmc_file*.txt]
set eval_board_file [open $eval_board_path r]
set eval_board_data [read $eval_board_file]
close $eval_board_file
set line_e [split $eval_board_data \n]
for {set i 1} {$i <= [llength $line_e]} {incr i} {
if {[string match [lindex $line_e $i] ""] || [string match " *" [lindex $line_e $i]] || $i == [llength $line_e]} {continue}
if {[string match #* [lindex $line_e $i]]} {continue}
set col_e [join [lindex $line_e $i] " "]
set col_e [constrToIntel $line_e $col_e $i]
for {set j 1} {$j < [llength $line_c]} {incr j} {
set col_c [join [lindex $line_c $j] " "]
if {[string match [lindex $col_e 0] [lindex $col_c 0]]} {
if {![string match [lindex $col_c 2] #N/A]} {
if {[string length [lindex $col_c 0]] > $col0_max} {
set col0_max [string length [lindex $col_c 0]]
}
if {[string length [lindex $col_c 1]] > $col1_max} {
set col1_max [string length [lindex $col_c 1]]
}
if {[string length [lindex $col_c 2]] > $col2_max} {
set col2_max [string length [lindex $col_c 2]]
}
}
if {[string length [lindex $col_e 3]] > $col3_max} {
set col3_max [string length [lindex $col_e 3]]
}
}
}
}
for {set i 1} {$i <= [llength $line_e]} {incr i} {
if {[string match #* [lindex $line_e $i]]} {
puts $constr_file [lindex $line_e $i]
continue
}
set col_e [join [lindex $line_e $i] " "]
set col_e [constrToIntel $line_e $col_e $i]
if {[string match "*serial_data*" [lindex $col_e 3]] && ![string match "*_data*" [lindex $line_e [expr $i+1]]]} {set serialFlag 1}
if {[string match [lindex $line_e $i] ""] || [string match " *" [lindex $line_e $i]] || $i == [llength $line_e]} {
puts $constr_file ""
if {$serialFlag} {
for {set k $current_index} {$k <= $i} {incr k} {
set col_e [join [lindex $line_e $k] " "]
set col_e [constrToIntel $line_e $col_e $k]
if {[string match "*[0]*" [lindex $col_e 3]] && ![string match "*(n)*" [lindex $col_e 3]]} {
puts $constr_file "set_instance_assignment -name XCVR_VCCR_VCCT_VOLTAGE 1_0V -to [string map -nocase {[0] ""} [lindex $col_e 3]]"
}
}
puts $constr_file ""
for {set k $current_index} {$k <= $i} {incr k} {
set col_e [join [lindex $line_e $k] " "]
set col_e [constrToIntel $line_e $col_e $k]
if {[string match "*[0]*" [lindex $col_e 3]] && ![string match "*(n)*" [lindex $col_e 3]]} {
set xcvrCount 0
puts $constr_file "set_instance_assignment -name IO_STANDARD \"HIGH SPEED DIFFERENTIAL I/O\" -to [string map -nocase {[0] ""} [lindex $col_e 3]]"
} else {incr xcvrCount}
}
puts $constr_file ""
puts $constr_file "for \{set i 0\} \{\$i < [expr $xcvrCount/2]\} \{incr i\} \{"
for {set k $current_index} {$k <= $i} {incr k} {
set col_e [join [lindex $line_e $k] " "]
set col_e [constrToIntel $line_e $col_e $k]
if {[string match "*[0]*" [lindex $col_e 3]] && ![string match "*(n)*" [lindex $col_e 3]]} {
if {[string match "*data_*" [lindex $col_e 3]]} {set xcvrType "xcvr_[string index [lindex $col_e 3] [expr [string last _ [lindex $col_e 3]] + 1]]_\$\{i\}"}
puts $constr_file " set_instance_assignment -name XCVR_RECONFIG_GROUP $xcvrType -to [string map -nocase {[0] \[\$\{i\}\]} [lindex $col_e 3]]"
}
}
puts $constr_file "\}"
set serialFlag 0
set current_index $i
}
for {set k $current_index} {$k < $i} {incr k} {
set col_e [join [lindex $line_e $k] " "]
set col_e [constrToIntel $line_e $col_e $k]
if {![string match [lindex $col_e 4] #N/A] && ![string match "*(n)*" [lindex $col_e 3]] && ![string match "" [lindex $col_e 4]]} {
set io_standard [string map -nocase {LVCMOS15 "\"1.8 V\"" LVCMOS18 "\"1.8 V\"" LVCMOS25 "\"1.8 V\""} [lindex $col_e 4]]
puts $constr_file "set_instance_assignment -name IO_STANDARD $io_standard -to [lindex $col_e 3]"
set spaceFlag 1
}
}
for {set k $current_index} {$k < $i} {incr k} {
set col_e [join [lindex $line_e $k] " "]
set col_e [constrToIntel $line_e $col_e $k]
if {![string match [lindex $col_e 5] #N/A] && ![string match "*(n)*" [lindex $col_e 3]] && ![string match "" [lindex $col_e 5]]} {
set io_standard [string map -nocase {DIFF_TERM "INPUT_TERMINATION DIFFERENTIAL"} [lindex $col_e 5]]
puts $constr_file "set_instance_assignment -name $io_standard -to [lindex $col_e 3]"
}
}
set current_index $i
if {$spaceFlag} {puts $constr_file ""}
continue
}
for {set j 1} {$j < [llength $line_c]} {incr j} {
set col_c [join [lindex $line_c $j] " "]
if {[string match [lindex $col_e 0] [lindex $col_c 0]]} {
if {![string match [lindex $col_c 2] #N/A]} {
set spaces_0 ""
set spaces_1 ""
set spaces_2 ""
set spaces_3 ""
for {set k 0} {$k < [expr $col0_max - [string length [lindex $col_c 0]]]} {incr k} {append spaces_0 " "}
for {set k 0} {$k < [expr $col1_max - [string length [lindex $col_c 1]]]} {incr k} {append spaces_1 " "}
for {set k 0} {$k < [expr $col2_max - [string length [lindex $col_c 2]]]} {incr k} {append spaces_2 " "}
for {set k 0} {$k < [expr $col3_max - [string length [lindex $col_e 3]]]} {incr k} {append spaces_3 " "}
puts $constr_file "set_location_assignment [lindex $col_c 2]$spaces_2 -to [lindex $col_e 3]$spaces_3 ; ## [lindex $col_c 0]$spaces_0 [lindex $col_c 1] $spaces_1 [lindex $col_c 3]"
}
}
}
}
}
proc constrToIntel {line_e col_e i} {
if {[string match "*_p*" [lindex $col_e 3]] && [string match "*_n*" [lindex $line_e [expr $i+1]]]} {set col_e [lreplace $col_e 3 3 [string map -nocase {_p ""} [lindex $col_e 3]]]}
if {[string match "*_n*" [lindex $col_e 3]] && [string match "*_p*" [lindex $line_e [expr $i-1]]]} {set col_e [lreplace $col_e 3 3 "\"[string map -nocase {_n ""} [lindex $col_e 3]](n)\""]}
if {[string match "*_data*" [lindex $col_e 3]] && ![string match "*serial_data*" [lindex $col_e 3]]} {
set col_e [lreplace $col_e 3 3 [string map -nocase {_data _serial_data} [lindex $col_e 3]]]
}
return $col_e
}
# Allow the script to be called or sourced
if { [info script] eq $::argv0 } {
if {$::argv == ""} {
puts "To create the fmc_constr.xdc, call the adi_fmc_constr_generator.tcl with argument(s) <fmc_port>"
puts "e.g. tclsh ../../scripts/adi_fmc_constr_generator.tcl fmc0"
puts "e.g. tclsh ../../scripts/adi_fmc_constr_generator.tcl fmc0 fmc1"
puts "NOTE: The fmc port name can be deduced from the git repo hdl/projects/common/<carrier>/<carrier>_<fmc_port>.txt"
} else {
gen_fmc_constr $::argv
}
} else {
puts "To create the fmc_constr.xdc call the gen_fmc_constr <fmc_port> procedure"
puts "e.g. gen_fmc_constr fmc0"
puts "e.g. gen_fmc_constr fmc0 fmc1"
puts "NOTE: The fmc port name can be deduced from the git repo hdl/projects/common/<carrier>/<carrier>_<fmc_port>.txt"
}