CDMEBES.mesa
Copyright © 1985 by Xerox Corporation. All rights reserved.
written by E. McCreight, November 2, 1983 6:03 pm
Last Edited by: Christian Jacobi, December 19, 1984 4:21:14 pm PST
Last Edited by: McCreight June 26, 1987 5:47:21 pm PDT
Hoel, February 27, 1986 11:19:49 am PST
McCreight, December 11, 1986 12:38:06 pm PST
A package to output a ChipnDale design in MEBES format for a Perkin-Elmer Lithographic System. Files produced herein should conform to the MEBES Mode I/II, extended mode, or reticle mode pattern file format described in the MEBES Software Manual, document A900-0102C, Data Files, document A900-0024D, publication of
Perkin-Elmer
Electron Beam Technology
3392 Investment Boulevard
Hayward, CA 94545
DIRECTORY
Atom, D2Basic, CD, CDSequencer, CStitching, IO, Rope;
CDMEBES: CEDAR DEFINITIONS =
BEGIN
Basic Types
This program, alas, uses several different units of measure.
One is the CD.Number, which is some fraction of the mythical Lambda. The CD.Number and the Lambda are related by a parameter in the CD.Technology. The ratio between a CD.number and a Nm can be set by the user.
Another is the Meter and the Nm (nanometer). These are related in the obvious way. The integer type Nm should be able to carry all measurements.
Another is the Tad. This is the smallest measuring quantum, in which every distance and position is expressible as an integer. The corner-stitched Tesselations that are passed among CoverProcs are expressed in Tads. At this writing there is no need for a Tad to be smaller than a Nm, but at some point.... The ratio between a Tad and a Nm can be set by the user.
And then there's the MEBESPixel. For reasonable people today, this is 1000 Nm or 500 Nm or 250 Nm, but the MEBES formats permit other sizes. The ratio between a MEBESPixel and a Nm can be set by the user.
Meters: TYPE = REAL;
Nm: TYPE = D2Basic.Number; -- nanometers
NmRect: TYPE = D2Basic.Rect;
NmPair: TYPE = D2Basic.Vector;
NmPosition: TYPE = D2Basic.Vector;
Tad: TYPE = D2Basic.Number; -- units smaller than nanometers
TadPair: TYPE = D2Basic.Vector;
TadPosition: TYPE = D2Basic.Vector;
TadRect: TYPE = D2Basic.Rect;
MEBESPixels: TYPE = D2Basic.Number; -- usually 500 or 200 nm
MEBESPosition: TYPE = D2Basic.Vector;
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,
interestingLayers: ARRAY CD.Layer OF BOOLALL[FALSE],
designClip: REF CD.Rect ← NIL,
ChipNDale Rect containing all design geometry
tadsPerNm: INT ← 1,
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 Tads and ChipNDale design units
mebesPixelPitch: Nm ← 500, -- for the current mask
mode: MEBESMode ← oneTwo,
drawCommand: REF DrawRectangle,
designStripeClip: CD.Rect ← [0,0,0,0],
tadStripeClip: TadRect ← [0,0,0,0],
stripe: [0..maxStripes] ← 1, -- 0 is illegal
stripeRectCount: INT ← 0,
maskSetName: ROPENIL,
patternFileNames: LIST OF ROPENIL, -- for the tape header
s: IO.STREAM,
EBES stream where rectangles are to be drawn
data: REFNIL
];
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: BOOLTRUE
];
CoverProc: TYPE = PROC [ ms: MaskState, spec: LIST OF REF ANY, extInfluenceDiameter: Tad ← 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;
segmentOrigin: CARDINAL = 1;
stripeOrigin: CARDINAL = 1;
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 CHARALL[' ]
];
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 ← 1 -- 0 is illegal
];
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 CHARALL[' ];
month [01..12], day [01..31], year [00..99]
PatternFileName: TYPE = PACKED ARRAY [0..12) OF CHARALL[' ];
[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;
defaultTadsPerNm: INT;
wDir: ROPE;
abortFlag: REF BOOL;
Central Procedures
StartMEBESMask: PROC [comm: CDSequencer.Command];
GenerateCover: PROC [ ms: MaskState, spec: CoverSpec, extInfluenceDiameter: Tad ← 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: TadPosition, explanation: ROPENIL, choice: LIST OF ROPENIL ] RETURNS [ chosen: NAT ];
... 0 for default, 1 for first choice, etc.
EBESOpen: PROC [ dest: IO.STREAM, eor: BOOLTRUE ] 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: REFNIL ] RETURNS [ tess: Tesselation ];
DisposeTesselation: PROC [ tess: Tesselation ] RETURNS [ Tesselation ];
ToRope: PROC [ ref: REF ] RETURNS [ rope: ROPE ];
RopeNeeded: SIGNAL [ ref: REF REF ];
ScaleCDToTad: PROC [ ms: MaskState, cdr: CD.Rect ] RETURNS [ tr: TadRect ];
ScaleTadToCD: PROC [ ms: MaskState, tr: TadRect ] RETURNS [ cdr: CD.Rect ];
ScaleRect: PROC [ r: D2Basic.Rect, factor: Rational ] RETURNS [ sr: D2Basic.Rect -- = factor*r -- ];
ScalePoint: PROC [ p: D2Basic.Vector, factor: Rational ] RETURNS [ sp: D2Basic.Vector -- = factor*r -- ];
Bloat: PROC [ r: TadRect, deltaDiameter: Tad ] RETURNS [ br: TadRect ];
TadTooLarge: ERROR; -- if deltaDiameter is not even
RatAdd, RatMul: PROC [ r1, r2: Rational ] RETURNS [ Rational ];
RatNeg, RatInv, ReduceRational: PROC [ r: Rational ] RETURNS [ Rational ];
Ceiling: PROC [ r: Rational ] RETURNS [ c: INT ];
GCD: PROC [ m, n: INT ] RETURNS [ INT ];
END. -- of CDMEBES