<> <> 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[" area: "]; TerminalIO.WriteInt[Result.area]; TerminalIO.WriteRope[", channelWidth: "]; TerminalIO.WriteInt[Result.channelWidth]; TerminalIO.WriteRope["\n wireLength: "]; TerminalIO.WriteInt[Result.wireLength]; TerminalIO.WriteRope[", numFts: "]; TerminalIO.WriteInt[Result.numFts]; TerminalIO.WriteLn[]}; 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: BOOLEAN _ FALSE] = { 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 _ TRUE}; 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[" improve row "]; TerminalIO.WriteInt[row]; TerminalIO.WriteRope[Rope.Cat[" doUpper: ", Convert.RopeFromBool[doUpper], " doLower: ", Convert.RopeFromBool[doLower]]]; TerminalIO.WriteLn[]; [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 logic result: ", oldResult]; [] _ SCRowUtil.EnumerateInstsOnRow[handle, row, 1, MAX[0, lgRow.nLgsOnRow-1], TrialInterchange]}}; <> PosImproveLeftRight: PROCEDURE[handle: SC.Handle, side: SC.Side, whichFom: SCPrivate.FomType] RETURNS [goodExch: BOOLEAN _ FALSE] = { 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 _ TRUE}; 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\n"]]; 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[" original ", SCRowUtil.sideName[side] ," result: "], oldResult]; [] _ SCRowUtil.EnumerateInstsOnSide[handle, side, 1, MAX[0, bpRow.nBpsOnSide -1], TrialInterchange]; SCWidthUtil.AllChanWidths[handle, areaFom]}}; <> PosImproveTopBot: PROCEDURE[handle: SC.Handle, side: SC.Side, whichFom: SCPrivate.FomType] RETURNS [goodExch: BOOLEAN _ FALSE] = { 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 _ TRUE}; 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\n"]]; [oldChWidth, oldWireLength] _ SCWidthUtil.GetChanWidth[handle, chan, whichFom, TRUE]; oldResult _ PosResult[oldChWidth * lgRows.maxRowWidth, oldChWidth, oldWireLength, numFts]; IF debug THEN WritePosResult[Rope.Cat[" original ", SCRowUtil.sideName[side]," result: "], oldResult]; [] _ SCRowUtil.EnumerateInstsOnSide[handle, side, 1, MAX[0, bpRow.nBpsOnSide-1], TrialInterchange]}}; PosImprove: PUBLIC PROCEDURE [handle: SC.Handle, whichFom: SCPrivate.FomType] = { layoutData: SCPrivate.LayoutData _ NARROW[handle.layoutData]; lgRows: SCPrivate.LgRows _ layoutData.lgRows; bpRows: SCPrivate.BpRows _ layoutData.bpRows; startArea: SC.Number; [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: BOOLEAN _ FALSE; EachRow: SCRowUtil.EachRowProc = { rowToDo: SCPrivate.LgRow; doUpper, doLower: BOOLEAN; [rowToDo, doUpper, doLower] _ ChosRow[handle, row]; goodExch _ goodExch OR PosImproveRow[handle, rowToDo, doUpper, doLower, whichFom]}; <> goodExch _ goodExch OR PosImproveLeftRight[handle, left, whichFom]; goodExch _ goodExch OR PosImproveLeftRight[handle, right, whichFom]; SCInstUtil.AsgnChanPos[handle]; [] _ SCRowUtil.EnumerateRows[handle, EachRow]; <> goodExch _ goodExch OR PosImproveTopBot[handle, top, whichFom]; goodExch _ goodExch OR PosImproveTopBot[handle, bottom, whichFom]; IF ~goodExch THEN EXIT; SCInstUtil.AsgnChanPos[handle]; 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 }.