define_proc_arguments add_io_buffer -info "Add repeater for IOs"
-define_args {
{-insts "Target IO insts" "insts" list required}
{-BOX "to core area, last location is the last inverter's location. {{x1 y1} {x2 y2} ...}" "path" list required}
{-prefix "Prefix for new insts and nets, default is IO_QYY" "prefix" string optional}
{-side "IO side, T,B,L or R" "side" string required}
}
proc add_io_buffer {args} {
set inputs(-prefix) IO_QYY
global _IO_REPEATER_INDEX _IO_REPEATER_INDEX
parse_proc_arguments -args $args inputs
if {[info exists inputs(-start_index)]} {
set _IO_REPEATER_INDEX $inputs(-start_index)
} elseif {![info exists _IO_REPEATER_INDEX]} {
set _IO_REPEATER_INDEX 0
}
set IOname $inputs(-insts)
set distance 70
set max_distance 750
foreach ioname $IOname {
set io [dbget [dbget top.insts.name $ioname -p1]]
#puts $io
set orient [dbget $io.orient]
set ioName [dbget $io.name]
set PinA [dbget $io.instTerms.name /A -p1]
set netA [dbget $PinA.net]
set Pinlists ""
if {$netA != "0x0"} {
lappend Pinlists $PinA
}
set PinY [dbget $io.instTerms.name /Y -p1]
set netY [dbget $PinY.net]
if {$netY != "0x0"} {
lappend Pinlists $PinY
}
foreach pins $Pinlists {
set pinsname [dbget $pins.name]
set obj [get_property [get_pins $pinsname] dbObject]
set x [dbget $obj.pt_x]
set y [dbget $obj.pt_y]
case $inputs(-side) {
T {
set y [expr $y - $distance]
}
B {
set y [expr $y + $distance]
}
L {
set x [expr $x + $distance]
}
default {
set x [expr $x - $distance]
}
}
set inv_locs [list [list $x $y]]
set loc [list $x $y]
set tot_len 0
#puts $tot_len
foreach tbox1 $inputs(-BOX) {
set ll [expr abs([lindex $tbox1 0] - [lindex $loc 0]) + abs([lindex $tbox1 1] - [lindex $loc 1])]
set tot_len [expr $tot_len + $ll]
set loc $tbox1
}
#invert_sum
set invnum [expr int(ceil($tot_len1.0/$max_distance))]
if {[expr $invnum%2]} {incr invnum} else {set invnum [expr $invnum+2]}
puts "invnum:$invnum"
#inv_space invert
set invspace [format %.2f [expr $tot_len1.0/($invnum-1)]]
#inv_location
set loc [lindex $inv_locs 0]
set nn 0
for {set i 0} {$i < [llength $inputs(-BOX)]} {} {
#puts "[llength $inputs(-BOX)]"
incr nn
set loc_i [lindex $inputs(-BOX) $i]
#puts "$loc_i"
set dx [expr [lindex $loc_i 0] - [lindex $loc 0]]
set dy [expr [lindex $loc_i 1] - [lindex $loc 1]]
set l [expr abs($dx) + abs($dy)]
#puts "$l"
set loc_last $loc_i
set loc_last1 $loc
#puts "$loc_last1"
set flag 0
set break_flag 0
while {$l < $invspace && $i < [llength $inputs(-BOX)]} {
incr i
if {$i == [llength $inputs(-BOX)]} {
set break_flag 1
break
}
set loc_i [lindex $inputs(-BOX) $i]
set dx [expr abs([lindex $loc_i 0] - [lindex $loc_last 0])]
set dy [expr abs([lindex $loc_i 1] - [lindex $loc_last 1])]
set loc_last1 $loc_last
set loc_last $loc_i
set l [expr $dx + $dy +$l]
set flag 1
#puts "$flag"
}
if {$break_flag} {if {$invnum != [llength $inv_locs]} {lappend inv_locs [lindex $inputs(-BOX) end]}} elseif {$flag} {set l1 [expr $l - $dx - $dy] set l2 [expr $invspace - $l1] set dx [expr [lindex $loc_last 0] - [lindex $loc_last1 0]]set dy [expr [lindex $loc_last 1] - [lindex $loc_last1 1]]if {[expr abs($dx)] < [expr abs($dy)]} {set x [lindex $loc_last 0] if {$dy > 0} {set y [expr [lindex $loc_last1 1] + $l2] } else {set y [expr [lindex $loc_last1 1] - $l2] } } else {set y [lindex $loc_last 1] if {$dx > 0} {set x [expr [lindex $loc_last1 0] + $l2] } else {set x [expr [lindex $loc_last1 0] - $l2] }}set loc [list $x $y] lappend inv_locs $loc } else { set l2 $invspace set dx [expr [lindex $loc_i 0] - [lindex $loc 0]]set dy [expr [lindex $loc_i 1] - [lindex $loc 1]]if {[expr abs($dx)] < [expr abs($dy)]} {set x [lindex $loc_i 0]if {$dy > 0} {set y [expr [lindex $loc 1] + $l2]} else {set y [expr [lindex $loc 1] - $l2]} } else {set y [lindex $loc_i 1]if {$dx > 0} {set x [expr [lindex $loc 0] + $l2]} else {set x [expr [lindex $loc 0] - $l2]}}set loc [list $x $y]lappend inv_locs $loc}if {[llength $inv_locs] == $invnum} {}if {$l < 40 && [expr [llength $inv_locs]%2] == 0} { break}if {$nn == 100} {break}}if {[expr [llength $inv_locs] %2]} {#puts "[join $inv_locs \n]"continue}set net [lindex [dbget $obj.net.name] 0]set pin_name [file tail $pinsname]#puts "$pin_name"set pre_pin "$ioname/$pin_name"puts "$inv_locs"set inv_locs_re [lreverse $inv_locs]for {set n 0} {$n < [expr $invnum/2]} {incr n} {set input [dbget $pins.isInput] set idx1 [expr {$n * 2}]set idx2 [expr {$n * 2 + 1}]set x1 [lindex [lindex $inv_locs_re $idx1] 0]set y1 [lindex [lindex $inv_locs_re $idx1] 1]set x2 [lindex [lindex $inv_locs_re $idx2] 0]set y2 [lindex [lindex $inv_locs_re $idx2] 1]if {$input} {redirect ../scr/addiobufftcl.tcl {puts "ecoAddRepeater -term [dbGet $pins.name] -cell JLSCL6CNMV2_INV_16 -loc {$x1 $y1 $x2 $y2}"} -append} else {redirect ../scr/addiobufftcl.tcl {puts "ecoAddRepeater -term [dbGet $pins.name] -cell JLSCL6CNMV2_INV_16 -loc {$x2 $y2 $x1 $y1}"} -append}}}
}
}