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

DIRE
CTORY

DJE
xtAllocDefs: FROM "DJExtAllocDefs" USING [AllocateDiffusion, FreeDiffusion, AllocateTransistor, FreeTransistor],
DJExtCombineDefs: FROM "DJExtCombineDefs" USING [GetNode,AttachNode],
DJExtTransDefs: FROM "DJExtTransDefs",
DJExtMergeDefs: FROM "DJExtMergeDefs" USING [Lookup,LookSmall,IsSmall],
DJExtTypes: FROM "DJExtTypes" USING [Node, NodeRecord, Diffusion, NodeNumber],
Runtime: FROM "Runtime" USING [CallDebugger];

DJExtTr
ans: PROGRAM
IMPORTS DJExtAllocDefs, DJExtCombineDefs, DJExtMergeDefs, Runtime
EXPORTS DJExtTransDefs =
BEGIN
OPEN DJExtAllocDefs, DJExtCombineDefs, DJExtMergeDefs, DJExtTypes, Runtime;

AddDiff:
PUBLIC PROCEDURE [trans:Node,node:NodeNumber,len:REAL] =
BEGIN
diff:Diffusion;
node ← Lookup[node];
FOR ptr: Diffusion ← trans.diff,ptr.next UNTIL ptr = NIL DO
ptr.node ← Lookup[ptr.node];
IF ptr.node = node THEN {
ptr.length ← ptr.length + len;
RETURN;
};
ENDLOOP;
diff ← AllocateDiffusion[];
diff.node ← node;
diff.length ← len;
diff.next ← trans.diff;
trans.diff ← diff;
END;

FindTrans
istor: PUBLIC PROCEDURE [num:NodeNumber, x,y:REAL] RETURNS[node:Node] =
BEGIN
node ← GetNode[num];
IF node # NIL THEN RETURN;
node ← MakeTransistor[x,y];
node.node ← Lookup[num];
AttachNode[node.node,node];
END;

CombineT
ransistors: PUBLIC PROCEDURE [t1,t2:Node] RETURNS[Node] =
BEGIN
next:Diffusion;
FOR ptr: Diffusion ← t2.diff,next UNTIL ptr = NIL DO
next ← ptr.next;
AddDiff[t1,ptr.node,ptr.length];
FreeDiffusion[ptr];
ENDLOOP;
IF t2.ion THEN t1.ion ← TRUE;
IF t2.nion THEN t1.nion ← TRUE;
t1.area ← t1.area + t2.area;
t1.perim ← t1.perim + t2.perim;
DeleteTransistor[t2];
RETURN[t1];
END;

ReleaseTr
ansistor: PUBLIC PROCEDURE [trans:Node] =
BEGIN
next:Diffusion;
FOR ptr: Diffusion ← trans.diff,next UNTIL ptr = NIL DO
next ← ptr.next;
FreeDiffusion[ptr];
ENDLOOP;
DeleteTransistor[trans];
END;

CopyTrans
: PUBLIC PROCEDURE[t:Node,offset:NodeNumber] RETURNS[trans:Node] =
BEGIN
trans ← AllocateTransistor[];
IF tList.next # NIL THEN tList.next.back ← trans;
trans.next ← tList.next;
trans.back ← @tList;
tList.next ← trans;

trans.node ← t.node+offset;
trans.type ← Transistor;
trans.poly ← t.poly+offset;
trans.ion ← t.ion;
trans.nion ← t.nion;
trans.area ← t.area;
trans.perim ← t.perim;
trans.x ← t.x;
trans.y ← t.y;
trans.diff ← NIL;
FOR d:Diffusion ← t.diff,d.next UNTIL d = NIL DO
AddDiff[trans,d.node+offset,d.length];
ENDLOOP;
END;

MakeTrans
istor: PUBLIC PROCEDURE[x,y:REAL] RETURNS[trans:Node] =
BEGIN
trans ← AllocateTransistor[];
IF tList.next # NIL THEN tList.next.back ← trans;
trans.next ← tList.next;
trans.back ← @tList;
tList.next ← trans;

trans.node ← 0;
trans.type ← Transistor;
trans.poly ← 0;
trans.diff ← NIL;
trans.ion ← FALSE;
trans.nion ← FALSE;
trans.x ← x;
trans.y ← y;
trans.area ← trans.perim ← 0;
END;

DeleteTra
nsistor: PUBLIC PROCEDURE[trans:Node] =
BEGIN
IF trans.next # NIL THEN trans.next.back ← trans.back;
IF trans.back # NIL THEN trans.back.next ← trans.next
ELSE CallDebugger["messed up on doubly linked lists for transistors"];
trans.type ← Unknown;
FreeTransistor[trans];
END;

GetTransi
storList: PUBLIC PROCEDURE RETURNS[trans:Node] =
BEGIN
trans ← tList.next;
tList.next ← NIL;
END;

SelectTra
nsistors: PUBLIC PROCEDURE RETURNS[intTrans,extTrans:Node] =
BEGIN
trans,next:Node;
intTrans ← NIL;
extTrans ← NIL;
FOR trans ← GetTransistorList[],next UNTIL trans = NIL DO
next ← trans.next;
IF IsSmall[trans.node] THEN {
-- it belongs on the external transistor list
trans.next ← extTrans;
extTrans ← trans;
}
ELSE {
-- it belongs on the internal transistor list
trans.next ← intTrans;
intTrans ← trans;
};
ENDLOOP;
END;

AddDiffS
mall: PROCEDURE [trans:Node,d:Diffusion] =
BEGIN
d.node ← LookSmall[d.node];
FOR ptr: Diffusion ← trans.diff,ptr.next UNTIL ptr = NIL DO
IF ptr.node = d.node THEN {
ptr.length ← ptr.length + d.length;
FreeDiffusion[d];
RETURN;
};
ENDLOOP;
d.next ← trans.diff;
trans.diff ← d;
END;

RenumberT
rans: PUBLIC PROCEDURE[trans:Node] =
BEGIN
d,next: Diffusion;
FOR trans ← trans,trans.next UNTIL trans = NIL DO
trans.node ← LookSmall[trans.node];
trans.poly ← LookSmall[trans.poly];
d ← trans.diff;
trans.diff ← NIL;
FOR d ← d,next UNTIL d = NIL DO
next ← d.next;
-- do a AddDiff without using Lookup
AddDiffSmall[trans,d];
ENDLOOP;
ENDLOOP;
END;

tList: trans NodeRecord;

tList.next ← NIL;
tList.back ← NIL;

END.