IO出pin

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
                    }
                }
            }
        }
    }
}
posted @ 2025-10-27 11:05  心随鸥鹭齐舒羽  阅读(7)  评论(0)    收藏  举报