RoutingCheckImpl.mesa
Copyright Ó 1987 by Xerox Corporation. All rights reserved.
Created by: Louis Monier September 29, 1987 8:01:56 pm PDT
Louis Monier October 1, 1987 8:45:57 pm PDT
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.ROPENARROW[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.