1122 lines
39 KiB
C
1122 lines
39 KiB
C
/*
|
|
* 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,v 1.7 2010/08/10 00:18:46 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 _MAGIC__EXTRACT__EXTRACTINT_H
|
|
#define _MAGIC__EXTRACT__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;
|
|
|
|
typedef struct {
|
|
char areaType; /* ANTENNAMODEL_SURFACE or ANTENNAMODEL_SIDEWALL */
|
|
float ratioGate;
|
|
float ratioDiffA; /* Proportional */
|
|
float ratioDiffB; /* Constant */
|
|
} RatioValues;
|
|
|
|
/* Antenna models */
|
|
#define ANTENNAMODEL_PARTIAL 0x01
|
|
#define ANTENNAMODEL_CUMULATIVE 0x02
|
|
#define ANTENNAMODEL_SURFACE 0x04
|
|
#define ANTENNAMODEL_SIDEWALL 0x08
|
|
|
|
/* ------------------------ Parameter lists --------------------------- */
|
|
|
|
/* These lists keep track of what parameter names subcircuit definitions
|
|
* use for parameters that magic knows how to generate. Valid pl_param
|
|
* values are a (area), p (perimeter), w (width), l (length), s (substrate),
|
|
* x (position), and y (position). Values "a" and "p" may be followed by
|
|
* an additional integer indicating the terminal from which the value is
|
|
* used (e.g., source area, drain perimeter, etc.). An integer "0"
|
|
* indicates the device identifier region (e.g., gate) and is equivalent
|
|
* to having no integer at all. Integers "1" and up indicate terminals,
|
|
* in order.
|
|
*/
|
|
|
|
typedef struct pl
|
|
{
|
|
int pl_count; /* Share this list. . . */
|
|
char pl_param[2]; /* Default character for parameter */
|
|
char *pl_name; /* Full name for parameter */
|
|
double pl_scale; /* Scaling of parameter, if specified */
|
|
int pl_offset; /* Offset of parameter, if specified */
|
|
int pl_maximum; /* Maximum value for this device model */
|
|
int pl_minimum; /* Minimum value for this device model */
|
|
struct pl *pl_next; /* Next parameter in list */
|
|
} ParamList;
|
|
|
|
/* -------------------------- 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 an ExtRegion, but subsequent fields are up to
|
|
* the individual client.
|
|
*
|
|
* Regions marked as GENERIC are the types accepted by
|
|
* procedures in ExtRegion.c.
|
|
*/
|
|
|
|
/*
|
|
* GENERIC ExtRegion struct.
|
|
* All this provides is a pointer to the next ExtRegion.
|
|
* 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 */
|
|
} ExtRegion;
|
|
|
|
/*
|
|
* 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;
|
|
dlong 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;
|
|
|
|
/* Structure to be kept in a hash table of node regions for the current */
|
|
/* extract cell. It tracks the original substrate cap calculated for */
|
|
/* each region used in the "node" line output, the final substrate cap */
|
|
/* calculated after taking all subcircuits into account, and a running */
|
|
/* total of all corrections to the node's substrate cap generated in */
|
|
/* "merge" lines by extSubtree() and extArray(). After both routines */
|
|
/* have run, any unaccounted capacitance is output to the .ext file as */
|
|
/* a "subcap" line. */
|
|
|
|
typedef struct {
|
|
NodeRegion *subcap_reg;
|
|
CapValue subcap_orig;
|
|
CapValue subcap_final;
|
|
CapValue subcap_adjust;
|
|
} SubCapAdjust;
|
|
|
|
/*
|
|
* 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.
|
|
*/
|
|
ExtRegion *(*fra_first)(); /* Function to init new region */
|
|
int (*fra_each)(); /* Function for each tile in region */
|
|
ExtRegion *fra_region; /* Ptr to ExtRegion 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 1 /* Inside is to right */
|
|
#define BD_TOP 2 /* Inside is below */
|
|
#define BD_RIGHT 4 /* Inside is to left */
|
|
#define BD_BOTTOM 8 /* 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 */
|
|
NodeRegion *ha_parentReg; /* Node region list from parent def */
|
|
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) */
|
|
int ec_offset; /* Offset to apply to separation */
|
|
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_pmask; /* specifies which planes are to be */
|
|
/* used. */
|
|
} 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;
|
|
|
|
/*
|
|
* Structure used to define transistors and other extracted devices
|
|
* One of these records is kept per tile type. However, the record
|
|
* can link to additional records through the "exts_next" record,
|
|
* so that multiple extraction devices can be defined for the same
|
|
* tile type, provided that each definition has a unique combination
|
|
* of exts_deviceSDTypes and exts_deviceSubstrateTypes.
|
|
*/
|
|
|
|
typedef struct extDevice
|
|
{
|
|
/* Name of each transistor type as output in .ext file */
|
|
char *exts_deviceName;
|
|
|
|
/* List of parameter names for each subcircuit type */
|
|
ParamList *exts_deviceParams;
|
|
|
|
/* Device class for each layer type */
|
|
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_deviceResist;
|
|
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_deviceSDTypes;
|
|
|
|
/*
|
|
* 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_deviceSDCount;
|
|
|
|
/* Currently unused: gate-source capacitance per unit perimeter */
|
|
CapValue exts_deviceSDCap;
|
|
|
|
/* Currently unused: gate-channel capacitance per unit area */
|
|
CapValue exts_deviceGateCap;
|
|
|
|
/*
|
|
* Each type of transistor has a substrate node. By default,
|
|
* it is the one given by exts_deviceSubstrateName[t]. However,
|
|
* if the mask exts_deviceSubstrateTypes 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_deviceSubstrateName;
|
|
TileTypeBitMask exts_deviceSubstrateTypes;
|
|
|
|
/*
|
|
* Each device type can have any number of extract models based
|
|
* on identifier layers (such as thickox, esd, etc.)
|
|
*/
|
|
TileTypeBitMask exts_deviceIdentifierTypes;
|
|
|
|
struct extDevice *exts_next;
|
|
} ExtDevice;
|
|
|
|
/*
|
|
* 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.
|
|
*/
|
|
|
|
typedef struct extstyle
|
|
{
|
|
char exts_status; /* Loaded, not loaded, or pending */
|
|
char *exts_name; /* Name of this style */
|
|
|
|
/*
|
|
* 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[NT];
|
|
|
|
/*
|
|
* Connectivity for determining electrical nodes.
|
|
* This should be essentially the same as DBConnectTbl[].
|
|
*/
|
|
TileTypeBitMask exts_nodeConn[NT];
|
|
|
|
/*
|
|
* 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[NT];
|
|
|
|
/*
|
|
* Connectivity for determining devices.
|
|
* Each devices type should connect only to itself.
|
|
* Nothing else should connect to anything else.
|
|
*/
|
|
TileTypeBitMask exts_deviceConn[NT];
|
|
|
|
/*
|
|
* Set of types to be considered for extraction. Types not in
|
|
* this list cannot be nodes (e.g., implant layers)
|
|
*/
|
|
TileTypeBitMask exts_activeTypes;
|
|
|
|
/*
|
|
* 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[NT];
|
|
|
|
/* Gives a mask of neighbors of a type with different resistivity */
|
|
TileTypeBitMask exts_typesResistChanged[NT];
|
|
|
|
/*
|
|
* 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[NT];
|
|
ResValue exts_resistByResistClass[NT];
|
|
int exts_numResistClasses;
|
|
|
|
/* Resistance per type */
|
|
ResValue exts_sheetResist[NT];
|
|
|
|
/*
|
|
* Resistances for via holes, given in milliohms. Number of
|
|
* cuts is determined by the "cifoutput" style "squares"
|
|
* parameters.
|
|
*/
|
|
ResValue exts_viaResist[NT];
|
|
|
|
/*
|
|
* Amount to scale resistance of a material on a corner.
|
|
* Defauts to 1.0. Often set to 0.5.
|
|
*/
|
|
float exts_cornerChop[NT];
|
|
|
|
/* Layer height and thickness used by the geometry extractor */
|
|
float exts_height[NT];
|
|
float exts_thick[NT];
|
|
|
|
char exts_antennaModel;
|
|
|
|
/* Antenna area ratio for each layer */
|
|
RatioValues exts_antennaRatio[NT];
|
|
|
|
/* Mask of types that tie down antennas */
|
|
TileTypeBitMask exts_antennaTieTypes;
|
|
|
|
/*
|
|
* 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[NT];
|
|
|
|
/*
|
|
* 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[NT][NT];
|
|
TileTypeBitMask exts_perimCapMask[NT];
|
|
|
|
/*
|
|
* 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_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.
|
|
*/
|
|
PlaneMask exts_overlapPlanes;
|
|
TileTypeBitMask exts_overlapTypes[NP];
|
|
|
|
/*
|
|
* 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[NT];
|
|
PlaneMask exts_overlapOtherPlanes[NT];
|
|
|
|
/*
|
|
* 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[NT][NT];
|
|
PlaneMask exts_overlapShieldPlanes[NT][NT];
|
|
|
|
/*
|
|
* 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[NT][NT];
|
|
|
|
/*
|
|
* exts_overlapMult is needed for modeling fringe shielding and
|
|
* partial fringing, whose models have multiplier coefficients
|
|
* that are proportional to area capacitance referred to some
|
|
* constant length (so that it scales with the internal grid,
|
|
* not with the internal grid squared).
|
|
*/
|
|
float exts_overlapMult[NT][NT];
|
|
|
|
/* 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[NP];
|
|
/* 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;
|
|
|
|
|
|
/*
|
|
* 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[NT][NT];
|
|
|
|
/*
|
|
* 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[NT][NT];
|
|
|
|
/*
|
|
* 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.
|
|
*
|
|
* To be done: Set this as a per-plane value with a
|
|
* corresponding method in the tech file to declare the value
|
|
* for each plane separately.
|
|
*/
|
|
int exts_sideCoupleHalo;
|
|
|
|
/*
|
|
* 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 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[NT][NT];
|
|
|
|
/*
|
|
* 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.
|
|
*/
|
|
PlaneMask exts_sideOverlapOtherPlanes[NT][NT];
|
|
TileTypeBitMask exts_sideOverlapOtherTypes[NT][NT];
|
|
PlaneMask exts_sideOverlapShieldPlanes[NT][NT];
|
|
|
|
/*
|
|
* 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.
|
|
*/
|
|
|
|
|
|
/* 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[].
|
|
*/
|
|
PlaneMask exts_sidePlanes;
|
|
TileTypeBitMask exts_sideTypes[NP];
|
|
|
|
/*
|
|
* 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[NT];
|
|
|
|
/* Devices */
|
|
|
|
/* Contains one for each type of device, zero for all other tile types */
|
|
TileTypeBitMask exts_deviceMask;
|
|
|
|
/* All information about a device goes in this record (see above) */
|
|
ExtDevice *exts_device[NT];
|
|
|
|
#ifdef ARIEL
|
|
TileTypeBitMask exts_subsTransistorTypes[NT];
|
|
#endif /* ARIEL */
|
|
|
|
/*
|
|
* There is a single name for global substrate, and a list of
|
|
* types that connect to the substrate. Since for non-SOI
|
|
* processes, this generally is used to specify that space on
|
|
* the well plane is the substrate, the plane number for the
|
|
* well plane is given, too. The "shield types" mask is a
|
|
* mask of types that prevent any types in exts_globSubstrateTypes
|
|
* from contacting the substrate (e.g., deep nwell might be a
|
|
* shielding type, or it could be a special marker layer like
|
|
* "not_substrate").
|
|
*/
|
|
char *exts_globSubstrateName;
|
|
TileTypeBitMask exts_globSubstrateTypes;
|
|
int exts_globSubstratePlane;
|
|
TileTypeBitMask exts_globSubstrateShieldTypes;
|
|
TileType exts_globSubstrateDefaultType;
|
|
|
|
/* 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;
|
|
} 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.
|
|
*/
|
|
int node_len; /* Number of entries in node_names */
|
|
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 */
|
|
|
|
/* 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)
|
|
|
|
/* ------------------------- Region finding --------------------------- */
|
|
|
|
extern ExtRegion *ExtFindRegions();
|
|
extern LabelList *ExtLabelRegions();
|
|
|
|
/* Filter functions for ExtFindRegions() */
|
|
extern ExtRegion *extTransFirst(); extern int extTransEach();
|
|
extern ExtRegion *extResFirst(); extern int extResEach();
|
|
extern ExtRegion *extNodeFirst(); extern int extNodeEach();
|
|
extern ExtRegion *extHierLabFirst(); extern int extHierLabEach();
|
|
|
|
extern Tile *extNodeToTile();
|
|
|
|
/* -------- Search for matching node in another ExtTree ---------- */
|
|
|
|
/*
|
|
* NODETONODE(nold, et, nnew)
|
|
* NodeRegion *nold;
|
|
* ExtTree *et;
|
|
* NodeRegion *nnew;
|
|
*
|
|
* Like extNodeToTile(), 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; \
|
|
tp = extNodeToTile((nold), (et)); \
|
|
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();
|
|
extern TileType extGetDevType();
|
|
extern void extMakeNodeNumPrint();
|
|
|
|
/* --------------------- Miscellaneous globals ------------------------ */
|
|
|
|
extern int extNumErrors; /* Number of 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 */
|
|
|
|
extern NodeRegion *glob_subsnode; /* Substrate node for cell def */
|
|
extern NodeRegion *temp_subsnode; /* Substrate connection to subcell */
|
|
|
|
/*
|
|
* 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;
|
|
|
|
/* C99 compat */
|
|
extern void ExtFindInteractions();
|
|
extern void ExtInterCount();
|
|
extern void ExtInterCount();
|
|
extern void ExtTimes();
|
|
extern void ExtParentArea();
|
|
extern void extHierCopyLabels();
|
|
extern int extTimesInitFunc();
|
|
extern int extTimesHierFunc();
|
|
extern int extTimesFlatFunc();
|
|
extern Plane *extCellFile();
|
|
extern int extInterAreaFunc();
|
|
extern int extTreeSrPaintArea();
|
|
extern int extMakeUnique();
|
|
|
|
/* ------------------ 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 /* _MAGIC__EXTRACT__EXTRACTINT_H */
|