<> <> <> <> DIRECTORY CD, CDBasics, CDCells, CDGenerate, Rope; PW: CEDAR DEFINITIONS IMPORTS CD, CDBasics, CDCells = BEGIN <> <> ROPE: TYPE = Rope.ROPE; ROPES: TYPE = LIST OF ROPE; <<>> <<-- The new hot types, identical to CD types>> Object: TYPE = CD.Object; -- an object, i.e. a definition Objects: TYPE = LIST OF Object; Instance: TYPE = CD.Instance; -- an instance InstanceList: TYPE = CD.InstanceList; Design: TYPE = CD.Design; UserProc: TYPE = CDGenerate.GeneratorProc; <> AbutProblem: SIGNAL [what: ROPE, isX: BOOL, ob1, ob2: Object]; <> <> Reverse: PUBLIC PROC [objects: Objects] RETURNS [result: Objects _ NIL]; <> <<>> <<-- The use of this subset is safe in the following sense: if a novice user (i.e. not Christian Jacobi or Don Curry) creates interactively cells with ChipNDale, and assembles them using only Abuts, MapFunction, and the like, then the resulting design is not going to give him any trouble: it should display, plot and turn into CIF with no complication.>> <<>> <<-- Abuts: the following procs create an Abut, which is not a cell, but a new class of CD object. >> <<-- All these proc can raise the signal AbutProblem>> <<-- The simple abutment uses the interestrect; it stops and complains if size mismatch; NIL is the neutral element. AbutX builds from left to right, and AbutY from bottom to top.>> AbutX: PROC [t1, t2, t3, t4, t5, t6: Object _ NIL] RETURNS [obj: Object]; AbutY: PROC [t1, t2, t3, t4, t5, t6: Object _ NIL] RETURNS [obj: Object]; AbutListX: PROC [listOb: Objects] RETURNS [obj: Object]; AbutListY: PROC [listOb: Objects] RETURNS [obj: Object]; <<>> <<-- Arrays and other repetitions>> <<-- MapFunction evaluates the function over the domain [lx..ux)*[ly..uy) and abuts the resulting tiles in an array. Creates empty cell when lx>=ux or ly>=uy.>> XYFunction: TYPE = PROC [x, y: INT] RETURNS [resultingOb: Object]; MapFunctionX: PROC [function: XYFunction, lx: INT _ 0, ux: INT] RETURNS [new: Object]; MapFunctionY: PROC [function: XYFunction, ly: INT _ 0, uy: INT] RETURNS [new: Object]; MapFunction: PROC [function: XYFunction, lx: INT _ 0, ux: INT, ly: INT _ 0, uy: INT] RETURNS [new: Object]; <<>> <<-- Aligns nx tiles in the X (--) direction. If nx<=0 an empty cell is created>> ArrayX: PROC [ob: Object, nx: INT _ 1] RETURNS [Object]; <<-- Aligns ny tiles in the Y (|) direction. If nx<=0 an empty cell is created>> ArrayY: PROC [ob: Object, ny: INT _ 1] RETURNS [Object]; <<-- Equivalent to ArrayY[ArrayX[ob, nx], ny]: no flat 2D array>> Array: PROC [ob: Object, nx, ny: INT _ 1] RETURNS [new: Object]; <<>> <<-- Planar tranformations and instance names: these properties are usually associated to instances, not objects, so we have to add an extra level of hierarchy>> ChangeOrientation: PUBLIC PROC [obj: Object, orientation: CD.Orientation] RETURNS [cell: Object]; <<-- Symmetry that changes X (so/Y)>> FlipX: PROC [ob: Object] RETURNS [Object] = INLINE {RETURN [ChangeOrientation[ob, mirrorX]]}; <> FlipY: PROC [ob: Object] RETURNS [Object] = INLINE {RETURN [ChangeOrientation[ob, rotate180X]]}; <> Identity: PROC [ob: Object] RETURNS [Object] = INLINE {RETURN [ob]}; <> Rot90: PROC [ob: Object] RETURNS [Object] = INLINE {RETURN [ChangeOrientation[ob, rotate90]]}; Rot180: PROC [ob: Object] RETURNS [Object] = INLINE {RETURN [ChangeOrientation[ob, rotate180]]}; Rot270: PROC [ob: Object] RETURNS [Object] = INLINE {RETURN [ChangeOrientation[ob, rotate270]]}; Flatten: PROC [cell: Object] RETURNS [new: Object]; <> <> <> Get: PROC [design: Design, name: ROPE] RETURNS [ob: Object]; <> OpenDesign: PROC [fileName: ROPE] RETURNS [design: Design]; <> Register: PROC [userProc: UserProc, name: ROPE]; <<-- Registration of a new UserProc>> <> SharedAbutX: PRIVATE PROC [t1, t2: Object _ NIL] RETURNS [obj: Object]; SharedAbutY: PRIVATE PROC [t1, t2: Object _ NIL] RETURNS [obj: Object]; SharedAbutListX: PRIVATE PROC [listOb: Objects] RETURNS [obj: Object]; SharedAbutListY: PRIVATE PROC [listOb: Objects] RETURNS [obj: Object]; FlushSharedCache: PRIVATE PROC; <> Draw: PROC [obj: CD.Object, technologyName: ATOM _ NIL] RETURNS [design: CD.Design]; <> <> <<-- Empty cell: must be repositionned and included in a directory when filled>> <> CreateEmptyCell: PRIVATE PROC RETURNS [cell: Object] = INLINE {cell _ CDCells.CreateEmptyCell[]}; <<>> <<-- Include an object in a cell; position is relative to the InterestRect>> <> IncludeInCell: PRIVATE PROC [cell: Object, obj: Object, position: CD.Position _ [0, 0], orientation: CD.Orientation _ original] RETURNS [newInst: Instance] = INLINE {newInst _ CDCells.IncludeOb[design: NIL, cell: cell, ob: obj, trans: [CDBasics.SubPoints[position, CDBasics.BaseOfRect[CDBasics.MapRect[CD.InterestRect[obj], [[0, 0], orientation]]]], orientation], mode: dontResize].newInst}; <> <> SetInterestRect: PRIVATE PROC [obj: Object, size: CD.Position] = INLINE {[] _ CDCells.SetInterestRect[NIL, obj, [0, 0, size.x, size.y], dontNotify]}; <<-- Reposition the object. Should be called for every cell created by CreateEmptyCell, once filled and once interestRect positionned>> <> RepositionCell: PRIVATE PROC [obj: Object] = INLINE {[] _ CDCells.ResizeCell[NIL, obj]}; <> <<-- Predicates>> ODD: PROC [i: INT] RETURNS [BOOL]; EVEN: PROC [i: INT] RETURNS [BOOL]; <<>> <<-- Dealing with Log2 of numbers>> Log2: PROC [n: INT] RETURNS [INT]; TwoToThe: PROC [x: INT] RETURNS [INT]; TwoToTheLog2: PROC [n: INT] RETURNS [INT]; <<>> <<-- Extract the xth bit in the interger N>> <<-- Warning: bit 0 is the LOW order bit (lsb). That is NOT the mesa convention!>> XthBitOfN: PROC [x, n: INT] RETURNS [BOOL]; END.