CD.mesa
Copyright © 1983, 1986 by Xerox Corporation. All rights reserved.
Created by: Christian Jacobi, June 24, 1983 3:54 pm
Last edited by: Christian Jacobi, October 28, 1986 6:23:43 pm PST
Main definitions for ChipNDale, a VLSI design editor and database.
DIRECTORY
D2Basic USING [Number, Rect, Vector],
D2Orient USING [Orientation, Transformation],
Imager USING [Color, Context],
PropertyLists USING [PropList],
Rope USING [ROPE],
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 ← programmingError, explanation: Rope.ROPE ← NIL];
ErrorCode: TYPE = {programmingError, callingError, noResource, doubleRegistration, missingRegistration, other};
-- Properties
PropList:
TYPE = PropertyLists.PropList;
-- Friendly use expected: don't assign properties without first registering
-- their names with CDProperties.
-- Use only CDProperties to modify ChipNDale PropList; NOT PropertyLists
PropRef:
TYPE =
REF PropList ← ;
--ABSOLUTELY NEVER NIL
InitPropRef:
PROC []
RETURNS [PropRef] =
INLINE {
RETURN [NEW[PropList←NIL]]
};
-- Layers
layerNum: NAT = 256;
Layer:
TYPE = [0..layerNum);
undefLayer: Layer = 0; -- layer 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] and others
-- the technolgy implementation must guarantee for uniqueness of uniqueKey's
-- (unique only for the technology)
FetchLayer:
PROC [t: Technology, uniqueKey:
ATOM]
RETURNS [Layer];
-- returns a layer given its technology and its unique 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
markNum: NAT = 256;
Object:
TYPE =
REF ObjectRep;
-- Objects are the main things in ChipNDale
-- Objects must draw the same way independant of their environment
ObjectRep:
TYPE =
RECORD [
class: ObjectClass, -- never modify class nor class^
bbox: Rect ← [0, 0, 2, 2], -- maximal area drawn, not electrical influence...
layer: Layer ← undefLayer,
marked: [0..markNum) ← 0, -- only for objects in the design's directory. try to avoid usage.
specific: REF ANY ← NIL,
properties: PropList ← NIL -- see warning
];
-- Several instances may point to same object: consider on modifications.
-- Some implementors of object-classes share the bits of different ObjectRep's
-- (therefore usage of properties of Objects not in the directory is restricted to
-- the object class implentor.)
InstanceSequence: TYPE = REF InstanceSequenceRep;
InstanceSequenceRep: TYPE = RECORD [length: NAT𡤀, 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
name: Rope.ROPE ← NIL, -- once included directory, use only CDDirectory to change it
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, -- explicitely specified interest rect
dummyCell: --READONLY-- BOOL ← FALSE, --if set, inhibits use of sequence
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 top levels only
reserved: BOOL ← FALSE, -- for experiments
properties: PropList ← NIL
];
ObjectClass: TYPE = REF ObjectClassRec;
ObjectClassRec:
TYPE =
RECORD [
-- generic procedures for an object
quickDrawMe: DrawProc ← NIL, -- an optimized draw procedure for viewers
drawMe: DrawProc ← NIL, -- drawing the object into any device
showMeSelected: DrawProc ← NIL, -- showing the selection
hitInside: HitInsideProc ← NIL, -- for fine grain selection
interestRect: RectProc ← NIL, -- the boundary the designer likes to think about
technology: Technology ← NIL, -- NIL for technology independent classes
objectType: ATOM ← NIL,
inDirectory:
BOOL ←
FALSE,
-- if inDirectory then objects of this class must be included in designs directory;
-- if ~inDirectory then objects of this class must be immutable;
-- object classes of objects which have children must have inDirectory=TRUE
directoryProcs: REF ← NIL,
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
symbolic: BOOL ← FALSE, -- object for interface specification; no mask
reserved: BOOL ← FALSE, -- for experiments
internalWrite: InternalWriteProc ← NIL,
internalRead: InternalReadProc ← NIL,
description: Rope.ROPE ← NIL, -- shortcut for the class implementor
describe: DescribeProc ← NIL,
describeInst: DescribeInstProc ← NIL,
newLayer: ChangeLayerProc ← NIL, -- used by some simple classes [~inDirectory] only
parent: ObjectClass ← NIL, -- for eventual subclassing
properties: PropRef ← NIL
];
DrawProc:
TYPE =
PROC [inst: Instance, trans: Transformation, pr:
REF DrawInformation];
-- procedure uses trans from parameter, ignores inst.trans, may use inst.properties
HitInsideProc: TYPE = PROC [ob: Object, hitRect: Rect] RETURNS [BOOL];
RectProc: TYPE = PROC [ob: Object] RETURNS [Rect];
InternalWriteProc: TYPE = PROC [h: TokenIO.Handle, ob: Object];
InternalReadProc: TYPE = PROC [h: TokenIO.Handle, key: ATOM] RETURNS [Object];
DescribeProc: TYPE = PROC [ob: Object] RETURNS [Rope.ROPE];
DescribeInstProc: TYPE = PROC [inst: Instance] RETURNS [Rope.ROPE];
ChangeLayerProc: TYPE = PROC [inst: Instance, layer: CD.Layer] RETURNS [BOOL←TRUE];
DrawContextProc:
TYPE =
PROC [pr: DrawRef, proc: DrawContextLayerProc, ob: Object, trans: Transformation, layer: Layer];
-- object classes which uses DrawContextProc must guarantee
-- ob#NIL
-- ob.size < [NAT.LAST, NAT.LAST]
DrawContextLayerProc: TYPE = PROC [context: Imager.Context, ob: Object, layer: Layer];
RegisterObjectClass:
PROC [objectType:
ATOM, class: ObjectClassRec]
RETURNS [ObjectClass];
-- objectType field must be initialized
-- may raise Error[doubleRegistration] and others
-- Also initializes procedures with default values
-- 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
FetchObjectClass:
PROC [objectType:
REF, technology: Technology←
NIL]
RETURNS [
--readonly-- ObjectClass];
-- NIL if not found
-- consider ObjectClass as readonly if you are not the implementor of the object type
-- 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
-- size 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
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
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,
properties: PropRef ← ,
edited: BOOL ← FALSE, -- treat readonly [internal invariants]
changedSinceSaving: BOOL ← FALSE, -- treat readonly [internal invariants]
cdDirectoryPriv: PRIVATE REF, -- used by CDDirectory for directory
cdDirectoryPriv2: PRIVATE REF, -- used by CDDirectory for ownership keys
cdValuePriv: PRIVATE PrivateValueDRef ← NIL, -- used by CDValue
cdSequencerPriv: PRIVATE PrivateSequencerDRef, -- used by CDSequencer
cdDrawQueuePriv: PRIVATE REF ← NIL, -- used by CDDrawQueue
delayedRedrawsPriv: PRIVATE REF ← NIL, -- used by single module
unDoBuffers: PRIVATE PropRef ←, -- expect use of InitPropRef to disable undos
reserved: PRIVATE REF ← NIL
];
PrivateSequencerDRef: TYPE = REF PrivateSequencerDRep;
PrivateSequencerDRep: TYPE;
PrivateValueDRef: TYPE = REF PrivateValueDRep;
PrivateValueDRep: TYPE;
-- 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, -- only technology dependent Layers
properties: PropRef ← ,
cdPriv: PRIVATE PrivateTRef,
cdValuePriv: PRIVATE PrivateValueTRef, -- used by CDValue
cdSequencerPriv: PRIVATE PrivateSequencerTRef -- used by CDSequencer
];
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
DrawRef: TYPE = REF DrawInformation;
DrawInformation:
TYPE =
RECORD [
interestClip: Rect ← [Number.
FIRST/2, Number.
FIRST/2, Number.
LAST/2, Number.
LAST/2],
(interest area; not device area), in doubt must be larger
drawChild: DrawProc ← NIL, -- drawing and recursing
drawRect: DrawRectProc ← NIL, -- design coordinates
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
specialFonts: 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)
dummyInst: CD.Instance ← NIL, -- space for object class implementors
design: Design ← NIL, -- optional for lots of devices
properties: PropRef ← NIL
];
-- use CreateDrawRef for creation of DrawInformation record, unless all fields are set.
ViewerPrivate: TYPE = REF ViewerPrivateRep;
ViewerPrivateRep: TYPE;
DrawRectProc: TYPE = PROC [r: Rect, l: Layer, pr: DrawRef];
DrawCommentProc: TYPE = PROC [r: Rect, comment: Rope.ROPE, pr: DrawRef];
SetGroundProc: TYPE = PROC [pr: DrawRef, pushedOut: BOOL];
CheckPriorityProc:
TYPE =
PROC [pr: DrawRef];
ContextFilter:
TYPE =
PACKED
ARRAY Layer
OF
BOOL ←
ALL[
FALSE];
-- 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];
-- and assigns usefull default procedures and values.
-- Vanilla procedures
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: CD.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: CD.Rect = ob.class.interestRect[ob];
RETURN [[r.x2-r.x1, r.y2-r.y1]];
};
END.