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, bottomOrLeftListOb, topOrRightListOb: PW.ListOb, params: RouterParams, isX: BOOL, routeType: RouteType] 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, bottomOrLeftObj, topOrRightObj, params, isX, routeType]; newListObj _ CONS[obj2, CONS[channel, newListObj]]; obj1 _ obj2; -- just before looping ENDLOOP; newListObj _ PW.Reverse[newListObj]; IF isX THEN obj _ PW.AbutListX[design, newListObj] ELSE obj _ PW.AbutListY[design, newListObj]; END; AbutChRouteListX: PUBLIC PROC [design: CD.Design, listOb: PW.ListOb, bottomListOb: PW.ListOb _ NIL, topListOb: PW.ListOb _ NIL, params: RouterParams _ defaultRouterParams] RETURNS [obj: PW.Object] = {obj _ AbutRouteList[design, listOb, bottomListOb, topListOb, params, TRUE, channel]}; AbutChRouteListY: PUBLIC PROC [design: CD.Design, listOb: PW.ListOb, leftListOb: PW.ListOb _ NIL, rightListOb: PW.ListOb _ NIL, params: RouterParams _ defaultRouterParams] RETURNS [obj: PW.Object] = {obj _ AbutRouteList[design, listOb, leftListOb, rightListOb, params, FALSE, channel]}; AbutSbRoute: PUBLIC PROC [design: CD.Design, bottomOb, rightOb, topOb, leftOb: PW.Object _ NIL, trunkDir: HorV _ horizontal, params: RouterParams _ defaultRouterParams] RETURNS [obj: PW.Object] = { IF trunkDir = horizontal THEN obj _ MakeChannel[design, bottomOb, topOb, leftOb, rightOb, params, FALSE, switchBox] ELSE obj _ MakeChannel[design, leftOb, rightOb, bottomOb, topOb, params, TRUE, switchBox]}; 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] = { EachPin: CDPinObjects.InstanceEnumerator = { IF PWPins.GetSide[obj, inst].side=side THEN InsertPin[tab, inst, side, params]; }; IF obj # NIL THEN [] _ PWPins.EnumerateEdgePins[obj, EachPin]; }; FromSideToSide: PROC [side: PWPins.Side] RETURNS [routeSide: Route.Side] = { routeSide _ 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] = { 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]; }; ShipNets: PROC [tab: SymTab.Ref, routingArea: Route.RoutingArea] = { 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]; }; MakeChannel: PUBLIC PROC[design: CD.Design, obj1, obj2, bottomOrLeftObj, topOrRightObj: CD.Object, params: RouterParams, isX: BOOL, routeType: RouteType] RETURNS [channel: CD.Object] = { tab: SymTab.Ref; result: Route.RoutingResult; sideCoords: Route.PositionVec; -- the positions of the sides in a "large" coord system r1, r2, rbl, rtr, routingRect: CD.Rect _ [0, 0, 0, 0]; pBottom, pLeft, pTop, pRight: CD.Position; 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]; IF obj1 # NIL THEN r1 _ CD.InterestRect[obj1]; IF obj2 # NIL THEN r2 _ CD.InterestRect[obj2]; IF bottomOrLeftObj # NIL THEN rbl _ CD.InterestRect[bottomOrLeftObj]; IF topOrRightObj # NIL THEN rtr _ CD.InterestRect[topOrRightObj]; IF isX THEN -- AbutX BEGIN pBottom _ [0, - rbl.y2 + rbl.y1]; pLeft _ [- r1.x2 + r1.x1, 0]; pTop _ [0, MAX[r1.y2 - r1.y1, r2.y2 - r2.y1]]; pRight _ [MAX[rbl.x2 - rbl.x1, rtr.x2 - rtr.x1], 0]; Route.IncludeRoutingAreaSide[routingArea, left, [r1.x1, r1.y1]]; Route.IncludeRoutingAreaSide[routingArea, right, [r2.x1, r2.y1]]; Route.IncludeRoutingAreaSide[routingArea, bottom, [rbl.x1, rbl.y1]]; Route.IncludeRoutingAreaSide[routingArea, top, [rtr.x1, rtr.y1]]; END ELSE BEGIN -- AbutY pBottom _ [0, - r1.y2 + r1.y1]; pLeft _ [- rbl.x2 + rbl.x1, 0]; pTop _ [0, MAX[rbl.y2 - rbl.y1, rtr.y2 - rtr.y1]]; pRight _ [MAX[r1.x2 - r1.x1, r2.x2 - r2.x1], 0]; Route.IncludeRoutingAreaSide[routingArea, bottom, [r1.x1, r1.y1]]; Route.IncludeRoutingAreaSide[routingArea, top, [r2.x1, r2.y1]]; Route.IncludeRoutingAreaSide[routingArea, left, [rbl.x1, rbl.y1]]; Route.IncludeRoutingAreaSide[routingArea, right, [rtr.x1, rtr.y1]]; 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]; ParsePins[design, topOrRightObj, tab, IF isX THEN bottom ELSE left, params]; ParsePins[design, bottomOrLeftObj, tab, IF isX THEN top ELSE right, params]; ShipNets[tab, routingArea]; sideCoords _ [pBottom, pRight, pTop, pLeft]; routingRect _ [0, 0, pRight.x, pTop.y]; SELECT routeType FROM channel => result _ Route.ChannelRoute[routingArea, sideCoords, routingRect]; switchBox => result _ Route.SwitchBoxRoute[routingArea, sideCoords, routingRect]; ENDCASE; channel _ Route.RetrieveRouting[result, result.routingArea.name, design, NIL, NIL].object; }; END. PWRouteImpl.mesa Copyright c 1985 by Xerox Corporation. All rights reversed. Last Edited by: Preas, October 29, 1985 3:30:23 pm PST -- 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 into nets and put 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! ΚZ˜– "Cedar" stylešœ™Jšœ Οmœ1™˜>Jšœ˜—J˜code–[]šŸœžœžœ˜Lšœ žœž˜K˜ Kšœ˜Kšœ ˜ Kšœ˜Kšžœžœ˜—K˜—K˜šŸ œžœžœ˜Ešœ žœž˜Kšœ˜Kšœ˜Kšœ˜Kšœ˜Kšžœžœ˜—K˜—J™J™(šŸ œžœžœ7˜aKšœžœ˜Kšœžœ˜ Kšœžœ˜ K˜ K˜KšœH˜HKšœ%˜%Kš œ žœžœžœ žœ˜TJšœ+˜+Jš œžœžœžœžœžœ˜>Jšœ žœ˜Jšœ%˜%Jšœ˜—J˜J™9šŸœžœ6˜DJ˜šœ$˜$Jšž˜Jšœ žœžœ˜Jšœ žœ˜Jšœ1˜1Jšžœžœ˜Jšžœ˜—K˜Jšœ$˜$Kšœ˜—J™šŸ œžœžœ žœ5žœ$žœžœ žœ ˜»Jšœ˜Jšœ˜Jšœ 7˜VJšœžœ˜6Jšœžœ ˜*J˜Jšœ+ ™=Jšœ žœ ˜.Jšœ:™:šœ˜šžœžœ" ˜5Jšœ˜Jšœ<˜