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
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: BOOLEANFALSE;
test: BOOLEANFALSE;
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]};
map a row index in to a row
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]};
improve positions on logic rows
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};
main body of 'PosImproveRow'
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]}
}
}};
improve positions on bonding pad sides
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]}};
improve positions on bonding pad sides
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: BOOLEANFALSE;
[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;
improve the left and right sides
goodLeftExch ← PosImproveLeftRight[handle, left, whichFom];
goodRightExch ← PosImproveLeftRight[handle, right, whichFom];
SCInstUtil.AsgnChanPos[handle];
[] ← SCRowUtil.EnumerateRows[handle, EachRow];
now improve the top and bottom sides
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
improve orientation on logic rows
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: BOOLEANFALSE;
[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
}.