DIRECTORY Basics, Convert, Rope, RTSets, SC, SCChanUtil, SCInstUtil, SCNetUtil, SCNewWidth, SCNewRoutePinsUtil, SCPrivate, SCPlaceUtil, SCSmash, SCWidthUtil, SCRowUtil, SCUtil, TerminalIO; SCNewPlaceImproveImpl: CEDAR PROGRAM IMPORTS Convert, Rope, SC, SCChanUtil, SCInstUtil, SCNetUtil, SCNewWidth, SCPlaceUtil, SCRowUtil, SCWidthUtil, SCSmash, SCUtil, TerminalIO EXPORTS SCPrivate SHARES SC = { debug: BOOLEAN _ FALSE; test: BOOLEAN _ FALSE; RowSpec: TYPE = RECORD[ row: SCPrivate.LgRow, doUpper, doLower: BOOLEAN]; 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.PutRope[header]; TerminalIO.PutRope[Rope.Cat[" area: ", Convert.RopeFromInt[Result.area]]]; TerminalIO.PutRope[Rope.Cat[", channelWidth: ", Convert.RopeFromInt[Result.channelWidth]]]; TerminalIO.PutRope[Rope.Cat["\n wireLength: ", Convert.RopeFromInt[Result.wireLength]]]; TerminalIO.PutRope[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, SCPrivate.maxPos]}; EachRowChan: SCChanUtil.EachRowChanProc = { IF doChanWidth[(chan )-1] THEN [rowChan.chanWidth, rowChan.wireLength] _ SCNewWidth.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[rowSpec: RowSpec] = { layoutData: SCPrivate.LayoutData _ NARROW[handle.layoutData]; lgRows: SCPrivate.LgRows _ layoutData.lgRows; row: SCPrivate.ZMaxRowSr; doUpper, doLower: BOOLEAN; 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 _ row = 1} ELSE {doUpper _ row = lgRows.count; doLower _ TRUE}}; rowSpec _ [lgRows.rows[row], doLower, doUpper]}; SwitchTwoInsts: PROCEDURE[handle: SC.Handle, index1, index2: SCPrivate.MaxPosSr, rowSpec:RowSpec, whichFom: SCPrivate.FomType] = { layoutData: SCPrivate.LayoutData _ NARROW[handle.layoutData]; lgRow: SCPrivate.LgRow _ rowSpec.row; instance1: SCPrivate.Instance _ lgRow.lgsOnRow[index1]; instance2: SCPrivate.Instance _ lgRow.lgsOnRow[index2]; deltaX1: SC.Number _ SCInstUtil.InstWidth[instance2]; deltaX2: SC.Number _ - SCInstUtil.InstWidth[instance1]; netList: SCPrivate.NetList _ NIL; IF rowSpec.doLower THEN SCNewWidth.SwapPinsInChanOnTwoInsts[handle, instance1, instance2, deltaX1, deltaX2, bottom, rowSpec.row.rowNum, whichFom]; IF rowSpec.doUpper THEN SCNewWidth.SwapPinsInChanOnTwoInsts[handle, instance1, instance2, deltaX1, deltaX2, top, rowSpec.row.rowNum + 1, whichFom]; SCPlaceUtil.ExchPosRow[handle, index1, index2, rowSpec.row.rowNum]}; PosImproveRow: PROCEDURE [handle: SC.Handle, rowSpec: RowSpec, 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 _ rowSpec.row.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, oldLowChWireLength, oldUpChWireLength: SC.Number; newLowChWidth, newUpChWidth, newLowChWireLength, newUpChWireLength: SC.Number; oldResult, newResult: PosResult; TrialInterchange: SCRowUtil.EachInstProc = { nextPos: SCPrivate.MaxPosSr _ pos + 1; SwitchTwoInsts[handle, pos, nextPos, rowSpec, whichFom]; IF rowSpec.doLower THEN { newLowChWidth _ lowerChan.chanWidth; newLowChWireLength _ lowerChan.wireLength} ELSE { newLowChWidth _ oldLowChWidth; newLowChWireLength _ oldLowChWireLength}; IF rowSpec.doUpper THEN { newUpChWidth _ upperChan.chanWidth; newUpChWireLength _ upperChan.wireLength} ELSE { newUpChWidth _ oldUpChWidth; newUpChWireLength _ oldUpChWireLength}; newResult _ PosResult[(newLowChWidth + newUpChWidth) * lgRows.maxRowWidth, (newLowChWidth + newUpChWidth), (newLowChWireLength + newUpChWireLength), numFts]; IF debug THEN WritePosResult[" trial result: ", newResult]; SELECT ComparePosResult[newResult, oldResult] FROM less => { -- strict improvement, thats good IF debug THEN TerminalIO.PutRope[" accept improvement\n"]; oldLowChWidth _ newLowChWidth; oldLowChWireLength _ newLowChWireLength; oldUpChWidth _ newUpChWidth; oldUpChWireLength _ newUpChWireLength; oldResult _ newResult; goodExch _ goodExch + 1}; equal, greater => { -- this change made it worse, restore old placement IF debug THEN WritePosResult[" restore old result: ", oldResult]; SwitchTwoInsts[handle, pos, nextPos, rowSpec, whichFom]}; ENDCASE}; IF rowSpec.row.nLgsOnRow > 0 AND ~rowSpec.row.fnlLgFxd AND (rowSpec.doUpper OR rowSpec.doLower) THEN { TerminalIO.PutRope[Rope.Cat[" improve row ", Convert.RopeFromInt[row], ", "]]; [] _ SCNewWidth.SetAuxiDS[handle, lowerChan, whichFom, rowSpec.doLower]; [] _ SCNewWidth.SetAuxiDS[handle, upperChan, whichFom, rowSpec.doUpper]; oldLowChWidth _ lowerChan.chanWidth; oldLowChWireLength _ lowerChan.wireLength; oldUpChWidth _ upperChan.chanWidth; oldUpChWireLength _ upperChan.wireLength; oldResult _ PosResult[(oldLowChWidth + oldUpChWidth) * lgRows.maxRowWidth, (oldLowChWidth + oldUpChWidth), (oldLowChWireLength + oldUpChWireLength), numFts]; IF debug THEN WritePosResult["\n original logic result: ", oldResult]; [] _ SCRowUtil.EnumerateInstsOnRow[handle, row, 1, MAX[0, rowSpec.row.nLgsOnRow-1], TrialInterchange]; TerminalIO.PutRope[Rope.Cat[Convert.RopeFromInt[goodExch], " good exchanges\n"]]; SCNewWidth.TermGetChanWidth[handle, upperChan]; SCNewWidth.TermGetChanWidth[handle, lowerChan]; IF test THEN { lowerChanWidth: SC.Number _ lowerChan.chanWidth; upperChanWidth: SC.Number _ upperChan.chanWidth; IF rowSpec.doLower THEN { IF lowerChanWidth # SCNewWidth.GetChanWidth[handle, lowerChan, whichFom, TRUE].chanWidth THEN SC.Signal[programmingError, "Call Maintainer."]; SCNewWidth.TermGetChanWidth[handle, lowerChan]}; IF rowSpec.doUpper THEN { IF upperChanWidth # SCNewWidth.GetChanWidth[handle, upperChan, whichFom, TRUE].chanWidth THEN SC.Signal[programmingError, "Call Maintainer."]; SCNewWidth.TermGetChanWidth[handle, upperChan]} } }}; 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.PutRope[" accept improvement\n"]; wireLength _ newWireLength; oldResult _ newResult; goodExch _ goodExch + 1}; equal => { -- neutral exchange, take it IF debug THEN TerminalIO.PutRope[" 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.PutRope[Rope.Cat[" improve ", SCRowUtil.sideName[side], " side, "]]; SCNewWidth.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.PutRope[Rope.Cat[Convert.RopeFromInt[goodExch], " good exchanges\n"]]; SCNewWidth.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] _ SCNewWidth.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.PutRope[" accept improvement\n"]; chan.chanWidth _ chWidth; oldResult _ newResult; goodExch _ goodExch + 1}; equal, 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.PutRope[Rope.Cat[" improve ", SCRowUtil.sideName[side], " side, "]]; [oldChWidth, oldWireLength] _ SCNewWidth.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.PutRope[Rope.Cat[Convert.RopeFromInt[goodExch], " good exchanges\n"]]}}; NewPosImprove: 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; stop: BOOLEAN _ FALSE; [lgRows.maxRowWidth, lgRows.numMaxRows] _ SCRowUtil.FindMaxRow[handle]; SCNewWidth.AllChanWidths[handle, areaFom]; SCInstUtil.AsgnChanPos[handle]; startArea _ SCUtil.WriteResults["Position improvement\n starting area:", handle, 0]; WHILE ~stop DO goodExch: INT _ 0; goodTopExch, goodBottomExch, goodRightExch, goodLeftExch: INT; EachRow: SCRowUtil.EachRowProc = { goodExch _ goodExch + PosImproveRow[handle, ChosRow[handle, row], whichFom]; quit _ stop}; 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]; SCNewWidth.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, rowSpec: RowSpec, 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 _ rowSpec.row.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] _ SCNewWidth.GetChanWidth[handle, lowerChan, whichFom, rowSpec.doLower]; [upChWidth, upWireLength] _ SCNewWidth.GetChanWidth[handle, upperChan, whichFom, rowSpec.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.PutRope[" accept improvement\n"]; lowerChan.chanWidth _ lowChWidth; upperChan.chanWidth _ upChWidth; oldResult _ newResult; goodExch _ goodExch + 1}; equal, greater => { -- this change made it worse, restore old placement IF debug THEN WritePosResult[" restore old result: ", oldResult]; SCPlaceUtil.ReverseOrientation[instance]}; ENDCASE}}; IF rowSpec.row.nLgsOnRow > 0 AND (rowSpec.doUpper OR rowSpec.doLower) THEN { TerminalIO.PutRope[Rope.Cat[" improve orientation on row ", Convert.RopeFromInt[row], ", "]]; [oldLowChWidth, oldLowWireLength] _ SCNewWidth.GetChanWidth[handle, lowerChan, whichFom, rowSpec.doLower]; [oldUpChWidth, oldUpWireLength] _ SCNewWidth.GetChanWidth[handle, upperChan, whichFom, rowSpec.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.PutRope[Rope.Cat[Convert.RopeFromInt[goodExch], " good exchanges\n"]]}}; NewOrientImprove: 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; stop: BOOLEAN _ FALSE; [lgRows.maxRowWidth, lgRows.numMaxRows] _ SCRowUtil.FindMaxRow[handle]; SCNewWidth.AllChanWidths[handle, areaFom]; SCInstUtil.AsgnChanPos[handle]; startArea _ SCUtil.WriteResults["Orientation improvement\n starting area:", handle, 0]; WHILE ~stop DO EachRow: SCRowUtil.EachRowProc = { goodExch _ OrientImproveRow[handle, ChosRow[handle, row], whichFom]; quit _ stop}; 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]; SCNewWidth.AllChanWidths[handle, areaFom]; SCInstUtil.AsgnChanPos[handle]; [] _ SCUtil.WriteResults["End orientation improvement\n ending area:", handle, startArea]; IF debug THEN SCPlaceUtil.WriteCurPlace[handle]}; -- OrientImprove }. βfile: SCPlaceImproveImpl.mesa Copyright Σ 1985, 1986, 1987 by Xerox Corporation. All rights reserved. last edited: Bryan Preas December 21, 1986 4:15:03 pm PST Cong, August 19, 1987 9:38:58 am PDT map a row index in to a row improve positions on logic rows main body of 'PosImproveRow' 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 ΚM˜šœ™IcodešœG™GKšœ6Οk™9Kšœ$™$—J˜š ˜ Jšœœ“˜΄J˜—šΟnœœ˜$J˜Jšœœq˜ŠJ˜Jšœ ˜Jšœœ˜J˜Jšœœœ˜Jšœœœ˜J˜šœ œœ˜Jšœ˜Jšœœ˜J˜—šœ œœ˜Jšœ œ˜*Jšœœ˜ —J˜šœ œœ˜Jšœ œ˜*Jšœœ˜ —J˜—š žœ œœžœΟc˜YJšœ˜JšœL˜LJšœ[˜[Jšœ]˜]JšœV˜VJ˜—šžœ œ˜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šœœ9˜T—J˜šž œ!˜,šœ˜JšœXœ˜^—JšœF˜F—J˜šž œ!˜-šœ œ œœ˜0Jšœ<˜Jšœ%˜%Jšœ7˜7Jšœ7˜7Jšœ œ*˜5Jšœ œ-˜8Jšœœ˜!J˜šœœ˜Jšœ{˜{—šœœ˜Jšœ}˜}—JšœD˜DJ˜—Jšœ ™ š ž œ œ œ8œ œ ˜{J˜Jšœ#œ˜=Jšœ)œ˜FJšœ-˜-Jšœ-˜-Jšœ3˜3Jšœ3˜3Jšœ5˜5Jšœœ"˜-JšœDœ˜NJšœDœ˜NJšœ ˜ J˜šžœ˜,Jšœ&˜&J˜Jšœ8˜8šœœ˜J˜$J˜*—šœ˜J˜J˜)—šœœ˜J˜#J˜)—šœ˜J˜J˜'—Jšœ˜Jšœœ0˜=J˜šœ(˜2šœ Ÿ"˜,Jšœœ/˜šžœ˜#JšœL˜LJšœ ˜ —J˜šœœœ˜$J˜—Jšœ!™!Jšœ;˜;Jšœ=˜=J˜Jšœ˜Jšœ.˜.J˜Jšœ%™%Jšœ6˜6Jšœ<˜Jšœ˜J˜šœœ˜Jšœ)˜)Jšœd˜dJšœb˜bJšœ‡˜‡Jšœœ0˜=J˜šœ(˜2šœ Ÿ"˜,Jšœœ/˜