-- File CIFExtNMOS2Defs.mesa
-- Written by Martin Newell, June 1980
-- Last updated: December 8, 1981 4:52 PM by CK

-- CIF Circuit Extractor NMOS dependent procedures

DIRECTORY CIFDevicesDefs, CIFExtDictDefs, CIFExtIODefs, CIFExtScanDefs, CIFExtUtilsDefs, RealFns, IODefs, MergeDefs, Real, SystemDefs, StreamDefs, StringDefs, SegmentDefs, XFSPDefs, CWF, CWFReal;



CIFExtNMOS2Defs: DEFINITIONS
IMPORTS CIFDevicesDefs, CIFExtDictDefs, CIFExtIODefs, CIFExtScanDefs, CIFExtUtilsDefs, RealFns, IODefs, MergeDefs, Real, SystemDefs, StreamDefs, StringDefs, SegmentDefs, XFSPDefs, CWF, CWFReal =

BEGIN
OPEN CIFDevicesDefs, CIFExtDictDefs, CIFExtIODefs, CIFExtScanDefs, CIFExtUtilsDefs, RealFns, IODefs, MergeDefs, Real, SystemDefs, StreamDefs, StringDefs, SegmentDefs, XFSPDefs;


ErrorFlag: BOOLEAN;
-- true when errors are on .extlog
AliasFlag: BOOLEAN;-- true when aliases are on .al

NoEnhaTrans, NoDeplTrans: LONG CARDINAL;

NodeNumberType: TYPE = LONG POINTER;
Transistor: TYPE = LONG POINTER TO TransistorRecord;
TransistorRecord: TYPE = RECORD[
link: Transistor,
polyNumber: NodeNumberType,
diffList: LONG POINTER TO DiffRecord,
ion: BOOLEAN,
marked: BOOLEAN,
old: BOOLEAN,
newNode: Transistor,
area,circumference: REAL,
x, y: REAL
];

FreeTransistors, AllocatedTransistors: Transistor;
FreeTransCount: CARDINAL;
TransAllocConstant: CARDINAL = 32;
CapacitorFile, TransistorFile: DiskHandle;
NodeFile, OutNodeFile: DiskHandle;
errorStream, out1: DiskHandle;
tmpErrorStream, defaultStream: StreamHandle;
--LabelLocationFile, -- LabelNodeFile: DiskHandle;

FreeDiffRecords: LONG POINTER TO DiffRecord;
DiffRecord: TYPE = RECORD [
next: LONG POINTER TO DiffRecord,
number: NodeNumberType,
length: REAL
];
FreeNodeSegments: NodeSegment;
NodeSegment: TYPE = LONG POINTER TO NodeSegmentRecord;
NodeSegmentRecord: TYPE = RECORD [
next: NodeSegment,
number: NodeNumberType,
left: REAL,
right: REAL,
mark: BOOLEAN,
transistor: SELECT COMPUTED BOOLEAN FROM
TRUE => [
leftLength: REAL,
rightLength: REAL],
FALSE => [
circumference, area: ARRAY [1 .. 4] OF REAL],
ENDCASE
];

Layers: TYPE = [diff .. metal];

CapRecord: TYPE = RECORD [
number: NodeNumberType,
layer: Layers,
perimeter, area: REAL
];

FreeNodeLabels: NodeLabel;
NodeLabel: TYPE = LONG POINTER TO NodeLabelRecord;
NodeLabelRecord: TYPE = RECORD [
next: NodeLabel,
label: STRING,
x,y: REAL,
layer: CARDINAL,
used: BOOLEAN
];
LabelList: NodeLabel;

YCurr, YPrev: REAL;
Scale: REAL;

newNodeList, oldNodeList, NodeList: ARRAY [0..MaxLENGTHLayerArray+2] OF NodeSegment;
ptrnewNodeList: ARRAY [0..MaxLENGTHLayerArray+2] OF LONG POINTER TO NodeSegment;
NodeNumber: NodeNumberType;

NoAllocTrans,NoAllocDiffRecord, NoAllocNodeSegment, NoAllocNodeLabel, NoAllocString: LONG CARDINAL;
scanCount, displayCount: CARDINAL;

BaseFileName: STRING;

one: REAL = 1;
half: REAL = 0.5;

trapleft: ARRAY [0..MaxLENGTHLayerArray+2] OF Edge;
implant: CARDINAL = 0;
diff: CARDINAL = 1;
poly: CARDINAL = 2;
contact: CARDINAL = 3;
metal: CARDINAL = 4;
buried: CARDINAL = 5;
glass: CARDINAL = 6;
undef: CARDINAL = 7;
depl: CARDINAL;
enha: CARDINAL;




SetPoly: PROCEDURE [trans: Transistor, polyNumber: NodeNumberType] = INLINE
BEGIN
IF trans.polyNumber = NIL THEN BEGIN
trans.polyNumber ← polyNumber;
RETURN;
END;
END;


