CDMEBES.mesa
Copyright © 1985 by Xerox Corporation. All rights reserved.
written by E. McCreight, November 2, 1983 6:03 pm
Last Edited by: Jacobi, December 19, 1984 4:21:14 pm PST
Hoel, February 27, 1986 11:19:49 am PST
McCreight, June 26, 1986 1:53:59 pm PDT
CDMEBES:
CEDAR
DEFINITIONS =
BEGIN
Basic Types
Nm: TYPE = D2Basic.Number;
NmPair: TYPE = D2Basic.Pos;
NmPosition: TYPE = D2Basic.Pos;
NmRect: TYPE = D2Basic.Rect;
Meters: TYPE = REAL;
MEBESPixels: TYPE = D2Basic.Number;
MEBESPosition: TYPE = D2Basic.Pos;
MEBESRect: TYPE = D2Basic.Rect;
Rational: TYPE = RECORD [num, denom: INT ← 1];
ROPE: TYPE = Rope.ROPE;
Tesselation: TYPE = CStitching.Tesselation;
TessList: TYPE = LIST OF Tesselation;
Sense: TYPE = {space, cover};
MEBESMode: TYPE = {oneTwo, extended, reticle}; -- see the Perkin-Elmer spec
Maskmaking State Record
MaskState: TYPE = REF MaskStateRec;
MaskStateRec:
TYPE =
RECORD [
design: CD.Design,
designClip:
REF
CD.Rect ←
NIL,
ChipNDale Rect containing all design geometry
nmPerLambda: INT ← 1000,
nmReticleClip: NmRect ← [0,0,0,0],
the final reticle. Its center is (the scaled center of designClip) - dieOffset.
dieOffset: NmPosition ← [0,0],
dropInList: LIST OF REF ANY -- DropIn -- ← NIL,
viewerArrow: CD.Position ← [0,0],
toolingSpec: ToolingSpec ← NIL,
derivationSpec: DerivationSpec ← NIL,
curMask: DerivationMaskSpec ← NIL, -- for the current mask
scale: Rational, -- relating MEBES pixels and ChipNDale design units
mebesPixelPitch: Nm ← 500, -- for the current mask
mode: MEBESMode ← oneTwo,
drawCommand: REF DrawRectangle,
designStripeClip: CD.Rect ← [0,0,0,0],
mebesStripeClip: MEBESRect ← [0,0,0,0],
stripe: [0..maxStripes] ← 0,
stripeRectCount: INT ← 0,
maskSetName: ROPE ← NIL,
patternFileNames: LIST OF ROPE ← NIL, -- for the tape header
s:
IO.
STREAM,
EBES stream where rectangles are to be drawn
data: REF ← NIL
];
Mask Set Specifications
ToolingSpec: TYPE = Atom.PropList -- .vals are ToolingMaskSpec's -- ;
ToolingMaskSpec: TYPE = REF ToolingMaskSpecRec;
ToolingPolarity: TYPE = {CL -- clear field --, DK -- dark field --};
ToolingMaskSpecRec: TYPE = RECORD [ maskNo: ROPE, fieldPolarity: ToolingPolarity, addrUnit, skewPerSide, scribeWidth, scribeOffset: Nm, mode: MEBESMode ← reticle ];
DerivationSpec: TYPE = LIST OF REF ANY -- MaskSpec -- ;
DerivationMaskSpec: TYPE = REF DerivationMaskSpecRec;
DerivationMaskSpecRec: TYPE = RECORD [ maskId: ATOM, cover: CoverSpec, props: Atom.PropList ← NIL];
Cover Specifications (which points on the mask are covered)
CoverSpec:
TYPE =
REF
ANY;
A CoverSpec is a LIST OF REF ANY, or a CDLayer. If it is a LIST OF REF ANY, it must be among the following forms:
LIST[ $NOT, CoverSpec ]
LIST[ $AND, CoverSpec1, CoverSpec2, ... ]
LIST[ $ANDNOT, CoverSpec1, CoverSpec2 ]
LIST[ $OR, CoverSpec1, CoverSpec2, ... ]
LIST[ $Enlarge, NEW[Nm ← x], CoverSpec ]
.. This enlarges the diameter of every feature in CoverSpec1 by x nm. If x is negative, this enlarges the diameter of every space in CoverSpec1 by -x nm.
LIST[ $RestrictedEnlarge, NEW[Nm ← x], CoverSpec1, CoverSpec2 ]
.. x>0. This enlarges the radius of every feature in CoverSpec1 by the smaller of x/2 nm and half the distance to the nearest feature in CoverSpec2.
LIST[ $DeNotch, NEW[Nm ← x], CoverSpec ]
.. x>0. This covers any space in CoverSpec whose smaller dimension is no larger than x.
LIST[ $SizeLEq, NEW[Nm ← width], NEW[Nm ← height], CoverSpec ]
This filters the features of CoverSpec, keeping only rectangles no larger than width x height, while discarding non-rectangular features and (rectangular) features larger than width x height.
LIST[ $MeasureRuns, "Description ROPE", CoverSpec, NEW[Nm ← coverHorizon], NEW[Nm ← coverMinFeature], NEW[Nm ← spaceHorizon], NEW[Nm ← spaceMinFeature] ]
.. This is executed for its side effects. It looks for too-small features and spaces, and it hangs a structure on ms.data that is later printed in the log, showing how many micrometers of various-width features and space were found.
... for example, LIST[$OR, NEW[CDLayerRec ← [source: %CMos.ndif, deltaDiameter: 1000 -- nm --]], NEW[CDLayerRec ← [source: %CMos.pdif, deltaDiameter: 1000 -- nm --]], NEW[CDLayerRec ← [source: %CMos.pwelCont, deltaDiameter: 1000 -- nm --]], NEW[CDLayerRec ← [source: %CMos.nwelCont, deltaDiameter: 1000 -- nm --]]]]
CDLayer: TYPE = REF CDLayerRec ← NIL;
CDLayerRec:
TYPE =
RECORD [
source: CD.Layer,
deltaDiameter: Nm ← 0 -- + means mask feature is bigger than CD.Layer feature
];
DropIn: TYPE = REF DropInRec ← NIL;
DropInRec:
TYPE =
RECORD [
name: ATOM,
fileNamePattern: ROPE, -- pattern for IO.PutF
pos: NmPosition,
clearBackground: BOOL ← TRUE
];
CoverProc:
TYPE =
PROC [ ms: MaskState, spec:
LIST
OF
REF
ANY, extInfluenceDiameter: Nm ← 0 ]
RETURNS [ result: Tesselation ];
MEBES Command Formats
bytesPerMebesWord: INT = 2;
mebesBlockSize: INT = 2048; -- bytes
stripeHeight: INT = 256; -- in EBES units
maxStripes: INT = 255;
maskHeight: INT = maxStripes*stripeHeight;
maskWidth: INT = 32768;
Mode12StartDrawing:
TYPE =
MACHINE
DEPENDENT
RECORD [
nFields (0: 0..7): [0..256) ← 2,
addressCode (0: 8..15): Mode12AddressCode ← Nm500,
cx (1): CARDINAL[0..maskWidth], -- 0 is illegal
cy (2): CARDINAL[0..maskHeight], -- 0 is illegal
moDayYr (3): Date,
field1Size (6): CARDINAL ← 6,
patternFileName (7): PatternFileName,
field2Size (13): CARDINAL ← 2,
maskInfo (14): PACKED ARRAY [0..4) OF CHAR ← ALL[' ]
];
Mode12AddressCode: TYPE = MACHINE DEPENDENT {Nm500(3), Nm250(6)};
Mode12StartStripe:
TYPE =
MACHINE
DEPENDENT
RECORD [
stripeNumber (0: 0..7): [0..maxStripes] ← 1, -- 0 is illegal
commandCode (0: 8..15): [0..256) ← 7];
ExtAddrModeStartDrawing:
TYPE =
MACHINE
DEPENDENT
RECORD [
nFields (0: 0..7): [0..256) ← 2,
commandCode (0: 8..15): [0..256) ← 5,
addrUnitHigh (1): CARDINAL, -- expressed as multiple of 2^-28 micrometer
addrUnitLow (2): CARDINAL,
stripeHeight (3): CARDINAL ← 256, -- stripe height in address units
cxHigh (4): CARDINAL ← 0, -- horizontal pattern size in address units
cxLow (5): CARDINAL,
cyHigh (6): CARDINAL ← 0, -- vertical pattern size in address units
cyLow (7): CARDINAL,
moDayYr (8): Date,
field1Size (11): CARDINAL ← 6,
patternFileName (12): PatternFileName,
field2Size (18): CARDINAL ← 1 -- +2*#reticle segments
patternFileBlockCount: CARDINAL ← 0, -- fill in after generation
segment1: SegDirectoryEntry,
segment2: SegDirectoryEntry, -- and so on ...
];
SegDirectoryEntry:
TYPE =
MACHINE
DEPENDENT
RECORD [
firstBlock (0): CARDINAL ← 1, -- 0 is illegal, block containing start drawing header is 1
firstWordWithinBlock (1): [0..1024] ← 1 -- 0 is illegal
];
ExtAddrModeStartStripe:
TYPE =
MACHINE
DEPENDENT
RECORD [
commandCode (0): CARDINAL ← 2,
stripeNumber (1): CARDINAL ← 0
];
StartSegment:
TYPE =
MACHINE
DEPENDENT
RECORD [
segmentNumber (0: 0..7): [0..256) ← 1, -- 0 is illegal
commandCode (0: 8..15): [0..256) ← 10];
Date:
TYPE =
PACKED
ARRAY [0..6)
OF
CHAR ←
ALL[' ];
month [01..12], day [01..31], year [00..99]
PatternFileName:
TYPE =
PACKED
ARRAY [0..12)
OF
CHAR ←
ALL[' ];
[9] must be '. , [10] is column ['A..'Z], [11] is row ['A..'Z]
DrawRectangle:
TYPE =
MACHINE
DEPENDENT
RECORD [
h (0: 0..9): [1..stripeHeight], -- Mesa biases subrange so 1 is represented as 0
commandCode (0: 10..15): [0..64) ← 16,
w (1): CARDINAL[0..maskWidth], -- 0 is illegal
x (2): CARDINAL[0..maskWidth),
unused (3: 0..7): [0..256) ← 0,
y (3: 8..15): [0..stripeHeight)];
DrawTrapezoid:
TYPE =
MACHINE
DEPENDENT
RECORD [
h (0: 0..9): [1..stripeHeight], -- Mesa biases subrange so 1 is represented as 0
commandCode (0: 10..15): [0..64) ← 20,
wLow (1): CARDINAL, -- w=0 is illegal
x1Low (2): CARDINAL,
deltaX2High (3: 0..5): [0..64),
y1 (3: 6..15): [0..1024),
deltaX1Low (4): CARDINAL,
deltaX2Low (5): CARDINAL,
deltaX1High (6: 0..5): [0..64),
x1High (6: 6..10): [0..32),
wHigh (6:11..15): [0..32)
];
BasicCommand: TYPE = MACHINE DEPENDENT RECORD [commandCode (0): NAT ←];
endStripe: BasicCommand = [commandCode: 8];
endRecord: BasicCommand = [commandCode: 9];
endDrawing: BasicCommand = [commandCode: 4];
Global Variables
stripesPerClump: INT;
wDir: ROPE;
abortFlag: REF BOOL;
Central Procedures
StartMEBESMask: PROC [comm: CDSequencer.Command];
GenerateCover: PROC [ ms: MaskState, spec: CoverSpec, extInfluenceDiameter: Nm ← 0 ] RETURNS [ rects: Tesselation ];
DrawLayersWithPosDeltas: PROC [ms: MaskState, rects: Tesselation, layers: LIST OF CDLayer, extInfluenceDiameter: Nm ← 0];
SendCommand: PROC [ s: IO.STREAM, comm: REF ]; -- for sending geometry to a MEBES file
Utility Procedures
InsertDropIn: PROC [ ms: MaskState, rects: Tesselation, di: DropIn, data: REF ] RETURNS [ newData: REF ]; -- either insert in rects or output directly to ms.s
ComplainAt:
PROC [ ms: MaskState, pos: MEBESPosition, explanation:
ROPE ←
NIL, choice:
LIST
OF
ROPE ←
NIL ]
RETURNS [ chosen:
NAT ];
... 0 for default, 1 for first choice, etc.
EBESOpen:
PROC [ dest:
IO.
STREAM, eor:
BOOL ←
TRUE ]
RETURNS [ self:
IO.
STREAM ];
opens a layered stream with 2048-byte records, padded with nulls, where MEBES items do not cross record boundaries
NewTesselation: PROC [ initValue: REF ← NIL ] RETURNS [ tess: Tesselation ];
DisposeTesselation: PROC [ tess: Tesselation ] RETURNS [ Tesselation ];
ToRope:
PROC [ ref:
REF ]
RETURNS [ rope:
ROPE ];
RopeNeeded: SIGNAL [ ref: REF REF ];
ScaleCDToEBES: PROC [ ms: MaskState, cdr: CD.Rect ] RETURNS [ mr: MEBESRect ];
ScaleEBESToCD: PROC [ ms: MaskState, mr: MEBESRect ] RETURNS [ cdr: CD.Rect ];
ScaleRect: PROC [ r: D2Basic.Rect, factor: Rational ] RETURNS [ sr: D2Basic.Rect -- = factor*r -- ];
ScalePoint: PROC [ p: D2Basic.Pos, factor: Rational ] RETURNS [ sp: D2Basic.Pos -- = factor*r -- ];
Bloat: PROC [ r: D2Basic.Rect, deltaDiameter: D2Basic.Number ] RETURNS [ br: D2Basic.Rect ];
ReduceRational: PROC [ r: Rational ] RETURNS [ Rational ];
Ceiling: PROC [ r: Rational ] RETURNS [ c: INT ];
GCD: PROC [ m, n: INT ] RETURNS [ INT ];
END. -- of CDMEBES