<> <> <> <> <<>> <
> DIRECTORY D2Basic USING [Number, Rect, Vector], D2Orient USING [Orientation, Transformation], Imager USING [Color, Context], Properties USING [PropList], RefTab USING [Ref], Rope USING [ROPE], SymTab USING [Ref], TokenIO USING [Handle]; CD: CEDAR DEFINITIONS = BEGIN <<-- Measuring>> Number: TYPE = D2Basic.Number; Position: TYPE = D2Basic.Vector; <<-- RECORD [x, y: Number];>> Rect: TYPE = D2Basic.Rect; <<-- RECORD [x1, y1, x2, y2: Number];>> <<-- A Rect is called normalized if (x1>x2) OR (y1>y2) means that the Rect is empty.>> <<-- Rects are normalized, except if an explicite comment denies. >> <<-- Rect's are closed: they include all the endpoints; as you expect, points have >> <<-- size 0.>> Orientation: TYPE = D2Orient.Orientation; <<-- MACHINE DEPENDENT {original(0), mirrorX(1), rotate90(2), rotate90X(3), >> <<-- rotate180(4), rotate180X(5), rotate270(6), rotate270X(7)};>> <<-- An orientation represents an anticlockwise rotation maybe followed by a reflection in x. >> <<-- [Reflection in x means: modify x coordinates, leave y coordinates]>> mirrorY: Orientation = rotate180X; Transformation: TYPE = D2Orient.Transformation; <<-- RECORD [off: D2Basic.Vector _ [0, 0], orient: Orientation _ original];>> <<-- A transformation represents an orientation followed by a translation. >> <<>> <<>> <<-- Errors>> Error: ERROR [ec: ErrorCode _ programming, explanation: Rope.ROPE _ NIL]; ErrorCode: TYPE = {programming, calling, noResource, doubleRegistration, missingRegistration, directoryInvariant, objectMutability, designMutability, classBehaviour, other}; <<>> <<-- Properties>> PropList: TYPE = Properties.PropList; <<-- Friendly use expected: don't assign properties without first registering their names >> <<-- with CDProperties.>> <<-- Use only CDProperties to modify ChipNDale PropList; never Properties directly>> <<-- to avoid problems with unmonitored concurrency. >> PropRef: TYPE = REF PropList _ ; --ABSOLUTELY NEVER NIL InitPropRef: PROC [] RETURNS [PropRef] = INLINE { <<-- Initialization for variables of type PropRef>> RETURN [NEW[PropList_NIL]] }; <<>> <<>> <<-- Layers>> layerNum: NAT = 256; Layer: TYPE = [0..layerNum); undefLayer: Layer = 0; -- Used for object containing different or unknown Layers shadeLayer: Layer = 1; -- Visualization; not for generating masks errorLayer: Layer = 2; -- Real layer reserved for error messages; rarely for generating masks backgroundLayer: Layer = 3; -- Special pushed-in backGround; not for generating masks outlineLayer: Layer = 4; -- Special color for outline; not for generating masks selectionLayer: Layer = 5;-- Special color for selection; not for generating masks commentLayer: Layer = 6;-- Real layer; may or may not be used by technologies NewLayer: PROC [technology: Technology, uniqueKey: ATOM] RETURNS [Layer]; <<-- Creates a new layer for technology>> <<-- May raise Error[noResource]>> <<-- The technolgy implementation must guarantee for uniqueness of uniqueKey's>> <<-- (unique only inside the technology)>> FetchLayer: PROC [t: Technology, uniqueKey: ATOM] RETURNS [Layer]; <<-- Returns a layer given a technology and an unique layer key>> <<-- May also return technology independent layers>> LayerTechnology: PROC [l: Layer] RETURNS [Technology]; <<-- Returns the technology of the layer, or, NIL if layer is technology independent>> LayerKey: PROC [l: Layer] RETURNS [ATOM]; <<-- Returns the technology specific unique key of the layer>> <<--Object, cells, instances>> Object: TYPE = REF ObjectRep; <<-- Objects are the main things in ChipNDale>> <<-- Objects must draw the same way independant of their environment>> <<-- Several different instances may use the same object! >> <<>> ObjectRep: TYPE = RECORD [--read-only except for class implementor class: ObjectClass, <<-- Clients: never modify class nor class^>> <<-- Be aware: Asynchrounous redrawing may be in progress>> bbox: Rect _ [0, 0, 2, 2], <<-- Maximal area drawn in DrawProcs, not electrical influence.>> <<-- Used for all graphical pruning purposes.>> layer: Layer _ undefLayer, immutable: BOOL _ FALSE, <<-- Readonly, even to object class!>> <<-- immutable being false does not mean the object can be changed: an object can be >> <<-- changed only if it is mutable, and, it is accessed in a way which allows changes.>> <<-- An immutable object must not have any mutable children.>> <<-- Once immutable, an object can not be made mutable again; but if read from a file,>> <<-- the new copy probably will be mutable.>> showErrors: BOOL _ FALSE, <<-- Owned by the error displaying module, not the class!>> reservedO: BOOL _ FALSE, <<-- Owned by ChipNDale's implementation [experimental]>> specific: REF ANY _ NIL, <<-- Owned by object class>> properties: PropList _ NIL <<-- Usage of properties of immutable Objects is restricted to object class implentors or>> <<-- users which provide unique property keys. >> ]; InstanceSequence: TYPE = REF InstanceSequenceRep; InstanceSequenceRep: TYPE = RECORD [length: NAT_0, elts: SEQUENCE size: NAT OF CD.Instance]; CellSpecific: TYPE = REF CellRep; CellRep: TYPE = RECORD [ contents: InstanceList _ NIL, <<-- Used for extras/large/pushed-in cells>> sequence: InstanceSequence _ NIL, <<-- Reduces memory access compared to list>> ir: Rect _ [0, 0, -1, -1], <<-- Interest rect>> simplifyOn: REAL _ LAST[NAT], <<-- A treshold for simplification on quickdraw>> drawBorder: BOOL _ FALSE, <<-- Border should be drawn >> changed: BOOL _ FALSE, <<-- Cell changed since push [not IO]>> specifiedIr: BOOL _ FALSE, <<-- Interest rect is explicitelly specified [not defaulted]>> dummyCell: --READONLY-- BOOL _ FALSE, <<-- Used in push stack of a design>> <<-- If set, inhibits use of sequence, assures mutable>> reserved1: BOOL _ FALSE, -- for experiments reserved2: BOOL _ FALSE -- for experiments ]; RectSpecific: TYPE = REF RectRep; RectRep: TYPE = RECORD [filler: PRIVATE REF]; InstanceList: TYPE = LIST OF Instance _ NIL; Instance: TYPE = REF InstanceRep; InstanceRep: TYPE = RECORD [ ob: Object, trans: Transformation _ [], selected: BOOL _ FALSE, <<-- Meaningfull for instances of pushed in cells only>> reservedI: BOOL _ FALSE, -- for experiments properties: PropList _ NIL ]; ObjectClass: TYPE = REF ObjectClassRec; ObjectClassRec: TYPE = RECORD [ -- generic class procedures for an object quickDrawMe: DrawProc _ NIL, <<-- An optimized draw procedure for viewers.>> drawMe: DrawProc _ NIL, <<-- Drawing the object into an abstract device.>> <<-- Children objects returned by drawMe must never be muted unless mutability >> <<-- is guaranteed using other means [immuable bit is NOT sufficient]. >> <<-- The draw procs defines the truth. >> showMeSelected: DrawProc _ NIL, <<-- Showing the selection [for top level only].>> hitInside: HitInsideProc _ NIL, <<-- For fine grain selection.>> interestRect: RectProc _ NIL, <<-- The boundary the designer likes to think about. >> <<-- The objects bounding box includes the interestRect. >> technology: Technology _ NIL, <<-- Or NIL for technology independent classes>> objectType: ATOM _ NIL, <<-- registration key>> composed: BOOL _ FALSE, << -- Objects which have children must be composed !>> << -- Only composed classes can have mutable objects; if class is not composed >> << -- objects are supposed immutable. >> << -- Composed classes have more invariants and class procedures in CDDirectory. >> directoryProcs: REF _ NIL, <<-- More class procedures for composed classes>> <<-- Field reserved for CDDirectory>> wireTyped: BOOL _ FALSE, <<-- Allows ChipNDale to stretch object in a certain way>> <<-- If wireTyped then [interestRect] y corresponds to the length>> atomicOb: BOOL _ FALSE, <<-- Creation using CDAtomicObjects class.>> <<-- A particular subset of non composed classes.>> symbolic: BOOL _ FALSE, <<-- Object used for interface specification; no mask>> xDesign: BOOL _ FALSE, <<-- Class allows children of composed classes across designs>> supressTruth: BOOL _ FALSE, <<-- Dont write objects of this class to permanent files in truth mode [expand object]>> showsErrors: BOOL _ FALSE, <<-- Tells whether drawMe's deal with error messages.>> <<-- Set by class, read by error message handling package.>> reservedC: BOOL _ FALSE, <<-- For experiments of ChipNDale itself>> describesSignal: BOOL _ FALSE, <<-- Hint that describe tells already about the SignalName >> description: Rope.ROPE _ NIL, <<-- Shortcut for NIL describe procs>> describe: DescribeProc _ NIL, <<-- Describes object, but description does not need to include name >> newLayer: ChangeLayerProc _ NIL, <<-- Used by some simple non-composed classes only>> internalWrite: InternalWriteProc _ NIL, internalRead: InternalReadProc _ NIL, parent: ObjectClass _ NIL, <<-- For subclassing purposes>> properties: PropRef _ NIL <<-- Used by ChipNDale, class, and clients>> ]; DrawProc: TYPE = PROC [pr: CD.DrawRef, ob: CD.Object, trans: CD.Transformation_[], readOnlyInstProps: CD.PropList_NIL]; HitInsideProc: TYPE = PROC [ob: CD.Object, hitRect: CD.Rect] RETURNS [BOOL]; RectProc: TYPE = PROC [ob: CD.Object] RETURNS [CD.Rect]; InternalWriteProc: TYPE = PROC [h: TokenIO.Handle, ob: CD.Object]; InternalReadProc: TYPE = PROC [h: TokenIO.Handle, key: ATOM] RETURNS [CD.Object]; DescribeProc: TYPE = PROC [ob: CD.Object, readOnlyInstProps: CD.PropList_NIL, verbosity: NAT_0] RETURNS [Rope.ROPE]; ChangeLayerProc: TYPE = PROC [inst: CD.Instance, layer: CD.Layer] RETURNS [BOOL_TRUE]; DrawContextProc: TYPE = PROC [pr: CD.DrawRef, proc: CD.DrawContextLayerProc, ob: CD.Object, trans: CD.Transformation, layer: CD.Layer]; <<-- Object classes which uses DrawContextProc must guarantee >> <<-- ob#NIL >> <<-- ob.bbox fits in [-NAT.LAST/2, -NAT.LAST/2, NAT.LAST/2, NAT.LAST/2] >> DrawContextLayerProc: TYPE = PROC [context: Imager.Context, ob: CD.Object, layer: CD.Layer]; RegisterObjectClass: PROC [objectType: ATOM, class: ObjectClassRec, inherit: REF_NIL] RETURNS [ObjectClass]; <<-- Registers an object class; initializes procedures with default values.>> <<-- May raise Error[doubleRegistration] and others>> <<-- An object type may be used either in arbitrary technology or technology-independent.>> <<-- This should be the only way to create data of type ObjectProcsRec>> <<-- inherit: objectType ATOM or class; overwrites class.parent>> <<-->> <<-- Think twice before implementing object classes outside the ChipNDale implementation.>> <<-- In general this is not a good idea and will introduce long living data and maintenance>> <<-- problems.>> FetchObjectClass: PROC [objectType: REF, technology: Technology_NIL] RETURNS [--readonly-- ObjectClass]; <<-- Returns registration of object class; NIL if not found>> <<-- Consider ObjectClass as readonly if you are not the implementor of the object class. >> <<-- Design>> PushRec: TYPE = RECORD [ dummyCell: Instance, <<-- An instance of a cell describing the current state of the pushed in cell. >> <<-- Originally a copy of mightReplace; dummyCell.ob is not included in the directory. >> <<-- Sub instances of cell are mapped to design coordinates. >> <<-- bbox of cell object may be wrong. >> mightReplace: Instance _ NIL, <<-- The original instance into which the design is pushed in. >> <<-- mightReplace is in the coordinate system of the next outer dummyCell. >> <<-- and is removed from [the next outer dummyCell's] instance list. >> <<-- Sub instances of mightReplace.ob are in cd coordinate system of the object >> <<-- May be NIL for top level>> desc: Rope.ROPE, <<-- Description of object pushed in>> specific: CellSpecific <<-- Cache of dummyCell.ob.specific>> ]; Design: TYPE = REF DesignRec; DesignRec: TYPE = RECORD [ <<-- Use only CDOps.CreateDesign to create DesignRec records>> <<-- Use CDValue or CDProperties for more fields >> <<-- Use CDSequencer to synchronize multi treaded access to designs>> actual: LIST OF PushRec, <<-- Stack of pushed in cells >> <<-- actual.first describes most deeply pushed in object >> name: Rope.ROPE _ NIL, <<-- Treat readonly ! [internal invariants]>> technology: Technology _ NIL, <<-- treat readonly >> properties: PropRef _ , <<-- Use CDProperties>> edited: BOOL _ FALSE, <<-- Treat readonly ! [internal invariants]>> mutability: Mutability _ findOut, <<-- Treat readonly ! Write only by CDSequencer>> changedSinceSaving: BOOL _ FALSE, <<-- Treat readonly ! [internal invariants]>> cdDirectory1: PRIVATE SymTab.Ref_NIL, <<-- Used by CDDirectory for directory>> cdDirectory2: PRIVATE RefTab.Ref_NIL, <<-- Used by CDDirectory for directory>> cdDirectoryPriv2: PRIVATE REF, <<-- Used by CDDirectory for ownership keys>> cdValuePriv: PRIVATE PrivateValueDRef _ NIL, <<-- Reserved for CDValue>> cdSequencerPriv: PRIVATE PrivateSequencerDRef, <<-- Reserved for CDSequencer>> cdDrawQueuePriv: PRIVATE REF _ NIL, <<-- Reserved for CDDrawQueue>> delayedRedrawsPriv: PRIVATE REF _ NIL, <<-- Reserved for single module>> unDoBuffers: PropRef _, <<-- It is ok to use InitPropRef to disable undos>> reservedD: PRIVATE REF _ NIL <<-- Reserved for ChipNDale experiments>> ]; PrivateSequencerDRef: TYPE = REF PrivateSequencerDRep; PrivateSequencerDRep: TYPE; PrivateValueDRef: TYPE = REF PrivateValueDRep; PrivateValueDRep: TYPE; Mutability: TYPE = {findOut, editable, inaccessible, readonly} _ findOut; <<--Mutability, defined to be useful for designs.>> <<-- findOut: mutability not yet defined.>> <<-- editable: design or its objects can be edited, but only if the designs lock is hold.>> <<-- inaccessible: this path inhibits any edits on the design, but does not guarantee>> <<-- that there is no other way some other process performs edits. >> <<-- readonly: No changes in design are made. >> <<--If a design is not editable this does not mean complete immutability:>> <<-- Top level instances may be made for visualization.>> <<-- Objects may but do not need to have the immutable flag.>> <<-- Objects accessed accross design boundaries may change.>> <<-- Technology>> <<>> Technology: TYPE = REF TechnologyRep; TechnologyRep: TYPE = RECORD [ <<-- use RegisterTechnology to create TechnologyRep record>> <<-- all fields except properties read only>> <<-- use CDValue or CDProperties for more fields >> key: ATOM _ NIL, name: Rope.ROPE _ NIL, lambda: CD.Number _ , usedLayers: LIST OF Layer, <<-- List of technology dependent Layers>> properties: PropRef _ , cdPriv: PRIVATE PrivateTRef, <<-- Reserved for CDImpl>> cdValuePriv: PRIVATE PrivateValueTRef, <<-- Reserved for CDValue>> cdSequencerPriv: PRIVATE PrivateSequencerTRef, <<-- Reserved for CDSequencer>> reservedCDSimpleRules: PRIVATE REF _ NIL, <<-- Reserved for CDSimpleRules>> reservedT: PRIVATE REF _ NIL <<-- Reserved for experiments>> ]; PrivateSequencerTRef: TYPE = REF PrivateSequencerTRep; PrivateSequencerTRep: TYPE; PrivateValueTRef: TYPE = REF PrivateValueTRep; PrivateValueTRep: TYPE; PrivateTRef: TYPE = PRIVATE REF PrivateTRep; PrivateTRep: TYPE; RegisterTechnology: PROC [key: ATOM, name: Rope.ROPE _ NIL, lambda: CD.Number _ 2] RETURNS [Technology]; <<-- This must be the only way to create data of type TechnologyRep>> <<-- May raise Error[doubleRegistration] and others>> FetchTechnology: PROC [key: ATOM] RETURNS [Technology]; <<-- NIL if not found>> EnumerateTechnologies: PROC [proc: TechnologyEnumerator] RETURNS [quit: BOOL]; TechnologyEnumerator: TYPE = PROC [tech: CD.Technology] RETURNS [quit: BOOL_FALSE]; <<>> <<-- Drawing>> <<-- The drawing process involves three actors:>> <<-- The object class provides drawing object specific features.>> <<-- The abstract device provides rendering procedures. >> <<-- ChipNDale itself provides some default procedures and the ground rules >> <<-- how the device and the object class must communicate. >> <<-- The drawing defines the truth of ChipNDale objects. >> DrawRef: TYPE = REF DrawInformation; --this describes an abstract device to draw objects into DrawInformation: TYPE = RECORD [ interestClip: Rect _ [Number.FIRST/2, Number.FIRST/2, Number.LAST/2, Number.LAST/2], <<-- interest area; not device area! >> <<-- might be slightly larger than device area, such that >> <<-- every feature visible in device area can be gotten with pruning to interest area,>> <<-- small enough, such that >> <<-- conversion from cd numbers to device numbers does not cause arithmetic overflow >> drawChild: DrawProc _ NIL, -- drawing and recursing drawRect: DrawRectProc _ NIL, -- coordinates in cd numbers stopFlag: REF BOOL _ NIL, -- setting stopFlag^ to true stops drawing drawOutLine: DrawRectProc _ NIL, -- visualization only; not for generating masks drawContext: DrawContextProc _ NIL, -- drawing into an imager context drawComment: DrawCommentProc _ NIL, -- visualization only; not for generating masks drawChildSel: DrawProc _ NIL, -- drawing of selection of child setGround: SetGroundProc _ NIL, priorityChecker: CheckPriorityProc _ NIL, --usually no-op scaleHint: REAL _ 0, -- to monitor simplifications; 0 means no simplifications environment: BOOL _ TRUE, -- draw the outside of pushed in cells symbolics: BOOL _ TRUE, -- draw symbolic objects selections: BOOL _ TRUE, -- draw selections showErrors: BOOL _ TRUE, -- draw error messages fontSubstitution: BOOL _ FALSE, -- usually FALSE; device may replace fonts checkPriority: BOOL _ FALSE, -- usually FALSE; priority of running process borders: BOOL _ FALSE, -- visualization only; not for generating masks b4: BOOL _ TRUE, -- reserved for experiments b5: BOOL _ TRUE, -- reserved for experiments devicePrivate: REF _ NIL, -- differentiate among multiple (viewers) with same drawProc's viewerPrivate: ViewerPrivate _ NIL, -- speed up for viewers devicePrivate deviceContext: Imager.Context _ NIL, -- may or may not be used contextFilter: REF ContextFilter _ NIL, -- (default uses filter only if deviceContext=NIL) contextColors: REF ContextColors _ NIL,-- (default uses colors only if deviceContext#NIL) design: Design _ NIL, <<-- Optional in general, but might be required by some devices.>> <<-- Object classes must not assume that drawn objects are included in this design.>> <<-- Class: Need not be maintained by drawing over design boundaries.>> properties: PropRef _ NIL ]; <<-- use CreateDrawRef for creation of DrawInformation record, unless all fields are set. >> ViewerPrivate: TYPE = REF ViewerPrivateRep; ViewerPrivateRep: TYPE; DrawRectProc: TYPE = PROC [pr: CD.DrawRef, r: CD.Rect, l: CD.Layer]; DrawCommentProc: TYPE = PROC [pr: CD.DrawRef, r: CD.Rect, comment: Rope.ROPE]; SetGroundProc: TYPE = PROC [pr: CD.DrawRef, pushedOut: BOOL]; CheckPriorityProc: TYPE = PROC [pr: CD.DrawRef]; ContextFilter: TYPE = PACKED ARRAY Layer OF BOOL _ ALL[TRUE]; <<-- A TRUE entry means the layer is visible>> ContextColors: TYPE = ARRAY Layer OF Imager.Color _ ALL[NIL]; <<-- A NIL color entry means the layer is invisible>> CreateDrawRef: PROC [inf: DrawInformation] RETURNS [DrawRef]; <<-- Creates an abstract device and assigns usefull default procedures and values.>> <<-- Vanilla procedures>> Describe: PROC [ob: Object, readOnlyInstProps: PropList_NIL, design: CD.Design_NIL, verbosity: NAT_1] RETURNS [Rope.ROPE]; <<-- Returns description of an object>> <<-- design: Its ok to ommit design for this procedure, but then name can't be included>> <<-- readOnlyInstProps: some object classes need to access instance properties for good description>> <<-- verbosity: degree of detail requested; 0 very short; 1 typical interaction >1 particular interest>> DrawOb: PROC [pr: DrawRef, ob: CD.Object, trans: Transformation_[], readOnlyInstProps: PropList_NIL] = INLINE { <<-- Calls the draw procedure; This defines the truth about objects!>> <<-- Drawn sub objects may be not accessible without having immuable flag set.>> ob.class.drawMe[pr, ob, trans, readOnlyInstProps] }; InterestRect: PROC [ob: Object] RETURNS [r: Rect] = INLINE { <<-- Returns the interest rect of the object.>> RETURN [ob.class.interestRect[ob]] }; InterestBase: PROC [ob: Object] RETURNS [sz: Position] = INLINE { <<-- Returns the base of the interest rect. >> r: Rect = ob.class.interestRect[ob]; RETURN [[r.x1, r.y1]]; }; InterestSize: PROC [ob: Object] RETURNS [sz: Position] = INLINE { <<-- Returns the size of the interest rect. >> r: Rect = ob.class.interestRect[ob]; RETURN [[r.x2-r.x1, r.y2-r.y1]]; }; DesignName: PROC [design: Design_NIL] RETURNS [Rope.ROPE]; <<-- Returns a name for a design [never returns a NIL ROPE]. >> END.