proc align_to_grid {value} {
set grid 0.005
return [expr round($value / $grid) * $grid]
}
define_proc_arguments VDD_IO_pin \
-info "Extend VDD IO pins" \
-define_args {
{-IOcelltype "IO instance name" IOcelltype string optional}
{-extend_length "Extension length" extend_pin_length string optional}
{-metal "Extension metal" Metal string optional}
}
proc VDD_IO_pin {args} {
parse_proc_arguments -args $args args_array
if {[info exists args_array(-IOcelltype)]} {
set macro1 $args_array(-IOcelltype)
set macro [dbget [dbget top.insts.cell.name $macro1 -p2].name]
} else {
puts "AKRO INFO: extend All macro pin shape"
set macro [dbget [dbget top.insts.cell.name RCMCU_PLVDD -p2].name]
}
if {[info exists args_array(-extend_length)]} {
set extend_pin_length $args_array(-extend_length)
} else {
set extend_pin_length 51.43
}
if {[info exists args_array(-metal)]} {
set metallayer $args_array(-metal)
} else {
set metallayer M2
}
foreach macro $macro {
if {$macro1 == "RCMCU_PLVDD"} {
set pin_name1 "VDDH"
set pin_name2 "VSSH"
set pin_name3 "POC"
set pin_name4 "GND"
set Tleng 58.21
} elseif {$macro1 == "RCMCU_PLVSS"} {
set pin_name1 "VDDH"
set pin_name2 "VSSH"
set pin_name3 "POC"
set pin_name4 "VDD"
set Tleng 57
} elseif {$macro1 == "RCMCU_PLVSSH"} {
set pin_name1 "VDDH"
set pin_name2 "GND"
set pin_name3 "POC"
set pin_name4 "VDD"
set Tleng 53.8
} else {
set pin_name1 "VDDH"
set pin_name2 "VSSH"
set pin_name3 "POC"
set pin_name4 "GND"
set Tleng 58.21
}
if {$metallayer == "M2"} {
set layerNumber 2
} elseif {$metallayer == "M3"} {
set layerNumber 3
} else {
set layerNumber 2
}
set inst_ptr [dbget top.insts.name $macro -p]
set macro_box [dbget $inst_ptr.box]
puts $macro_box
set inst_terms_ptr [dbget $inst_ptr.PGInstTerms]
foreach ptr $inst_terms_ptr {
set term_name [dbget $ptr.name]
puts $term_name
if {[regexp $pin_name1 $term_name]} {continue}
if {[regexp $pin_name2 $term_name]} {continue}
if {[regexp $pin_name3 $term_name]} {continue}
if {[regexp $pin_name4 $term_name]} {continue}
if {[lsearch [dbget $ptr.term.pins.layerShapeShapes.layer.num] 10] == "-1"} {
set layerNum $layerNumber
set orien [dbget $ptr.inst.orient]
if {$orien == "R90" || $orien == "R270"} {
set cell_pin_rect [dbget [dbget [dbget [dbget $ptr.term.pins.layerShapeShapes.shapes.rect_sizex $Tleng -p2].layer.name $metallayer -p2].shapes.rect_sizex $Tleng -p1].rect]
set pin_mask [dbget [dbget [dbget [dbget $ptr.term.pins.layerShapeShapes.shapes.rect_sizex $Tleng -p2].layer.name $metallayer -p2].shapes.rect_sizex $Tleng -p1].mask]
set abs_pin_rect [dbTransform -inst $inst_ptr -localPt $cell_pin_rect]
set stretch_rect [dbShape $abs_pin_rect SIZEX $extend_pin_length]
set wire_rect [dbShape [dbShape $stretch_rect ANDNOT $macro_box] SIZEX 0.72]
set net [regsub -all {{|}} [dbget $ptr.net.name] "" ]
puts $net
if {![dbget [dbget top.nets.name $net -p].isPwrOrGnd]} {
editDelete -net $net -type Regular
}
set original_rect [lindex $wire_rect 0]
set llx [align_to_grid [lindex $original_rect 0]]
set lly [align_to_grid [lindex $original_rect 1]]
set urx [align_to_grid [lindex $original_rect 2]]
set ury [align_to_grid [lindex $original_rect 3]]
set total_height [expr $ury - $lly]
set segment_height [align_to_grid [expr ($total_height - 2 * 0.54) / 3.0]]
set actual_total_height [expr $segment_height * 3 + 2 * 0.54]
if {abs($actual_total_height - $total_height) > 0.001} {
set ury [align_to_grid [expr $lly + $actual_total_height]]
}
for {set i 0} {$i < 3} {incr i} {
set seg_lly [align_to_grid [expr $lly + $i * ($segment_height + 0.54)]]
set seg_ury [align_to_grid [expr $seg_lly + $segment_height]]
dbCreateWire $net $llx $seg_lly $urx $seg_ury $layerNum 0 STRIPE
set seg_rect [list $llx $seg_lly $urx $seg_ury]
set new_wire [dbQuery -areas [lindex [dbShape $seg_rect SIZE -0.01] 0] -objType sWire -layers $layerNum]
deselectAll
select_obj $new_wire
editChangeMask -to $pin_mask
deselectAll
}
} else {
set cell_pin_rect [dbget [dbget [dbget [dbget $ptr.term.pins.layerShapeShapes.shapes.rect_sizex $Tleng -p2].layer.name $metallayer -p2].shapes.rect_sizex $Tleng -p1].rect]
set pin_mask [dbget [dbget [dbget [dbget $ptr.term.pins.layerShapeShapes.shapes.rect_sizex $Tleng -p2].layer.name $metallayer -p2].shapes.rect_sizex $Tleng -p1].mask]
puts $pin_mask
set abs_pin_rect [dbTransform -inst $inst_ptr -localPt $cell_pin_rect]
set stretch_rect [dbShape $abs_pin_rect SIZEY $extend_pin_length]
set wire_rect [dbShape [dbShape $stretch_rect ANDNOT $macro_box] SIZEY 0.72]
set net [regsub -all {{|}} [dbget $ptr.net.name] ""]
puts $net
if {![dbget [dbget top.nets.name $net -p].isPwrOrGnd]} {
editDelete -net $net -type Regular
}
set original_rect [lindex $wire_rect 0]
set llx [align_to_grid [lindex $original_rect 0]]
set lly [align_to_grid [lindex $original_rect 1]]
set urx [align_to_grid [lindex $original_rect 2]]
set ury [align_to_grid [lindex $original_rect 3]]
set total_width [expr $urx - $llx]
set segment_width [align_to_grid [expr ($total_width - 2 * 0.54) / 3.0]]
set actual_total_width [expr $segment_width * 3 + 2 * 0.54]
if {abs($actual_total_width - $total_width) > 0.001} {
set urx [align_to_grid [expr $llx + $actual_total_width]]
}
for {set i 0} {$i < 3} {incr i} {
set seg_llx [align_to_grid [expr $llx + $i * ($segment_width + 0.54)]]
set seg_urx [align_to_grid [expr $seg_llx + $segment_width]]
dbCreateWire $net $seg_llx $lly $seg_urx $ury $layerNum 1 STRIPE
set seg_rect [list $seg_llx $lly $seg_urx $ury]
set new_wire [dbQuery -areas [lindex [dbShape $seg_rect SIZE -0.01] 0] -objType sWire -layers $layerNum]
deselectAll
select_obj $new_wire
editChangeMask -to $pin_mask
deselectAll
}
}
}
}
}
}