<> <> <> <> DIRECTORY CD, CDDirectory, CDProperties, CDRoutingObjects, CoreGeometry, InstanceTable, IO, PWCore, Rope, RoutingCheck, SymTab, TerminalIO; RoutingCheckImpl: CEDAR PROGRAM IMPORTS CDDirectory, CDProperties, CDRoutingObjects, CoreGeometry, InstanceTable, IO, PWCore, Rope, SymTab, TerminalIO EXPORTS RoutingCheck = BEGIN Error: SIGNAL [msg: Rope.ROPE] ~ CODE; Check: PUBLIC PROC [design: CD.Design] ~ {[] _ CDDirectory.EnumerateDesign [design: design, proc: CheckObject, dir: FALSE, top: TRUE, recurse: TRUE, dummy: FALSE]}; CheckObject: CDDirectory.EachObjectProc ~ { CheckForNeighboors: PROC [inst: CoreGeometry.Instance, value: REF] ~ { CheckWhoTouchesIt: PROC [neighboor: CoreGeometry.Instance, ref: REF] ~ { label2: Rope.ROPE = NARROW[ref]; IF NOT touchProc[touchProc, inst, neighboor] THEN RETURN; IF NOT Rope.Equal[label2, label] THEN { SIGNAL Error[IO.PutFR["Short between %g and %g", IO.rope[label], IO.rope[label2]]]}}; rect: CD.Rect = CoreGeometry.BBox[inst]; label: Rope.ROPE = NARROW[value]; InstanceTable.Enumerate[table, CheckWhoTouchesIt, rect]}; touchProc: CoreGeometry.TouchProc = PWCore.extractMode.touchProc; specific: CDRoutingObjects.RoutingSpecific; table: InstanceTable.Table _ InstanceTable.Create[InstanceTable.universe]; names: SymTab.Ref _ SymTab.Create[]; IF me.class#CDRoutingObjects.routingClass THEN RETURN; specific _ NARROW[me.specific]; TerminalIO.PutF["Checking a routing cell with %g nets\n", IO.int[specific.size]]; <<-- checks that labels are all different>> FOR i: NAT IN [0..specific.size) DO node: CDRoutingObjects.Node _ specific.nodes[i]; label: Rope.ROPE _ NARROW[CDProperties.GetProp[node.properties, $SignalName]]; IF ~SymTab.Insert[names, label, node] THEN { SIGNAL Error[IO.PutFR["Name conflict for %g", IO.rope[label]]]}; ENDLOOP; SymTab.Erase[names]; <<-- insert all instances (rectangles, contacts) in a table and checks that there are no short between different nets>> FOR i: NAT IN [0..specific.size) DO node: CDRoutingObjects.Node _ specific.nodes[i]; label: Rope.ROPE _ NARROW[CDProperties.GetProp[node.properties, $SignalName]]; FOR j: NAT IN [0..node.size) DO InstanceTable.Insert[table, [obj: node[j].object, trans: [node[j].position]], label]; ENDLOOP; ENDLOOP; InstanceTable.Enumerate[table, CheckForNeighboors]}; -- enumerate all instances END.