DIRECTORY IO, RTBasic, SC, SCChanUtil, SCInstUtil, SCNetUtil, SCPrivate, SCRowUtil, SCPlaceUtil, Rope, RTSets, SCSmash, SCUtil, SCWidthUtil, TerminalIO; SCSmashImpl: CEDAR PROGRAM IMPORTS IO, RTBasic, SC, SCChanUtil, SCInstUtil, SCNetUtil, SCWidthUtil, SCPlaceUtil, SCRowUtil, SCSmash, SCUtil, RTSets, TerminalIO EXPORTS SCSmash SHARES SC = { debug: BOOLEAN _ FALSE; GetGoodFtPos: PROC [net: SCPrivate.Net, row: SCPrivate.MaxRowSr, nLgsOnRow: SCPrivate.ZMaxPosSr] RETURNS [midPos: SCPrivate.MaxPosSr] = { minPos: SC.Number _ LAST[SC.Number]; maxPos: SC.Number _ FIRST[SC.Number]; EachPin: SCNetUtil.EachPinProc = { instance: SCPrivate.Instance _ netPin.instance; SELECT instance.whichClass FROM ft, logic => { SELECT instance.curRow FROM row, row+1, row-1 => { minPos _ MIN[minPos, instance.curPos]; maxPos _ MAX[maxPos, instance.curPos]}; ENDCASE; }; ENDCASE }; [] _ SCNetUtil.EnumeratePinsOnNet[net, EachPin]; IF minPos = LAST[SC.Number] AND maxPos = FIRST[SC.Number] THEN midPos _ (1+ nLgsOnRow)/2 -- no instances in channels near row ELSE { minPos _ SELECT minPos FROM < 1 => 1, > nLgsOnRow => nLgsOnRow+1, ENDCASE => minPos; maxPos _ SELECT maxPos FROM < 1 => 1, > nLgsOnRow => nLgsOnRow+1, ENDCASE => maxPos; midPos _ (minPos + maxPos)/2}}; AddFt: PROCEDURE[handle: SC.Handle, lgRow: SCPrivate.LgRow, net: SCPrivate.Net] RETURNS [ftInst: SCPrivate.Instance] = { layoutData: SCPrivate.LayoutData _ NARROW[handle.layoutData]; lgRows: SCPrivate.LgRows _ layoutData.lgRows; bpRows: SCPrivate.BpRows _ layoutData.bpRows; row: SCPrivate.MaxRowSr _ lgRow.rowNum; savPos: SCPrivate.MaxPosSr _ 1; ftInst _ NewFt[handle, net, lgRow]; IF net.ftsOnRow[(row)-1] THEN SC.Error[programmingError, NIL]; net.ftsOnRow _ RTSets.RTMdSetUnion[net.ftsOnRow, RTSets.RTMdSetGenerateElement[(row)-1]]; savPos _ GetGoodFtPos[net, row, lgRow.nLgsOnRow]; -- find a good (not best) position for better performance SCPlaceUtil.PutLgPos[handle, ftInst, row, savPos]}; DetermineExits: PROCEDURE[handle: SC.Handle, side: SCPrivate.LRSide, net: SCPrivate.Net] RETURNS [onChan: SCPrivate.ChanSet _ RTSets.RTMdSetEmpty] = { ChanExitProc: SCChanUtil.EachRowChanProc = { IF onChan[(chan) - 1] THEN AddExit[handle, rowChan, side, net]}; layoutData: SCPrivate.LayoutData _ NARROW[handle.layoutData]; rowChans: SCPrivate.RowChans _ layoutData.rowChans; acBuses: SCPrivate.AcBuses _ layoutData.acBuses; chanSide: RTBasic.Side _ RTBasic.OtherSide[side]; instList: SCPrivate.InstanceList _ SCNetUtil.InstsOnNets[LIST[net]]; touchesChan: SCPrivate.ChanSet _ SCInstUtil.ChansForInsts[handle, instList]; net.chanExits[side] _ RTSets.RTMdSetEmpty; FOR pList: SCPrivate.NetPinsList _ net.pins, pList.rest WHILE pList # NIL DO instance: SCPrivate.Instance _ pList.first.instance; pin: SCPrivate.ObjectPin _ pList.first.pin; SELECT instance.whichClass FROM io => {IF net.feedThrusAllowed THEN { p: SCInstUtil.PinDescription _ SCInstUtil.PosOf[instance, pin]; IF instance.curSide = side AND instance.curPos > 0 AND p.sideOn = chanSide THEN { ChanProc: SCChanUtil.EachRowChanProc = { IF touchesChan[(chan)-1] THEN { SetMinMaxDists: PROCEDURE [] = {IF dist < minDist THEN {minDistChan _ chan; minDist _ dist}; IF chanPos > maxChanPos THEN {maxChan _ chan; maxChanPos _ chanPos}; IF chanPos < minChanPos THEN {minChan _ chan; minChanPos _ chanPos}}; chanPos: SC.Number _ rowChan.chanPos + rowChan.chanWidth/2; dist: SC.Number _ ABS[chanPos - holdBpPos]; layoutParms: SCPrivate.LayoutParms _ layoutData.layoutParms; useInteriorChanExits: BOOLEAN _ layoutParms.useInteriorChanExits; SELECT TRUE FROM ~useInteriorChanExits => SetMinMaxDists; useInteriorChanExits => IF (1 < chan AND chan < rowChans.count) THEN SetMinMaxDists; ENDCASE}}; minDist, minChanPos: SC.Number _ LAST[INT]; maxChanPos: SC.Number _ -LAST[INT]; minDistChan, maxChan, minChan: SCPrivate.ZMaxChanSr _ 0; holdBpPos: SC.Number _ SCInstUtil.BpPos[handle, instance] + p.yPos; [] _ SCChanUtil.EnumerateRowChans[handle, ChanProc]; SELECT TRUE FROM holdBpPos > maxChanPos AND maxChan > 0 => onChan _ RTSets.RTMdSetUnion[onChan, RTSets.RTMdSetGenerateElement[(maxChan)-1]]; holdBpPos < minChanPos AND minChan > 0 => onChan _ RTSets.RTMdSetUnion[onChan, RTSets.RTMdSetGenerateElement[(minChan)-1]]; minDistChan > 0 => onChan _ RTSets.RTMdSetUnion[onChan, RTSets.RTMdSetGenerateElement[(minDistChan)-1]]; ENDCASE}}}; logic => {IF ~net.feedThrusAllowed THEN { chan: SCPrivate.ZMaxChanSr _ 0; pinSide: RTBasic.Side _ SCInstUtil.PosOf[instance, pin].sideOn; IF pinSide = bottom THEN chan _ instance.curRow ELSE IF pinSide = top THEN chan _ instance.curRow + 1; IF chan # 0 AND net.acBus.onSide = side THEN onChan _ RTSets.RTMdSetUnion[onChan, RTSets.RTMdSetGenerateElement[(chan)-1]]}}; ENDCASE; ENDLOOP; [] _ SCChanUtil.EnumerateRowChans[handle, ChanExitProc]}; DoChans: PROC [net: SCPrivate.Net, lChan, uChan, maxChan: SCPrivate.MaxChanSr] ~ { lastTopology: SCPrivate.UpperLowerConnection _ net.routeTopology[lChan-1]; FOR chan: SCPrivate.MaxChanSr IN [lChan .. uChan] DO IF chan = maxChan THEN net.routeTopology[chan] _ [full, full] ELSE net.routeTopology[chan] _ IF lastTopology.upper = full THEN [min, min] ELSE [full, full]; lastTopology _ net.routeTopology[chan]; ENDLOOP}; ConnectRows: PROCEDURE[handle: SC.Handle, net: SCPrivate.Net, onRow: SCPrivate.RowSet, leftOnChan, rightOnChan, inDoChans: SCPrivate.ChanSet, inDoRows: SCPrivate.RowSet] RETURNS [doChanWidth: SCPrivate.ChanSet, doRowWidths: SCPrivate.RowSet] = { layoutData: SCPrivate.LayoutData _ NARROW[handle.layoutData]; lgRows: SCPrivate.LgRows _ layoutData.lgRows; rowChans: SCPrivate.RowChans _ layoutData.rowChans; onChan: SCPrivate.ChanSet _ RTSets.RTMdSetUnion[leftOnChan, rightOnChan]; lRow: SCPrivate.MaxRowSr _ 1; uRow: SCPrivate.ZMaxRowSr _ lgRows.count; found: BOOLEAN _ FALSE; doRowWidths _ inDoRows; doChanWidth _ inDoChans; WHILE lRow <= lgRows.count AND NOT found DO IF onRow[(lRow)-1] THEN found _ TRUE ELSE lRow _ lRow + 1; ENDLOOP; found _ FALSE; WHILE uRow >= 1 AND ~found DO IF onRow[(uRow)-1] THEN found _ TRUE ELSE uRow _ uRow -1; ENDLOOP; IF lRow = 1 THEN { net.routeTopology[1] _ [full, full]; DoChans[net, 2, uRow+1, rowChans.count]} ELSE IF lRow = lgRows.count THEN { net.routeTopology[rowChans.count-1] _ [min, min]; net.routeTopology[rowChans.count] _ [full, full]} ELSE { net.routeTopology[lRow] _ IF onChan[lRow-1] THEN [min, min] ELSE [none, none]; DoChans[net, lRow, uRow+1, rowChans.count]}; FOR row: SCPrivate.MaxRowSr IN [lRow .. uRow] DO IF ~onRow[(row)-1] THEN { [] _ AddFt[handle, lgRows.rows[row], net]; doRowWidths _ RTSets.RTMdSetUnion[doRowWidths, RTSets.RTMdSetGenerateElement[(row)-1]]; doChanWidth _ RTSets.RTMdSetUnion[doChanWidth, RTSets.RTMdSetAddElement[(row)-1, RTSets.RTMdSetGenerateElement[(row + 1)-1]]]}; ENDLOOP}; SmashNets: PUBLIC PROCEDURE[handle: SC.Handle, nets: SCPrivate.NetList, doWidths: BOOLEAN, inDoChans: SCPrivate.ChanSet, inDoSides: SCPrivate.LRSideSet, inDoRows: SCPrivate.RowSet] RETURNS [doChanWidths: SCPrivate.ChanSet, doSideWidths: SCPrivate.LRSideSet, doRowWidths: SCPrivate.RowSet] = { EachNet: SCNetUtil.EachNetProc = { onSide: SCPrivate.SideSet; onRow: SCPrivate.RowSet; leftOnChan, rightOnChan: SCPrivate.ChanSet _ RTSets.RTMdSetEmpty; instList: SCPrivate.InstanceList _ SCNetUtil.InstsOnNets[LIST[net]]; numInstances: SCPrivate.ZMaxInstanceSr _ SCInstUtil.NumInstsOnList[instList]; doChanWidths _ inDoChans; doSideWidths _ inDoSides; doRowWidths _ inDoRows; CleanUpNet[handle, net]; IF numInstances >= 2 THEN { [onSide, onRow] _ SCRowUtil.RowsForInsts[instList]; IF onSide[LOOPHOLE[SC.Side[left], INTEGER]] OR ~net.feedThrusAllowed THEN {leftOnChan _ DetermineExits[handle, left, net]; doSideWidths _ RTSets.RTSmSetUnion[doSideWidths, RTSets.RTSmSetGenerateElement[LOOPHOLE[SCPrivate.LRSide[left], INTEGER]]]}; doChanWidths _ RTSets.RTMdSetUnion[doChanWidths, leftOnChan]; IF onSide[LOOPHOLE[SC.Side[right], INTEGER]] OR ~net.feedThrusAllowed THEN {rightOnChan _ DetermineExits[handle, right, net]; doSideWidths _ RTSets.RTSmSetUnion[doSideWidths, RTSets.RTSmSetGenerateElement[LOOPHOLE[SCPrivate.LRSide[right], INTEGER]]]}; doChanWidths _ RTSets.RTMdSetUnion[doChanWidths, rightOnChan]; IF net.feedThrusAllowed THEN { IF onSide[LOOPHOLE[SC.Side[bottom], INTEGER]] AND ~ onRow[(1)-1] THEN { [] _ AddFt[handle, lgRows.rows[1], net]; doRowWidths _ RTSets.RTMdSetUnion[doRowWidths, RTSets.RTMdSetGenerateElement[(1)-1]]; onRow _ RTSets.RTMdSetUnion[ RTSets.RTMdSetGenerateElement[(1)-1], onRow]; doChanWidths _ RTSets.RTMdSetUnion[ RTSets.RTMdSetUnion[doChanWidths, RTSets.RTMdSetGenerateElement[(1)-1]], RTSets.RTMdSetGenerateElement[(2)-1]]}; IF (onSide[LOOPHOLE[SC.Side[top], INTEGER]]) AND ~onRow[(lgRows.count)-1] THEN { [] _ AddFt[handle, lgRows.rows[lgRows.count], net]; doRowWidths _ RTSets.RTMdSetUnion[doRowWidths, RTSets.RTMdSetGenerateElement[(lgRows.count)-1]]; onRow _ RTSets.RTMdSetUnion[ RTSets.RTMdSetGenerateElement[(lgRows.count)-1], onRow]; doChanWidths _ RTSets.RTMdSetUnion[ RTSets.RTMdSetUnion[doChanWidths , RTSets.RTMdSetGenerateElement[(lgRows.count)-1]], RTSets.RTMdSetGenerateElement[(lgRows.count + 1)-1]]}; [doChanWidths, doRowWidths] _ ConnectRows[handle, net, onRow, leftOnChan, rightOnChan, doChanWidths, doRowWidths]}; IF doWidths THEN { EachRow: SCRowUtil.EachRowProc = {IF doRowWidths[row - 1] THEN SCInstUtil.LgOffsets[handle, row, 0, 0]}; EachChan: SCChanUtil.EachRowChanProc = {IF doChanWidths[chan - 1] THEN [rowChan.chanWidth, rowChan.wireLength] _ SCWidthUtil.GetChanWidth[handle, rowChan, areaFom, TRUE]}; [] _ SCRowUtil.EnumerateRows[handle, EachRow]; [] _ SCChanUtil.EnumerateRowChans[handle, EachChan]}}}; layoutData: SCPrivate.LayoutData _ NARROW[handle.layoutData]; lgRows: SCPrivate.LgRows _ layoutData.lgRows; rowChans: SCPrivate.RowChans _ layoutData.rowChans; FOR netLst: SCPrivate.NetList _ nets, netLst.rest WHILE netLst # NIL DO [] _ EachNet[netLst.first.netNum, netLst.first]; ENDLOOP; IF debug THEN {CheckExits[handle]; CheckFts[handle]}; }; SmashAllNets: PUBLIC PROCEDURE [handle: SC.Handle, doChanWidths: BOOLEAN] = { NetProc: SCNetUtil.EachNetProc = { [] _ SmashNets[handle, LIST[net], doChanWidths, RTSets.RTMdSetEmpty, RTSets.RTSmSetEmpty, RTSets.RTMdSetEmpty]}; layoutData: SCPrivate.LayoutData _ NARROW[handle.layoutData]; lgRows: SCPrivate.LgRows _ layoutData.lgRows; TerminalIO.WriteRope["Begin topological route\n"]; [] _ SCNetUtil.EnumerateNets[handle, NetProc]; SCInstUtil.AllOffsets[handle]; [lgRows.maxRowWidth, lgRows.numMaxRows] _ SCRowUtil.FindMaxRow[handle]; SCWidthUtil.AllChanWidths[handle, areaFom]; SCInstUtil.AsgnChanPos[handle]; [] _ SCUtil.WriteResults["End topological route\n estimated size:", handle, 0]}; RemoveSmash: PUBLIC PROCEDURE [handle: SC.Handle] = { NetProc: SCNetUtil.EachNetProc = { [] _ SCSmash.RemoveNetsWFts[handle, LIST[net], FALSE, RTSets.RTMdSetEmpty, RTSets.RTSmSetEmpty, RTSets.RTMdSetEmpty]}; TerminalIO.WriteRope["Remove topological route\n"]; [] _ SCNetUtil.EnumerateNets[handle, NetProc]; SCInstUtil.AllOffsets[handle]; TerminalIO.WriteRope["End remove topological route\n"]}; ReSmash: PUBLIC PROCEDURE [handle: SC.Handle, doChanWidths: BOOLEAN] = { RemoveSmash[handle]; SmashAllNets[handle, doChanWidths]}; NewFt: PUBLIC PROCEDURE[handle: SC.Handle, net: SCPrivate.Net, lgRow: SCPrivate.LgRow] RETURNS [ftInst: SCPrivate.Instance] = { parms: SCPrivate.Parms _ NARROW[handle.parms]; name: Rope.ROPE _ IO.PutFR["%g-%g", IO.rope[net.name], IO.int[lgRow.rowNum]]; ftInst _ SCInstUtil.DefineInstance[handle, name, parms.ftObject, NIL, NIL]; ftInst.ftNet _ net; SCNetUtil.AddConnection[handle, net, ftInst, parms.ftObject.pins.p[0], 0]; SCNetUtil.AddConnection[handle, net, ftInst, parms.ftObject.pins.p[1], 1]}; AddExit: PUBLIC PROCEDURE[handle: SC.Handle, rowChan: SCPrivate.RowChan, side: SC.Side, net: SCPrivate.Net] = { IF rowChan.chanNum = 0 THEN SC.Error[programmingError, NIL] ELSE { index: NAT _ rowChan.numExits[side] _ rowChan.numExits[side] + 1; net.chanExits[side] _ RTSets.RTMdSetUnion[net.chanExits[side], RTSets.RTMdSetGenerateElement[(rowChan.chanNum)-1]]; rowChan.exits[side][index].net _ net; rowChan.exits[side][index].pos _ 0; rowChan.exits[side][index].layer _ handle.rules.rowRules.trunkLayer}}; RemvAllExits: PUBLIC PROCEDURE[handle: SC.Handle, net: SCPrivate.Net, lRSide: SCPrivate.LRSide] = { ChanProc: SCChanUtil.EachRowChanProc = { RemoveExit[handle, net, rowChan, lRSide]}; [] _ SCChanUtil.EnumerateRowChans[handle, ChanProc]}; RemoveExit: PUBLIC PROCEDURE[handle: SC.Handle, net: SCPrivate.Net, rowChan: SCPrivate.RowChan, lrSide: SCPrivate.LRSide] = { ChanExitProc: SCChanUtil.EachExitProc = { IF exit.net # net THEN { index _ index + 1; rowChan.exits[lrSide][index] _ rowChan.exits[lrSide][exitNum]}}; index: SCPrivate.ZMaxExitsSr _ 0; net.chanExits[lrSide] _ RTSets.RTMdSetDifference[net.chanExits[lrSide], RTSets.RTMdSetGenerateElement[(rowChan.chanNum)-1]]; [] _ SCChanUtil.EnumerateExits[handle, rowChan, lrSide, ChanExitProc]; rowChan.numExits[lrSide] _ index}; RemoveNetsWFts: PUBLIC PROCEDURE[handle: SC.Handle, netLst: SCPrivate.NetList, save: BOOLEAN, inDoChans: SCPrivate.ChanSet, inDoSides: SCPrivate.LRSideSet, inDoRows: SCPrivate.RowSet] RETURNS [doChanWidths: SCPrivate.ChanSet, doSideWidths: SCPrivate.LRSideSet, doRowWidths: SCPrivate.RowSet] = { layoutData: SCPrivate.LayoutData _ NARROW[handle.layoutData]; globalRoute: SCSmash.GlobalRoute _ NEW[SCSmash.GlobalRouteRec]; layoutData.globalRoute _ globalRoute; doChanWidths _ inDoChans; doSideWidths _ inDoSides; doRowWidths _ inDoRows; IF save THEN {globalRoute.numFts _ globalRoute.numNets _ 0}; FOR nets: SCPrivate.NetList _ netLst, nets.rest WHILE nets # NIL DO EachInst: SCNetUtil.EachInstProc = { IF instance.whichClass = ft THEN { IF save THEN { IF globalRoute.numFts >= SCSmash.maxFtsSaved THEN SC.Error[noResource, NIL]; globalRoute.numFts _ globalRoute.numFts + 1; globalRoute.fts[globalRoute.numFts] _ NEW[SCSmash.FtDataRec _ [net, instance.curRow, instance.curPos]]; IF ~net.feedThrusAllowed THEN SC.Error[programmingError, NIL]}; doRowWidths _ RTSets.RTMdSetUnion[doRowWidths, RTSets.RTMdSetGenerateElement[(instance.curRow)-1]]; doChanWidths _ RTSets.RTMdSetUnion[ RTSets.RTMdSetUnion[doChanWidths, RTSets.RTMdSetGenerateElement[(instance.curRow)-1]], RTSets.RTMdSetGenerateElement[(instance.curRow + 1)-1]]; SCPlaceUtil.RemvLgComp[handle, instance]}}; EachChan: SCChanUtil.EachRowChanProc = { FOR lrSide: SCPrivate.LRSide IN SCPrivate.LRSide DO IF net.chanExits[lrSide][(chan)-1] THEN {doChanWidths _ RTSets.RTMdSetUnion[doChanWidths, RTSets.RTMdSetGenerateElement[(chan)-1]]; doSideWidths _ RTSets.RTSmSetUnion[doSideWidths , RTSets.RTSmSetGenerateElement[LOOPHOLE[lrSide, INTEGER]]]}; ENDLOOP}; net: SCPrivate.Net _ nets.first; SCNetUtil.RemoveFtsOnNet[handle, net]; [] _ SCNetUtil.EnumerateInstsOnNets[LIST[net], EachInst]; IF save THEN { IF globalRoute.numNets >= SCSmash.maxNetsSaved THEN SC.Error[noResource, NIL]; globalRoute.numNets _ globalRoute.numNets + 1; globalRoute.nets[globalRoute.numNets].net _ net; globalRoute.nets[globalRoute.numNets].exit[left] _ net.chanExits[left]; globalRoute.nets[globalRoute.numNets].exit[right] _ net.chanExits[right]}; [] _ SCChanUtil.EnumerateRowChans[handle, EachChan]; CleanUpNet[handle, net]; ENDLOOP; IF debug THEN {CheckExits[handle]; CheckFts[handle]}; }; RestoreNetsWFts: PUBLIC PROCEDURE[handle: SC.Handle, netLst: SCPrivate.NetList, inDoChans: SCPrivate.ChanSet, inDoSides: SCPrivate.LRSideSet, inDoRows: SCPrivate.RowSet] RETURNS [doChanWidths : SCPrivate.ChanSet, doSideWidths: SCPrivate.LRSideSet, doRowWidths: SCPrivate.RowSet]= { ChanRowProc: SCRowUtil.EachRowProc = { IF doRowWidths[(row)-1] THEN SCInstUtil.LgOffsets[handle, row, 0, 0]}; CheckConnection: PROCEDURE[net: SCPrivate.Net, leftExitChan, rightExitChan: SCPrivate.RowChan] = { instList: SCPrivate.InstanceList _ SCNetUtil.InstsOnNets[LIST[net]]; onSide: SCPrivate.SideSet; onRow: SCPrivate.RowSet; [onSide, onRow] _ SCRowUtil.RowsForInsts[instList]; IF leftExitChan.chanNum = 1 OR rightExitChan.chanNum = 1 THEN { IF NOT (onSide[LOOPHOLE[SC.Side[bottom], INTEGER]] OR onRow[(1)-1]) THEN SC.Error[programmingError, NIL]} ELSE IF leftExitChan.chanNum = rowChans.count OR rightExitChan.chanNum = rowChans.count THEN { IF NOT (onSide[LOOPHOLE[SC.Side[top ], INTEGER]] OR onRow[(rowChans.count-1)-1]) THEN SC.Error[programmingError, NIL]}; IF 1 < leftExitChan.chanNum AND leftExitChan.chanNum < rowChans.count THEN { IF NOT (onRow[(leftExitChan.chanNum) - 1] OR onRow[(leftExitChan.chanNum-1) - 1]) THEN SC.Error[programmingError, NIL]}; IF 1 < rightExitChan.chanNum AND rightExitChan.chanNum < rowChans.count THEN { IF NOT (onRow[(rightExitChan.chanNum)-1] OR onRow[(rightExitChan.chanNum-1)-1]) THEN SC.Error[programmingError, NIL]}}; layoutData: SCPrivate.LayoutData _ NARROW[handle.layoutData]; globalRoute: SCSmash.GlobalRoute _ NARROW[layoutData.globalRoute]; rowChans: SCPrivate.RowChans _ layoutData.rowChans; lgRows: SCPrivate.LgRows _ layoutData.lgRows; doChanWidths _ inDoChans; doSideWidths _ inDoSides; doRowWidths _ inDoRows; FOR ftIndex: SCSmash.ZMFtsSavedSr DECREASING IN [1 .. globalRoute.numFts] DO net: SCPrivate.Net _ globalRoute.fts[ftIndex].net; row: NAT _ globalRoute.fts[ftIndex].row; ftInst: SCPrivate.Instance _ NewFt[handle, net, lgRows.rows[row]]; IF ~net.feedThrusAllowed THEN SC.Error[programmingError, NIL]; SCPlaceUtil.PutLgPos[handle, ftInst, row, globalRoute.fts[ftIndex].pos]; doRowWidths _ RTSets.RTMdSetUnion[doRowWidths, RTSets.RTMdSetGenerateElement[(row)-1]]; doChanWidths _ RTSets.RTMdSetUnion[doChanWidths, RTSets.RTMdSetAddElement[(row)-1, RTSets.RTMdSetGenerateElement[(row + 1)-1]]]; ENDLOOP; [] _ SCRowUtil.EnumerateRows[handle, ChanRowProc]; FOR netIndex: SCSmash.MNetsSavedSr DECREASING IN [1 .. globalRoute.numNets] DO ChanRowProc: SCChanUtil.EachRowChanProc = { FOR lrSide: SC.Side IN SCPrivate.LRSide DO RemoveExit[handle, net, rowChan, lrSide]; IF globalRoute.nets[netIndex].exit[lrSide][(chan)-1] THEN { exitChan[lrSide] _ rowChan; AddExit[handle, rowChan, lrSide, net]; doChanWidths _ RTSets.RTMdSetUnion[doChanWidths, RTSets.RTMdSetGenerateElement[(chan)-1]]; doSideWidths _ RTSets.RTSmSetUnion[doSideWidths , RTSets.RTSmSetGenerateElement[LOOPHOLE[lrSide, INTEGER]]]}; ENDLOOP}; exitChan: ARRAY SCPrivate.LRSide OF SCPrivate.RowChan _ [NIL, NIL]; net: SCPrivate.Net _ globalRoute.nets[netIndex].net; net.chanExits[left] _ RTSets.RTMdSetEmpty; net.chanExits[right] _ RTSets.RTMdSetEmpty; [] _ SCChanUtil.EnumerateRowChans[handle, ChanRowProc]; CheckConnection[net, exitChan[left], exitChan[right]]; ENDLOOP; IF debug THEN {CheckExits[handle]; CheckFts[handle]}; }; CheckExits: PUBLIC PROCEDURE [handle: SC.Handle] = { NetProc: SCNetUtil.EachNetProc = { ChanExitProc: SCChanUtil.EachRowChanProc = { SideProc: SCChanUtil.EachSideChanProc = { ExitProc: SCChanUtil.EachExitProc = { IF exit.net = net THEN quit _ TRUE}; exitPresent: BOOLEAN _ RTSets.RTMdSetIsSubset[ RTSets.RTMdSetGenerateElement[chan - 1], net.chanExits[lrSide]]; found: BOOLEAN _ SCChanUtil.EnumerateExits[handle, rowChan, lrSide, ExitProc]; IF exitPresent AND ~found OR ~exitPresent AND found THEN SC.Error[programmingError, NIL]}; [] _ SCChanUtil.EnumerateSideChans[handle, SideProc]}; [] _ SCChanUtil.EnumerateRowChans[handle, ChanExitProc]}; [] _ SCNetUtil.EnumerateNets[handle, NetProc]}; CheckFts: PUBLIC PROCEDURE [handle: SC.Handle] = { EachNet: SCNetUtil.EachNetProc = {CheckFtsOnNet[handle, net]}; [] _ SCNetUtil.EnumerateNets[handle, EachNet]}; CheckFtsOnNet: PUBLIC PROCEDURE[handle: SC.Handle, net: SCPrivate.Net] = { EachRow: SCRowUtil.EachRowProc = { PosProc: SCRowUtil.EachInstProc = { IF instance.whichClass = ft THEN { netPin1: SCPrivate.Net _ instance.pinNets.n[0].net; netPin2: SCPrivate.Net _ instance.pinNets.n[1].net; IF netPin1 = NIL OR netPin2 = NIL OR netPin1 # netPin2 THEN SC.Error[programmingError, NIL]; IF netPin1 = net THEN { IF ftsOnRow[row-1] THEN SC.Error[programmingError, NIL]; ftsOnRow _ RTSets.RTMdSetUnion[ftsOnRow, RTSets.RTMdSetGenerateElement[(row)-1]]}}}; [] _ SCRowUtil.EnumerateAllInstsOnRow[handle, row, PosProc]}; ftsOnRow: SCPrivate.RowSet _ RTSets.RTMdSetEmpty; [] _ SCRowUtil.EnumerateRows[handle, EachRow]; IF ~RTSets.RTMdSetIsSame[ftsOnRow, net.ftsOnRow] THEN SC.Error[programmingError, NIL]}; CleanUpNet: PROCEDURE [handle: SC.Handle, net: SCPrivate.Net] = { EachChan: SCChanUtil.EachRowChanProc = {net.routeTopology[chan] _ [none, none]}; net.ftsOnRow _ RTSets.RTMdSetEmpty; RemvAllExits[handle, net, left]; RemvAllExits[handle, net, right]; [] _ SCChanUtil.EnumerateRowChans[handle, EachChan]}; }. j///StdCell/SCSmashImpl.mesa Copyright c 1985, 1986 by Xerox Corporation. All rights reserved. Frank Bowers February 13, 1986 11:04:31 am PST Preas April 9, 1986 10:30:52 am PST add ft's on interior rows as required add side exits as required to net lists find preferred position for exit to side surface get position of instance on side find distance of port to closest existing channel determine channel to exit found channels to exit from, indicated in onChan find lowest row that needs ft find upper row that needs ft determine global route for channels between lChan and uChan inclusive add fts to required rows between lrow and urow now update the channel widths add feedthrus to required rows alter the smash of the nets add ft to row width get a component entry for the ft, construct a new entry for instance construct and add an entry to net list for this instance add an exit to a channel remove all exits for net on a lRSide remove an exit for net on chan remove specified nets with fts save indicates whether current smash is to be saved now remove the ft run through the comps on this net now work on the exits save route data for specified nets make sure feed throughs are in proper channels RestoreNetsWFts first restore the feedthroughs find row widths now the channel exits check to make sure the net is connected audit the exits for consistancy audit the Fts on all nets for consistancy audit the Fts on net for consistancy error in connection of net more than one ft on row for this net on this row row data does not correspond to instance data remove the global route on nets Κΰ˜šœ™Icodešœ Οmœ7™BK™.K™#—J˜šΟk ˜ Jšžœ˜J˜Jšžœ˜J˜ Jšœ ˜ Jšœ ˜ J˜ Jšœ ˜ Jšœ ˜ J˜Jšœ˜Jšœ˜J˜Jšœ ˜ Jšœ ˜ J˜—šΟn œžœž˜Jšžœžœ žœm˜„Jšžœ˜Jšžœžœ˜J˜Jšœžœžœ˜J˜šŸ œžœOžœ!˜‰Jšœžœ žœžœ ˜$Jšœžœ žœžœ ˜%J˜šŸœ˜"Jšœ/˜/šžœž˜ šœ˜šžœž˜˜Kšœ žœ˜&Kšœ žœ˜'—Kšžœ˜—K˜—Jšž˜—J˜J˜—Jšœ1˜1Jšžœ žœžœ žœ žœžœ žœΟc$˜~šžœ˜šœ žœž˜Jšœ&žœ ˜8—šœ žœž˜Jšœ&žœ ˜8—Jšœ˜—J˜—šŸœž œ žœ4˜OJšžœ!˜(Jšœ&™&J˜Jšœ#žœ˜=Jšœ-˜-Jšœ-˜-J˜'Jšœ˜Jšœ#˜#Jšžœžœžœžœ˜>šœ1˜1Jšœ(˜(—J™Jšœ2 9˜kšœ4˜4J˜——šŸœž œ žœ4˜XJšžœ6˜=Jšœ(™(J˜Jšœ0™0šŸ œ ˜,Jšžœžœ&˜@J˜—Jšœ#žœ˜=Jšœ3˜3Jšœ0˜0Jšœ1˜1Jšœ9žœ˜DJšœL˜LJ˜Jšœ*˜*J˜šžœ5žœ žœžœ˜MJšœ4˜4Jšœ+˜+J˜Jšœ!™!šžœž˜šœžœžœ˜%Jšœ?˜?šžœ˜Jšžœžœžœ˜6šŸœ ˜(šžœžœ˜J˜šŸœž œ˜Jšœžœžœ&˜=Jšžœžœ(˜Dšžœžœ)˜EJ˜——Jšœ žœ0˜;Jšœžœ žœ˜+Jšœ<˜˜>J˜šžœžœ˜š žœžœžœžœžœžœ˜GJšœ(˜(JšœU˜UJšœJ˜JJšœ”˜”—J˜š žœ žœžœ žœžœžœ˜PJšœ3˜3Jšœ`˜`JšœU˜UJšœ―˜―—J˜Jšœs˜sJ™—Jšœ™šžœ žœ˜JšŸœžœžœ*˜išŸœ!žœž˜GJšœ]žœ˜d—J˜Jšœ.˜.Jšœ7˜7J˜———Jšœ#žœ˜=Jšœ-˜-Jšœ3˜3šžœ/žœ žœžœ˜HJšœ0˜0Jšžœ˜J˜—Jšžœžœ(˜5Jšœ˜J˜—š Ÿ œžœž œ žœžœ˜MJšœ™J˜šŸœ˜"JšœžœU˜p—J˜Jšœ#žœ˜=Jšœ-˜-Jšœ2˜2Jšœ.˜.Jšœ˜JšœG˜GJšœ+˜+Jšœ˜JšœP˜PJ˜—šŸ œžœž œ žœ ˜5Jšœ™šŸœ˜"Jšœ$žœžœB˜v—J˜Jšœ3˜3Jšœ.˜.Jšœ˜Jšœ8˜8J˜—š Ÿœžœž œ žœžœ˜HJšœ˜Jšœ$˜$J˜—š Ÿœžœž œ žœ5žœ!˜Jšœ™JšœE™EJšœžœ˜.Jš œ žœžœžœžœ˜MJšœAžœžœ˜KJ˜J™Jšœ9™9JšœJ˜JJšœK˜K—J™š Ÿœžœž œ žœ+žœ˜oJšœ™J˜Jšžœžœžœžœ˜;šžœ˜Jšœžœ7˜Ašœ˜Jšœ]˜]—Jšœ%˜%Jšœ#˜#JšœF˜F——J˜šŸ œžœž œ žœ:˜cJšœ%™%J˜šŸœ ˜(Jšœ*˜*—J˜Jšœ5˜5J˜—šŸ œžœž œ žœV˜}Jšœ™šŸ œ˜)šžœžœ˜Jšœ˜Jšœ@˜@——J˜Jšœ!˜!Jšœ|˜|JšœF˜FJšœ"˜"J˜—š Ÿœžœž œ žœ*žœ[˜·˜Jšžœh˜o—Jšœ™J˜Jšœ#žœ˜=Jšœ#žœ˜?Jšœ%˜%Jšœ˜Jšœ˜Jšœ˜J˜Jšœ4™4Jšžœžœ0˜˜gJšžœžœžœžœ˜?—J˜Jšœ™Jšœc˜cJ˜šœ#˜#Jšœ!˜!Jšœ4˜4Jšœ8˜8—Jšœ+˜+—J˜—šŸœ ˜(šžœžœž˜3šžœ!ž˜'Jšœ[˜[JšœPžœ žœ˜m—Jšžœ˜ —J˜—Jšœ ˜ J™Jšœ"™"Jšœ&˜&Jšœ$žœ˜9J˜J˜Jšœ™šžœžœ˜Jšžœ-žœžœžœ˜NJšœ.˜.Jšœ0˜0JšœG˜GJšœJ˜J—J˜Jšœ4˜4J˜Jšœ˜Jšžœ˜—Jšžœžœ(˜5Jšœ˜J˜—šŸœžœž œ žœ}˜©Jšžœh˜oJšœ#™#J˜šŸ œ˜&Jšžœžœ*˜FJ˜—šŸœž œH˜bJšœ.™.J˜Jšœ9žœ˜DJšœ˜Jšœ˜J˜Jšœ3˜3šžœžœžœ˜?š žœžœ žœžœžœžœž˜HJšžœžœ˜ ——šžœžœ'žœ(žœ˜^š žœžœ žœžœ žœžœž˜UJšžœžœ˜!——šžœžœ'žœ˜Lšžœžœ$žœ&ž˜VJšžœžœ˜!——šžœžœ(žœ˜Nšžœžœ#žœ%ž˜TJšžœžœ˜"———J˜Jšœ™Jšœ™Jšœ#žœ˜=Jšœ#žœ˜BJšœ3˜3Jšœ-˜-Jšœ˜Jšœ˜Jšœ˜J˜šžœž œžœžœ˜MJšœ2˜2Jšœžœ ˜(JšœB˜BJšžœžœžœžœ˜>J˜JšœH˜Hšœ/˜/Jšœ(˜(—šœ1˜1Jšœ"˜"Jšœ-˜-—Jšžœ˜—J˜Jšœ™Jšœ2˜2J™Jšœ™šžœ ž œžœžœ˜OšŸ œ ˜+šžœ žœžœž˜*Jšœ)˜)šžœ3žœ˜;Jšœ˜Jšœ&˜&šœ1˜1Jšœ)˜)—JšœPžœ žœ˜m—Jšžœ˜ —J˜—Jš œ žœžœžœžœ˜CJšœ4˜4Jšœ*˜*Jšœ+˜+Jšœ7˜7J˜Jšœ(™(Jšœ6˜6Jšžœ˜—J™Jšžœžœ(˜5Jšœ˜—˜šŸ œžœž œ žœ ˜4Jšœ™šŸœ˜"šŸ œ ˜,šŸœ!˜)šŸœ˜%Jšžœžœžœ˜$J˜—Jšœ žœ[˜oJšœžœ@˜Nš žœ žœžœžœž˜8Jšžœžœ˜!—J˜—Jšœ6˜6—Jšœ9˜9—Jšœ/˜/—J˜šŸœžœž œ žœ ˜2Jšœ)™)J˜JšŸœ7˜>Jšœ/˜/—J˜šŸ œžœž œ žœ ˜JJšœ$™$J˜šŸœ˜"šŸœ˜#šžœžœ˜"Jšœ3˜3Jšœ3˜3š žœ žœžœ žœžœž˜;Jšœ™Jšžœžœ˜ —šžœžœ˜šžœž˜Jšœ0™0Jšžœžœ˜ —JšœT˜T——J˜—Jšœ=˜=J˜—Jšœ1˜1Jšœ.˜.šžœ/ž˜5Jšœ-™-Jšžœžœ˜!——J˜šŸ œž œ žœ ˜AJšœ™J˜JšŸœI˜QJ˜Jšœ#˜#Jšœ ˜ Jšœ!˜!Jšœ5˜5—Jšœ˜———…—PΚk