<> <> <> <> <<>> <<-- 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 >> <> <<>> <> <> <> <> <<>> <> <<>> <> <<>> <> <<>> <<>> <> 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. <> <> <> 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.