file: SCPlaceImproveImpl.mesa
Copyright Ó 1985, 1986, 1987 by Xerox Corporation. All rights reserved.
last edited: Bryan Preas September 29, 1987 3:48:59 pm PDT
DIRECTORY
Basics, Convert, Rope, RTSets, SC, SCChanUtil, SCInstUtil, SCNetUtil, SCPrivate, SCPlaceUtil, SCSmash, SCWidthUtil, SCRowUtil, SCUtil, TerminalIO;
SCPlaceImproveImpl: CEDAR PROGRAM
IMPORTS Convert, Rope, SC, SCChanUtil, SCInstUtil, SCNetUtil, SCPlaceUtil, SCRowUtil, SCWidthUtil, SCSmash, SCUtil, TerminalIO
EXPORTS SCPrivate
SHARES SC = {
debug: 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 = {
-- PROC [row: SCPrivate.MaxRowSr, lgRow: SCPrivate.LgRow] RETURNS [quit: BOOLFALSE];
IF doRowWidth[(row)-1] THEN SCInstUtil.LgOffsets[handle, row, 0, SCPrivate.maxPos]};
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]};
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]};
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, oldLowWireLength, oldUpWireLength: SC.Number;
oldResult: PosResult;
TrialInterchange: SCRowUtil.EachInstProc = {
PROC [pos: NAT, instance: SCPrivate.Instance] RETURNS [quit: BOOL ← FALSE];
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, rowSpec.doLower];
[upChWidth, upWireLength] ← SCWidthUtil.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.ExchPosRow[handle, pos, nextPos, row]};
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], ", "]];
[oldLowChWidth, oldLowWireLength] ← SCWidthUtil.GetChanWidth[handle, lowerChan, whichFom, rowSpec.doLower];
[oldUpChWidth, oldUpWireLength] ← SCWidthUtil.GetChanWidth[handle, upperChan, whichFom, rowSpec.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, rowSpec.row.nLgsOnRow-1], TrialInterchange];
TerminalIO.PutRope[Rope.Cat[Convert.RopeFromInt[goodExch], " good exchanges\n"]]}};
improve positions of feed thrus on logic rows
PosImproveFT: 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;
lgRow: SCPrivate.LgRow ← layoutData.lgRows.rows[row];
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 = {
PROC [pos: NAT, instance: SCPrivate.Instance] RETURNS [quit: BOOL ← FALSE];
nextPos: SCPrivate.MaxPosSr ← pos + 1;
lowChWidth, upChWidth, upWireLength, lowWireLength: SC.Number;
newResult: PosResult;
IF lgRow.lgsOnRow[pos].whichClass = ft OR lgRow.lgsOnRow[nextPos].whichClass = ft THEN {
SCPlaceUtil.ExchPosRow[handle, pos, nextPos, row];
[lowChWidth, lowWireLength] ← SCWidthUtil.GetChanWidth[handle, lowerChan, whichFom, rowSpec.doLower];
[upChWidth, upWireLength] ← SCWidthUtil.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.ExchPosRow[handle, pos, nextPos, row]};
ENDCASE}};
IF rowSpec.doUpper OR rowSpec.doLower THEN {
TerminalIO.PutRope[Rope.Cat[" improve row ", Convert.RopeFromInt[row], ", "]];
[oldLowChWidth, oldLowWireLength] ← SCWidthUtil.GetChanWidth[handle, lowerChan, whichFom, rowSpec.doLower];
[oldUpChWidth, oldUpWireLength] ← SCWidthUtil.GetChanWidth[handle, upperChan, whichFom, rowSpec.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, rowSpec.row.nLgsOnRow-1], TrialInterchange];
TerminalIO.PutRope[Rope.Cat[Convert.RopeFromInt[goodExch], " good exchanges\n"]]}};
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 = {
PROC [pos: NAT, instance: SCPrivate.Instance] RETURNS [quit: BOOL ← FALSE];
doChanWidth: SCPrivate.ChanSet ← RTSets.RTLgSetEmpty;
doRowWidth: SCPrivate.ChanSet ← RTSets.RTLgSetEmpty;
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.RTLgSetEmpty, RTSets.RTSmSetEmpty, RTSets.RTLgSetEmpty];
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, "]];
SCWidthUtil.AllChanWidths[handle, whichFom];
wireLength ← DoWidths[handle, RTSets.RTLgSetEmpty, RTSets.RTSmSetEmpty, RTSets.RTLgSetEmpty, 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"]];
SCWidthUtil.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 = {
PROC [pos: NAT, instance: SCPrivate.Instance] RETURNS [quit: BOOL ← FALSE];
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.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] ← 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.PutRope[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;
startArea: SC.Number;
numCycles: INT ← 0;
stop: BOOLEANFALSE;
[lgRows.maxRowWidth, lgRows.numMaxRows] ← SCRowUtil.FindMaxRow[handle];
SCWidthUtil.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 = {
-- PROC [row: SCPrivate.MaxRowSr, lgRow: SCPrivate.LgRow] RETURNS [quit: BOOLFALSE];
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];
SCWidthUtil.AllChanWidths[handle, areaFom];
SCInstUtil.AsgnChanPos[handle];
[] ← SCUtil.WriteResults["End position improvement\n ending area:", handle, startArea];
IF debug THEN SCPlaceUtil.WriteCurPlace[handle]}; -- PosImprove
FTImprove: 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];
SCWidthUtil.AllChanWidths[handle, areaFom];
SCInstUtil.AsgnChanPos[handle];
startArea ← SCUtil.WriteResults["FeedThru position improvement\n starting area:", handle, 0];
WHILE ~stop DO
goodExch: INT ← 0;
EachRow: SCRowUtil.EachRowProc = {
-- PROC [row: SCPrivate.MaxRowSr, lgRow: SCPrivate.LgRow] RETURNS [quit: BOOLFALSE];
goodExch ← goodExch + PosImproveFT[handle, RowSpec[lgRow, TRUE, TRUE], whichFom];
quit ← stop};
IF numCycles >= maxCycles THEN EXIT;
[] ← 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 FeedThru 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 = {
PROC [pos: NAT, instance: SCPrivate.Instance] RETURNS [quit: BOOL ← FALSE];
lowChWidth, upChWidth, upWireLength, lowWireLength: SC.Number;
newResult: PosResult;
IF instance.fnlOrien = 0 THEN {
SCPlaceUtil.ReverseOrientation[instance];
[lowChWidth, lowWireLength] ← SCWidthUtil.GetChanWidth[handle, lowerChan, whichFom, rowSpec.doLower];
[upChWidth, upWireLength] ← SCWidthUtil.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] ← SCWidthUtil.GetChanWidth[handle, lowerChan, whichFom, rowSpec.doLower];
[oldUpChWidth, oldUpWireLength] ← SCWidthUtil.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"]]}};
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;
stop: BOOLEANFALSE;
[lgRows.maxRowWidth, lgRows.numMaxRows] ← SCRowUtil.FindMaxRow[handle];
SCWidthUtil.AllChanWidths[handle, areaFom];
SCInstUtil.AsgnChanPos[handle];
startArea ← SCUtil.WriteResults["Orientation improvement\n starting area:", handle, 0];
WHILE ~stop DO
EachRow: SCRowUtil.EachRowProc = {
-- PROC [row: SCPrivate.MaxRowSr, lgRow: SCPrivate.LgRow] RETURNS [quit: BOOLFALSE];
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];
SCWidthUtil.AllChanWidths[handle, areaFom];
SCInstUtil.AsgnChanPos[handle];
[] ← SCUtil.WriteResults["End orientation improvement\n ending area:", handle, startArea];
IF debug THEN SCPlaceUtil.WriteCurPlace[handle]}; -- OrientImprove
}.