Parquet.mesa
Copyright © 1984 by Xerox Corporation. All rights reserved.
Created by: Mayo, June 8, 1984 12:40:57 pm PDT
Last Edited by: Mayo, August 6, 1984 12:28:49 pm PDT
-- Parquet: A VLSI Layout Tiler
-- A program to place cells down by alignment marks on those cells.
-- This program forms the layout portion of many (I hope) module generators.
DIRECTORY
Rope USING [ROPE],
SymTab USING [Ref],
CD USING [Design, ObPtr, Position, Technology, Orientation, original];
Parquet: CEDAR DEFINITIONS =
BEGIN
-- Types
There are several types of data defined by the tiler program:
Tiles: ChipNDale cells that have additional annotations such as alignment marks and stretch lines:
Alignment Marks: Named points used to align tiles
Stretch Lines: Labeled lines used to stretch tiles and mask geometry.
Check Marks: Marks that must be matched up with at least one other mark in the finished module.
PlacedTiles: Tiles that have been placed into a Module at a specific point.
Designs: ChipNDale designs that contain collections of ChipNDale cells that are to be used as tiles.
Modules: Collections of tiles that have been assembled.
Each module generator is written as a proc that is registered with the tiler. When invoked, it should look at the variables defined in the passed parameter table and produce a Module. It may return NIL if it couldn't make the module. If all the parameters are not present in the table the generator can prompt for them using the TerminalIO package.
ModuleGeneratorProc: TYPE = PROC[parameters: SymTab.Ref] RETURNS [Module];
Position: TYPE = CD.Position;    -- a point (x, y pair)
Mark: TYPE = REF MarkRec;    -- an alignment mark on a cell
MarkRec: TYPE = RECORD [
name: Rope.ROPE,
pos: Position,        -- the location of the mark in containing tile
owner: PRIVATE INT
];
Tile: TYPE = REF TileRec;      -- a cell
TileRec: TYPE =RECORD [
obj: CD.ObPtr,       -- obj.specificRec will be a CD.CellPtr
left, right, top, bottom: Mark ← NIL, -- location of the 4 standard marks
markList: PRIVATE MarkList ← NIL, -- a list of all marks in this cell, to be retrieved via GetMark[]
checkList: PRIVATE CheckList ← NIL,
placedInto: PRIVATE Module ← NIL
];
MarkList: TYPE = PRIVATE LIST OF Mark;
CheckList: TYPE = PRIVATE LIST OF CD.Position;
PlacedTile: TYPE = REF PlacedTileRec;  -- a cell that has been placed into a design
PlacedTileRec: TYPE = RECORD [
pos: Position,        -- the location of the lower-left corner of the cell
tile: Tile,
orient: Orientation,
owner: Module
]; 
Design: TYPE = CD.Design;    -- a design (a collection of tiles)
Technology: TYPE = CD.Technology; -- each design is in a particular technology
Module: TYPE = REF;   -- a structre containing placed tiles
-- Orientations, look in CDOrient.mesa (ChipNDale) for definitions
-- Warning: rotations are specified in the counter-clockwise direction
Orientation: TYPE = CD.Orientation ← CD.original; -- a description of rotation and mirroring
IdentityOrient: CD.Orientation = CD.original; -- a no-op orientation
Error: ERROR [ec: ErrorCode];
ErrorCode: TYPE = {Null,     -- never raised
NoSuchMark,       -- a bad Mark was passed
NoSuchTile,        -- a bad Tile was passed
NoSuchPlacedTile,      -- a bad PlacedTile was passed
NoSuchDesign,       -- a bad Design was passed
MarkNotInTile,       -- the Mark is not in the specified cell or design
PlacedTileNotInDesign,     -- the PlacedTile is not in the specified design
ObjectMustBeTileOrDesign,    -- something else was passed
TileInTwoModules      -- you attempted to place a tile into two different modules
};
-- General procedures
-- Register a module generator with the tiler, returns TRUE if this is a new generator,
-- and FALSE if it has replaced another generator's command.
RegisterGenerator: PROC[generatorName: Rope.ROPE, proc: ModuleGeneratorProc] RETURNS [BOOL];
-- Loading in tiles
-- load design from a file
ReadDesign: PROC [fileName: Rope.ROPE] RETURNS [Design, Technology, SymTab.Ref];
-- returns NIL for the Design if not found
-- SymTab is a new symbol table containing TVs defined by the Design (set of tiles)
-- Retrieve a fully instantiated cell given it's name and a table of parameters. The variables 'SizeX' and 'SizeY' in the table are filled in with the size of the uninstantiated cell so that the cell may use these as parameters. Some objects in cells (such as stretch lines) look values up in the parameter table passed. The parameter table contains refs to type 'AMTypes.TypedVariable'.
-- This procedure is slow, and therefor should not be called needlessly.
InstantiateTile: PROC [fromDesign: Design, cellName: Rope.ROPE, parameters: SymTab.Ref ← NIL] RETURNS [Tile];
-- NIL if not found
-- Creating a module
-- create a new empty module in a particular technology
-- also returns an empty PlacedTile with which to align things via AlignTile
NewModule: PROC [tech: Technology] RETURNS [Module, PlacedTile];
-- It is an ERROR to place a tile into more than one module (ChipNDale restriction). If this is must be done, another tile may be created via the InstantiateTile[] procedure.
-- place a cell next to another, using the "left", "right", "top", and "bottom" alignment marks.
AdjacentTile: PROC [oldTile: PlacedTile, newTile: Tile, dir: Direction, orient: Orientation] RETURNS [PlacedTile];
Direction: TYPE = {above, below, rightOf, leftOf};
-- place a cell into a design using alignment marks
AlignTile: PROC [oldTile: PlacedTile, oldMark: Mark, newTile: Tile, newMark: Mark, orient: Orientation] RETURNS [PlacedTile];
-- Place the new cell such that it's mark is aligned with the mark on the old cell.
-- Value returned is the new placed cell.
-- Specifying Hierarchy
-- Switch to a new block in the hierarchy. Subsequent cells will appear in this block. When the generator is done, each block will be put into a chipndale cell. blockName does not have to be declared: if that block doesn't exist a new one is created. The topmost block can be switched to by passing a NIL blockName.
SwitchBlock: PROC [module: Module, blockName: Rope.ROPE];
-- Returns the last rope passed to SwitchBlock for this module.
GetCurrentBlock: PROC [module: Module] RETURNS [Rope.ROPE];
-- Nest one block inside of another. If the block is already nested or if the nesting creates a circularity then the call is ignored and FALSE is returned. The topmost block is refered to by NIL. Unnested blocks will be put in the topmost block.
NestBlock: PROC [module: Module, child, parent: Rope.ROPE] RETURNS [done: BOOL];
-- Dealing with Marks
-- retrieve a mark given it's name
-- Special names: If the mark is named "left", "right", "top", or "bottom", and the mark
-- does not exist, a ficticous mark centered on that side is returned.
GetMark: PROC [fromTile: Tile, markName: Rope.ROPE] RETURNS [Mark];
-- NIL if not found
-- Place a new alignment mark into a module on top of an existing tiles's mark. The mark goes in the topmost block of the module.
AlignMark: PROC [oldTile: PlacedTile, oldMark: Mark, newMarkName: Rope.ROPE];
-- Find what mark (of "left", "right", "top", or "bottom") ends up in the specified position after rotation & mirroring.
As an example, if a sideways flip was specified, then "left" will turn into "right".
If a 90 degree clockwise rotation was specified, "left" would turn into "bottom" (if you were expecting "top", remember that is where "left" moves to, not what ends up in left's old spot).
If the name is not one of the 4 special ones, the name is just returned intact.
OrientMark: PROC [markName: Rope.ROPE, orient: Orientation] RETURNS [Rope.ROPE];
-- Operations on Modules
-- Turn a module into a tile, TRASHING the initial module. The module MUST NOT be used again. Any unmatched check marks are propogated up into the tile.
ModuleIntoTile: PROC [module: Module] RETURNS [Tile];
-- Checks alignment marks to make sure that the ones placed by the tiler match up properly, as indicated by the syntax of the mark name.
-- Return result is the number of errors found, and as a side effect error paint is put in the Module over any problem areas.
CheckModule: PROC [module: Module] RETURNS [INT];
-- Low-level Procedures (Use of these routines is rare, but not unheard of.)
-- place a cell into a design at absolute coordinates
PlaceTile: PROC [into: Module, tile: Tile, lowerLeftCorner: Position, orient: Orientation] RETURNS [PlacedTile];
-- find out the size of a tile
TileSize: PROC [tile: Tile] RETURNS [Position];
-- return position of upper right corner relative to lower-left corner
-- find out the location of an placed cell in a module (lower-left corner)
PlacedTileLoc: PROC [tile: PlacedTile] RETURNS [Position];
-- find the absolute coordinates of a mark on a placed cell
PlacedMarkLoc: PROC [oldTile: PlacedTile, oldMark: Mark] RETURNS [Position];
-- add a mark to a Design at absolute coordinates
PlaceMark: PROC [into: Module, markName: Rope.ROPE, markPos: Position];
END.