SetDiff: PROCEDURE [trans: Transistor, diffNumber: NodeNumberType, length: REAL] = INLINE
BEGIN
diffptr, newptr: LONG POINTER TO DiffRecord;
-- Check to see that diffNumber is not already in diffusion list
FOR diffptr ← trans.diffList, diffptr.next
UNTIL diffptr = NIL DO
IF diffptr.number = diffNumber THEN BEGIN
diffptr.length ← diffptr.length + length;
RETURN;
END;
ENDLOOP;
-- diffNumber is not in diffusion list so enter it at the front of the list
-- on the assumption that this new diffusion number is likely to reappear
-- and therefore must be searched for.
newptr ← AllocateDiffRecord[];
newptr.number ← diffNumber;
newptr.length ← length;
newptr.next ← trans.diffList;
trans.diffList ← newptr;
END;

GenNodeNumber: PROCEDURE [layer: CARDINAL] RETURNS[NodeNumberType];

MakeTransistor: PROCEDURERETURNS[trans: Transistor];

FreeTransistor: PROCEDURE[trans: Transistor];

AllocateTransistor: PROCEDURE RETURNS[trans: Transistor];

CollectTransistors
: PROCEDURE;

OutputTransistors: PROCEDURE = INLINE
BEGIN
NodeList[depl] ← NIL;
newNodeList[depl] ← NIL;
NodeList[enha] ← NIL;
newNodeList[enha] ← NIL;
CollectTransistors;-- Writes all the remaining transistors
ReleaseTransistors[];-- Free core space
END;

ReleaseTransistors: PROCEDURE;

AllocateDiffRecord: PROCEDURE RETURNS[d: LONG POINTER TO DiffRecord];

FreeDiffRecord: PROCEDURE[diffptr: LONG POINTER TO DiffRecord];

NodeToTransistor: PROCEDURE [node: NodeNumberType] RETURNS[trans: Transistor] = INLINE
BEGIN
temp: Transistor ← node;
FOR trans ← temp, trans.newNode WHILE trans.old DO ENDLOOP;
temp.newNode ← trans;-- This avoids chasing pointers several times
END;


MakeNodeSegment: PROCEDURE[nodeNumber: NodeNumberType, left,right: REAL, trans:BOOLEAN ← FALSE]
RETURNS[nodeSegment: NodeSegment];

AllocateNodeSegment: PROCEDURE[trans: BOOLEAN] RETURNS[ns: NodeSegment];

FreeNodeSegment: PROCEDURE[nodeSegment: NodeSegment];

Combine: PROCEDURE[n1,n2: NodeSegment, layer: CARDINAL];

EqualToNodeNumber
: PROCEDURE[n,m: NodeNumberType] RETURNS[BOOLEAN] = INLINE
BEGIN
RETURN[ LOOPHOLE[n,LONG CARDINAL] = LOOPHOLE[m,LONG CARDINAL] ];
END;

LessThanNodeNumber
: PROCEDURE[n,m: NodeNumberType] RETURNS[BOOLEAN] = INLINE
BEGIN
RETURN[ LOOPHOLE[n,LONG CARDINAL] < LOOPHOLE[m,LONG CARDINAL] ];
END;

WriteNodeNumber
: PROCEDURE[n: NodeNumberType];

WriteNodeName
: PROCEDURE[n: NodeNumberType];

GetNodeNumber
: PROCEDURE [s: DiskHandle] RETURNS[x: NodeNumberType];

PutNodeNumber
: PROCEDURE [x: NodeNumberType, s: DiskHandle];

ConvertTransToText
: PROCEDURE [s:StreamHandle];

WriteLocation
: PROCEDURE[x,y: REAL, s:StreamHandle];

WriteCapacitor: PROCEDURE[n: NodeSegment, s:StreamHandle];

WriteNodeCap: PROCEDURE[n: NodeSegment, s:DiskHandle];

ReadCapacitor: PROCEDURE[s:DiskHandle, n: POINTER TO CapRecord];

EnterCapacitor: PROCEDURE[newNode: POINTER TO CapRecord];

WriteTransistor
: PROCEDURE[n: Transistor];

CorrectLabelNodes: PROCEDURE [name: STRING];

WriteNodeLocation: PROCEDURE[n: NodeNumberType, x,y: REAL, layer:CARDINAL];

WriteNodeLabel
: PROCEDURE[label: NodeLabel, n: NodeNumberType];

AllocateNodeLabel: PROCEDURE RETURNS[n: NodeLabel];

FreeNodeLabel
: PROCEDURE [n: NodeLabel];

PrintAllocation: PROCEDURE[force: BOOLEAN];

PrintTransistors: PROCEDURE;

WriteFloat: PROCEDURE[r: REAL];

SetErrorStream: PROCEDURE[p: BOOLEAN];

ResetErrorStream: PROCEDURE[];


END.