DIRECTORY CD, CDPinObjects, CDSimpleRules, PW, PWPins, PWRoute, Route, SymTab; PWRouteImpl: CEDAR PROGRAM IMPORTS CD, CDPinObjects, CDSimpleRules, PW, PWPins, Route, SymTab EXPORTS PWRoute = BEGIN OPEN PWRoute; AbutRouteList: PROC [design: CD.Design, listOb, topOrRightListOb, bottomOrLeftListOb: PW.ListOb, params: RouterParams, isX: BOOL] RETURNS [obj: PW.Object] = BEGIN newListObj: PW.ListOb _ NIL; obj1, obj2, topOrRightObj, bottomOrLeftObj, channel: PW.Object; IF listOb=NIL THEN RETURN[NIL]; obj1 _ listOb.first; listOb _ listOb.rest; newListObj _ CONS[obj1]; FOR l: PW.ListOb _ listOb, l.rest WHILE l#NIL DO obj2 _ l.first; IF topOrRightListOb=NIL THEN topOrRightObj _ NIL ELSE {topOrRightObj _ topOrRightListOb.first; topOrRightListOb _ topOrRightListOb.rest}; IF bottomOrLeftListOb=NIL THEN bottomOrLeftObj _ NIL ELSE {bottomOrLeftObj _ bottomOrLeftListOb.first; bottomOrLeftListOb _ bottomOrLeftListOb.rest}; channel _ MakeChannel[design, obj1, obj2, topOrRightObj, bottomOrLeftObj, params, TRUE]; newListObj _ CONS[obj2, CONS[channel, newListObj]]; obj1 _ obj2; -- just before looping ENDLOOP; newListObj _ PW.Reverse[newListObj]; obj _ PW.AbutListX[design, newListObj]; END; AbutRouteListX: PUBLIC PROC [design: CD.Design, listOb: PW.ListOb, topListOb: PW.ListOb _ NIL, bottomListOb: PW.ListOb _ NIL, params: RouterParams _ defaultRouterParams] RETURNS [obj: PW.Object] = {obj _ AbutRouteList[design, listOb, topListOb, bottomListOb, params, TRUE]}; AbutRouteListY: PUBLIC PROC [design: CD.Design, listOb: PW.ListOb, rightListOb: PW.ListOb _ NIL, leftListOb: PW.ListOb _ NIL, params: RouterParams _ defaultRouterParams] RETURNS [obj: PW.Object] = {obj _ AbutRouteList[design, listOb, rightListOb, leftListOb, params, FALSE]}; Net: TYPE = REF NetRec; NetRec: TYPE = RECORD[ name: ROPE _ NIL, -- net name pins: Route.PinList _ NIL]; -- the list of pins in the net defaultRouterParams: PUBLIC RouterParams _ NEW[RouterParamsRec _ ["metal", "poly"]]; ParsePins: PROC[design: CD.Design, obj: CD.Object, tab: SymTab.Ref, side: PWPins.Side, params: RouterParams] = BEGIN EachPin: CDPinObjects.InstanceEnumerator = { IF PWPins.GetSide[obj, inst].side=side THEN InsertPin[tab, inst, side, params]; }; [] _ PWPins.EnumerateEdgePins[obj, EachPin]; END; FromSideToSide: PROC [side: PWPins.Side] RETURNS [bryanSide: Route.Side] = { bryanSide _ SELECT side FROM left => left, right => right, top => top, bottom => bottom, ENDCASE => ERROR; }; OtherSide: PROC [side: Route.Side] RETURNS [opposite: Route.Side] = { opposite _ SELECT side FROM left => right, right => left, top => bottom, bottom => top, ENDCASE => ERROR; }; InsertPin: PROC [tab: SymTab.Ref, inst: CD.Instance, side: PWPins.Side, params: RouterParams] = BEGIN pinName, netName: ROPE; found: BOOL; val: REF; net: Net; pin: Route.Pin _ Route.CreatePin[inst, OtherSide[FromSideToSide[side]]]; pinName _ CDPinObjects.GetName[inst]; netName _ IF params.makeNetsProc=NIL THEN pinName ELSE params.makeNetsProc[pinName]; [found, val] _ SymTab.Fetch[tab, netName]; net _ IF ~found THEN NEW[NetRec _ [netName]] ELSE NARROW[val]; net.pins _ CONS[pin, net.pins]; [] _ SymTab.Store[tab, netName, net]; END; ShipNets: PROC [tab: SymTab.Ref, routingArea: Route.RoutingArea] = BEGIN EnterOneNet: SymTab.EachPairAction = BEGIN netName: ROPE _ NARROW[key]; net: Net _ NARROW[val]; Route.IncludeNet[routingArea, netName, net.pins]; RETURN[FALSE]; END; [] _ SymTab.Pairs[tab, EnterOneNet]; END; MakeChannel: PUBLIC PROC[design: CD.Design, obj1, obj2, topOrRightObj, bottomOrLeftObj: CD.Object, params: RouterParams, isX: BOOL] RETURNS [channel: CD.Object] = BEGIN tab: SymTab.Ref; result: Route.RoutingResult; sideCoords: Route.PositionVec; -- the positions of the sides in a "large" coord system r1, r2: CD.Rect; technology: CD.Technology _ design.technology; rules: Route.DesignRules _ IF isX THEN Route.CreateDesignRules[ -- abutX technology.key, CDSimpleRules.GetLayer[technology.key, params.branchLayer], CDSimpleRules.GetLayer[technology.key, params.trunkLayer], vertical] ELSE Route.CreateDesignRules[ -- abutY technology.key, CDSimpleRules.GetLayer[technology.key, params.trunkLayer], CDSimpleRules.GetLayer[technology.key, params.branchLayer], horizontal]; routingArea: Route.RoutingArea _ Route.CreateRoutingArea["Channel", rules]; r1 _ CD.InterestRect[obj1]; r2 _ CD.InterestRect[obj2]; IF isX THEN -- AbutX BEGIN Route.IncludeRoutingAreaSide[routingArea, left, [r1.x2, r1.y1]]; Route.IncludeRoutingAreaSide[routingArea, right, [r2.x1, r2.y1]]; Route.IncludeRoutingAreaSide[routingArea, bottom, [0, 0]]; -- to be changed Route.IncludeRoutingAreaSide[routingArea, top, [0, 0]]; -- to be changed END ELSE BEGIN -- AbutY Route.IncludeRoutingAreaSide[routingArea, bottom, [r1.x1, r1.y2]]; Route.IncludeRoutingAreaSide[routingArea, top, [r2.x1, r2.y1]]; Route.IncludeRoutingAreaSide[routingArea, left, [0, 0]]; -- to be changed Route.IncludeRoutingAreaSide[routingArea, right, [0, 0]]; -- to be changed END; tab _ SymTab.Create[mod: 17, case: TRUE]; -- the table of all nets ParsePins[design, obj1, tab, IF isX THEN right ELSE top, params]; ParsePins[design, obj2, tab, IF isX THEN left ELSE bottom, params]; IF topOrRightObj#NIL THEN ParsePins[design, topOrRightObj, tab, IF isX THEN bottom ELSE left, params]; IF bottomOrLeftObj#NIL THEN ParsePins[design, bottomOrLeftObj, tab, IF isX THEN top ELSE right, params]; ShipNets[tab, routingArea]; sideCoords _ [[0, 0], [0, 0], [0, r1.y2-r1.y1], [0, 0]]; result _ Route.ChannelRoute[routingArea, sideCoords]; [channel, ] _ Route.RetrieveRouting[result, result.routingArea.name, design, NIL, NIL]; END; END. tPWRouteImpl.mesa Copyright c 1985 by Xerox Corporation. All rights reversed. Last Edited by: Monier, August 16, 1985 11:03:47 am PDT Bertrand Serlet August 28, 1985 6:51:43 pm PDT Louis Monier August 22, 1985 1:15:09 pm PDT -- AbutRoute: uses a channel router to connect adjacent objects -- Given two cells that we plan to abut, this module parses the corresponding edges, extract the pins, build nets according to the names on the pins, then calls the router to produce a cell containing the channel routing. -- Gets all the pins on the edge; pack them Bryan-style into nets and in the SymTab.Ref [inst: CD.Instance] RETURNS [quit: BOOL _ FALSE] -- Group pins in net and insert in table -- Read the table and ship the nets to the channel router -- Get the technology from thew CD design: better not be NIL! -- Make the design rules for proper spacing in this techno -- Initialise the channel: no fancy option for now -- In prevision of the use of the IRect coord system, origins are [0, 0] -- Parse the objects, get the pins, make the nets, put in table -- Read the table and ship the nets to the channel router -- Now route! ΚI˜– "Cedar" stylešœ™Jšœ Οmœ1™Jšœ žœ˜Jšœ%˜%Jšžœ˜—J˜J™9šŸœžœ5˜CKšž˜šŸ œ˜$Jšž˜Jšœ žœžœ˜Jšœ žœ˜Jšœ1˜1Jšžœžœ˜Jšžœ˜—K˜Jšœ$˜$Kšžœ˜—J™šŸ œžœžœ žœ5žœ$žœžœ žœ ˜£Jšž˜Jšœ˜Jšœ˜Jšœ 7˜VJšœžœ˜J˜Jšœ+ ™=Jšœ žœ ˜.Jšœ:™:šœ˜šžœžœ" ˜5Jšœ˜Jšœ<˜