1054 lines
36 KiB
Plaintext
1054 lines
36 KiB
Plaintext
|
|
/*
|
||
|
|
* extractInt.h --
|
||
|
|
*
|
||
|
|
* Defines things shared internally by the extract module of Magic,
|
||
|
|
* but not generally needed outside the extract module.
|
||
|
|
*
|
||
|
|
* rcsid "$Header: /usr/cvsroot/magic-8.0/extract/extractInt.h.new,v 1.2 2008/06/01 18:37:42 tim Exp $"
|
||
|
|
*
|
||
|
|
* *********************************************************************
|
||
|
|
* * Copyright (C) 1985, 1990 Regents of the University of California. *
|
||
|
|
* * Permission to use, copy, modify, and distribute this *
|
||
|
|
* * software and its documentation for any purpose and without *
|
||
|
|
* * fee is hereby granted, provided that the above copyright *
|
||
|
|
* * notice appear in all copies. The University of California *
|
||
|
|
* * makes no representations about the suitability of this *
|
||
|
|
* * software for any purpose. It is provided "as is" without *
|
||
|
|
* * express or implied warranty. Export of this software outside *
|
||
|
|
* * of the United States of America may require an export license. *
|
||
|
|
* *********************************************************************
|
||
|
|
*
|
||
|
|
* This module has been modified at DEC/WRL and Stanford University.
|
||
|
|
* The above disclaimers apply.
|
||
|
|
*
|
||
|
|
*/
|
||
|
|
|
||
|
|
#ifndef _EXTRACTINT_H
|
||
|
|
#define _EXTRACTINT_H
|
||
|
|
|
||
|
|
#include "database/database.h"
|
||
|
|
|
||
|
|
#undef NT
|
||
|
|
#define NT TT_MAXTYPES
|
||
|
|
#undef NP
|
||
|
|
#define NP PL_MAXTYPES
|
||
|
|
|
||
|
|
/* ------------------------ Capacitance Values ------------------------- */
|
||
|
|
|
||
|
|
typedef double CapValue; /* No longer allowed to define back to integer,
|
||
|
|
* as this touches too many parts of the code.
|
||
|
|
*/
|
||
|
|
|
||
|
|
/* Procs to manipulate capacitance hash tables. */
|
||
|
|
extern CapValue extGetCapValue();
|
||
|
|
extern void extSetCapValue();
|
||
|
|
extern void extCapHashKill();
|
||
|
|
|
||
|
|
typedef int ResValue; /* Warning: in some places resistances are stored
|
||
|
|
* as ints. This is here for documentation only.
|
||
|
|
*/
|
||
|
|
|
||
|
|
/* -------------------------- Label lists ----------------------------- */
|
||
|
|
|
||
|
|
/*
|
||
|
|
* List of labels for a node.
|
||
|
|
* We keep around pointers to the entire labels for
|
||
|
|
* later figuring out which are attached to the gates,
|
||
|
|
* sources, or drains of transistors.
|
||
|
|
*/
|
||
|
|
typedef struct ll
|
||
|
|
{
|
||
|
|
Label *ll_label; /* Actual Label in the source CellDef */
|
||
|
|
struct ll *ll_next; /* Next LabelList in this region */
|
||
|
|
int ll_attr; /* Which terminal of a transistor this is
|
||
|
|
* an attribute of.
|
||
|
|
*/
|
||
|
|
} LabelList;
|
||
|
|
|
||
|
|
#define LL_NOATTR -1 /* Value for ll_attr above if the label is
|
||
|
|
* not a transistor attribute.
|
||
|
|
*/
|
||
|
|
#define LL_GATEATTR -2 /* Value for ll_attr if the label is a gate
|
||
|
|
* attribute, rather than one of the diffusion
|
||
|
|
* terminals' attributes.
|
||
|
|
*/
|
||
|
|
#define LL_SORTATTR -3 /* value for ll_attr used in
|
||
|
|
* ExtBasic.c/ExtSortTerminals() to swap
|
||
|
|
* the attributes as well as the regions
|
||
|
|
* -- Stefanos 5/96
|
||
|
|
*/
|
||
|
|
#define LL_PORTATTR -4 /* value for ll_attr used to declare
|
||
|
|
* the label to be a subcircuit port
|
||
|
|
* -- Tim 5/02
|
||
|
|
*/
|
||
|
|
/*
|
||
|
|
* Types of labels.
|
||
|
|
* These can be or'd into a mask and passed to extLabType().
|
||
|
|
*/
|
||
|
|
#define LABTYPE_NAME 0x01 /* Normal node name */
|
||
|
|
#define LABTYPE_NODEATTR 0x02 /* Node attribute */
|
||
|
|
#define LABTYPE_GATEATTR 0x04 /* Transistor gate attribute */
|
||
|
|
#define LABTYPE_TERMATTR 0x08 /* Transistor terminal (source/drain)
|
||
|
|
* attribute.
|
||
|
|
*/
|
||
|
|
#define LABTYPE_PORTATTR 0x10 /* Subcircuit port */
|
||
|
|
|
||
|
|
/* ----------------------------- Regions ------------------------------ */
|
||
|
|
|
||
|
|
/*
|
||
|
|
* The following are the structures built up by the various
|
||
|
|
* clients of ExtFindRegions. The general rule for these
|
||
|
|
* structures is that their initial fields must be identical
|
||
|
|
* to those in a Region, but subsequent fields are up to
|
||
|
|
* the individual client.
|
||
|
|
*
|
||
|
|
* Regions marked as GENERIC are the types accepted by
|
||
|
|
* procedures in ExtRegion.c.
|
||
|
|
*/
|
||
|
|
|
||
|
|
/*
|
||
|
|
* GENERIC Region struct.
|
||
|
|
* All this provides is a pointer to the next Region.
|
||
|
|
* This is the type passed to functions like ExtFreeRegions,
|
||
|
|
* and is the type returned by ExtFindRegions. Clients should
|
||
|
|
* cast pointers of this type to their own, client type.
|
||
|
|
*/
|
||
|
|
typedef struct reg
|
||
|
|
{
|
||
|
|
struct reg *reg_next; /* Next region in list */
|
||
|
|
} Region;
|
||
|
|
|
||
|
|
/*
|
||
|
|
* GENERIC region with labels.
|
||
|
|
* Any other structure that wants to reference node names
|
||
|
|
* must include the same fields as this one as its first part.
|
||
|
|
*/
|
||
|
|
typedef struct lreg
|
||
|
|
{
|
||
|
|
struct lreg *lreg_next; /* Next region in list */
|
||
|
|
int lreg_pnum; /* Lowest numbered plane in this region */
|
||
|
|
int lreg_type; /* Type of tile that contains lreg_ll */
|
||
|
|
Point lreg_ll; /* Lower-leftmost point in this region on
|
||
|
|
* plane lreg_pnum. We take the min first
|
||
|
|
* in X, then in Y.
|
||
|
|
*/
|
||
|
|
LabelList *lreg_labels; /* List of labels for this region. These are
|
||
|
|
* any labels connected to the geometry making
|
||
|
|
* up this region. If the list is empty, make
|
||
|
|
* up a name from lreg_pnum and lreg_ll.
|
||
|
|
*/
|
||
|
|
} LabRegion;
|
||
|
|
|
||
|
|
/*
|
||
|
|
* Node region: labelled region with resistance and capacitance.
|
||
|
|
* Used for each node in the flat extraction of a cell.
|
||
|
|
*/
|
||
|
|
|
||
|
|
typedef struct
|
||
|
|
{
|
||
|
|
int pa_perim;
|
||
|
|
int pa_area;
|
||
|
|
} PerimArea;
|
||
|
|
|
||
|
|
typedef struct nreg
|
||
|
|
{
|
||
|
|
struct nreg *nreg_next; /* Next region in list */
|
||
|
|
int nreg_pnum; /* Lowest numbered plane in this region */
|
||
|
|
int nreg_type; /* Type of tile that contains nreg_ll */
|
||
|
|
Point nreg_ll; /* Lower-leftmost point in this region on
|
||
|
|
* plane nreg_pnum. We take the min first
|
||
|
|
* in X, then in Y.
|
||
|
|
*/
|
||
|
|
LabelList *nreg_labels; /* See LabRegion for description */
|
||
|
|
CapValue nreg_cap; /* Capacitance to ground */
|
||
|
|
ResValue nreg_resist; /* Resistance estimate */
|
||
|
|
PerimArea nreg_pa[1]; /* Dummy; each node actually has
|
||
|
|
* ExtCurStyle->exts_numResistClasses
|
||
|
|
* array elements allocated to it.
|
||
|
|
*/
|
||
|
|
} NodeRegion;
|
||
|
|
|
||
|
|
/*
|
||
|
|
* Transistor region: labelled region with perimeter and area.
|
||
|
|
* Used for each transistor in the flat extraction of a cell.
|
||
|
|
*/
|
||
|
|
typedef struct treg
|
||
|
|
{
|
||
|
|
struct treg *treg_next; /* Next region in list */
|
||
|
|
int treg_pnum; /* UNUSED */
|
||
|
|
int treg_type; /* Type of tile that contains treg_ll */
|
||
|
|
Point treg_ll; /* UNUSED */
|
||
|
|
LabelList *treg_labels; /* Attribute list */
|
||
|
|
Tile *treg_tile; /* Some tile in the channel */
|
||
|
|
int treg_area; /* Area of channel */
|
||
|
|
} TransRegion;
|
||
|
|
|
||
|
|
typedef struct { /* Maintain plane information when pushing */
|
||
|
|
Rect area; /* tiles on the node stack. For use with */
|
||
|
|
int plane; /* function extNbrPushFunc(). */
|
||
|
|
} PlaneAndArea;
|
||
|
|
|
||
|
|
/*
|
||
|
|
* The following constructs a node name from the plane number 'n'
|
||
|
|
* and lower left Point l, and places it in the string 's' (which must
|
||
|
|
* be large enough).
|
||
|
|
*/
|
||
|
|
#define extMakeNodeNumPrint(buf, plane, coord) \
|
||
|
|
(void) sprintf((buf), "%s_%s%d_%s%d#", DBPlaneShortName(plane), \
|
||
|
|
((coord).p_x < 0) ? "n": "", abs((coord).p_x), \
|
||
|
|
((coord).p_y < 0) ? "n": "", abs((coord).p_y))
|
||
|
|
|
||
|
|
/* Old way: cryptic numbers, but a bit shorter
|
||
|
|
*
|
||
|
|
* #define extMakeNodeNumPrint(s, n, l) \
|
||
|
|
* (void) sprintf((s), "%d_%d_%d#", (n), extCoord((l).p_x), extCoord((l).p_y))
|
||
|
|
*
|
||
|
|
* The following is used to map the full coordinate space into
|
||
|
|
* the positive integers, for constructing internally generated
|
||
|
|
* node names.
|
||
|
|
*
|
||
|
|
* #define extCoord(x) (((x) < 0) ? (1 - ((x) << 1)) : ((x) << 1))
|
||
|
|
*/
|
||
|
|
|
||
|
|
/*
|
||
|
|
* Argument passed to filter functions for finding regions.
|
||
|
|
*/
|
||
|
|
typedef struct
|
||
|
|
{
|
||
|
|
TileTypeBitMask *fra_connectsTo; /* Array of TileTypeBitMasks. The
|
||
|
|
* element fra_connectsTo[t] has a
|
||
|
|
* bit set for each type that
|
||
|
|
* connects to 't'.
|
||
|
|
*/
|
||
|
|
CellDef *fra_def; /* Def being searched */
|
||
|
|
int fra_pNum; /* Plane currently searching */
|
||
|
|
ClientData fra_uninit; /* This value appears in the ti_client
|
||
|
|
* field of a tile if it's not yet
|
||
|
|
* been visited.
|
||
|
|
*/
|
||
|
|
Region *(*fra_first)(); /* Function to init new region */
|
||
|
|
int (*fra_each)(); /* Function for each tile in region */
|
||
|
|
Region *fra_region; /* Ptr to Region struct for current
|
||
|
|
* region. May be set by fra_first
|
||
|
|
* and used by fra_each.
|
||
|
|
*/
|
||
|
|
} FindRegion;
|
||
|
|
|
||
|
|
#define TILEAREA(tp) ((TOP(tp) - BOTTOM(tp)) * (RIGHT(tp) - LEFT(tp)))
|
||
|
|
|
||
|
|
/* -------------------- Perimeter of a region ------------------------- */
|
||
|
|
|
||
|
|
/*
|
||
|
|
* Segment of the boundary of a region whose perimeter
|
||
|
|
* is being traced by ExtTracePerimeter() and extEnumTilePerim().
|
||
|
|
*/
|
||
|
|
typedef struct
|
||
|
|
{
|
||
|
|
Tile *b_inside; /* Pointer to tile just inside segment */
|
||
|
|
Tile *b_outside; /* Pointer to tile just outside segment */
|
||
|
|
Rect b_segment; /* Actual coordinates of segment */
|
||
|
|
unsigned char b_direction; /* Direction following segment (see below) */
|
||
|
|
int b_plane; /* extract argument for extSideOverlap */
|
||
|
|
} Boundary;
|
||
|
|
|
||
|
|
#define BoundaryLength(bp) \
|
||
|
|
((bp)->b_segment.r_xtop - (bp)->b_segment.r_xbot \
|
||
|
|
+ (bp)->b_segment.r_ytop - (bp)->b_segment.r_ybot)
|
||
|
|
|
||
|
|
/* Directions in which we can be following the boundary of a perimeter */
|
||
|
|
|
||
|
|
#define BD_LEFT 0 /* Inside is to right */
|
||
|
|
#define BD_TOP 1 /* Inside is below */
|
||
|
|
#define BD_RIGHT 2 /* Inside is to left */
|
||
|
|
#define BD_BOTTOM 3 /* Inside is above */
|
||
|
|
|
||
|
|
/* -------- Yank buffers for hierarchical and array extraction -------- */
|
||
|
|
|
||
|
|
extern CellUse *extYuseCum;
|
||
|
|
extern CellDef *extYdefCum;
|
||
|
|
|
||
|
|
/* --------------- Argument passed to extHierYankFunc ----------------- */
|
||
|
|
|
||
|
|
typedef struct
|
||
|
|
{
|
||
|
|
Rect *hy_area; /* Area (in parent coordinates) to be yanked */
|
||
|
|
CellUse *hy_target; /* Yank into this use */
|
||
|
|
bool hy_prefix; /* If TRUE, prefix labels with use id */
|
||
|
|
} HierYank;
|
||
|
|
|
||
|
|
/* ----- Arguments to filter functions in hierarchical extraction ---- */
|
||
|
|
|
||
|
|
/*
|
||
|
|
* The following defines an extracted subtree.
|
||
|
|
* The CellUse et_use will be either a cell we are extracting,
|
||
|
|
* or a flattened subtree. If et_lookNames is non-NULL, it
|
||
|
|
* points to a CellDef that we should look in for node names.
|
||
|
|
*/
|
||
|
|
typedef struct extTree
|
||
|
|
{
|
||
|
|
CellUse *et_use; /* Extracted cell, usually flattened */
|
||
|
|
CellUse *et_realuse; /* If et_use is flattened, et_realuse
|
||
|
|
* points to the unflattened subtree's
|
||
|
|
* root use; otherwise it is NULL.
|
||
|
|
*/
|
||
|
|
CellDef *et_lookNames; /* See above */
|
||
|
|
NodeRegion *et_nodes; /* List of nodes */
|
||
|
|
HashTable et_coupleHash; /* Table for coupling capacitance.
|
||
|
|
* key is type CoupleKey
|
||
|
|
* value is pointer to type CapValue
|
||
|
|
*/
|
||
|
|
struct extTree *et_next; /* Next one in list */
|
||
|
|
} ExtTree;
|
||
|
|
|
||
|
|
/*
|
||
|
|
* The following structure contains information passed down
|
||
|
|
* through several levels of filter functions during hierarchical
|
||
|
|
* extraction.
|
||
|
|
*
|
||
|
|
* The procedure ha_nodename is used to map from a tile into the
|
||
|
|
* name of the node to which that tile belongs. It should be of
|
||
|
|
* the following format:
|
||
|
|
*
|
||
|
|
* char *
|
||
|
|
* proc(tp, et, ha)
|
||
|
|
* Tile *tp;
|
||
|
|
* ExtTree *et;
|
||
|
|
* HierExtractArg *ha;
|
||
|
|
* {
|
||
|
|
* }
|
||
|
|
*
|
||
|
|
* It should always return a non-NULL string; if the name of a
|
||
|
|
* node can't be determined, the string can be "(none)".
|
||
|
|
*/
|
||
|
|
typedef struct
|
||
|
|
{
|
||
|
|
FILE *ha_outf; /* The .ext file being written */
|
||
|
|
CellUse *ha_parentUse; /* Use pointing to the def being extracted */
|
||
|
|
char *(*ha_nodename)();/* Map (tp, et, ha) into nodename; see above */
|
||
|
|
ExtTree ha_cumFlat; /* Cumulative yank buffer */
|
||
|
|
HashTable ha_connHash; /* Connections made during hier processing */
|
||
|
|
|
||
|
|
/* All areas are in parent coordinates */
|
||
|
|
|
||
|
|
Rect ha_interArea; /* Area of whole interaction being considered */
|
||
|
|
Rect ha_clipArea; /* Only consider capacitance, perimeter, and
|
||
|
|
* area that come from inside this area. This
|
||
|
|
* rectangle is contained within ha_interArea.
|
||
|
|
*/
|
||
|
|
CellUse *ha_subUse; /* Root of the subtree being processed now */
|
||
|
|
Rect ha_subArea; /* Area of ha_subUse inside the interaction
|
||
|
|
* area, i.e, contained within ha_interArea.
|
||
|
|
*/
|
||
|
|
Tile *hierOneTile; /* Used in ExtHier.c, tile from extHierOneFlat */
|
||
|
|
int hierPNum; /* Used in ExtHier.c, plane of tile above */
|
||
|
|
TileType hierType; /* Used in ExtHier.c, type of tile above */
|
||
|
|
int hierPNumBelow; /* Used in ExtHier.c, plane of tile below */
|
||
|
|
} HierExtractArg;
|
||
|
|
|
||
|
|
/*
|
||
|
|
* Normally, nodes in overlapping subcells are expected to have labels
|
||
|
|
* in the area of overlap. When this is not the case, we have to use
|
||
|
|
* a much more expensive algorithm for finding the labels attached to
|
||
|
|
* the subcells' geometry in the overlap area. The following structure
|
||
|
|
* is used to hold information about the search in progress for such
|
||
|
|
* labels.
|
||
|
|
*/
|
||
|
|
typedef struct
|
||
|
|
{
|
||
|
|
HierExtractArg *hw_ha; /* Describes context of search */
|
||
|
|
Label *hw_label; /* We update hw_label with a ptr to a
|
||
|
|
* newly allocated label if successful.
|
||
|
|
*/
|
||
|
|
Rect hw_area; /* Area in parent coordinates of the
|
||
|
|
* area where we're searching.
|
||
|
|
*/
|
||
|
|
bool hw_autogen; /* If TRUE, we trace out all geometry
|
||
|
|
* in the first node in the first cell
|
||
|
|
* found to overlap the search area,
|
||
|
|
* and use the internal name for that
|
||
|
|
* node.
|
||
|
|
*/
|
||
|
|
TerminalPath hw_tpath; /* Hierarchical path down to label
|
||
|
|
* we are searching for, rooted at
|
||
|
|
* the parent being extracted.
|
||
|
|
*/
|
||
|
|
TileTypeBitMask hw_mask; /* Mask of tile types that connect to
|
||
|
|
* the tile whose node is to be found,
|
||
|
|
* and which are on the same plane.
|
||
|
|
* Used when calling ExtFindRegions.
|
||
|
|
*/
|
||
|
|
bool hw_prefix; /* If FALSE, we skip the initial
|
||
|
|
* use identifier when building
|
||
|
|
* hierarchical labels (as when
|
||
|
|
* extracting arrays; see hy_prefix
|
||
|
|
* in the HierYank struct).
|
||
|
|
*/
|
||
|
|
int (*hw_proc)();
|
||
|
|
} HardWay;
|
||
|
|
|
||
|
|
/* --------------------- Coupling capacitance ------------------------- */
|
||
|
|
|
||
|
|
/*
|
||
|
|
* The following structure is the hash key used for computing
|
||
|
|
* internodal coupling capacitance. Each word is a pointer to
|
||
|
|
* one of the nodes being coupled. By convention, the first
|
||
|
|
* word is the lesser of the two NodeRegion pointers.
|
||
|
|
*/
|
||
|
|
typedef struct
|
||
|
|
{
|
||
|
|
NodeRegion *ck_1, *ck_2;
|
||
|
|
} CoupleKey;
|
||
|
|
|
||
|
|
extern void extCoupleHashZero(); /* Clears out all pointers to data in table */
|
||
|
|
|
||
|
|
/* ------------------ Interface to debugging module ------------------- */
|
||
|
|
|
||
|
|
extern ClientData extDebugID; /* Identifier returned by the debug module */
|
||
|
|
|
||
|
|
/* ----------------- Technology-specific information ------------------ */
|
||
|
|
|
||
|
|
/*
|
||
|
|
* Structure used to define sidewall coupling capacitances.
|
||
|
|
*/
|
||
|
|
typedef struct edgecap
|
||
|
|
{
|
||
|
|
struct edgecap *ec_next; /* Next edge capacitance rule in list */
|
||
|
|
CapValue ec_cap; /* Capacitance (attofarads) */
|
||
|
|
TileTypeBitMask ec_near; /* Types closest to causing edge, or in
|
||
|
|
* the case of sideOverlaps, the
|
||
|
|
* types we are overlapping.
|
||
|
|
*/
|
||
|
|
TileTypeBitMask ec_far; /* Types farthest from causing edge, or
|
||
|
|
* in the case of sideOverlaps, the
|
||
|
|
* types that shield the edge from
|
||
|
|
* the overlaped tile.
|
||
|
|
*/
|
||
|
|
int ec_plane; /* if ec_near is TT_SPACE, ec_plane */
|
||
|
|
/* specifies which plane is to be */
|
||
|
|
/* used. -1 if ec_near isn't space */
|
||
|
|
} EdgeCap;
|
||
|
|
|
||
|
|
|
||
|
|
/* A type used to determine if current style needs planeorder or not */
|
||
|
|
typedef enum { noPlaneOrder, needPlaneOrder, seenPlaneOrder } planeOrderStatus ;
|
||
|
|
|
||
|
|
/*
|
||
|
|
* Because a large TT_MAXTYPES value quickly generates huge extract section
|
||
|
|
* structures, we want to keep around only the style names, and dynamically
|
||
|
|
* load and destroy the extract section values as needed, when doing an
|
||
|
|
* extraction command.
|
||
|
|
*/
|
||
|
|
|
||
|
|
typedef struct extkeep
|
||
|
|
{
|
||
|
|
struct extkeep *exts_next;
|
||
|
|
char *exts_name;
|
||
|
|
} ExtKeep;
|
||
|
|
|
||
|
|
/*
|
||
|
|
* Parameters for the process being extracted.
|
||
|
|
* We try to use use integers here, rather than floats, to be nice to
|
||
|
|
* machines like Sun workstations that don't have hardware
|
||
|
|
* floating point.
|
||
|
|
*
|
||
|
|
* In the case of capacitances, though, we may have to use floats, depending
|
||
|
|
* upon the type CapValue. In some newer processes the capacitance per
|
||
|
|
* lambda^2 is less than 1 attofarad.
|
||
|
|
*/
|
||
|
|
|
||
|
|
/*---------------------------------------------------------------*/
|
||
|
|
/* Structure containing inter-layer information (NT x NT matrix) */
|
||
|
|
/*---------------------------------------------------------------*/
|
||
|
|
|
||
|
|
typedef struct extinterlayerstyle
|
||
|
|
{
|
||
|
|
/*
|
||
|
|
* Capacitance per unit perimeter. Sidewall capacitance depends both
|
||
|
|
* on the type inside the perimeter as well as the type outside it,
|
||
|
|
* so the table is doubly indexed by TileType.
|
||
|
|
*
|
||
|
|
* The mask exts_perimCapMask[t] contains bits for all those TileTypes
|
||
|
|
* 's' such that exts_perimCap[t][s] is nonzero.
|
||
|
|
*/
|
||
|
|
CapValue exts_perimCap;
|
||
|
|
|
||
|
|
/*
|
||
|
|
* Both exts_overlapShieldTypes[][] and exts_overlapShieldPlanes[][]
|
||
|
|
* are indexed by the same pair of types used to index the table
|
||
|
|
* exts_overlapCap[][]; they identify the types and planes that
|
||
|
|
* shield capacitance between their index types.
|
||
|
|
*/
|
||
|
|
TileTypeBitMask exts_overlapShieldTypes;
|
||
|
|
int exts_overlapShieldPlanes;
|
||
|
|
|
||
|
|
/*
|
||
|
|
* The table extOverlapCap[][] is indexed by two types to give the
|
||
|
|
* overlap coupling capacitance between them, per unit area. Only
|
||
|
|
* one of extOverlapCap[i][j] and extOverlapCap[j][i] should be
|
||
|
|
* nonzero. The capacitance to substrate of the tile of type 'i'
|
||
|
|
* is deducted when an overlap between i and j is detected, if
|
||
|
|
* extOverlapCap[i][j] is nonzero. This is only done, however, if
|
||
|
|
* tile i is below tile j in exts_planeOrder;
|
||
|
|
*/
|
||
|
|
CapValue exts_overlapCap;
|
||
|
|
|
||
|
|
/*
|
||
|
|
* Sidewall coupling capacitance. This capacitance is between edges
|
||
|
|
* on the same plane, and is in units of attofarads. It is multiplied
|
||
|
|
* by the value interpolated from a fringing-field table indexed by the
|
||
|
|
* common length of the pair of edges divided by their separation:
|
||
|
|
*
|
||
|
|
* | |
|
||
|
|
* E1 +----------------------------+
|
||
|
|
* ^
|
||
|
|
* +--- distance between edges
|
||
|
|
* v
|
||
|
|
* +-----------------------------------+ E2
|
||
|
|
* | |
|
||
|
|
*
|
||
|
|
* <-----------------------> length in common
|
||
|
|
*/
|
||
|
|
|
||
|
|
/*
|
||
|
|
* The entry exts_sideCoupleCap[i][j] is a list of the coupling
|
||
|
|
* capacitance info between edges with type 'i' on the inside
|
||
|
|
* and 'j' on the outside, and other kinds of edges.
|
||
|
|
*/
|
||
|
|
EdgeCap *exts_sideCoupleCap;
|
||
|
|
|
||
|
|
/*
|
||
|
|
* exts_sideCoupleOtherEdges[i][j] is a mask of those types on the
|
||
|
|
* far sides of edges to which an edge with 'i' on the inside and
|
||
|
|
* 'j' on the outside has coupling capacitance.
|
||
|
|
*/
|
||
|
|
TileTypeBitMask exts_sideCoupleOtherEdges;
|
||
|
|
/*
|
||
|
|
* The entry exts_sideOverlapCap[i][j] is a list of the coupling
|
||
|
|
* capacitance info between edges with type 'i' on the inside
|
||
|
|
* and 'j' on the outside, and other kinds of tiles on other
|
||
|
|
* planes. The ec_near mask in the EdgeCap record identifies the
|
||
|
|
* types to which we have sidewall overlap capacitance, and the
|
||
|
|
* ec_far mask identifies the types that shield the tiles preventing
|
||
|
|
* a capacitance.
|
||
|
|
*/
|
||
|
|
EdgeCap *exts_sideOverlapCap;
|
||
|
|
|
||
|
|
/*
|
||
|
|
* extSideOverlapOtherTypes[i][j] is a mask of those types to which
|
||
|
|
* an edge with 'i' on the inside and 'j' on the outside has coupling
|
||
|
|
* capacitance. extSideOverlapOtherPlanes[i][j] is a mask of those
|
||
|
|
* planes to which edge [i][j] has overlap coupling capacitance.
|
||
|
|
* exts_sideOverlapShieldPlanes[s][t] is a list of the planes that
|
||
|
|
* need to be examined for shielding material when we are considering
|
||
|
|
* a sidewall overlap capacitor between types s and t. This may
|
||
|
|
* be the "or" of the planes needed by several sideoverlap rules,
|
||
|
|
* since there can be several types of edges in which type s is
|
||
|
|
* the "intype" member and the "outtype" member varies. Note that
|
||
|
|
* sideOverlapShieldPlanes is indexed like overlapShieldPlanes, not
|
||
|
|
* like sideOverlapOtherPlanes.
|
||
|
|
*/
|
||
|
|
int exts_sideOverlapOtherPlanes;
|
||
|
|
int exts_sideOverlapShieldPlanes;
|
||
|
|
TileTypeBitMask exts_sideOverlapOtherTypes;
|
||
|
|
|
||
|
|
} ExtInterLayerStyle;
|
||
|
|
|
||
|
|
/*-----------------------------------------------------------*/
|
||
|
|
/* Structure containing per-layer information (1 x NT array) */
|
||
|
|
/*-----------------------------------------------------------*/
|
||
|
|
|
||
|
|
typedef struct extlayerstyle
|
||
|
|
{
|
||
|
|
/*
|
||
|
|
* Connectivity tables.
|
||
|
|
* Each table is an array of TileTypeBitMasks indexed by TileType.
|
||
|
|
* The i-th element of each array is a mask of those TileTypes
|
||
|
|
* to which type 'i' connects.
|
||
|
|
*/
|
||
|
|
|
||
|
|
/* Everything is connected to everything else in this table */
|
||
|
|
TileTypeBitMask exts_allConn;
|
||
|
|
|
||
|
|
/*
|
||
|
|
* Connectivity for determining electrical nodes.
|
||
|
|
* This should be essentially the same as DBConnectTbl[].
|
||
|
|
*/
|
||
|
|
TileTypeBitMask exts_nodeConn;
|
||
|
|
|
||
|
|
/*
|
||
|
|
* Connectivity for determining resistive regions.
|
||
|
|
* Two types should be marked as connected here if
|
||
|
|
* they are both connected in exts_nodeConnect[], and
|
||
|
|
* if they both have the same resistance per square.
|
||
|
|
*/
|
||
|
|
TileTypeBitMask exts_resistConn;
|
||
|
|
|
||
|
|
/*
|
||
|
|
* Connectivity for determining transistors.
|
||
|
|
* Each transistor type should connect only to itself.
|
||
|
|
* Nothing else should connect to anything else.
|
||
|
|
*/
|
||
|
|
TileTypeBitMask exts_transConn;
|
||
|
|
|
||
|
|
/*
|
||
|
|
* Sheet resistivity for each tile type, in milli-ohms per square.
|
||
|
|
* For types that are transistors or capacitors, this corresponds
|
||
|
|
* to the sheet resistivity of the gate.
|
||
|
|
*/
|
||
|
|
|
||
|
|
/* Maps from a tile type to the index of its sheet resistance entry */
|
||
|
|
int exts_typeToResistClass;
|
||
|
|
|
||
|
|
/* Gives a mask of neighbors of a type with different resistivity */
|
||
|
|
TileTypeBitMask exts_typesResistChanged;
|
||
|
|
|
||
|
|
/*
|
||
|
|
* Resistance information is also provided by the following tables:
|
||
|
|
* exts_typesByResistClass[] is an array of masks of those types
|
||
|
|
* having the same sheet resistivity, for each different value
|
||
|
|
* of sheet resistivity; exts_resistByResistClass[] is a parallel array
|
||
|
|
* giving the actual value of sheet resistivity. Both are indexed
|
||
|
|
* from 0 up to (but not including) exts_numResistClasses.
|
||
|
|
*/
|
||
|
|
TileTypeBitMask exts_typesByResistClass;
|
||
|
|
ResValue exts_resistByResistClass;
|
||
|
|
|
||
|
|
/* Resistance per type */
|
||
|
|
ResValue exts_sheetResist;
|
||
|
|
|
||
|
|
/*
|
||
|
|
* Resistances for via holes.
|
||
|
|
* These have four parts: the size, border, and spacing
|
||
|
|
* of a minimum-size contact (it's assumed to be square),
|
||
|
|
* and the resistance of its via hole. The resistance is
|
||
|
|
* given in milliohms.
|
||
|
|
*/
|
||
|
|
int exts_viaSize;
|
||
|
|
int exts_viaSpacing;
|
||
|
|
int exts_viaBorder;
|
||
|
|
ResValue exts_viaResist;
|
||
|
|
|
||
|
|
/* Layer height and thickness used by the geometry extractor */
|
||
|
|
float exts_height;
|
||
|
|
float exts_thick;
|
||
|
|
|
||
|
|
/*
|
||
|
|
* Capacitance to substrate for each tile type, in units of
|
||
|
|
* attofarads per square lambda.
|
||
|
|
*/
|
||
|
|
|
||
|
|
/*
|
||
|
|
* Capacitance per unit area. This is zero for explicit capacitor
|
||
|
|
* types, which handle gate-channel capacitance specially. For
|
||
|
|
* transistor types, this is at best an approximation that is
|
||
|
|
* truly valid only when the transistor is switched off.
|
||
|
|
*/
|
||
|
|
CapValue exts_areaCap;
|
||
|
|
|
||
|
|
TileTypeBitMask exts_perimCapMask;
|
||
|
|
|
||
|
|
/*
|
||
|
|
* Overlap coupling capacitance for each pair of tile types, in units
|
||
|
|
* of attofarads per square lambda of overlap.
|
||
|
|
* Internodal capacitance due to overlap only occurs between tile
|
||
|
|
* types on different tile planes that are not shielded by intervening
|
||
|
|
* tiles.
|
||
|
|
*/
|
||
|
|
|
||
|
|
/*
|
||
|
|
* The mask exts_overlapOtherPlanes[t] is a mask of the planes that
|
||
|
|
* must be searched for tiles having overlap capacitance with tiles
|
||
|
|
* of type 't', and exts_overlapOtherTypes[t] is a mask of the types
|
||
|
|
* with which our overlap capacitance is non-zero.
|
||
|
|
*/
|
||
|
|
TileTypeBitMask exts_overlapOtherTypes;
|
||
|
|
int exts_overlapOtherPlanes;
|
||
|
|
|
||
|
|
/*
|
||
|
|
* Sidewall-overlap coupling capacitance.
|
||
|
|
* This is between an edge on one plane and a type on another plane
|
||
|
|
* that overlaps the edge (from the outside of the edge), and is in
|
||
|
|
* units of attofarads per lambda.
|
||
|
|
*
|
||
|
|
* When an edge with sidewall capacitance to substrate is found to
|
||
|
|
* overlap a type to which it has sidewall overlap capacitance, the
|
||
|
|
* original capacitance to substrate is replaced with the overlap
|
||
|
|
* capacitance to the tile overlapped, if the edge is above the tile
|
||
|
|
* being overlapped (according to ext_planeOrder). If the tiles are
|
||
|
|
* the other way around, then this replacement is not done.
|
||
|
|
*/
|
||
|
|
|
||
|
|
/*
|
||
|
|
* The mask exts_sideEdges[i] is just a mask of those types j for
|
||
|
|
* which either exts_sideCoupleCap[i][j] or exts_sideOverlapCap[i][j]
|
||
|
|
* is non-empty.
|
||
|
|
*/
|
||
|
|
TileTypeBitMask exts_sideEdges;
|
||
|
|
|
||
|
|
/* Transistors */
|
||
|
|
|
||
|
|
/* Name of each transistor type as output in .ext file */
|
||
|
|
char *exts_transName;
|
||
|
|
|
||
|
|
/* Device class */
|
||
|
|
char exts_deviceClass;
|
||
|
|
|
||
|
|
/*
|
||
|
|
* Per-square resistances for each possible transistor type,
|
||
|
|
* in the various regions that such a type might operate.
|
||
|
|
* The only operating region currently used is "linear",
|
||
|
|
* which the resistance extractor uses in its thresholding
|
||
|
|
* operation. NOTE: resistances in this table are in OHMS
|
||
|
|
* per square, not MILLIOHMS!
|
||
|
|
*/
|
||
|
|
HashTable exts_transResist;
|
||
|
|
ResValue exts_linearResist;
|
||
|
|
|
||
|
|
/*
|
||
|
|
* Mask of the types of tiles that connect to the channel terminals
|
||
|
|
* of a transistor type. The intent is that these will be the
|
||
|
|
* diffusion terminals of a transistor, ie, its source and drain.
|
||
|
|
* UPDATED May, 2008: Record is a list of type masks, allowing
|
||
|
|
* multiple terminal types in the case of, e.g., high-voltage
|
||
|
|
* or other asymmetric devices. The last entry in the list should
|
||
|
|
* be equal to DBSpaceBits.
|
||
|
|
*/
|
||
|
|
TileTypeBitMask *exts_transSDTypes;
|
||
|
|
|
||
|
|
/*
|
||
|
|
* Maximum number of terminals (source/drains) per transistor type.
|
||
|
|
* This table exists to allow the possibility of transistors with
|
||
|
|
* more than two diffusion terminals at some point in the future.
|
||
|
|
*/
|
||
|
|
int exts_transSDCount;
|
||
|
|
|
||
|
|
/* Currently unused: gate-source capacitance per unit perimeter */
|
||
|
|
CapValue exts_transSDCap;
|
||
|
|
|
||
|
|
/* Currently unused: gate-channel capacitance per unit area */
|
||
|
|
CapValue exts_transGateCap;
|
||
|
|
|
||
|
|
/*
|
||
|
|
* Each type of transistor has a substrate node. By default,
|
||
|
|
* it is the one given by exts_transSubstrateName[t]. However,
|
||
|
|
* if the mask exts_transSubstrateTypes[t] is non-zero, and if
|
||
|
|
* the transistor overlaps material of one of the types in the
|
||
|
|
* mask, then the transistor substrate node is the node of the
|
||
|
|
* material it overlaps.
|
||
|
|
*/
|
||
|
|
char *exts_transSubstrateName;
|
||
|
|
TileTypeBitMask exts_transSubstrateTypes;
|
||
|
|
TileTypeBitMask exts_subsTransistorTypes;
|
||
|
|
|
||
|
|
ExtInterLayerStyle *eils[NT]; /* inter-layer information */
|
||
|
|
/* (dynamically allocated) */
|
||
|
|
} ExtLayerStyle;
|
||
|
|
|
||
|
|
/*-----------------------------------------------------------*/
|
||
|
|
/* Structure containing per-plane information (1 x NP array) */
|
||
|
|
/*-----------------------------------------------------------*/
|
||
|
|
|
||
|
|
typedef struct extplanestyle
|
||
|
|
{
|
||
|
|
/* Specifies an ordering of the planes, so we can determine which
|
||
|
|
* tile is above another one. This is used only when determining
|
||
|
|
* if we should subtract capacitance to substrate for overlap and
|
||
|
|
* sideoverlap rules. If no planeorder is specified and the style
|
||
|
|
* does not contain a noplaneordering command a warning is issued
|
||
|
|
* and the default planeorder is used for the style.
|
||
|
|
*/
|
||
|
|
int exts_planeOrder;
|
||
|
|
/*
|
||
|
|
* The mask exts_overlapPlanes is a mask of those planes that must
|
||
|
|
* be searched for tiles having overlap capacitance, and the mask
|
||
|
|
* exts_overlapTypes[p] is those types having overlap capacitance
|
||
|
|
* on each plane p. The intent is that exts_overlapTypes[p] lists
|
||
|
|
* only those types t for which some entry of exts_overlapCap[t][s]
|
||
|
|
* is non-zero.
|
||
|
|
*/
|
||
|
|
TileTypeBitMask exts_overlapTypes;
|
||
|
|
|
||
|
|
/* Common to both sidewall coupling and sidewall overlap */
|
||
|
|
|
||
|
|
/*
|
||
|
|
* exts_sideTypes[p] is a mask of those types 't' having sidewall
|
||
|
|
* coupling or sidewall overlap capacitance on plane p (i.e, for
|
||
|
|
* which a bin in exts_sideCoupleCap[t][] or exts_sideOverlapCap[t][]
|
||
|
|
* is non-empty), and exts_sidePlanes a mask of those planes containing
|
||
|
|
* tiles in exts_sideTypes[].
|
||
|
|
*/
|
||
|
|
TileTypeBitMask exts_sideTypes;
|
||
|
|
|
||
|
|
} ExtPlaneStyle;
|
||
|
|
|
||
|
|
/*--------------------------------------------------------------*/
|
||
|
|
/* Main extraction style information */
|
||
|
|
/*--------------------------------------------------------------*/
|
||
|
|
|
||
|
|
typedef struct extstyle
|
||
|
|
{
|
||
|
|
char exts_status; /* Loaded, not loaded, or pending */
|
||
|
|
char *exts_name; /* Name of this style */
|
||
|
|
|
||
|
|
int exts_sidePlanes;
|
||
|
|
int exts_overlapPlanes;
|
||
|
|
|
||
|
|
/* set/reset with planeorder commands to determine whether
|
||
|
|
* we will warn if no planeorder is specified. This is done
|
||
|
|
* because at Stanford we use a lot of diagnostic extraction
|
||
|
|
* styles (for floating wells etc.) and we don't want to specify
|
||
|
|
* the planeorder for each and every one of them.
|
||
|
|
*/
|
||
|
|
|
||
|
|
planeOrderStatus exts_planeOrderStatus;
|
||
|
|
|
||
|
|
/*
|
||
|
|
* We search out a distance exts_sideCoupleHalo from each edge
|
||
|
|
* for other types with which we have coupling capacitance.
|
||
|
|
* This value determines how much extra gets yanked when
|
||
|
|
* computing hierarchical adjustments, so should be kept
|
||
|
|
* small to insure reasonable performance.
|
||
|
|
*/
|
||
|
|
int exts_sideCoupleHalo;
|
||
|
|
|
||
|
|
int exts_numResistClasses;
|
||
|
|
|
||
|
|
/* Scaling */
|
||
|
|
/*
|
||
|
|
* Step size used when breaking up a large cell for interaction
|
||
|
|
* checks during hierarchical extraction. We check exts_stepSize
|
||
|
|
* by exts_stepSize chunks for interactions one at a time.
|
||
|
|
*/
|
||
|
|
int exts_stepSize;
|
||
|
|
|
||
|
|
/*
|
||
|
|
* Number of linear units per lambda. All perimeter dimensions
|
||
|
|
* that we output to the .ext file should be multiplied by
|
||
|
|
* exts_unitsPerLambda; we produce a "scale" line in the .ext file
|
||
|
|
* indicating this. All area dimensions should be multiplied
|
||
|
|
* by exts_unitsPerLambda**2.
|
||
|
|
* (changed to type float May 11, 2006 to accommodate, e.g., 90
|
||
|
|
* and 130 nm technologies)
|
||
|
|
*/
|
||
|
|
float exts_unitsPerLambda;
|
||
|
|
|
||
|
|
/*
|
||
|
|
* Scaling for resistance and capacitance.
|
||
|
|
* All resistances in the .ext file should be multiplied by
|
||
|
|
* exts_resistScale to get milliohms, and all capacitances by
|
||
|
|
* exts_capScale to get attofarads. These numbers appear in
|
||
|
|
* the "scale" line in the .ext file.
|
||
|
|
*/
|
||
|
|
int exts_capScale;
|
||
|
|
int exts_resistScale;
|
||
|
|
|
||
|
|
/* Contains one for each type of fet, zero for all other types */
|
||
|
|
TileTypeBitMask exts_transMask;
|
||
|
|
|
||
|
|
ExtLayerStyle *els[NT]; /* Per-layer information (allocated) */
|
||
|
|
ExtPlaneStyle *eps[NP]; /* Per-plane information (allocated) */
|
||
|
|
|
||
|
|
} ExtStyle;
|
||
|
|
|
||
|
|
#define EXT_PLUG_GND 1
|
||
|
|
#define EXT_PLUG_VDD 2
|
||
|
|
|
||
|
|
extern ExtStyle *ExtCurStyle;
|
||
|
|
|
||
|
|
/* ------------------- Hierarchical node merging ---------------------- */
|
||
|
|
|
||
|
|
/*
|
||
|
|
* Table used to hold all merged nodes during hierarchical extraction.
|
||
|
|
* Used for duplicate suppression.
|
||
|
|
*/
|
||
|
|
extern HashTable extHierMergeTable;
|
||
|
|
|
||
|
|
/*
|
||
|
|
* Each hash entry in the above table points to a NodeName struct.
|
||
|
|
* Each NodeName points to the Node corresponding to that name.
|
||
|
|
* Each Node points back to a list of NodeNames that point to that
|
||
|
|
* Node, and which are linked together along their nn_next fields.
|
||
|
|
*/
|
||
|
|
typedef struct nn
|
||
|
|
{
|
||
|
|
struct node *nn_node; /* Node for which this is a name */
|
||
|
|
char *nn_name; /* Text of name */
|
||
|
|
struct nn *nn_next; /* Other names of nn_node */
|
||
|
|
} NodeName;
|
||
|
|
|
||
|
|
typedef struct node
|
||
|
|
{
|
||
|
|
NodeName *node_names; /* List of names for this node. The first name
|
||
|
|
* in the list is the "official" node name.
|
||
|
|
*/
|
||
|
|
CapValue node_cap; /* Capacitance to substrate */
|
||
|
|
PerimArea node_pa[1]; /* Dummy; each node actually has
|
||
|
|
* ExtCurStyle->exts_numResistClasses
|
||
|
|
* array elements allocated to it.
|
||
|
|
*/
|
||
|
|
} Node;
|
||
|
|
|
||
|
|
/* -------------------------------------------------------------------- */
|
||
|
|
|
||
|
|
/*
|
||
|
|
* Value normally resident in the ti_client field of a tile,
|
||
|
|
* indicating that the tile has not yet been visited in a
|
||
|
|
* region search.
|
||
|
|
*/
|
||
|
|
extern ClientData extUnInit;
|
||
|
|
|
||
|
|
#define extGetRegion(tp) ( (tp)->ti_client )
|
||
|
|
#define extHasRegion(tp,und) ( (tp)->ti_client != (und) )
|
||
|
|
|
||
|
|
|
||
|
|
/* For non-recursive flooding algorithm */
|
||
|
|
#define VISITPENDING ((ClientData) NULL) /* Marks tiles on stack */
|
||
|
|
|
||
|
|
#ifdef NONMANHATTAN
|
||
|
|
|
||
|
|
/* Note that this macro depends on MAXPLANES being small */
|
||
|
|
/* compared to the bit position of TT_SIDE. Since tens of */
|
||
|
|
/* thousands of planes is inconceivable, this should not be a */
|
||
|
|
/* problem. It is necessary to push the tile's TT_SIDE bit */
|
||
|
|
/* because the search algorithm can overwrite it between the */
|
||
|
|
/* time the tile is pushed and the time that it is popped. */
|
||
|
|
|
||
|
|
#define PUSHTILE(tp, pl) \
|
||
|
|
(tp)->ti_client = VISITPENDING; \
|
||
|
|
STACKPUSH((ClientData)(pointertype)(pl | \
|
||
|
|
((TileType)(spointertype)(tp)->ti_body & TT_SIDE)), extNodeStack); \
|
||
|
|
STACKPUSH((ClientData)(pointertype)tp, extNodeStack)
|
||
|
|
|
||
|
|
#define POPTILE(tp, pl) \
|
||
|
|
tp = (Tile *) STACKPOP(extNodeStack); \
|
||
|
|
pl = (spointertype) STACKPOP(extNodeStack); \
|
||
|
|
if (pl & TT_SIDE) { \
|
||
|
|
TiSetBody((tp), TiGetTypeExact(tp) | TT_SIDE); \
|
||
|
|
pl &= (~TT_SIDE); \
|
||
|
|
} \
|
||
|
|
else \
|
||
|
|
TiSetBody((tp), TiGetTypeExact(tp) & (~TT_SIDE))
|
||
|
|
|
||
|
|
/* Variations of "pushtile" to force a specific value on TT_SIDE */
|
||
|
|
|
||
|
|
#define PUSHTILEBOTTOM(tp, pl) \
|
||
|
|
(tp)->ti_client = VISITPENDING; \
|
||
|
|
STACKPUSH((ClientData)(pointertype)(pl | \
|
||
|
|
((SplitDirection(tp)) ? 0 : TT_SIDE)), extNodeStack) ;\
|
||
|
|
STACKPUSH((ClientData)(pointertype)tp, extNodeStack)
|
||
|
|
|
||
|
|
#define PUSHTILETOP(tp, pl) \
|
||
|
|
(tp)->ti_client = VISITPENDING; \
|
||
|
|
STACKPUSH((ClientData)(pointertype)(pl | \
|
||
|
|
((SplitDirection(tp)) ? TT_SIDE : 0)), extNodeStack) ;\
|
||
|
|
STACKPUSH((ClientData)(pointertype)tp, extNodeStack)
|
||
|
|
|
||
|
|
#define PUSHTILELEFT(tp, pl) \
|
||
|
|
(tp)->ti_client = VISITPENDING; \
|
||
|
|
STACKPUSH((ClientData)(pointertype)(pl), extNodeStack); \
|
||
|
|
STACKPUSH((ClientData)(pointertype)tp, extNodeStack)
|
||
|
|
|
||
|
|
#define PUSHTILERIGHT(tp, pl) \
|
||
|
|
(tp)->ti_client = VISITPENDING; \
|
||
|
|
STACKPUSH((ClientData)(pointertype)(pl | TT_SIDE), extNodeStack); \
|
||
|
|
STACKPUSH((ClientData)(pointertype)tp, extNodeStack)
|
||
|
|
|
||
|
|
#else
|
||
|
|
|
||
|
|
#define PUSHTILE(tp, pl) \
|
||
|
|
(tp)->ti_client = VISITPENDING; \
|
||
|
|
STACKPUSH((ClientData)pl, extNodeStack); \
|
||
|
|
STACKPUSH((ClientData)tp, extNodeStack)
|
||
|
|
|
||
|
|
#define POPTILE(tp, pl) \
|
||
|
|
tp = (Tile *) STACKPOP(extNodeStack); \
|
||
|
|
pl = (int) STACKPOP(extNodeStack)
|
||
|
|
|
||
|
|
#endif
|
||
|
|
|
||
|
|
/* ------------------------- Region finding --------------------------- */
|
||
|
|
|
||
|
|
extern Region *ExtFindRegions();
|
||
|
|
|
||
|
|
/* Filter functions for ExtFindRegions() */
|
||
|
|
extern Region *extTransFirst(); extern int extTransEach();
|
||
|
|
extern Region *extResFirst(); extern int extResEach();
|
||
|
|
extern Region *extNodeFirst(); extern int extNodeEach();
|
||
|
|
extern Region *extHierLabFirst(); extern int extHierLabEach();
|
||
|
|
|
||
|
|
/* -------- Search for matching tile/node in another ExtTree ---------- */
|
||
|
|
|
||
|
|
/*
|
||
|
|
* NODETOTILE(np, et, tp)
|
||
|
|
* NodeRegion *np;
|
||
|
|
* ExtTree *et;
|
||
|
|
* Tile *tp;
|
||
|
|
*
|
||
|
|
* Sets tp to be the tile containing the lower-leftmost point of the
|
||
|
|
* NodeRegion *np, but in the tile planes of the ExtTree *et instead
|
||
|
|
* of the tile planes originally containing *np.
|
||
|
|
*/
|
||
|
|
#define NODETOTILE(np, et, tp) \
|
||
|
|
if (1) { \
|
||
|
|
Plane *myplane = (et)->et_use->cu_def->cd_planes[(np)->nreg_pnum]; \
|
||
|
|
\
|
||
|
|
(tp) = myplane->pl_hint; \
|
||
|
|
GOTOPOINT(tp, &(np)->nreg_ll); \
|
||
|
|
myplane->pl_hint = (tp); \
|
||
|
|
}
|
||
|
|
|
||
|
|
/*
|
||
|
|
* NODETONODE(nold, et, nnew)
|
||
|
|
* NodeRegion *nold;
|
||
|
|
* ExtTree *et;
|
||
|
|
* NodeRegion *nnew;
|
||
|
|
*
|
||
|
|
* Like NODETOTILE above, but leaves nnew pointing to the node associated
|
||
|
|
* with the tile we find.
|
||
|
|
*/
|
||
|
|
#define NODETONODE(nold, et, nnew) \
|
||
|
|
if (1) { \
|
||
|
|
Tile *tp; \
|
||
|
|
\
|
||
|
|
(nnew) = (NodeRegion *) NULL; \
|
||
|
|
NODETOTILE((nold), (et), tp); \
|
||
|
|
if (tp && extHasRegion(tp, extUnInit)) \
|
||
|
|
(nnew) = (NodeRegion *) extGetRegion(tp); \
|
||
|
|
}
|
||
|
|
|
||
|
|
/* -------------------- Miscellaneous procedures ---------------------- */
|
||
|
|
|
||
|
|
extern char *extNodeName();
|
||
|
|
extern NodeRegion *extBasic();
|
||
|
|
extern NodeRegion *extFindNodes();
|
||
|
|
extern ExtTree *extHierNewOne();
|
||
|
|
extern int extNbrPushFunc();
|
||
|
|
|
||
|
|
/* --------------------- Miscellaneous globals ------------------------ */
|
||
|
|
|
||
|
|
extern int extNumFatal; /* Number fatal errors encountered so far */
|
||
|
|
extern int extNumWarnings; /* Number warning messages so far */
|
||
|
|
extern CellUse *extParentUse; /* Dummy use for def being extracted */
|
||
|
|
extern ClientData extNbrUn; /* Ditto */
|
||
|
|
|
||
|
|
/*
|
||
|
|
* This is really a (Stack *), but we use the struct tag to avoid
|
||
|
|
* having to include stack.h in every .c file. Used in the non-recursive
|
||
|
|
* flooding algorithm.
|
||
|
|
*/
|
||
|
|
extern struct stack *extNodeStack;
|
||
|
|
|
||
|
|
/* ------------------ Connectivity table management ------------------- */
|
||
|
|
|
||
|
|
/*
|
||
|
|
* The following is true if tile types 'r' and 's' are connected
|
||
|
|
* according to the connectivity table 'tbl'
|
||
|
|
*/
|
||
|
|
#define extConnectsTo(r, s, tbl) ( TTMaskHasType(&(tbl)[(r)], (s)) )
|
||
|
|
|
||
|
|
/* -------------------------------------------------------------------- */
|
||
|
|
|
||
|
|
#include "extDebugInt.h"
|
||
|
|
|
||
|
|
#endif /* _EXTRACTINT_H */
|