DIRECTORY CD, CDCells, CDOps, CDProperties, Convert, Core, CoreGeometry, CoreOps, CoreRoute, DABasics, Rope, Route, RouteUtil, RoutePrivate, RTBasic, SC, SCChanUtil, SCInstUtil, SCNetUtil, SCPrivate, SCNewRoutePinsUtil, SCRowUtil, SCUtil, SCNewWidth, Sinix, SinixOps; SCNewRouteImpl: CEDAR PROGRAM IMPORTS CDCells, CDOps, CDProperties, Convert, CoreGeometry, CoreOps, CoreRoute, Rope, Route, RouteUtil, RTBasic, SC, SCChanUtil, SCInstUtil, SCNetUtil, SCNewRoutePinsUtil, SCRowUtil, SCUtil, SCNewWidth, SinixOps EXPORTS SCPrivate SHARES SC = BEGIN SegInChan: TYPE = REF SegInChanRec; SegInChanRec: TYPE = RECORD [ segNum: INT _ 0, netNum: SCPrivate.ZMaxNetsSr _ 0, leftExit, rightExit: BOOL _ FALSE, pinsInSeg: PinsInSeg _ NIL]; PinsInSeg: TYPE = LIST OF RoutePrivate.Pin; DetailRoute: PUBLIC PROC [handle: SC.Handle] RETURNS [result: SC.Result] = { lgRows: SCPrivate.LgRows _ NARROW[handle.layoutData, SCPrivate.LayoutData].lgRows; SCNewWidth.ComputeAllChanDW[handle, areaFom]; SCInstUtil.AllOffsets[handle]; [lgRows.maxRowWidth, lgRows.numMaxRows] _ SCRowUtil.FindMaxRow[handle]; ConstructRows[handle]; result _ NEW[SC.ResultRec _ [handle: handle, object: RouteChannels[handle]]]; SCInstUtil.AsgnChanPos[handle]; [] _ SCUtil.WriteResults["End detailed routing\n", handle, 0]}; ConstructRows: PROC [handle: SC.Handle] = { ForEachRow: SCRowUtil.EachRowProc = { lgRow.cdOb _ ConstructRow[handle, lgRow]}; [] _ SCRowUtil.EnumerateRows[handle: handle, eachRow: ForEachRow]}; ConstructRow: PROC [handle: SC.Handle, lgRow: SCPrivate.LgRow] RETURNS [row: CD.Object _ CDCells.CreateEmptyCell[]] ~ { LeftEnumerateSegments: PROC [eachSegment: PROC [CoreRoute.Segment]] ~ { EachWirePin: CoreGeometry.EachWirePinProc = { IF side=left THEN eachSegment[[label: CoreOps.GetShortWireName[wire], min: min, max: max, layer: layer]]}; [] _ CoreGeometry.EnumerateWireSides[mode.decoration, lgRow.lgsOnRow[1].object.cellType, EachWirePin]}; RightEnumerateSegments: PROC [eachSegment: PROC [CoreRoute.Segment]] ~ { EachWirePin: CoreGeometry.EachWirePinProc = { IF side=right THEN eachSegment[[label: CoreOps.GetShortWireName[wire], min: min, max: max, layer: layer]]}; [] _ CoreGeometry.EnumerateWireSides[mode.decoration, lgRow.lgsOnRow[lgRow.nLgsOnRow].object.cellType, EachWirePin]}; ForEachInstance: SCRowUtil.EachInstProc = { LabelProc: PROC [pinName: Rope.ROPE] RETURNS [label: Route.Label _ NIL] ~ { EachPin: SCInstUtil.EachPinProc ~ { IF netPin.pin.name = pinName THEN {label _ netPin.net.name; quit _ TRUE}}; IF SCUtil.IsPowerName[handle, pinName] THEN label _ pinName ELSE IF ~SCInstUtil.EnumeratePinsOnInst[instance: instance, eachPin: EachPin] THEN SC.Signal[callingError, "FeedThrough definition in library does not have all rectangles marked."]}; instOrientation: CD.Orientation _ SCInstUtil.CDOrien[instance]; object: CD.Object _ IF instance.whichClass = ft THEN CoreRoute.MakeRoutingCell[instance.object.cdOb, LabelProc] ELSE instance.object.cdOb; instPosition: CD.Position _ CDOps.FitObjectI[ob: object, location: [offset, 0], orientation: instOrientation].off; cdInst: CD.Instance _ RouteUtil.Include[cell: row, ob: object, position: instPosition, orientation: instOrientation]; CDProperties.PutInstanceProp[cdInst, $InstanceName, instance.name]; offset _ offset + RTBasic.IRSize[object].x}; mode: Sinix.Mode = SinixOps.GetExtractMode[handle.rules.rowParms.technology]; layoutData: SCPrivate.LayoutData _ NARROW[handle.layoutData]; maxRowWidth: CD.Number _ layoutData.lgRows.maxRowWidth; rowLength: SC.Number _ lgRow.size.p; rowOffset: SC.Number _ lgRow.rowOrg.p - layoutData.lgRows.horzRowOrg; offset: SC.Number _ 0; IF rowOffset > 0 THEN { leftObject: CD.Object _ CoreRoute.ExtendObject[enumerateSegments: LeftEnumerateSegments, size: [rowOffset, lgRow.size.q], side: left, extendProc: CoreRoute.ExtendSegment]; [] _ RouteUtil.Include[cell: row, ob: leftObject, position: [offset, 0]]; offset _ offset + RTBasic.IRSize[leftObject].x}; [] _ SCRowUtil.EnumerateAllInstsOnRow[handle, lgRow.rowNum, ForEachInstance]; IF rowOffset + rowLength < maxRowWidth THEN { rightObject: CD.Object _ CoreRoute.ExtendObject[enumerateSegments: RightEnumerateSegments, size: [maxRowWidth - (rowOffset + rowLength), lgRow.size.q], side: right, extendProc: CoreRoute.ExtendSegment]; [] _ RouteUtil.Include[cell: row, ob: rightObject, position: [offset, 0]]; offset _ offset + RTBasic.IRSize[rightObject].x}; RTBasic.RepositionCell[row]}; RouteChannels: PROC [handle: SC.Handle] RETURNS [obj: CD.Object _ CDCells.CreateEmptyCell[]] ~ { RouteChannel: PROC [enumerateNets: Route.EnumerateChannelNetsProc, rowChan: SCPrivate.RowChan] ~ { BrokenNet: Route.BrokenNetProc ~ { net: SCPrivate.Net _ NARROW[netData]; IF net.externNet = internalNet THEN newLabel _ NIL ELSE { net.numberOfRegions _ net.numberOfRegions + 1; newLabel _ CoreRoute.LabelBrokenNet[net.name, net.numberOfRegions]; net.brokenNets _ CONS[newLabel, net.brokenNets]}}; channel: CD.Object _ Route.Channel[enumerateNets: enumerateNets, min: lgRows.horzRowOrg, max: lgRows.horzRowOrg + lgRows.maxRowWidth, rulesParameters: handle.rules.rowParms, name: Rope.Cat[handle.name, "Chan", Convert.RopeFromInt[rowChan.chanNum]], brokenNets: BrokenNet, channelData: handle].object; [] _ RouteUtil.Include[cell: obj, ob: channel, position: [0, offset]]; offset _ offset + RTBasic.IRSize[channel].y; rowChan.chanWidth _ RTBasic.IRSize[channel].y}; EachChannel: SCChanUtil.EachRowChanProc ~ { LowerChannel: Route.EnumerateChannelNetsProc ~ { LowerChannelNet: SCNetUtil.EachNetProc ~ { FOR segList: LIST OF REF ANY _ net.segsInChan, segList.rest WHILE segList # NIL DO segInChan: SegInChan _ NARROW[segList.first]; eachNet[name: net.name, enumeratePins: LowerChannelPins, exitLeftOrBottom: segInChan.leftExit, exitRightOrTop: segInChan.rightExit, trunkSize: net.trunkWidth, netData: segInChan]; ENDLOOP}; [] _ SCNetUtil.EnumerateNets[handle, LowerChannelNet]}; LowerChannelPins: Route.EnumerateChannelPinsProc ~ { segInChan: SegInChan _ NARROW[netData]; net: SCPrivate.Net _ NARROW[structureData.nets.nets[segInChan.netNum]]; FOR pins: PinsInSeg _ segInChan.pinsInSeg, pins.rest UNTIL pins = NIL DO pin: RoutePrivate.Pin _ pins.first; bottomOrLeftSide: BOOL _ pin.side = bottom; xfer: BOOLEAN _ net.externNet = externalNet AND SCNetUtil.ExitOnSide[handle, net, bottom] AND pin.side = top; eachPin[bottomOrLeftSide: bottomOrLeftSide, min: pin.min, max: pin.max, depth: pin.depth, layer: pin.layer]; IF xfer THEN eachPin[bottomOrLeftSide: ~bottomOrLeftSide, min: pin.min, max: pin.max, depth: pin.depth, layer: pin.layer]; ENDLOOP}; InteriorChannel: Route.EnumerateChannelNetsProc ~ { InteriorChannelNet: SCNetUtil.EachNetProc ~ { FOR segList: LIST OF REF ANY _ net.segsInChan, segList.rest WHILE segList # NIL DO segInChan: SegInChan _ NARROW[segList.first]; eachNet[name: Rope.Cat[net.name, "-", Convert.RopeFromInt[segInChan.segNum]], enumeratePins: InteriorChannelPins, exitLeftOrBottom: segInChan.leftExit, exitRightOrTop: segInChan.rightExit, trunkSize: net.trunkWidth, netData: segInChan]; ENDLOOP}; [] _ SCNetUtil.EnumerateNets[handle, InteriorChannelNet]}; InteriorChannelPins: Route.EnumerateChannelPinsProc ~ { segInChan: SegInChan _ NARROW[netData]; net: SCPrivate.Net _ structureData.nets.nets[segInChan.netNum]; FOR pins: PinsInSeg _ segInChan.pinsInSeg, pins.rest UNTIL pins = NIL DO pin: RoutePrivate.Pin _ pins.first; bottomOrLeftSide: BOOL _ pin.side = bottom; eachPin[bottomOrLeftSide: bottomOrLeftSide, min: pin.min, max: pin.max, depth: pin.depth, layer: pin.layer]; ENDLOOP}; GetGlobalRouteForChannel[handle: handle, rowChan: rowChan]; IF chan # 1 THEN { -- include the specified row in the object being constructed [] _ RouteUtil.Include[cell: obj, ob: lgRows.rows[chan-1].cdOb, position: [0, offset]]; offset _ offset + lgRows.rows[chan-1].size.q}; IF chan = 1 AND rowChans.count = 2 THEN { RouteChannel[LowerChannel, rowChan]}; IF chan # rowChans.count AND chan # 1 THEN { RouteChannel[InteriorChannel, rowChan]}}; layoutData: SCPrivate.LayoutData _ NARROW[handle.layoutData]; structureData: SCPrivate.StructureData _ NARROW[handle.structureData]; rowChans: SCPrivate.RowChans _ layoutData.rowChans; lgRows: SCPrivate.LgRows _ layoutData.lgRows; offset: SC.Number _ 0; [] _ SCChanUtil.EnumerateRowChans[handle, EachChannel]; RTBasic.SetCDCellName[obj, handle.name]; RTBasic.RepositionCell[obj]}; GetGlobalRouteForChannel: PROC [handle: SC.Handle, rowChan: SCPrivate.RowChan] ~ { InitNet: SCNetUtil.EachNetProc = {net.segsInChan _ NIL}; MakeNetSeg: SCNewRoutePinsUtil.SegProc = { seg: SegInChan _ NEW[SegInChanRec _ [segNum: segNum, netNum: net.num, leftExit: leftExit, rightExit: rightExit, pinsInSeg: pinList]]; net.segsInChan _ CONS[seg, net.segsInChan]; pinList _ NIL; leftExit _ rightExit _ FALSE}; MakeNetPin: SCNewRoutePinsUtil.PinProc = { pin: RoutePrivate.Pin _ NEW[RoutePrivate.PinRec _ [min: min, max: max, depth: depth, layer: layer, side: side]]; pinList _ CONS[pin, pinList]}; MakeNetExit: SCNewRoutePinsUtil.ExitProc = { IF side = left THEN leftExit _ TRUE ELSE IF side = right THEN rightExit _ TRUE ELSE SC.Error[programmingError, "Not suppose to happen."]}; pinList: PinsInSeg _ NIL; leftExit, rightExit: BOOL _ FALSE; [] _ SCNetUtil.EnumerateNets[handle, InitNet]; SCNewRoutePinsUtil.GetAllNetSegInChan[handle, rowChan, MakeNetSeg, MakeNetPin, MakeNetExit]}; END. SCNewRouteImpl.mesa: Implements of SC.DetailedRoute Copyright c 1986, 1987 by Xerox Corporation. All rights reserved. Frank Bowers June 3, 1986 10:58:48 am PDT Last Edited by: Bryan Preas August 12, 1987 4:08:01 pm PDT Local Types Detail Route Operation Construct The Rows [row: SCPrivate.MaxRowSr, lgRow: SCPrivate.LgRow] RETURNS [quit: BOOL _ FALSE] enumerate public wires for left side of row PROC [wire: Wire, min, max: INT, side: Side, layer: CD.Layer] RETURNS [quit: BOOL _ FALSE]; enumerate public wires for right side of row PROC [wire: Wire, min, max: INT, side: Side, layer: CD.Layer] RETURNS [quit: BOOL _ FALSE]; [pos: NAT, instance: SCPrivate.Instance] RETURNS [quit: BOOL _ FALSE] find label for this pin PROC [instance: SCPrivate.Instance, pin: NAT, netPin: SCPrivate.PinNet] RETURNS [quit: BOOL _ FALSE]; Route The Channels route the channels and include rows and channels into the layout route the specified channeland include in the object being constructed PROC [channelData, netData: REF, sourceNet: Label, regionNumber, numberOfRegions: NAT] RETURNS [newLabel: Label]; [chan: SCPrivate.MaxChanSr, rowChan: SCPrivate.RowChan] RETURNS [quit: BOOL _ FALSE] route the channel specified by rowChan PROC [channelData: REF, eachNet: EachChannelNetProc]; PROC [netIndex: NAT, net: SCPrivate.Net] RETURNS [quit: BOOL _ FALSE]; PROC [channelData, netData: REF, eachPin: EachChannelPinProc]; PROC [name: Label, enumeratePins: EnumerateChannelPinsProc, exitLeftOrBottom, exitRightOrTop: BOOL _ FALSE, mayExit: BOOL _ TRUE, trunkSize: CD.Number _ 0, channelData, netData: REF _ NIL]; PROC [netIndex: NAT, net: SCPrivate.Net] RETURNS [quit: BOOL _ FALSE]; PROC [channelData, netData: REF, eachPin: EachChannelPinProc]; do the bottom channel if it is the only one do the interior channels collect the pins that are to be connected for this channel PROC [segNum: SC.Number, net: SCPrivate.Net]; PROC [min, max, depth: SC.Number, side: SC.Side, layer: SC.Layer, net: SCPrivate.Net]; PROC [side: SCPrivate.LRSide, layer: SC.Layer, net: SCPrivate.Net]; Κ ˜codešœ$Οkœ™4Kšœ Οmœ7™BKšœ&™)Kšœ:™:K™—š ˜ KšœŠœs˜K˜—šΟnœœ˜šœΝ˜ΤKšœ˜—Kšœ ˜Kšœœ˜—head™ Kšœ œ˜#šœœœ˜K˜Kšœ!˜!K˜"Kšœ˜—Kšœ œ˜+—šŸœ™š Ÿ œœœ œ œ œ ˜LK˜Kšœœ1˜RKšœ-˜-Kšœ˜KšœG˜GKšœ˜Kšœ œœ>˜MKšœ˜Kšœ?˜?——™šŸ œœ œ ˜+K˜šŸ œ˜%Kšœ2œœœ™NK˜Kšœ*˜*K˜—KšœC˜CK˜—š Ÿ œœ œ!œœ(˜wK˜šŸœœœ˜GKšœ+™+K˜šŸ œ"˜-Kšœ[™[Kšœ œY˜jK˜—Kšœg˜gK˜—šŸœœœ˜HKšœ,™,K˜šŸ œ"˜-Kšœ[™[Kšœ œY˜k—Kšœu˜uK˜—šŸœ˜+Kš œœ œœœ™EK˜š Ÿ œœœœœ˜KKšœ™šŸœ˜#Kš œ%œœœœ™eKšœœ"œ˜JK˜—Kšœ%œ˜;šœœGœ˜SKšœa˜c—K˜—Kšœœ,˜?šœœ œœ;˜oKšœ˜—Kšœœb˜rKšœœk˜uKšœC˜CKšœ,˜,K˜—KšœM˜MKšœ#œ˜=Kšœ œ(˜7Kšœ œ˜$Kšœ œ8˜EKšœœ ˜K˜šœœ˜Kšœ œ˜«KšœI˜IKšœ0˜0K˜—šœM˜MK˜—šœ%œ˜-Kšœ œ»˜ΚKšœJ˜JKšœ1˜1K˜—Kšœ˜——™š Ÿ œœ œ œœ(˜`Kšœ@™@K˜šŸ œœP˜bšœF™FK˜—šŸ œ˜"Kšœœ3œœ™qKšœœ ˜%Kšœœ ˜2šœ˜K˜.KšœC˜CKšœœ˜2K˜——Kšœ œ‘˜¬KšœF˜FKšœ,˜,Kšœ/˜/K˜—šŸ œ ˜+Kšœ8œœœ™TKšœ&™&K˜šŸ œ$˜0Kšœœ™5šŸœ˜*Kš œ œœœœ™Fš œ œœ(œ œ˜RKšœœ˜-šœ˜Kšœ ˜ Kšœ%˜%Kšœ$˜$Kšœ˜Kšœ˜Kšœ˜ ———Kšœ7˜7K˜—šŸœ$˜4Kšœœ™>K˜Kšœœ ˜'Kšœœ,˜Gšœ2œœ˜HKšœ#˜#Kšœœ˜+Kšœœœ+œ˜mKšœl˜lKšœœn˜zKšœ˜ —K˜—šŸœ$˜3KšœZœœ œœ œ#œœ™½šŸœ˜-Kš œ œœœœ™Fš œ œœ(œ œ˜RKšœœ˜-šœM˜MKšœ#˜#Kšœ%˜%Kšœ$˜$Kšœ˜Kšœ˜—Kšœ˜ ——Kšœ:˜:K˜—šŸœ$˜7Kšœœ™>K˜Kšœœ ˜'Kšœ?˜?šœ2œœ˜HKšœ#˜#Kšœœ˜+Kšœl˜lKšœ˜ —K˜—Kšœ;˜;K˜šœ œΟc<˜OKšœW˜WKšœ.˜.—K˜šœ œœ˜)Kšœ+™+Kšœ%˜%K˜—šœœ œ˜,Kšœ™Kšœ)˜)—K˜—Kšœ#œ˜=Kšœ)œ˜FKšœ3˜3Kšœ-˜-Kšœœ ˜Kšœ7˜7Kšœ(˜(Kšœ˜K˜—šŸœœ œ(˜RKšœ:™:K˜KšŸœ,œ˜8K˜šŸ œ ˜*Kšœ œ™-Kšœœq˜…Kšœœ˜+Kšœ œœ˜.K˜—šŸ œ ˜*Kšœœœœ™VK™KšœœU˜pKšœ œ˜K˜—šŸ œ!˜,Kšœ!œ™CK™Kšœ œ ˜#Kšœœœ ˜*Kšœœ4˜;K˜—Kšœœ˜Kšœœœ˜"Kšœ.˜.Kšœ]˜]K˜——šœ˜K˜K˜K˜—K˜—…—$’5Ά