<> <> <> DIRECTORY CD, CDSymbolicObjects, Connections, HashTable, PWPins, Rope, RTBasic; ConnectionsImpl: CEDAR PROGRAM IMPORTS CDSymbolicObjects, HashTable, PWPins EXPORTS Connections = BEGIN CreateForRopes: PUBLIC PROC [mod: Connections.SeqIndex _ 17] RETURNS [Connections.Table] ~ { RETURN[HashTable.Create[mod, HashTable.RopeEqual, HashTable.HashRope]]}; CreateForRefs: PUBLIC PROC [mod: Connections.SeqIndex _ 17] RETURNS [Connections.Table] ~ { RETURN[HashTable.Create[mod]]}; <> Fetch: PUBLIC PROC [table: Connections.Table, key: Connections.Key] RETURNS [found: BOOLEAN, net: Connections.Net] ~ { <> <> <> value: REF; [found, value] _ HashTable.Fetch[table, key]; net _ NARROW[value]}; Store: PUBLIC PROC [table: Connections.Table, key: Connections.Key, net: Connections.Net] RETURNS [BOOLEAN] ~ { <> <> RETURN[HashTable.Store[table, key, net]]}; InsertPins: PUBLIC PROC [table: Connections.Table, object: CD.Object, pinFilter: Connections.PinFilterProc, makeHashKey: Connections.HashKeyProc] ~ { <> EachPin: CDSymbolicObjects.InstEnumerator = { <<[inst: CD.Instance] RETURNS [quit: BOOL _ FALSE]>> usePin: BOOLEAN _ IF pinFilter = NIL THEN TRUE ELSE pinFilter[inst, object]; IF usePin THEN InsertSegments[table, object, inst, makeHashKey]}; IF object # NIL THEN [] _ PWPins.EnumerateEdgePins[object, EachPin]; }; <> EnumerateNets: PUBLIC PROC [table: Connections.Table, action: Connections.EachNetAction] RETURNS [BOOLEAN] ~ { <> <> <> <> eachPair: HashTable.EachPairAction ~ { TRUSTED{net _ LOOPHOLE[value]}; quit _ action[key, net]}; net: Connections.Net; RETURN[HashTable.Pairs[table, eachPair]]}; EnumerateSegments: PUBLIC PROC [net: Connections.Net, action: Connections.EachSegmentAction] RETURNS [quit: BOOLEAN _ FALSE] ~ { <> <> <> <> FOR l: Connections.Segments _ net.segments, l.rest WHILE ~quit AND l # NIL DO segment: Connections.Segment _ l.first; quit _ action[net, segment]; ENDLOOP}; <> <> InsertSegments: PROC [table: Connections.Table, object: CD.Object, instance: CD.Instance, makeHashKey: Connections.HashKeyProc] ~ { found: BOOL; val: REF; net: Connections.Net; side: RTBasic.Side _ FromSideToSide[PWPins.GetSide[object, instance].side]; rect: CD.Rect _ CDSymbolicObjects.Denotes[instance]; name: Rope.ROPE _ CDSymbolicObjects.GetName[instance]; segment: Connections.Segment _ NEW[Connections.SegmentRec _ [name, object, CoordsAlongSide[instance, side], side, CDSymbolicObjects.GetLayer[instance]]]; tabIndex: Rope.ROPE _ IF makeHashKey=NIL THEN name ELSE makeHashKey[instance]; [found, val] _ Fetch[table, tabIndex]; net _ IF ~found THEN NEW[Connections.NetRec _ [name: name]] ELSE NARROW[val]; net.segments _ CONS[segment, net.segments]; [] _ Store[table, tabIndex, net]}; CoordsAlongSide: PROC [instance: CD.Instance, side: RTBasic.Side] RETURNS [range: Connections.Range] ~ { rect: CD.Rect _ CDSymbolicObjects.Denotes[instance]; SELECT side FROM top, bottom => range _ [rect.x1, rect.x2]; left, right => range _ [rect.y1, rect.y2]; ENDCASE}; FromSideToSide: PROC [side: PWPins.Side] RETURNS [routeSide: RTBasic.Side] = { routeSide _ SELECT side FROM left => left, right => right, top => top, bottom => bottom, ENDCASE => ERROR; }; END.