DIRECTORY CD, CDCells, CDOps, D2Orient, GC, GCPrivate, IPCTG, IPCoTab, IPTop, RefTab, RouteDiGraph, RTBasic, CoreRouteFlat; GCUtilImpl: CEDAR PROGRAM IMPORTS GC, CDCells, CDOps, GCPrivate, IPCoTab, IPCTG, IPTop, RefTab, RouteDiGraph, RTBasic EXPORTS GCPrivate = { nameProp: PUBLIC ATOM _ $GCName; FindTopologicalOrder: PUBLIC PROC [topology: IPTop.Ref] RETURNS [topologicalOrder: GCPrivate.TopologicalOrder _ RouteDiGraph.CreateGraph["TopologicalOrder"]] = { AddConstraint: PROC [from, to: GCPrivate.Channel] ~ { IF from.topoOrder = NIL THEN from.topoOrder _ RouteDiGraph.AddNewNode[topologicalOrder, from]; IF to.topoOrder = NIL THEN to.topoOrder _ RouteDiGraph.AddNewNode[topologicalOrder, to]; IF RouteDiGraph.PathExists[topologicalOrder, from.topoOrder, to.topoOrder] THEN -- RouteDiGraph.PathExists[topologicalOrder, to.topoOrder, from.topoOrder] -- BTP November 2, 1987 4:11:13 pm PST GC.Signal[callingError, "Improper channel topology; you must change schematic."] ELSE [] _ RouteDiGraph.AddNewArc[topologicalOrder, NIL, to.topoOrder, from.topoOrder]}; EachChannel: IPCTG.EachChannelAction ~ { llCh: IPCTG.Channel _ IPCTG.End[ch, neg].ch; urCh: IPCTG.Channel _ IPCTG.End[ch, pos].ch; IF ch # bottomCh AND ch # topCh THEN { AddConstraint[NARROW[ch.any], NARROW[llCh.any]]; AddConstraint[NARROW[ch.any], NARROW[urCh.any]]}}; bottomCh, topCh: IPCTG.Channel; bottomChannel, topChannel: GCPrivate.Channel; [bottomCh, , topCh, ] _ IPCTG.GetBoundingChannels[topology.ctg]; bottomChannel _ NARROW[bottomCh.any]; bottomChannel.lowerIntType _ bottomChannel.upperIntType _ inverted; topChannel _ NARROW[topCh.any]; topChannel.lowerIntType _ topChannel.upperIntType _ inverted; [] _ IPCTG.Channels[topology.ctg, EachChannel]}; EnumerateChannelsInTopologicalOrder: PUBLIC PROC [context: GC.Context, eachChannel: GCPrivate.EachChannelAction] RETURNS [quit: BOOLEAN _ FALSE] = { WrapProc: RouteDiGraph.EnumNodeProc ~ { quit _ eachChannel[context, NARROW[node.nodeInfo]]}; [] _ RouteDiGraph.EnumNodesInTopoOrder[NARROW[context.topologicalOrder], WrapProc]}; AssignCoordinates: PUBLIC PROC [context: GC.Context] = { SetInstancePosition: IPCoTab.EachComponentAction ~ { instance: CoreRouteFlat.Instance _ NARROW[co.any]; instance.position _ co.origin}; SetChannelPosition: IPCTG.EachChannelAction ~ { channel: GCPrivate.Channel _ NARROW[ch.any]; channel.position _ GCPrivate.LowerChannelPosition[channel]; -- modify bounding channels because of a bug in Phoenix -- remove this SELECT TRUE FROM when bug is fixed -- SELECT TRUE FROM -- channel.ch = bottomChannel => channel.position.y _ channel.position.y - channel.width/2; -- channel.ch = leftChannel => channel.position.x _ channel.position.x - channel.width/2; -- ENDCASE; }; bottomChannel, rightChannel, topChannel, leftChannel: IPCTG.Channel; topology: IPTop.Ref _ NARROW[context.topology]; topology.initialized _ FALSE; [bottomChannel, rightChannel, topChannel, leftChannel] _ IPCTG.GetBoundingChannels[topology.ctg]; IPTop.Geometrize[topology, 0, 0]; IPCoTab.AllComponents[topology.coTab, SetInstancePosition]; [] _ IPCTG.Channels[topology.ctg, SetChannelPosition]}; CDOrien: PUBLIC PROCEDURE[num: INT] RETURNS [orien: CD.Orientation] = { SELECT num FROM 0 => orien _ original; 1 => orien _ original; 2 => orien _ rotate270; 3 => orien _ rotate180; 4 => orien _ rotate90; 5 => orien _ mirrorX; 6 => orien _ rotate180X; 7 => orien _ rotate270X; 8 => orien _ rotate90X; ENDCASE}; LowerChannelPQ: PUBLIC PROCEDURE[channel: GCPrivate.Channel] RETURNS [pq: RTBasic.PQPos] ~ { endCh: GCPrivate.Channel _ NARROW[IPCTG.End[channel.ch, neg].ch.any]; p: INT _ IF channel.lowerIntType = normal THEN ChannelLimits[endCh].upper ELSE ChannelLimits[endCh].lower; q: INT _ ChannelLimits[channel].lower; RETURN[[p, q]]}; UpperChannelPQ: PUBLIC PROCEDURE[channel: GCPrivate.Channel] RETURNS [pq: RTBasic.PQPos] ~ { endCh: GCPrivate.Channel _ NARROW[IPCTG.End[channel.ch, pos].ch.any]; p: INT _ IF channel.upperIntType = normal THEN ChannelLimits[endCh].lower ELSE ChannelLimits[endCh].upper; q: INT _ ChannelLimits[channel].upper; RETURN[[p, q]]}; ChannelLimits: PUBLIC PROCEDURE[channel: GCPrivate.Channel] RETURNS [lower, upper: INT] ~ { DoPosWidths: IPCTG.EachComponentAction ~ { upper _ MIN[upper, IF channel.ch.type = hor THEN co.origin.y ELSE co.origin.x]}; DoNegWidths: IPCTG.EachComponentAction ~ { lower _ MAX[lower, IF channel.ch.type = hor THEN co.origin.y + IPCoTab.GetDim[co].y ELSE co.origin.x + IPCoTab.GetDim[co].x]}; IF IPCTG.NoComponent[channel.ch, neg] THEN lower _ channel.ch.coord - channel.ch.width/2 ELSE { lower _ FIRST[INT]; [] _ IPCTG.Components[channel.ch, neg, DoNegWidths]}; IF IPCTG.NoComponent[channel.ch, pos] THEN upper _ channel.ch.coord + channel.ch.width/2 ELSE { upper _ LAST[INT]; [] _ IPCTG.Components[channel.ch, pos, DoPosWidths]}}; CreateChannels: PUBLIC PROC [context: GC.Context] ~ { CreateChannel: IPCTG.EachChannelAction ~ { channel: GCPrivate.Channel _ NEW[GCPrivate.ChannelRec _ [name: IPCTG.GetName[ch], connections: RefTab.Create[], width: IPCTG.GetWidth[ch], position: [0, 0], direction: IF ch.type = hor THEN horizontal ELSE vertical, ch: ch]]; ch.any _ channel}; topology: IPTop.Ref _ NARROW[context.topology]; [] _ IPCTG.Channels[topology.ctg, CreateChannel]}; DestroyChannels: PUBLIC PROC [context: GC.Context] ~ { DestroyChannel: IPCTG.EachChannelAction ~ { IF ch.any # NIL THEN { oldChannel: GCPrivate.Channel _ NARROW[ch.any]; oldChannel.ch _ NIL}; -- remove circular REF }; topology: IPTop.Ref _ NARROW[context.topology]; [] _ IPCTG.Channels[topology.ctg, DestroyChannel]}; PinOnList: PUBLIC PROC [netDesc: GCPrivate.NetDesc, phyPin: GCPrivate.PhyPinDesc] RETURNS [onList: BOOLEAN _ FALSE] ~ { IF netDesc # NIL THEN FOR list: LIST OF GCPrivate.PhyPinDesc _ netDesc.pinList, list.rest WHILE list # NIL AND ~onList DO IF list.first.instance = phyPin.instance AND list.first.oPin = phyPin.oPin AND list.first.pPin = phyPin.pPin THEN onList _ TRUE ENDLOOP}; -- [] _ CDProperties.RegisterProperty[GCPrivate.nameProp, NIL]; gets double registration IntersectionOnList: PUBLIC PROC [netDesc: GCPrivate.NetDesc, int: GCPrivate.IntersectionPinDesc] RETURNS [onList: BOOLEAN _ FALSE] ~ { IF netDesc # NIL THEN FOR list: LIST OF GCPrivate.IntersectionPinDesc _ netDesc.intersectionList, list.rest WHILE list # NIL AND ~onList DO IF list.first.channel = int.channel THEN onList _ TRUE ENDLOOP}; IncludeOb: PUBLIC PROC [cell: CD.Object, ob: CD.Object, position: CD.Position_[0, 0], orientation: D2Orient.Orientation_original] RETURNS [application: CD.Instance _ NIL] = { trans: CD.Transformation _ CDOps.FitObjectI[ob: ob, location:position, orientation: orientation]; application _ CDCells.IncludeOb[design: NIL, cell: cell, ob: ob, trans: trans].newInst}; }. όGCUtilImpl.mesa Copyright Σ 1986, 1987 by Xerox Corporation. All rights reserved. Bryan Preas, January 15, 1987 11:46:23 am PST Don Curry December 4, 1987 11:59:02 am PST Determine order in which to route channels. Enumerate routing channels in route order. Assign locations to all channels and components. get the CD orientation find position of a channel in PQ space of the channel find upper right position of a channel in PQ space of the channel find limits of width of a channel create channels for the context destroy channels for the context onList _ TRUE iff phyPin is on the global routing list for net onList _ TRUE iff phyPin is on the global routing list for net include an object in a cell; position refers to base of interest rect Κ‘– "cedar" style˜šœ™JšœB™BJšœ.™.Icode™*—J˜šΟk ˜ Jšœœ œ@˜rJ˜—šΟn œœœ˜Kšœœ&œ&˜[Kšœ˜K˜šœ œœ ˜ K˜——šžœœœœb˜‘Kšœ-™-K˜šž œœ"˜5šœœ˜KšœA˜A—šœœ˜Kšœ=˜=—šœI˜OKšœJ˜JK˜&KšœN˜P—š˜Kšœ.œ!˜R—K˜—šž œœ˜(Kšœœ œ˜,Kšœœ œ˜,šœœ œ˜&Kšœœ œ ˜0Kšœœ œ˜2—K˜—Kšœœ ˜Kšœ-˜-K˜Kšœœ#˜@Kšœœ˜%KšœC˜CKšœ œ ˜Kšœ=˜=K˜Kšœœ&˜0K˜—šž#œœœ œ4œœœ˜”Kšœ,™,K™šžœ˜'Kšœœ˜4K˜—Kšœ'œ'˜TK˜—šžœœœ œ ˜8Kšœ2™2K˜šžœ!˜4Kšœ#œ ˜2Kšœ˜K˜—šžœœ˜/Kšœœ ˜,Kšœ;˜;K˜K˜7Kšœœœœ˜1š œœ˜Kšœ[˜[KšœY˜YKš œ˜ —Kšœ˜K˜—Kšœ6œ ˜DKšœœ˜/Kšœœ˜Kšœ9œ#˜aKšœ!˜!Kšœ;˜;Kšœœ-˜7K˜—š žœœ œ œ œ˜GKšœ™K˜šœ˜Kšœ˜Kšœ˜Kšœ˜Kšœ˜Kšœ˜Kšœ˜Kšœ˜Kšœ˜Kšœ˜Kšœ˜ —K˜—šžœœ œœ˜\Kšœ5™5K˜Kšœœœ˜EKšœœœœ˜IKšœ˜ Kšœœ ˜&Kšœ ˜K˜—šžœœ œœ˜\KšœA™AK˜Kšœœœ˜Ešœœœœ˜IKšœ˜ —Kšœœ ˜&Kšœ ˜K˜—š ž œœ œœœ˜[Kšœ!™!K˜šž œœ˜*Kš œœœœ œ˜QK˜—šž œœ˜*Kš œœœœ$œ'˜K˜—šœœ˜*Kšœ-˜-—šœ˜Kšœœœœ+˜I—šœœ˜*Kšœ-˜-—šœ˜Kšœœœœ,˜I—K˜—šžœœœ œ ˜5Kšœ™K˜šž œœ˜*Kš œœœ3œ,œœ œ˜αK˜K˜—Kšœœ˜/Kšœœ(˜2K˜—šžœœœ œ ˜6Kšœ ™ K˜šžœœ˜+šœ œœ˜Kšœ œ ˜/KšœœΟc˜,—K˜K˜—Kšœœ˜/Kšœœ)˜3K˜—š ž œœœ<œ œœ˜wKšœ?™?šœ˜š œœœ3œœœ ˜cKš œ'œœ œ ˜€Kšœ˜ ——K˜—šœX˜XK˜—š žœœœBœ œœ˜†Kšœ œ2™?šœ œ˜š œœœEœœœ ˜uKšœ#œ ˜7Kšœ˜ ——K˜—š ž œœœœ œ ˜8Kšœ œ>œœ˜vKšœE™EK˜KšœœX˜aKšœ(œ-˜X—˜Jšœ˜—J˜J˜J˜J˜—…—‚%