<> <> <> <> DIRECTORY CD, CDBasics, CDDirectory, CDProperties, CDRoutingObjects, CoreGeometry, InstanceTable, IO, PW, PWCore, Rope, RoutingCheck, SymTab, TerminalIO; RoutingCheckImpl: CEDAR PROGRAM IMPORTS CDBasics, CDDirectory, CDProperties, CDRoutingObjects, CoreGeometry, InstanceTable, IO, PW, PWCore, Rope, SymTab, TerminalIO EXPORTS RoutingCheck = BEGIN Error: SIGNAL [msg: Rope.ROPE] ~ CODE; Check: PUBLIC PROC [design: CD.Design] ~ { [] _ CDDirectory.EnumerateDesign [design: design, proc: CheckAnObject, dir: FALSE, top: TRUE, recurse: TRUE, dummy: FALSE]}; CheckObject: PUBLIC PROC [obj: CD.Object] ~ { -- check all routing cells inside the object [] _ CDDirectory.EnumerateObject[ob: obj, proc: CheckAnObject, recurse: TRUE]; }; CheckAnObject: CDDirectory.EachObjectProc ~ { CheckForNeighboors: PROC [inst: CoreGeometry.Instance, value: REF] ~ { CheckWhoTouchesIt: PROC [neighboor: CoreGeometry.Instance, ref: REF] ~ { label2: Rope.ROPE = NARROW[ref]; IF touchProc[touchProc, inst, neighboor] AND 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[me.bbox]; names: SymTab.Ref _ SymTab.Create[]; IF me.class#CDRoutingObjects.routingClass THEN RETURN; specific _ NARROW[me.specific]; TerminalIO.PutF["Checking routing cell %g with %g nets\n", IO.rope[PW.Name[me]], IO.int[specific.size]]; <<-- checks that labels are all different>> <<-- 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 -- insert all rectangles in table, check they fit in BBox node: CDRoutingObjects.Node = specific.nodes[i]; label: Rope.ROPE _ NARROW[CDProperties.GetProp[node.properties, $SignalName]]; IF NOT SymTab.Insert[names, label, node] THEN -- two nodes must have different labels SIGNAL Error[IO.PutFR["There are two occurences of net %g", IO.rope[label]]]; FOR j: NAT IN [0..node.size) DO instance: CoreGeometry.Instance = [obj: node[j].object, trans: [node[j].position]]; IF NOT CDBasics.Inside[CoreGeometry.InlineBBox[instance], me.bbox] THEN SIGNAL Error[IO.PutFR["Node on net %g is not inside bounding box", IO.rope[label]]] ELSE InstanceTable.Insert[table, instance, label]; ENDLOOP; ENDLOOP; InstanceTable.Enumerate[table, CheckForNeighboors]; -- enumerate all instances SymTab.Erase[names]; -- erase the name table InstanceTable.DeleteOutside[table]; -- erase the instance table }; END.