DIRECTORY Convert, IO, Rope, Real, SC, SCChanUtil, SCInitialPlace, SCInstUtil, SCPlaceUtil, SCPrivate, SCRowUtil, TerminalIO; SCPrePlaceImpl: CEDAR PROGRAM IMPORTS Convert, IO, Real, Rope, SC, SCChanUtil, SCInstUtil, SCPlaceUtil, SCRowUtil, TerminalIO EXPORTS SCInitialPlace SHARES SC = { debug: BOOLEAN _ FALSE; ChooseNonZero: PROCEDURE [num1, num2, num3: SC.Number _ 0] RETURNS[ result: SC.Number] = { IF num1 # 0 THEN result _ num1 ELSE IF num2 # 0 THEN result _ num2 ELSE result _ num3}; IntBounds: PROCEDURE[checkNum, lowLimit, upLimit, default: SC.Number, name: Rope.ROPE] RETURNS[ result: SC.Number] = { IF lowLimit <= checkNum AND checkNum <= upLimit THEN result _ checkNum ELSE { result _ default; TerminalIO.PutRope[Rope.Cat[Rope.Cat[" instance: ", name, " variable: ", Convert.RopeFromInt[checkNum], " limits: "], Rope.Cat[Convert.RopeFromInt[lowLimit], " .. ", Convert.RopeFromInt[upLimit], "\n"]]]}}; SideBounds: PROCEDURE[checkNum, lowLimit, upLimit, default: SC.SideOrNone, name: Rope.ROPE] RETURNS[ result: SC.SideOrNone] = { IF lowLimit <= checkNum AND checkNum <= upLimit THEN result _ checkNum ELSE { result _ default; TerminalIO.PutRope[Rope.Cat[Rope.Cat[" instance: ", name, " variable: ", SCRowUtil.sideName[checkNum], " limits: "], Rope.Cat[SCRowUtil.sideName[lowLimit], " .. ", SCRowUtil.sideName[upLimit], "\n"]]]}}; InitBpSide: PROCEDURE [handle: SC.Handle] = { SideProc: SCRowUtil.EachSideProc = { bpRow.maxBpsOnSide _ bpRow.initMaxBpsOnSide; bpRow.size.p _ 0; bpRow.size.q _ 0; bpRow.dimInvalid _ FALSE; bpRow.nBpsOnSide _ 0; bpRow.fnlBpFxd _ FALSE; bpRow.initBpFxd _ FALSE}; [] _ SCRowUtil.EnumerateSides[handle, SideProc]}; InitLgRow: PROCEDURE [handle: SC.Handle] = { RowProc: SCRowUtil.EachRowProc = { lgRow.size.p _ 0; lgRow.size.q _ 0; lgRow.dimInvalid _ FALSE; lgRow.nLgsOnRow _ 0; lgRow.nFtsOnRow _ 0; lgRow.fnlLgFxd _ FALSE; lgRow.initLgFxd _ FALSE}; [] _ SCRowUtil.EnumerateRows[handle, RowProc]}; PrePlaceComps: PROCEDURE [handle: SC.Handle, initialized: BOOLEAN] = { PrePlacLg: PROCEDURE[handle: SC.Handle, instance: SCPrivate.Instance, initialized: BOOLEAN] = { layoutData: SCPrivate.LayoutData _ NARROW[handle.layoutData]; lgRows: SCPrivate.LgRows _ layoutData.lgRows; iRow, fRow: SCPrivate.ZMaxRowSr; IF initialized THEN { instance.curRow _ instance.initRow; instance.curPos _ instance.initPos; instance.curOrien _ instance.initOrien}; fRow _ IntBounds[instance.fnlRow, 0, SCPrivate.maxLgRows, 0, instance.name]; iRow _ IntBounds[instance.initRow, 0, SCPrivate.maxLgRows, 0, instance.name]; IF instance.preRow > 0 THEN { instance.preRow _ IntBounds[instance.preRow, 1, SCPrivate.maxLgRows, 0, instance.name]; instance.prePos _ IntBounds[instance.prePos, FIRST[INT], LAST[INT], 0, instance.name]; instance.preOrien _ IntBounds[instance.preOrien, 1, SCPrivate.maxOrien, SCInstUtil.defltLgOrien, instance.name]; IF instance.preRow = 0 OR instance.prePos = 0 OR instance.preOrien = 0 THEN { instance.preRow _ 0; instance.prePos _ 0; instance.preOrien _ 0}} ELSE IF fRow > 0 THEN { instance.preRow _ fRow; instance.prePos _ IntBounds[ChooseNonZero[instance.fnlPos, instance.initPos], FIRST[INT], LAST[INT], 0, instance.name]; instance.preOrien _ IntBounds[ChooseNonZero[instance.fnlOrien, instance.initOrien, SCInstUtil.defltLgOrien], 1, SCPrivate.maxOrien, SCInstUtil.defltLgOrien, instance.name]} ELSE IF iRow > 0 THEN { instance.preRow _ iRow; instance.prePos _ IntBounds[ChooseNonZero[instance.fnlPos, instance.initPos], FIRST[INT], LAST[INT], 0, instance.name]; instance.preOrien _ IntBounds[ChooseNonZero[instance.fnlOrien, instance.initOrien, SCInstUtil.defltLgOrien], 1, SCPrivate.maxOrien, SCInstUtil.defltLgOrien, instance.name]}; IF instance.preRow > 0 THEN SCPlaceUtil.PutLgRow[handle, instance, instance.preRow, instance.preOrien] ELSE {instance.curRow _ 0; instance.curPos _ 0; instance.curOrien _ 0}; IF instance.preRow > 0 AND instance.prePos > 0 THEN { IF fRow > 0 AND instance.fnlPos > 0 THEN lgRows.rows[fRow].fnlLgFxd _ TRUE; IF iRow > 0 AND instance.initPos > 0 THEN lgRows.rows[iRow].initLgFxd _ TRUE}}; PrePlacBp: PROCEDURE[handle: SC.Handle, instance: SCPrivate.Instance, initialized:BOOLEAN] = { layoutData: SCPrivate.LayoutData _ NARROW[handle.layoutData]; bpRows: SCPrivate.BpRows _ layoutData.bpRows; iSide, fSide: SC.SideOrNone; IF initialized THEN { instance.curSide _ instance.initSide; instance.curPos _ instance.initPos; instance.curOrien _ instance.initOrien}; iSide _ SideBounds[instance.initSide, bottom, none, none, instance.name]; fSide _ SideBounds[instance.fnlSide, bottom, none, none, instance.name]; IF instance.preSide # none THEN { instance.preSide _ SideBounds[instance.preSide, bottom, right, none, instance.name]; instance.prePos _ IntBounds[instance.prePos, FIRST[INT], LAST[INT], 0, instance.name]; instance.preOrien _ IntBounds[instance.preOrien, 1, SCPrivate.maxOrien, SCInstUtil.defltBpOrien[instance.preSide], instance.name]; IF instance.preSide = none OR instance.prePos = 0 OR instance.preOrien = 0 THEN { instance.preSide _ none; instance.prePos _ 0; instance.preOrien _ 0}} ELSE IF fSide # none THEN { instance.preSide _ fSide; instance.prePos _ IntBounds[ChooseNonZero[instance.fnlPos, instance.initPos], FIRST[INT], LAST[INT], 0, instance.name]; instance.preOrien _ IntBounds[ChooseNonZero[instance.fnlOrien, instance.initOrien, SCInstUtil.defltBpOrien[instance.preSide]], 1, SCPrivate.maxOrien, SCInstUtil.defltBpOrien[instance.preSide], instance.name]} ELSE IF iSide # none THEN { instance.preSide _ iSide; instance.prePos _ IntBounds[ChooseNonZero[instance.fnlPos, instance.initPos], FIRST[INT], LAST[INT], 0, instance.name]; instance.preOrien _ IntBounds[ChooseNonZero[instance.fnlOrien, instance.initOrien, SCInstUtil.defltBpOrien[iSide]], 1, SCPrivate.maxOrien, SCInstUtil.defltBpOrien[iSide], instance.name]}; IF instance.preSide # none THEN SCPlaceUtil.PutBpSide[handle, instance, instance.preSide] ELSE {instance.curSide _ none; instance.curPos _ 0; instance.curOrien _ 0}; IF instance.preSide # none AND instance.prePos > 0 THEN { IF fSide # none AND instance.fnlPos > 0 THEN bpRows[fSide].fnlBpFxd _ TRUE; IF iSide # none AND instance.initPos >0 THEN bpRows[iSide].initBpFxd _ TRUE}}; EachInstance: SCInstUtil.EachInstanceProc = { SELECT instance.whichClass FROM logic, ft => PrePlacLg[handle, instance, initialized]; io => PrePlacBp[handle, instance, initialized]; ENDCASE}; [] _ SCInstUtil.EnumerateAllInstances[handle, EachInstance]}; DetermineRows: PROCEDURE [handle: SC.Handle, numRows: NAT, routingFactor: REAL] RETURNS[width, height: SC.Number]= { EachInstance: SCInstUtil.EachInstanceProc = { IF instance.whichClass = logic THEN { maxRowSpec _ MAX[instance.initRow, MAX[maxRowSpec, instance.fnlRow]]; totLinComps _ totLinComps + SCInstUtil.InstWidth[instance]; avgHeight _ avgHeight + SCInstUtil.InstHeight[instance]}}; layoutData: SCPrivate.LayoutData _ NARROW[handle.layoutData]; lgRows: SCPrivate.LgRows _ layoutData.lgRows; structureData: SCPrivate.StructureData _ NARROW[handle.structureData]; instances: SCPrivate.Instances _ structureData.instances; routFact: REAL = 3.0; detRow: NAT; maxRowSpec, avgHeight, totLinComps: SC.Number _ 0; area: REAL; [] _ SCInstUtil.EnumerateAllInstances[handle, EachInstance]; avgHeight _ avgHeight /MAX[1, instances.numLogics]; area _ totLinComps * avgHeight* routingFactor; IF avgHeight <= 0 THEN detRow _ 0 ELSE { temp: NAT _ Real.Round[Real.SqRt[area] / (avgHeight * routingFactor)]; detRow _ MAX[1, temp]}; IF numRows > 0 THEN lgRows.count _ MIN[SC.Number[SCPrivate.maxLgRows], MAX[maxRowSpec, numRows]] ELSE IF maxRowSpec > 0 THEN lgRows.count _ MIN[SC.Number[SCPrivate.maxLgRows], MAX[maxRowSpec, detRow]] ELSE lgRows.count _ MIN[SCPrivate.maxLgRows, detRow]; lgRows.count _ MAX[1, lgRows.count]; layoutData.rowChans.count _ lgRows.count +1; height _ Real.Round[avgHeight*(lgRows.count + layoutData.rowChans.count*routingFactor)]; width _ Real.Round[area / height]; TerminalIO.PutRope[" number of rows calculation:\n"]; TerminalIO.PutF1[" maximum row specified: %g\n", IO.int[maxRowSpec]]; TerminalIO.PutF1[" computed number of rows: %g\n", IO.int[detRow]]; TerminalIO.PutF1[" number of rows specified: %g\n", IO.int[numRows]]; TerminalIO.PutF1[" number of rows used: %g\n", IO.int[lgRows.count]]}; DetermineSides: PROCEDURE [handle: SC.Handle, width, height: SC.Number] = { SideSlots: SCRowUtil.EachSideProc = { bpRow.maxBpsOnSide _ MAX[bpRow.initMaxBpsOnSide, bpRow.nBpsOnSide]; IF bpRow.maxBpsOnSide > 0 THEN { totBpSlots _ totBpSlots + bpRow.maxBpsOnSide; nSidesAvail _ nSidesAvail -1}}; SetSlots: SCRowUtil.EachSideProc = { IF bpRow.maxBpsOnSide <= 0 THEN bpRow.maxBpsOnSide _ nBps*2; bpRow.bpSpacing _ IF side = top OR side = bottom THEN width/bpRow.maxBpsOnSide ELSE height/bpRow.maxBpsOnSide}; structureData: SCPrivate.StructureData _ NARROW[handle.structureData]; instances: SCPrivate.Instances _ structureData.instances; nSidesAvail: NAT[0..4] _ 4; totBpSlots: NAT _ 0; nBps: NAT; [] _ SCRowUtil.EnumerateSides[handle, SideSlots]; IF nSidesAvail > 0 THEN nBps _ MAX[0, (instances.numIOs - totBpSlots +3) /nSidesAvail] ELSE { nBps _ 0; IF instances.numIOs > totBpSlots THEN SC.Error[callingError, "Too many IO's"]}; [] _ SCRowUtil.EnumerateSides[handle, SetSlots]}; PrePlace: PUBLIC PROCEDURE[handle: SC.Handle, numRows: NAT _ 0, routingFactor: REAL _ 2.5, initialized: BOOLEAN _ TRUE] = { width, height: SC.Number; TerminalIO.PutRope["Pre placement\n"]; InitBpSide[handle]; InitLgRow[handle]; SCChanUtil.ClearRouteDat[handle]; PrePlaceComps[handle, initialized]; [width, height] _ DetermineRows[handle, numRows, routingFactor]; DetermineSides[handle, width, height]; TerminalIO.PutRope["End pre placement\n"]; IF debug THEN SCPlaceUtil.WriteCurPlace[handle]}; }. ŽSCPrePlaceImpl.mesa Copyright Σ 1986, 1987 by Xerox Corporation. All rights reserved. last edited by Bryan Preas, July 10, 1987 9:11:56 pm PDT Choose non zero num in priority order make the bonding pad rows empty PROC [side: SC.Side, bpRow: SCPrivate.BpRow] RETURNS [quit: BOOL _ FALSE]; make the interior rows empty PROC [row: SCPrivate.MaxRowSr, lgRow: SCPrivate.LgRow] RETURNS [quit: BOOL _ FALSE]; pre place the components preplace the logic component instance check if this instance has a currently defined position check if the final position is specified check for initial position specified check if this instance restricts a row by specifying a position on a row preplace the bonding pad component instance check if this instance has a currently defined position check if the final position is specified check for initial position specified check to see if this bp restricts this side by having a position assigned determine the number of rows to use PROC [instance: SCPrivate.Instance] RETURNS [quit: BOOL _ FALSE]; must use direct data access, no placement exists yet Cedar problem: mixing NAT's and INT's determine the number of Bps on sides to use -- PROC [side: SC.Side, bpRow: SCPrivate.BpRow] RETURNS [quit: BOOL _ FALSE]; -- PROC [side: SC.Side, bpRow: SCPrivate.BpRow] RETURNS [quit: BOOL _ FALSE]; 2X is a HACK compute number of slots to put on currently empty sides Κ τ˜codešœ™KšœB™BKšœ5Οk™8—K˜š ˜ Kšœ œœX˜sK˜—šΟnœœ˜Kšœ œœ<˜_Kšœ˜Kšœœ˜ Kšœœœ˜K˜—šž œ œœ ˜:Kšœ œ ˜Kšœ™Kšœ%™%Kšœ œ˜Kšœœ œ˜#Kšœ˜K˜—šž œ œ'œœ˜VKšœ œ ˜K˜šœœ˜4Kšœ˜—šœ˜Kšœ˜KšœΞ˜Ξ—K˜—šž œ œ'œœ˜[Kšœ œ˜#K˜šœœ˜4Kšœ˜—šœ˜Kšœ˜KšœΛ˜ΛK˜——šž œ œ œ ˜-Kšœ™Kšœ™šžœ˜$KšœJ™JKšœ,˜,Kšœ˜Kšœ˜Kšœœ˜Kšœ˜Kšœœ˜Kšœœ˜K˜—Kšœ1˜1K˜—šž œ œ œ ˜,Kšœ™Kšœ™šžœ˜"KšœT™TKšœ˜Kšœ˜Kšœœ˜Kšœ˜Kšœ˜Kšœœ˜Kšœœ˜K˜—Kšœ/˜/K˜—šž œ œ œœ˜GKšœ™K˜šž œ œ œ4œ˜_Kšœ&™&K˜Kšœ#œ˜=K˜-Kšœ ˜ K˜šœ œ˜Kšœ#˜#Kšœ#˜#Kšœ(˜(—K˜Kšœ8™8KšœL˜LKšœM˜MK™šœœ˜KšœW˜WKš œ-œœœœ˜VKšœp˜pšœœœœ˜MKšœ˜Kšœ˜Kšœ˜——K™Kšœ)™)šœœ œ˜Kšœ˜Kš œNœœœœ˜wKšœ¬˜¬—K™Kšœ%™%šœœ œ˜Kšœ˜Kš œNœœœœ˜wKšœ­˜­—K˜KšœœK˜fKšœC˜GK™KšœI™Išœœœ˜5Kšœ œœœ˜KKšœ œœœ˜O——K˜šž œ œ œ3œ˜^Kšœ,™,K˜Kšœ#œ˜=K˜-Kšœœ ˜K˜šœ œ˜K˜%K˜#Kšœ(˜(K™—Kšœ8™8KšœI˜IKšœH˜HK˜šœœ˜!KšœT˜TKš œ-œœœœ˜VKšœ‚˜‚šœœœœ˜QKšœ˜Kšœ˜Kšœ˜——K™Kšœ)™)šœœœ˜Kšœ˜Kš œNœœœœ˜wKšœΠ˜ΠK™—Kšœ%™%šœœœ˜Kšœ˜Kš œNœœœœ˜wKšœ»˜»—K˜Kšœœ:˜YKšœG˜KK™KšœJ™Jšœœœ˜9Kšœœœœ˜KKšœœœœ˜N——K˜šž œ!˜-šœ˜Kšœ6˜6Kšœ/˜/Kšœ˜ K˜——Kšœ>˜>K˜—šž œ œ œœœœœ ˜uKšœ$™$K˜šž œ!˜-KšœA™Ašœœ˜%Kšœ œœ˜EKšœ4™4Kšœ;˜;Kšœ:˜:—K˜—Kšœ#œ˜=Kšœ-˜-Kšœ)œ˜FKšœ9˜9Kšœ œ˜K˜Kšœœ˜ Kšœ$œ ˜2Kšœœ˜ K˜Kšœ<˜—šœ˜Kšœ ˜ šœœœ'˜OK˜——Kšœ2˜2K˜—šžœœ œ œœœœœ˜{K˜Kšœœ˜Kšœ&˜&Kšœ˜Kšœ˜Kšœ!˜!Kšœ#˜#Kšœ@˜@Kšœ&˜&Kšœ*˜*Kšœœ%˜2—Kšœ˜—…—&H5Κ