-- File: DJExtCap.mesa
-- capactor routines used by the disjoint circuit extractor
-- Written by Martin Newell/Dan Fitzpatrick July 1981
-- Last edited: 12-Aug-81 13:54:50

DIRE
CTORY

DJE
xtAllocDefs: FROM "DJExtAllocDefs" USING [AllocateCap, FreeCap],
DJExtCombineDefs: FROM "DJExtCombineDefs" USING [GetNode,AttachNode],
DJExtCapDefs: FROM "DJExtCapDefs",
DJExtMergeDefs: FROM "DJExtMergeDefs" USING [Lookup,LookSmall,IsSmall],
DJExtTypes: FROM "DJExtTypes" USING [Node, NodeRecord, NodeNumber, CapLayer,poly,diff,metal,gate],
Runtime: FROM "Runtime" USING [CallDebugger];

DJExtCa
p: PROGRAM
IMPORTS DJExtAllocDefs, DJExtCombineDefs, DJExtMergeDefs, Runtime
EXPORTS DJExtCapDefs =
BEGIN
OPEN DJExtAllocDefs, DJExtCombineDefs, DJExtMergeDefs, DJExtTypes, Runtime;


FindCap
: PUBLIC PROCEDURE[num:NodeNumber] RETURNS[node:Node] =
BEGIN
node ← GetNode[num];
IF node # NIL THEN RETURN;
node ← MakeCap[];
node.node ← Lookup[num];
AttachNode[node.node,node];
END;

AddCapAre
a: PUBLIC PROCEDURE[cap:Node, layer:INTEGER, area:REAL] =
BEGIN
SELECT layer FROM
poly => cap.carea[Poly] ← cap.carea[Poly] + area;
diff => cap.carea[Diff] ← cap.carea[Diff] + area;
metal => cap.carea[Metal] ← cap.carea[Metal] + area;
ENDCASE => CallDebugger["bad layer in AddCapArea"];
END;

AddCapPer
im: PUBLIC PROCEDURE[cap:Node, layer:INTEGER, perim:REAL] =
BEGIN
SELECT layer FROM
poly => cap.cperim[Poly] ← cap.cperim[Poly] + perim;
diff => cap.cperim[Diff] ← cap.cperim[Diff] + perim;
metal => cap.cperim[Metal] ← cap.cperim[Metal] + perim;
gate => cap.perim ← cap.perim + perim;-- might be a trans
ENDCASE => CallDebugger["bad layer in AddCapPerim"];
END;

CombineC
ap: PUBLIC PROCEDURE [c1,c2:Node] RETURNS[Node] =
BEGIN
FOR layer: CapLayer IN CapLayer DO
c1.carea[layer] ← c1.carea[layer] + c2.carea[layer];
c1.cperim[layer] ← c1.cperim[layer] + c2.cperim[layer];
ENDLOOP;
DeleteCap[c2];
RETURN[c1];
END;

CopyCap:
PUBLIC PROCEDURE[c:Node,offset:NodeNumber] RETURNS[cap:Node] =
BEGIN
cap ← AllocateCap[];
IF cList.next # NIL THEN cList.next.back ← cap;
cap.next ← cList.next;
cap.back ← @cList;
cList.next ← cap;

cap.node ← c.node+offset;
cap.type ← Capacitor;
FOR layer: CapLayer IN CapLayer DO
cap.carea[layer] ← c.carea[layer];
cap.cperim[layer] ← c.cperim[layer];
ENDLOOP;
END;

MakeCap:
PUBLIC PROCEDURE[] RETURNS[cap:Node] =
BEGIN
cap ← AllocateCap[];
IF cList.next # NIL THEN cList.next.back ← cap;
cap.next ← cList.next;
cap.back ← @cList;
cList.next ← cap;

cap.node ← 0;
cap.type ← Capacitor;
FOR layer: CapLayer IN CapLayer DO
cap.carea[layer] ← 0;
cap.cperim[layer] ← 0;
ENDLOOP;
END;

DeleteCap
: PUBLIC PROCEDURE[cap:Node] =
BEGIN
IF cap.next # NIL THEN cap.next.back ← cap.back;
IF cap.back # NIL THEN cap.back.next ← cap.next
ELSE CallDebugger["messed up on doubly linked lists for capacitor"];
cap.type ← Unknown;
FreeCap[cap];
END;

GetCapLis
t: PUBLIC PROCEDURE RETURNS[cap:Node] =
BEGIN
cap ← cList.next;
cList.next ← NIL;
END;

SelectCap
: PUBLIC PROCEDURE RETURNS[intCap,extCap:Node] =
BEGIN
cap,next:Node;
intCap ← NIL;
extCap ← NIL;
FOR cap ← GetCapList[],next UNTIL cap = NIL DO
next ← cap.next;
IF IsSmall[cap.node] THEN {
-- it belongs on the external capacitor list
cap.next ← extCap;
extCap ← cap;
}
ELSE {
-- it belongs on the internal capacitor list
cap.next ← intCap;
intCap ← cap;
};
ENDLOOP;
END;

Renumber
Cap: PUBLIC PROCEDURE[cap:Node] =
BEGIN
FOR cap ← cap,cap.next UNTIL cap = NIL DO
cap.node ← LookSmall[cap.node];
ENDLOOP;
END;

cList: cap NodeRecord;

cList.next ← NIL;
cList.back ← NIL;

END.