DIRECTORY Basics, Convert, Rope, SC, SCChanUtil, SCInstUtil, SCNetUtil, SCPrivate, SCPlaceUtil, SCSmash, SCWidthUtil, SCRowUtil, SCUtil, RTSets, TerminalIO; SCPlaceImproveImpl: CEDAR PROGRAM IMPORTS Convert, Rope, SC, SCChanUtil, SCInstUtil, SCNetUtil, SCPlaceUtil, SCRowUtil, SCWidthUtil, SCSmash, SCUtil, TerminalIO EXPORTS SCPrivate SHARES SC = { debug: BOOLEAN _ FALSE; PosResult: TYPE = RECORD[ area, channelWidth, wireLength: SC.Number, numFts: INT]; PlaceResult: TYPE = RECORD[ area, channelWidth, wireLength: SC.Number, numFts: INT]; WritePosResult: PROCEDURE [header: Rope.ROPE, Result: PosResult] = { -- write the results TerminalIO.WriteRope[header]; TerminalIO.WriteRope[Rope.Cat[" area: ", Convert.RopeFromInt[Result.area]]]; TerminalIO.WriteRope[Rope.Cat[", channelWidth: ", Convert.RopeFromInt[Result.channelWidth]]]; TerminalIO.WriteRope[Rope.Cat["\n wireLength: ", Convert.RopeFromInt[Result.wireLength]]]; TerminalIO.WriteRope[Rope.Cat[", numFts: ", Convert.RopeFromInt[Result.numFts], "\n"]]}; ComparePosResult: PROCEDURE [result1, result2: PosResult] RETURNS [FirstRelationSecond: Basics.Comparison] = { IF result1.area < result2.area THEN FirstRelationSecond _ less ELSE IF result1.area > result2.area THEN FirstRelationSecond _ greater ELSE IF result1.channelWidth < result2.channelWidth THEN FirstRelationSecond _ less ELSE IF result1.channelWidth > result2.channelWidth THEN FirstRelationSecond _ greater ELSE IF result1.wireLength < result2.wireLength THEN FirstRelationSecond _ less ELSE IF result1.wireLength > result2.wireLength THEN FirstRelationSecond _ greater ELSE IF result1.numFts < result2.numFts THEN FirstRelationSecond _ less ELSE IF result1.numFts > result2.numFts THEN FirstRelationSecond _ greater ELSE FirstRelationSecond _ equal}; -- they are equal ComparePlaceResult: PROCEDURE [result1, result2: PlaceResult] RETURNS [FirstRelationSecond: Basics.Comparison] = BEGIN IF result1.area < result2.area THEN FirstRelationSecond _ less ELSE IF result1.area > result2.area THEN FirstRelationSecond _ greater ELSE IF result1.channelWidth < result2.channelWidth THEN FirstRelationSecond _ less ELSE IF result1.channelWidth > result2.channelWidth THEN FirstRelationSecond _ greater ELSE IF result1.wireLength < result2.wireLength THEN FirstRelationSecond _ less ELSE IF result1.wireLength > result2.wireLength THEN FirstRelationSecond _ greater ELSE IF result1.numFts < result2.numFts THEN FirstRelationSecond _ less ELSE IF result1.numFts > result2.numFts THEN FirstRelationSecond _ greater ELSE FirstRelationSecond _ equal; -- they are equal END; -- ComparePlaceResult DoWidths: PROCEDURE [handle: SC.Handle, doChanWidth: SCPrivate.ChanSet, doSideWidth: SCPrivate.LRSideSet, doRowWidth: SCPrivate.RowSet, fom: SCPrivate.FomType] RETURNS [wireLength: SC.Number _ 0] = { EachRow: SCRowUtil.EachRowProc = { IF doRowWidth[(row)-1] THEN SCInstUtil.LgOffsets[handle, row, 0, 0]}; EachRowChan: SCChanUtil.EachRowChanProc = { IF doChanWidth[(chan )-1] THEN [rowChan.chanWidth, rowChan.wireLength] _ SCWidthUtil.GetChanWidth[handle, rowChan, fom, TRUE]; wireLength _ wireLength + layoutData.rowChans.chans[chan].wireLength}; EachSideChan: SCChanUtil.EachSideChanProc = { IF doSideWidth[LOOPHOLE[lrSide, INTEGER]] THEN { sideChan: SCPrivate.SideChan _ layoutData.sideChans[lrSide]; [sideChan.sideChanWidth, sideChan.wireLength] _ SCWidthUtil.GetSideWidth[handle, lrSide, fom]}; wireLength _ wireLength + sideChan.wireLength}; layoutData: SCPrivate.LayoutData _ NARROW[handle.layoutData]; [] _ SCRowUtil.EnumerateRows[handle, EachRow]; [] _ SCChanUtil.EnumerateRowChans[handle, EachRowChan]; [] _ SCChanUtil.EnumerateSideChans[handle, EachSideChan]}; ChosRow: PROCEDURE[handle: SC.Handle, rowIndex: SCPrivate.ZMaxRowSr] RETURNS[rowToDo: SCPrivate.LgRow, doUpper, doLower: BOOLEAN] = { layoutData: SCPrivate.LayoutData _ NARROW[handle.layoutData]; lgRows: SCPrivate.LgRows _ layoutData.lgRows; row: SCPrivate.ZMaxRowSr; SELECT TRUE FROM layoutData.bpRows[top].fnlBpFxd AND layoutData.bpRows[bottom].fnlBpFxd => {IF (rowIndex MOD 2) # 0 THEN row _ (lgRows.count+1) /2 - (rowIndex-1) /2 ELSE row _ (lgRows.count+1) /2 + rowIndex /2; doUpper _ doLower _ TRUE}; layoutData.bpRows[top].fnlBpFxd => {row _ lgRows.count - rowIndex + 1; doUpper _ TRUE; doLower _ FALSE}; layoutData.bpRows[bottom].fnlBpFxd => {row _ rowIndex; doUpper _ FALSE; doLower _ TRUE}; ENDCASE => {IF (rowIndex MOD 2) # 0 THEN row _ (lgRows.count+1) /2 - (rowIndex-1) /2 ELSE row _ (lgRows.count+1) /2 + rowIndex /2; IF row = (lgRows.count+1) /2 THEN {doUpper _ TRUE; doLower _ TRUE} ELSE IF row < (lgRows.count+1) /2 THEN {doUpper _ TRUE; doLower _ FALSE} ELSE {doUpper _ FALSE; doLower _ TRUE}}; rowToDo _ lgRows.rows[row]}; PosImproveRow: PROCEDURE [handle: SC.Handle, lgRow: SCPrivate.LgRow, doUpper, doLower: BOOLEAN, whichFom: SCPrivate.FomType] RETURNS [goodExch: INT _ 0] = { layoutData: SCPrivate.LayoutData _ NARROW[handle.layoutData]; structureData: SCPrivate.StructureData _ NARROW[handle.structureData]; lgRows: SCPrivate.LgRows _ layoutData.lgRows; row: SCPrivate.MaxRowSr _ lgRow.rowNum; rowChans: SCPrivate.RowChans _ layoutData.rowChans; lowerChan: SCPrivate.RowChan _ rowChans.chans[row]; upperChan: SCPrivate.RowChan _ rowChans.chans[row+1]; numFts: INT _ structureData.instances.numFts; oldLowChWidth, oldUpChWidth, oldLowWireLength, oldUpWireLength: SC.Number; oldResult: PosResult; TrialInterchange: SCRowUtil.EachInstProc = { nextPos: SCPrivate.MaxPosSr _ pos + 1; lowChWidth, upChWidth, upWireLength, lowWireLength: SC.Number; newResult: PosResult; SCPlaceUtil.ExchPosRow[handle, pos, nextPos, row]; [lowChWidth, lowWireLength] _ SCWidthUtil.GetChanWidth[handle, lowerChan, whichFom, doLower]; [upChWidth, upWireLength] _ SCWidthUtil.GetChanWidth[handle, upperChan, whichFom, doUpper]; newResult _ PosResult[(lowChWidth + upChWidth) * lgRows.maxRowWidth, (lowChWidth + upChWidth), (lowWireLength + upWireLength), numFts]; IF debug THEN WritePosResult[" trial result: ", newResult]; SELECT ComparePosResult[newResult, oldResult] FROM less => { -- strict improvement, thats good IF debug THEN TerminalIO.WriteRope[" accept improvement\n"]; lowerChan.chanWidth _ lowChWidth; upperChan.chanWidth _ upChWidth; oldResult _ newResult; goodExch _ goodExch + 1}; equal => { -- neutral improvement, take it IF debug THEN TerminalIO.WriteRope[" accept neutral exchange\n"]; lowerChan.chanWidth _ lowChWidth; upperChan.chanWidth _ upChWidth; oldResult _ newResult}; greater => { -- this change made it worse, restore old placement IF debug THEN WritePosResult[" restore old result: ", oldResult]; SCPlaceUtil.ExchPosRow[handle, pos, nextPos, row]}; ENDCASE}; IF lgRow.nLgsOnRow > 0 AND ~lgRow.fnlLgFxd AND (doUpper OR doLower) THEN { TerminalIO.WriteRope[Rope.Cat[" improve row ", Convert.RopeFromInt[row], ", "]]; [oldLowChWidth, oldLowWireLength] _ SCWidthUtil.GetChanWidth[handle, lowerChan, whichFom, doLower]; [oldUpChWidth, oldUpWireLength] _ SCWidthUtil.GetChanWidth[handle, upperChan, whichFom, doUpper]; oldResult _ PosResult[(oldLowChWidth + oldUpChWidth) * lgRows.maxRowWidth, (oldLowChWidth + oldUpChWidth), (oldLowWireLength + oldUpWireLength), numFts]; IF debug THEN WritePosResult["\n original logic result: ", oldResult]; [] _ SCRowUtil.EnumerateInstsOnRow[handle, row, 1, MAX[0, lgRow.nLgsOnRow-1], TrialInterchange]; TerminalIO.WriteRope[Rope.Cat[Convert.RopeFromInt[goodExch], " good exchanges\n"]]}}; PosImproveLeftRight: PROCEDURE[handle: SC.Handle, side: SC.Side, whichFom: SCPrivate.FomType] RETURNS [goodExch: INT _ 0] = { layoutData: SCPrivate.LayoutData _ NARROW[handle.layoutData]; structureData: SCPrivate.StructureData _ NARROW[handle.structureData]; lgRows: SCPrivate.LgRows _ layoutData.lgRows; bpRow: SCPrivate.BpRow _ layoutData.bpRows[side]; sideChan: SCPrivate.SideChan _ layoutData.sideChans[side]; wireLength: SC.Number; oldResult: PlaceResult; TrialInterchange: SCRowUtil.EachInstProc = { doChanWidth: SCPrivate.ChanSet _ RTSets.RTMdSetEmpty; doRowWidth: SCPrivate.ChanSet _ RTSets.RTMdSetEmpty; doSideWidth: SCPrivate.LRSideSet _ RTSets.RTSmSetEmpty; nextPos: SCPrivate.MaxPosSr _ pos +1; newWireLength: SC.Number; newResult: PlaceResult; nets: SCPrivate.NetList _ SCNetUtil.NetsOnInst[LIST[bpRow.bpsOnSide[pos], bpRow.bpsOnSide[nextPos]]]; [doChanWidth, doSideWidth, doRowWidth] _ SCSmash.RemoveNetsWFts[handle, nets, TRUE, doChanWidth, doSideWidth, doRowWidth]; SCPlaceUtil.ExchPosSide[handle, pos, nextPos, side]; [doChanWidth, doSideWidth, doRowWidth] _ SCSmash.SmashNets[handle, nets, FALSE, doChanWidth, doSideWidth, doRowWidth]; newWireLength _ DoWidths[handle, doChanWidth, doSideWidth, doRowWidth, whichFom]; [lgRows.maxRowWidth, lgRows.numMaxRows] _ SCRowUtil.FindMaxRow[handle]; SCInstUtil.AsgnChanPos[handle]; newResult _ PlaceResult[layoutData.totWidth * layoutData.totHeight, layoutData.sideChans[side].sideChanWidth, newWireLength, structureData.instances.numFts]; IF debug THEN WritePosResult[" trial result: ", newResult]; SELECT ComparePlaceResult[newResult, oldResult] FROM less => { -- strict improvement, thats good IF debug THEN TerminalIO.WriteRope[" accept improvement\n"]; wireLength _ newWireLength; oldResult _ newResult; goodExch _ goodExch + 1}; equal => { -- neutral exchange, take it IF debug THEN TerminalIO.WriteRope[" accept neutral exchange\n"]; wireLength _ newWireLength; oldResult _ newResult}; greater => { -- this change made it worse, restore old placement IF debug THEN WritePosResult[" restore old result: ", oldResult]; [doChanWidth, doSideWidth, doRowWidth] _ SCSmash.RemoveNetsWFts[handle, nets, FALSE, RTSets.RTMdSetEmpty, RTSets.RTSmSetEmpty, RTSets.RTMdSetEmpty]; SCPlaceUtil.ExchPosSide[handle, pos, nextPos, side]; [doChanWidth, doSideWidth, doRowWidth] _ SCSmash.RestoreNetsWFts[handle, nets, doChanWidth, doSideWidth, doRowWidth]; wireLength _ DoWidths[handle, doChanWidth, doSideWidth, doRowWidth, whichFom]; [lgRows.maxRowWidth, lgRows.numMaxRows] _ SCRowUtil.FindMaxRow[handle]; SCInstUtil.AsgnChanPos[handle]}; ENDCASE}; IF ~ bpRow.fnlBpFxd THEN { TerminalIO.WriteRope[Rope.Cat[" improve ", SCRowUtil.sideName[side], " side, "]]; SCWidthUtil.AllChanWidths[handle, whichFom]; wireLength _ DoWidths[handle, RTSets.RTMdSetEmpty, RTSets.RTSmSetEmpty, RTSets.RTMdSetEmpty, whichFom]; [lgRows.maxRowWidth, lgRows.numMaxRows] _ SCRowUtil.FindMaxRow[handle]; SCInstUtil.AsgnChanPos[handle]; oldResult _ PlaceResult[layoutData.totWidth * layoutData.totHeight, sideChan.sideChanWidth, wireLength, structureData.instances.numFts]; IF debug THEN WritePosResult[Rope.Cat["\n original ", SCRowUtil.sideName[side] ," result: "], oldResult]; [] _ SCRowUtil.EnumerateInstsOnSide[handle, side, 1, MAX[0, bpRow.nBpsOnSide -1], TrialInterchange]; TerminalIO.WriteRope[Rope.Cat[Convert.RopeFromInt[goodExch], " good exchanges\n"]]; SCWidthUtil.AllChanWidths[handle, areaFom]}}; PosImproveTopBot: PROCEDURE[handle: SC.Handle, side: SC.Side, whichFom: SCPrivate.FomType] RETURNS [goodExch: INT _ 0] = { layoutData: SCPrivate.LayoutData _ NARROW[handle.layoutData]; structureData: SCPrivate.StructureData _ NARROW[handle.structureData]; lgRows: SCPrivate.LgRows _ layoutData.lgRows; bpRow: SCPrivate.BpRow _ layoutData.bpRows[side]; rowChans: SCPrivate.RowChans _ layoutData.rowChans; numFts: INT _ structureData.instances.numFts; oldChWidth, oldWireLength: SC.Number; oldResult: PosResult; chan: SCPrivate.RowChan _ SELECT side FROM top => rowChans.chans[rowChans.count], bottom => rowChans.chans[1], ENDCASE => SC.Error[programmingError, "Invalid side in Placement Improvement"]; TrialInterchange: SCRowUtil.EachInstProc = { nextPos: SCPrivate.MaxPosSr _ pos + 1; chWidth, wireLength: SC.Number; newResult: PosResult; SCPlaceUtil.ExchPosSide[handle, pos, nextPos, side]; [chWidth, wireLength] _ SCWidthUtil.GetChanWidth[handle, chan, whichFom, TRUE]; newResult _ PosResult[chWidth * lgRows.maxRowWidth, chWidth, wireLength, numFts]; IF debug THEN WritePosResult[" trial result: ", newResult]; SELECT ComparePosResult[newResult, oldResult] FROM less => { -- strict improvement, thats good IF debug THEN TerminalIO.WriteRope[" accept improvement\n"]; chan.chanWidth _ chWidth; oldResult _ newResult; goodExch _ goodExch + 1}; equal => { -- neutral exchange, take what you can get IF debug THEN TerminalIO.WriteRope[" accept neutral exchange\n"]; chan.chanWidth _ chWidth; oldResult _ newResult}; greater => { -- this change made it worse, restore old placement IF debug THEN WritePosResult[" restore old result: ", oldResult]; SCPlaceUtil.ExchPosSide[handle, pos, nextPos, side]}; ENDCASE}; IF ~ bpRow.fnlBpFxd THEN { TerminalIO.WriteRope[Rope.Cat[" improve ", SCRowUtil.sideName[side], " side, "]]; [oldChWidth, oldWireLength] _ SCWidthUtil.GetChanWidth[handle, chan, whichFom, TRUE]; oldResult _ PosResult[oldChWidth * lgRows.maxRowWidth, oldChWidth, oldWireLength, numFts]; IF debug THEN WritePosResult[Rope.Cat["\n original ", SCRowUtil.sideName[side]," result: "], oldResult]; [] _ SCRowUtil.EnumerateInstsOnSide[handle, side, 1, MAX[0, bpRow.nBpsOnSide-1], TrialInterchange]; TerminalIO.WriteRope[Rope.Cat[Convert.RopeFromInt[goodExch], " good exchanges\n"]]}}; PosImprove: PUBLIC PROCEDURE [handle: SC.Handle, whichFom: SCPrivate.FomType, maxCycles: INT] = { layoutData: SCPrivate.LayoutData _ NARROW[handle.layoutData]; lgRows: SCPrivate.LgRows _ layoutData.lgRows; bpRows: SCPrivate.BpRows _ layoutData.bpRows; startArea: SC.Number; numCycles: INT _ 0; [lgRows.maxRowWidth, lgRows.numMaxRows] _ SCRowUtil.FindMaxRow[handle]; SCWidthUtil.AllChanWidths[handle, areaFom]; SCInstUtil.AsgnChanPos[handle]; startArea _ SCUtil.WriteResults["Position improvement\n starting area:", handle, 0]; DO goodExch: INT _ 0; goodTopExch, goodBottomExch, goodRightExch, goodLeftExch: INT; EachRow: SCRowUtil.EachRowProc = { rowToDo: SCPrivate.LgRow; doUpper, doLower: BOOLEAN; [rowToDo, doUpper, doLower] _ ChosRow[handle, row]; goodExch _ goodExch + PosImproveRow[handle, rowToDo, doUpper, doLower, whichFom]}; IF numCycles >= maxCycles THEN EXIT; goodLeftExch _ PosImproveLeftRight[handle, left, whichFom]; goodRightExch _ PosImproveLeftRight[handle, right, whichFom]; SCInstUtil.AsgnChanPos[handle]; [] _ SCRowUtil.EnumerateRows[handle, EachRow]; goodTopExch _ PosImproveTopBot[handle, top, whichFom]; goodBottomExch _ PosImproveTopBot[handle, bottom, whichFom]; IF goodExch + goodLeftExch + goodRightExch + goodTopExch + goodBottomExch <= 0 THEN EXIT; SCInstUtil.AsgnChanPos[handle]; numCycles _ numCycles + 1; ENDLOOP; SCInstUtil.AllOffsets[handle]; [lgRows.maxRowWidth, lgRows.numMaxRows] _ SCRowUtil.FindMaxRow[handle]; SCWidthUtil.AllChanWidths[handle, areaFom]; SCInstUtil.AsgnChanPos[handle]; [] _ SCUtil.WriteResults["End position improvement\n ending area:", handle, startArea]; IF debug THEN SCPlaceUtil.WriteCurPlace[handle]}; -- PosImprove OrientImproveRow: PROCEDURE [handle: SC.Handle, lgRow: SCPrivate.LgRow, doUpper, doLower: BOOLEAN, whichFom: SCPrivate.FomType] RETURNS [goodExch: INT _ 0] = { layoutData: SCPrivate.LayoutData _ NARROW[handle.layoutData]; structureData: SCPrivate.StructureData _ NARROW[handle.structureData]; lgRows: SCPrivate.LgRows _ layoutData.lgRows; row: SCPrivate.MaxRowSr _ lgRow.rowNum; rowChans: SCPrivate.RowChans _ layoutData.rowChans; lowerChan: SCPrivate.RowChan _ rowChans.chans[row]; upperChan: SCPrivate.RowChan _ rowChans.chans[row+1]; numFts: INT _ structureData.instances.numFts; oldLowChWidth, oldUpChWidth, oldLowWireLength, oldUpWireLength: SC.Number; oldResult: PosResult; TrialInterchange: SCRowUtil.EachInstProc = { lowChWidth, upChWidth, upWireLength, lowWireLength: SC.Number; newResult: PosResult; IF instance.fnlOrien = 0 THEN { SCPlaceUtil.ReverseOrientation[instance]; [lowChWidth, lowWireLength] _ SCWidthUtil.GetChanWidth[handle, lowerChan, whichFom, doLower]; [upChWidth, upWireLength] _ SCWidthUtil.GetChanWidth[handle, upperChan, whichFom, doUpper]; newResult _ PosResult[(lowChWidth + upChWidth) * lgRows.maxRowWidth, (lowChWidth + upChWidth), (lowWireLength + upWireLength), numFts]; IF debug THEN WritePosResult[" trial result: ", newResult]; SELECT ComparePosResult[newResult, oldResult] FROM less => { -- strict improvement, thats good IF debug THEN TerminalIO.WriteRope[" accept improvement\n"]; lowerChan.chanWidth _ lowChWidth; upperChan.chanWidth _ upChWidth; oldResult _ newResult; goodExch _ goodExch + 1}; equal => { -- neutral improvement, take it IF debug THEN TerminalIO.WriteRope[" accept neutral exchange\n"]; lowerChan.chanWidth _ lowChWidth; upperChan.chanWidth _ upChWidth; oldResult _ newResult}; greater => { -- this change made it worse, restore old placement IF debug THEN WritePosResult[" restore old result: ", oldResult]; SCPlaceUtil.ReverseOrientation[instance]}; ENDCASE}}; IF lgRow.nLgsOnRow > 0 AND (doUpper OR doLower) THEN { TerminalIO.WriteRope[Rope.Cat[" improve orientation on row ", Convert.RopeFromInt[row], ", "]]; [oldLowChWidth, oldLowWireLength] _ SCWidthUtil.GetChanWidth[handle, lowerChan, whichFom, doLower]; [oldUpChWidth, oldUpWireLength] _ SCWidthUtil.GetChanWidth[handle, upperChan, whichFom, doUpper]; oldResult _ PosResult[(oldLowChWidth + oldUpChWidth) * lgRows.maxRowWidth, (oldLowChWidth + oldUpChWidth), (oldLowWireLength + oldUpWireLength), numFts]; IF debug THEN WritePosResult[" original result: ", oldResult]; [] _ SCRowUtil.EnumerateAllInstsOnRow[handle, row, TrialInterchange]; TerminalIO.WriteRope[Rope.Cat[Convert.RopeFromInt[goodExch], " good exchanges\n"]]}}; OrientImprove: PUBLIC PROCEDURE [handle: SC.Handle, whichFom: SCPrivate.FomType, maxCycles: INT] = { layoutData: SCPrivate.LayoutData _ NARROW[handle.layoutData]; lgRows: SCPrivate.LgRows _ layoutData.lgRows; startArea: SC.Number; numCycles: INT _ 0; [lgRows.maxRowWidth, lgRows.numMaxRows] _ SCRowUtil.FindMaxRow[handle]; SCWidthUtil.AllChanWidths[handle, areaFom]; SCInstUtil.AsgnChanPos[handle]; startArea _ SCUtil.WriteResults["Orientation improvement\n starting area:", handle, 0]; DO EachRow: SCRowUtil.EachRowProc = { rowToDo: SCPrivate.LgRow; doUpper, doLower: BOOLEAN; [rowToDo, doUpper, doLower] _ ChosRow[handle, row]; goodExch _ OrientImproveRow[handle, rowToDo, doUpper, doLower, whichFom]}; goodExch: INT _ 0; IF numCycles >= maxCycles THEN EXIT; SCInstUtil.AsgnChanPos[handle]; [] _ SCRowUtil.EnumerateRows[handle, EachRow]; IF goodExch <= 0 THEN EXIT; SCInstUtil.AsgnChanPos[handle]; numCycles _ numCycles + 1; ENDLOOP; SCInstUtil.AllOffsets[handle]; [lgRows.maxRowWidth, lgRows.numMaxRows] _ SCRowUtil.FindMaxRow[handle]; SCWidthUtil.AllChanWidths[handle, areaFom]; SCInstUtil.AsgnChanPos[handle]; [] _ SCUtil.WriteResults["End orientation improvement\n ending area:", handle, startArea]; IF debug THEN SCPlaceUtil.WriteCurPlace[handle]}; -- PosImprove }. Zfile: SCPlaceImproveImpl.mesa Copyright c 1985 by Xerox Corporation. All rights reserved. map a row index in to a row improve positions on logic rows improve positions on bonding pad sides improve positions on bonding pad sides improve the left and right sides now improve the top and bottom sides improve orientation on logic rows ΚŽ˜šœ™Icodešœ Οmœ0™;—J˜šΟk ˜ J˜Jšœ˜Jšœ˜Jšžœ˜J˜ Jšœ ˜ J˜ J˜ Jšœ ˜ Jšœ ˜ Jšœ ˜ Jšœ ˜ J˜Jšœ˜Jšœ ˜ J˜—šΟnœžœž˜!J˜Jšžœžœe˜~J˜Jšžœ ˜Jšžœžœ˜J˜Jšœžœžœ˜J˜šœ žœžœ˜Jšœ žœ˜*Jšœžœ˜ —J˜šœ žœžœ˜Jšœ žœ˜*Jšœžœ˜ —J˜š Ÿœž œžœŸœΟc˜YJšœ˜JšœN˜NJšœ]˜]Jšœ_˜_JšœX˜XJ˜—šŸœž œ˜9JšžœŸœ˜4šžœž˜#Jšœ˜—šžœžœž˜(Jšœ˜—šžœžœ-ž˜8Jšœ˜—šžœžœ-ž˜8Jšœ˜—šžœžœ)ž˜4Jšœ˜—šžœžœ)ž˜4Jšœ˜—šžœžœ!ž˜,Jšœ˜—šžœžœ!ž˜,Jšœ˜—šž˜Jšœ ˜/——J˜šŸœž œ ˜=JšžœŸœ˜2J˜Jšž˜šžœž˜#Jšœ˜—šžœžœž˜(Jšœ˜—šžœžœ-ž˜8Jšœ˜—šžœžœ-ž˜8Jšœ˜—šžœžœ)ž˜4Jšœ˜—šžœžœ)ž˜4Jšœ˜—šžœžœ!ž˜,Jšœ˜—šžœžœ!ž˜,Jšœ˜—šž˜Jšœ ˜.—Jšžœ ˜J˜—šŸœž œ žœ˜'Jšœ˜Jšœ!˜!Jšœ˜Jšœ˜Jšžœžœ˜'J˜šŸœ˜#Jšžœžœ*˜E—J˜šŸ œ!˜,šžœž˜JšœYžœ˜_—JšœF˜F—J˜šŸ œ!˜-šžœ žœ žœžœ˜0Jšœ<˜Jšœ˜J˜Jšœ2˜2Jšœ]˜]Jšœ[˜[Jšœ‡˜‡Jšžœžœ0˜=J˜šžœ(ž˜2šœ  "˜,Jšžœžœ1˜>Jšœ!˜!Jšœ ˜ Jšœ˜Jšœ˜—J˜šœ   ˜+Jšžœžœ6˜CJšœ!˜!Jšœ ˜ Jšœ˜—J˜šœ  4˜AJšžœžœ6˜CJšœ3˜3—Jšžœ˜ —J˜—š žœžœžœ žœ žœ˜JJšœQ˜QJ˜Jšœc˜cJšœa˜aJšœ™˜™Jšžœžœ;˜HJ˜Jšœ3žœ*˜`JšœU˜U——J˜Jšœ'™'š Ÿœž œ žœžœ$žœ žœ ˜}J˜Jšœ#žœ˜=Jšœ)žœ˜FJšœ-˜-Jšœ1˜1Jšœ:˜:Jšœ žœ˜Jšœ˜J˜šŸœ˜,Jšœ5˜5Jšœ4˜4Jšœ7˜7Jšœ%˜%Jšœžœ˜Jšœ˜J˜Jšœ/žœ2˜eJšœNžœ(˜zJšœ4˜4JšœIžœ(˜vJšœQ˜QJšœG˜GJšœ˜Jšœ˜Jšžœžœ0˜=J˜šžœ*ž˜4šœ  !˜+Jšžœžœ1˜>Jšœ˜Jšœ˜Jšœ˜—J˜šœ  ˜'Jšžœžœ6˜CJšœ˜Jšœ˜—J˜šœ  4˜AJšžœžœ6˜CJšœNžœA˜”Jšœ4˜4Jšœu˜uJ˜JšœN˜NJšœG˜GJšœ ˜ —Jšžœ˜ J˜——šžœžœ˜JšœR˜RJ˜Jšœ,˜,Jšœg˜gJšœG˜GJšœ˜Jšœˆ˜ˆJšžœžœ^˜kJ˜Jšœ5žœ,˜dJšœS˜SJ˜Jšœ-˜-—J˜—Jšœ'™'š Ÿœž œ žœžœ$žœ žœ ˜zJ˜Jšœ#žœ˜=Jšœ)žœ˜FJšœ-˜-Jšœ1˜1Jšœ3˜3Jšœžœ"˜-Jšœžœ˜%Jšœ˜šœžœž˜*Jšœ&˜&Jšœ˜JšžœžœB˜O—J˜šŸœ˜,Jšœ&˜&Jšœžœ˜Jšœ˜J˜Jšœ4˜4JšœIžœ˜OJšœQ˜QJšžœžœ0˜=J˜Jšžœ(ž˜2šœ  "˜,Jšžœžœ1˜>Jšœ˜Jšœ˜Jšœ˜—J˜šœ  +˜6šžœžœ˜Jšœ5˜5—Jšœ˜Jšœ˜—J˜šœ  4˜AJšžœžœ6˜CJšœ5˜5—Jšžœ˜ —J˜šžœžœ˜JšœQ˜QJ˜JšœOžœ˜UJšœZ˜ZJšžœžœ]˜jJ˜Jšœ5žœ+˜cJšœU˜U——J˜š Ÿ œžœž œ žœ1žœ˜aJ˜Jšœ#žœ˜=Jšœ-˜-Jšœ-˜-Jšœ žœ˜Jšœ žœ˜J˜JšœG˜GJšœ+˜+Jšœ˜JšœT˜TJ˜šž˜Jšœ žœ˜Jšœ:žœ˜>šŸœ˜#Jšœ˜Jšœžœ˜Jšœ3˜3JšœR˜R—J˜šžœžœžœ˜$J˜—Jšœ!™!Jšœ;˜;Jšœ=˜=J˜Jšœ˜Jšœ.˜.J˜Jšœ%™%Jšœ6˜6Jšœ<˜Jšœ˜J˜šžœžœ˜Jšœ)˜)Jšœ]˜]Jšœ[˜[Jšœ‡˜‡Jšžœžœ0˜=J˜šžœ(ž˜2šœ  "˜,Jšžœžœ1˜>Jšœ!˜!Jšœ ˜ Jšœ˜Jšœ˜—J˜šœ   ˜+Jšžœžœ6˜CJšœ!˜!Jšœ ˜ Jšœ˜—J˜šœ  4˜AJšžœžœ6˜CJšœ*˜*—Jšžœ˜ —J˜——šžœžœ žœ žœ˜6Jšœ`˜`J˜Jšœc˜cJšœa˜aJšœ™˜™Jšžœžœ3˜@J˜JšœE˜EJšœU˜UJ˜——š Ÿ œžœž œ žœ1žœ˜dJ˜Jšœ#žœ˜=Jšœ-˜-Jšœ žœ˜Jšœ žœ˜J˜JšœG˜GJšœ+˜+Jšœ˜JšœW˜WJ˜šž˜šŸœ˜#Jšœ˜Jšœžœ˜Jšœ3˜3šœJ˜JJ˜——Jšœ žœ˜Jšžœžœžœ˜$Jšœ˜Jšœ.˜.J˜Jšžœžœžœ˜Jšœ˜Jšœ˜Jšžœ˜—J˜Jšœ˜JšœG˜GJšœ+˜+Jšœ˜J˜JšœZ˜ZJšžœžœ%  ˜?—Jšœ˜——…—IΚZ²