file: SCPlaceImproveImpl.mesa
Copyright © 1985 by Xerox Corporation. All rights reserved.
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: BOOLEANFALSE;
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]};
map a row index in to a row
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]};
improve positions on logic rows
PosImproveRow: PROCEDURE [handle: SC.Handle, lgRow: SCPrivate.LgRow, doUpper, doLower: BOOLEAN, whichFom: SCPrivate.FomType] RETURNS [goodExch: BOOLEANFALSE] = {
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]}};
improve positions on bonding pad sides
PosImproveLeftRight: PROCEDURE[handle: SC.Handle, side: SC.Side, whichFom: SCPrivate.FomType] RETURNS [goodExch: BOOLEANFALSE] = {
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]}};
improve positions on bonding pad sides
PosImproveTopBot: PROCEDURE[handle: SC.Handle, side: SC.Side, whichFom: SCPrivate.FomType] RETURNS [goodExch: BOOLEANFALSE] = {
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: BOOLEANFALSE;
goodTopExch, goodBottomExch, goodRightExch, goodLeftExch: BOOLEAN;
EachRow: SCRowUtil.EachRowProc = {
rowToDo: SCPrivate.LgRow;
doUpper, doLower: BOOLEAN;
goodRowExch: BOOLEAN;
[rowToDo, doUpper, doLower] ← ChosRow[handle, row];
goodRowExch ← PosImproveRow[handle, rowToDo, doUpper, doLower, whichFom];
goodExch ← goodExch OR goodRowExch};
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 OR goodLeftExch OR goodRightExch OR goodTopExch OR goodBottomExch) 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
}.