##### Start metal8 section... @M8TrackSummary = split (/\s+/,$M8TrackLocations); $M8GCellWidth = $M8TrackSummary[$#M8TrackSummary] - $M8TrackSummary[0]; if (($M8StrapLocations[1] =~ /^0$/) && ($M8StrapWidths[1] =~ /^0$/)) { for ($y = $M8TrackSummary[0]; $y <= $NewBlockUY; $y = $y + $M8GCellWidth) { for ($m = 1; $m <= $#M8TrackSummary; $m++) { $M8CurrentTrackLoc = sprintf ("%0.3f", $M8TrackSummary[$m] + $y); push (@AvailableM8TrackLocations, $M8CurrentTrackLoc); } } $NumAvailableM8Tracks = @AvailableM8TrackLocations; } else { $M8StrapSeries1Width = $M8StrapWidths[1]; @M8StrapSeries1Summary = split (/\s+/,$M8StrapLocations[1]); $M8StrapSeries1StartY = $M8StrapSeries1Summary[0]; $M8StrapSeries1PitchY = $M8StrapSeries1Summary[1]; $M8StrapSeries1StepY = $M8StrapSeries1Summary[2]; for ($y = $M8TrackSummary[0]; $y <= $NewBlockUY; $y = $y + $M8GCellWidth) { for ($m = 1; $m <= $#M8TrackSummary; $m++) { $M8CurrentTrackLoc = sprintf ("%0.3f", $M8TrackSummary[$m] + $y); $NumM8Tracks++; for ($M8StrapSeries1Y = $M8StrapSeries1StartY; $M8StrapSeries1Y <= $NewBlockUY; $M8StrapSeries1Y = $M8StrapSeries1Y + $M8StrapSeries1StepY) { if (($M8CurrentTrackLoc >= ($M8StrapSeries1Y - ($M8StrapSeries1Width/2) - $M8Pitch)) && ($M8CurrentTrackLoc <= ($M8StrapSeries1Y + ($M8StrapSeries1Width/2) + $M8Pitch))) {push (@UnavailableM8TrackLocations, $M8CurrentTrackLoc);} if (($M8CurrentTrackLoc >= ($M8StrapSeries1Y - ($M8StrapSeries1Width/2) - $M8Pitch + $M8StrapSeries1PitchY)) && ($M8CurrentTrackLoc <= ($M8StrapSeries1Y + ($M8StrapSeries1Width/2) + $M8Pitch + $M8StrapSeries1PitchY))) {push (@UnavailableM8TrackLocations, $M8CurrentTrackLoc);} } } } $NumUnavailableM8Tracks = @UnavailableM8TrackLocations; $NumAvailableM8Tracks = $NumM8Tracks - $NumUnavailableM8Tracks; if ($NumUnavailableM8Tracks == 1) { print ("1 M8 track is blocked by a p/g strap.\n"); } elsif ($NumUnavailableM8Tracks > 1) { print ("$NumUnavailableM8Tracks M8 tracks are blocked by M8 p/g straps.\n"); } print ("$NumAvailableM8Tracks M8 tracks are available for M8 pin snapping.\n"); for ($y = $M8TrackSummary[0]; $y <= $NewBlockUY; $y = $y + $M8GCellWidth) { for ($m = 1; $m <= $#M8TrackSummary; $m++) { $M8CurrentTrackLoc = sprintf ("%0.3f", $M8TrackSummary[$m] + $y); $SkipM8Track = 0; foreach $UnavailableM8Track (@UnavailableM8TrackLocations) { if ($M8CurrentTrackLoc == $UnavailableM8Track) { $SkipM8Track = 1; last; } } if ($SkipM8Track == 0) {push (@AvailableM8TrackLocations, $M8CurrentTrackLoc);} } } } my @M8PinContentSorted = sort { $M8PinContentHash{$a} <=> $M8PinContentHash{$b} } keys %M8PinContentHash; $NumM8Pins = @M8PinContentSorted; if ($NumM8Pins == 0) { print ("No pins on layer M8.\n"); } elsif ($NumM8Pins == 1) { print ("1 pin on layer M8.\n"); if ($NumM8Pins > $NumAvailableM8Tracks) {die ("There are more M8 pins than available M8 tracks!\n");} } elsif ($NumM8Pins > 1) { print ("$NumM8Pins pins on layer M8.\n"); if ($NumM8Pins > $NumAvailableM8Tracks) {die ("There are more M8 pins than available M8 tracks!\n");} } if ($DebugMode == 1) { foreach $Entry (@M8PinContentSorted) { @EntryAL = split (/\s+/,$Entry); $PinName = $EntryAL[0]; print DEBUG ("$PinName\n"); } } foreach $M8Pin (@M8PinContentSorted) { @M8PinDetails = split (/\s+/,$M8Pin); $M8PinName = $M8PinDetails[0]; $M8OwnerPort = $M8PinDetails[1]; $M8LayerName = $M8PinDetails[2]; $M8LX = $M8PinDetails[3]; $M8LY = $M8PinDetails[4]; $M8UX = $M8PinDetails[5]; $M8UY = $M8PinDetails[6]; $M8Width = abs ($M8UY - $M8LY); #$M8Height = abs ($M8UX - $M8LX); $M8AccessDirection = $M8PinDetails[7]; $M8Direction = $M8PinDetails[8]; $c = 0; foreach $M8Track (@AvailableM8TrackLocations) { if ($M8Track >= $M8LY) { $M8Intervals = int ($M8Width/$M8Pitch); if ($M8Intervals < 1) { $NewM8LY = sprintf ("%0.3f", $M8Track - ($M8Width/2)); $NewM8UY = sprintf ("%0.3f", $M8Track + ($M8Width/2)); splice (@AvailableM8TrackLocations, $c, 1); } else { $M8SpliceWidth = $M8Intervals + 2; splice (@AvailableM8TrackLocations, $c, $M8SpliceWidth); if (exists $AvailableM8TrackLocations[$c]) { $NewM8LY = sprintf ("%0.3f", $AvailableM8TrackLocations[$c] - ($M8Width/2)); $NewM8UY = sprintf ("%0.3f", $AvailableM8TrackLocations[$c] + ($M8Width/2)); } else { print ("ERROR: Problem processing pin $M8PinName!\n"); } } print OUT ("create_terminal \\\n"); print OUT ("-name {$M8PinName} \\\n"); print OUT ("-port $M8OwnerPort \\\n"); print OUT ("-layer $M8LayerName \\\n"); print OUT ("-bounding_box {{$M8LX $NewM8LY} {$M8UX $NewM8UY}}\n\n"); print OUT ("set obj [get_terminal {\"$M8PinName\"}]\n"); print OUT ("set_attribute -quiet \$obj layer $M8LayerName\n"); print OUT ("set_attribute -quiet \$obj owner_port $M8OwnerPort\n"); print OUT ("set_attribute -quiet \$obj bbox {{$M8LX $NewM8LY} {$M8UX $NewM8UY}}\n"); print OUT ("set_attribute -quiet \$obj status Placed\n"); print OUT ("set_attribute -quiet \$obj access_direction $M8AccessDirection\n"); print OUT ("set_attribute -quiet \$obj direction $M8Direction\n"); print OUT ("set_attribute -quiet \$obj eeq_class 0\n\n"); last; } $c++; } } ##### End metal8 section...