magic/resis/resis.h

655 lines
19 KiB
C

/* Header files for resistance extraction */
#ifndef _MAGIC__RESIS__RESIS_H
#define _MAGIC__RESIS__RESIS_H
/*
* Contact points: keeps track where contacts are and what tiles they refer to both
* before and after processing.
*/
#define LAYERS_PER_CONTACT 4
#define TILES_PER_JUNCTION 2
typedef struct contactpoint
{
struct contactpoint *cp_nextcontact; /* Next contact in linked list. */
Point cp_center; /* Center of contact */
Rect cp_rect; /* Tile rectangle */
Tile *cp_contactTile; /* The following two keep track of
* the tiles where the contact was
* before preprocessing, and the
* next contact in that tile's area.
*/
Tile *cp_tile[LAYERS_PER_CONTACT];
int cp_currentcontact; /* keeps track of tile being processed */
TileType cp_type; /* Type of contact */
int cp_width; /* Width (in x) of contact region */
int cp_height; /* Height (in y) of contact region */
struct resnode *cp_cnode[LAYERS_PER_CONTACT]; /* this contact's nodes */
int cp_status; /* status of processing on this contact */
} ResContactPoint;
typedef struct resistor
{
struct resistor *rr_nextResistor; /* Doubly linked list pointers */
struct resistor *rr_lastResistor;
struct resnode *rr_node[2];
float rr_value; /* Resistor's value in milliohms */
int rr_status; /* Status bit used for processing */
union
{
float rr_area; /* area in resistor. Used to */
/* distribute capacitance */
float rr_i; /* Branch current in mA */
} rr_float;
int rr_cl; /* resistor centerline for geometry */
int rr_width; /* resistor width for geometry */
TileType rr_tt; /* type that composes this */
} resResistor;
#define rr_connection1 rr_node[0]
#define rr_connection2 rr_node[1]
/* Definitions for old FET-style MOSFET devices */
#define RT_GATE 0
#define RT_SOURCE 1
#define RT_DRAIN 2
#define RT_SUBS 3
#define rd_fet_gate rd_terminals[RT_GATE]
#define rd_fet_source rd_terminals[RT_SOURCE]
#define rd_fet_drain rd_terminals[RT_DRAIN]
#define rd_fet_subs rd_terminals[RT_SUBS]
typedef struct device
{
int rd_status; /* status bits */
struct device *rd_nextDev; /* next device in linked list */
/* terminals of device */
struct resnode **rd_terminals;
int rd_nterms; /* number of terminals in rt_terminals */
int rd_perim; /* info about device */
int rd_area; /* used in .ext file */
int rd_length; /* patches. */
int rd_width;
int rd_tiles; /* number of tiles in device */
int rd_devtype; /* tiletype of device. */
Rect rd_inside; /* 1x1 rectangle inside device */
Tile *rd_tile; /* pointer to a tile in device */
} resDevice;
/*
* A junction is formed when two tiles that connect are next to one another.
*/
typedef struct junction
{
struct junction *rj_nextjunction[TILES_PER_JUNCTION];
Tile *rj_Tile[TILES_PER_JUNCTION];
Point rj_loc;
int rj_status;
struct resnode *rj_jnode;
} ResJunction;
/*
* A port is declared for subcircuits; its name overrides any locally-generated
* node name.
*/
typedef struct resport
{
struct resport *rp_nextPort;
Rect rp_bbox;
Point rp_loc;
char *rp_nodename;
} resPort;
/*
* *element are 'cons' (in the LISP sense) cells used to make linked lists of
* their referential structures.
*/
typedef struct reselement
{
struct reselement *re_nextEl;
resResistor *re_thisEl;
} resElement;
typedef struct relement
{
struct relement *rel_nextEl;
struct relement *rel_lastEl;
resResistor *rel_thisEl;
} rElement;
typedef struct jelement
{
struct jelement *je_nextj;
ResJunction *je_thisj;
} jElement;
typedef struct telement
{
struct telement *te_nextt;
resDevice *te_thist;
} tElement;
typedef struct celement
{
struct celement *ce_nextc;
ResContactPoint *ce_thisc;
} cElement;
/*
* Nodes formed from network. These are linked both forwards and backwards
* to other nodes. Lists of devices, resistors, junctions, and contacts
* corresponding to this node are kept.
*/
typedef struct resnode
{
struct resnode *rn_more; /* doubly linked list pointers */
struct resnode *rn_less;
tElement *rn_te; /* widgets connected to this node */
resElement *rn_re;
jElement *rn_je;
cElement *rn_ce;
int rn_noderes; /* resistance from origin node */
Point rn_loc; /* location of node */
unsigned rn_why; /* Why is there a node here? */
int rn_status; /* Status bits */
union { /* At various times, we need to */
/* keep track of the node area, */
/* node capacitance, and node */
/* voltage. Since none of these */
/* values is used concurrently */
/* only one word of storage is */
/* needed. */
float rn_area; /* area of resistors collapsed */
/* into node. */
float rn_cap; /* capacitance of node. */
} rn_float;
char *rn_name; /* Pointer to hash table name */
/* for this node. */
ClientData rn_client; /* Random pointer */
int rn_id;
} resNode;
typedef struct nelement
{
struct nelement *ne_nextEl;
struct nelement *ne_lastEl;
resNode *ne_thisEl;
} nElement;
/*
* Breakpoints are places on a tile which may serve as sources/sinks of
* current. When resistance is calculated for a tile. this is calculated
* between these points.
*/
typedef struct breakpoint
{
struct breakpoint *br_next;
resNode *br_this;
Point br_loc;
Rect *br_crect;
} Breakpoint;
/*
* Each tile needs to keep track of the following things associated with it.
* Since there are too many things to fit in the single ti_client field,
* this 1 to 7 adaptor is used.
*/
typedef struct resinfo
{
cElement *contactList; /* widgets connected to this tile */
resDevice *deviceList; /* devices this tile is part of */
resPort *portList; /* ports connected to this tile */
ResJunction *junctionList; /* junctions inside the tile */
Breakpoint *breakList; /* breakpoints inside the tile */
int sourceEdge; /* used in device tiles to keep
* track of which diffusion edges
* are a transistor's source
*/
int ri_status; /* status of tile processing */
} resInfo;
/* ResDevTile keeps track of the location and type of devices.
* These areas are painted into our copied def after the tree is totally
* flattened. (They can't be painted right away becasue the copy routine
* uses the new def to keep track of where it is in the design. It is also
* used when devices are preproceesed.
*/
typedef struct resdevtile
{
struct resdevtile *nextDev;
Rect area;
TileType type;
ExtDevice *devptr;
int perim;
int overlap;
} ResDevTile;
/*
* Linked list structure to use to store the substrate plane from each
* extracted CellDef so that they can be returned to the original after
* extraction.
*/
struct saveList {
Plane *sl_plane;
CellDef *sl_def;
struct saveList *sl_next;
};
/* Structure stores information required to be sent to ExtResisForDef() */
typedef struct resoptions
{
/* Global options for extresist */
float tdiTolerance;
float frequency;
float rthresh;
struct saveList *savePlanes;
CellDef *mainDef;
/*
* Various information passed between the node extractor and
* ResCheckExtNodes. The location of a start tile and the resistive
* tolerance are passed down, while the derived network is passed back.
*/
TileType rg_ttype;
float rg_maxres;
float rg_nodecap;
float rg_Tdi;
int rg_bigdevres;
int rg_tilecount;
int rg_status;
Point *rg_devloc;
char *rg_name;
} ResisData;
/* Structure used in RC delay calculations for Tdi filter. */
/* Attaches to rn_client field of resNode */
typedef struct rcdelaystuff
{
float rc_Cdownstream; /* capacitance down the tree from node */
float rc_Tdi; /* Tdi for node */
} RCDelayStuff;
/* More type declarations */
typedef struct rdev
{
struct rdev *nextDev; /* Next device in linked list */
struct rdev *realDev; /* Single Lumped Device for */
/* devices connected in parallel */
resDevice *layout; /* pointer to resDevice that */
/* corresponds to RDev */
int status;
struct resextnode *gate; /* Terminals of transistor. */
struct resextnode *source;
struct resextnode *drain;
struct resextnode *subs; /* Used with subcircuit type only */
Point location; /* Location of lower left point of */
/* device. */
float resistance; /* "Resistance" of device. */
TileType rs_ttype; /* tile type for device */
ExtDevice *rs_devptr; /* device extraction record */
char *rs_gattr; /* Gate attributes, if any */
char *rs_sattr;
char *rs_dattr;
} RDev;
typedef struct resextnode
{
struct resextnode *nextnode; /* next node in OriginalNodes */
/* linked list. */
int status;
struct resextnode *forward; /* If node has been merged, this */
/* points to the merged node. */
float capacitance; /* Capacitance between node and */
/* substrate */
float cap_couple; /* Coupling capacitance */
float resistance; /* Lumped resistance */
float minsizeres; /* Minimum size resistor allowed */
Point drivepoint; /* optional, user specified drive */
/* point for network. */
TileType rs_ttype; /* Tiletype of drivepoint */
Point location; /* Location of bottom of leftmost */
/* tile in the lowest numbered */
/* plane contained in the node. */
Rect rs_bbox; /* Location of bottom of leftmost */
/* tile in the lowest numbered */
/* plane contained in the node. */
TileType type; /* Tile type of tile at location */
struct devptr *firstDev; /* Linked list of devices */
/* connected to node. */
char *name; /* Pointer to name of node stored */
/* in hash table. */
char *oldname; /* Pointer to previous name of */
/* node, if it exists */
} ResExtNode;
#define RES_SUB_GND 0
#define RES_SUB_VDD 1
/* `cons' cell for linked list of devices connected to node */
typedef struct devptr
{
struct devptr *nextDev;
struct rdev *thisDev;
int terminal; /* which terminal of device */
/* is connected to node. */
} devPtr;
typedef struct resfixpoint /* Keeps track of where voltage sources are */
{
struct resfixpoint *fp_next;
Point fp_loc;
TileType fp_ttype;
int fp_status;
Tile *fp_tile;
resNode *fp_node;
char fp_name[1];
} ResFixPoint;
/*
* Multipliers telling what portion of capacitance is to Vdd and what part is
* to ground. Right now, coupling capacitance is counted twice, so
* cap[0] + cap[1] = (c_vdd + c_gnd + 2 * c_couple) / (c_vdd + c_gnd + c_couple);
*/
typedef struct capval
{
float cap[1][2];
} ResCapVal;
/* Node flags ("rn_status" field) */
#define RES_TRUE 0x00000001
#define RES_PENDING 0x00000002
#define RES_FINISHED 0x00000004
#define RES_MARKED 0x00000100
#define RES_MAXTDI 0x00001000
#define RES_DONE_ONCE 0x00002000
#define RES_REACHED_NODE 0x00200000
#define RES_NODE_XADJ 0x00400000
#define RES_NODE_YADJ 0x00800000
/* Resistor flags ("rr_status" field) */
#define RES_EW 0x00000200
#define RES_NS 0x00000400
#define RES_DIAGONAL 0x00000800
#define RES_DEADEND 0x00001000
#define RES_TDI_IGNORE 0x00010000
#define RES_REACHED_RESISTOR 0x00100000
#define RES_HEAP 0x00200000
/* Note that RES_DONE_ONCE and RES_MARKED are used both for rn_status and
* rr_status, and these bit values must not collide with any other field
* values.
*/
/* Device flags ("rd_status" field) */
#define RES_DEV_SAVE 0x00000001
/* Type of node flags ("why" field) */
#define RES_NODE_JUNCTION 0x00000001
#define RES_NODE_DEVICE 0x00000002
#define RES_NODE_CONTACT 0x00000004
#define RES_NODE_ORIGIN 0x00000008
#define RES_NODE_SINK 0x00000010
/* Flags for tiles ("ri_status" field) */
#define RES_TILE_SUBS 0x01 /* A tile which is part of a substrate region. */
#define RES_TILE_SD 0x02 /* A tile which is part of a source/drain region. */
#define RES_TILE_DEV 0x04 /* A tile which is actually a device */
#define RES_TILE_DONE 0x08 /* Indicates whether tile has been processed */
#define RES_TILE_MARK 0x10 /* A temporary marking flag */
#define RES_TILE_PUSHED 0x20 /* Another temporary marking flag */
/* Tree walking flags */
#define RES_LOOP_OK 1
#define RES_NO_LOOP 1
#define RES_DO_LAST 0
#define RES_DO_FIRST 1
#define RES_NO_FLAGS 0
/* Constants (ResExtNode "status" field) */
#define FORWARD 0x0000010
#define SKIP 0x0000020
#define FORCE 0x0000040
#define MINSIZE 0x0000080
#define DRIVELOC 0x0000100
#define PORTNODE 0x0000200
#define REDUNDANT 0x0000400
#define DONTKILL 0x0000800
/* Capacitance table constants */
#define OHMSTOMILLIOHMS 1000
#define UNTOUCHED 0
#define SERIES 1
#define PARALLEL 2
#define LOOP 4
#define SINGLE 8
#define TRIANGLE 32
#define LEFTEDGE 1
#define RIGHTEDGE 4
#define TOPEDGE 8
#define BOTTOMEDGE 16
#define OTHERPLANE 32
#define GATE 1
#define SOURCE 2
#define DRAIN 3
#define SUBS 4
/* "rg_status" flag */
#define DRIVEONLY 0x00001000
/* Magic's normal value of infinity is too small---67108863 is only 67K ohms. */
#define RES_INFINITY 0x3FFFFFFF
/* The following turns on and off various options */
#define ResOpt_ExtractAll 0x0001
#define ResOpt_Simplify 0x0002
#define ResOpt_DoExtFile 0x0004
#define ResOpt_DoLumpFile 0x0008
#define ResOpt_RunSilent 0x0010
#define ResOpt_Stats 0x0020
#define ResOpt_Tdi 0x0040
#define ResOpt_Signal 0x0080
#define ResOpt_Geometry 0x0100
#define ResOpt_FastHenry 0x0200
#define ResOpt_Blackbox 0x0300
#define ResOpt_DoSubstrate 0x0800
#define ResOpt_Box 0x1000
/* Assorted Variables */
extern RDev *ResRDevList;
extern int ResOptionsFlags;
extern char *ResCurrentNode;
extern ResExtNode *ResOriginalNodes;
extern CellUse *ResUse;
extern CellDef *ResDef;
extern TileTypeBitMask ResConnectWithSD[NT];
extern TileTypeBitMask ResCopyMask[NT];
extern resResistor *ResResList;
extern resNode *ResNodeList;
extern resDevice *ResDevList;
extern ResContactPoint *ResContactList;
extern resNode *ResNodeQueue;
extern resNode *ResNodeAtOrigin;
extern resNode *resCurrentNode;
extern HashTable ResNodeTable;
extern HashTable ResExtDevTable;
extern ResFixPoint *ResFixList;
extern int ResTileCount;
extern ResExtNode **ResNodeArray;
extern CellDef *mainDef;
extern TileTypeBitMask ResSDTypesBitMask;
extern TileTypeBitMask ResSubTypesBitMask;
extern HashTable ResDevTable;
extern TileTypeBitMask ResNoMergeMask[NT];
extern int ResPortIndex;
/* Routines used by ResReadExt() */
extern ResisData *ResInit();
extern int ResReadDevice();
extern int ResReadCapacitor();
extern int ResReadResistor();
extern int ResReadAttribute();
extern int ResReadMerge();
extern int ResReadSubckt();
extern int ResProcessNode();
extern int ResExtCombineParallel();
extern int dbSrConnectStartFunc();
extern int ResEach();
extern int ResAddPlumbing();
extern int ResRemovePlumbing();
extern float ResCalculateChildCapacitance();
extern ResDevTile *DBTreeCopyConnectDCS();
extern Tile *ResFindTile();
extern resDevice *ResGetDevice();
extern resInfo *resAddField();
extern int ResCheckPorts();
extern int ResCheckBlackbox();
extern void ResCheckExtNodes();
extern void ResSortByGate();
extern void ResFixDevName();
extern void ResWriteLumpFile();
extern void ResSortBreaks();
extern Plane *extResPrepSubstrate();
/* C99 compat */
extern void ExtResisForDef(CellDef *celldef, ResisData *resisdata);
extern char *ResExtGetAttribute(char *sptr);
extern int ResReadFET(int argc, char *argv[]);
extern int ResReadPort(int argc, char *argv[]);
extern char *ResExtGetAttribute(char *sptr);
extern ResExtNode *ResExtInitNode();
extern void ResAddToQueue();
extern bool ResCalcTileResistance();
extern void ResCleanNode();
extern void ResCleanUpEverything();
extern void ResDeleteResPointer();
extern void ResDoContacts();
extern int ResDoSimplify();
extern void ResDoneWithNode();
extern void ResEliminateResistor();
extern bool ResExtractNet();
extern int ResFracture();
extern void ResMergeNodes();
extern void ResNewSDDevice();
extern void ResNewSubDevice();
extern void ResPreProcessDevices();
extern void ResPrintDeviceList();
extern void ResPrintExtDev();
extern void ResPrintReference();
extern void ResPrintResistorList();
extern void ResPrintStats();
extern void ResProcessJunction();
extern ResExtNode *ResReadNode(int argc, char *argv[]);
extern int ResReadExt();
extern void ResRemoveFromQueue();
extern int ResExtNewNode();
extern void ResExtProcessDrivePoints();
extern int ResWriteExtFile();
extern void ResPrintExtNode();
extern void ResPrintExtRes();
extern void ResPrintFHNodes();
extern void ResPrintFHRects();
extern int ResCreateCenterlines();
extern int ResSeriesCheck();
extern int ResParallelCheck();
extern int ResTriangleCheck();
extern int gettokens();
extern int resWalkdown();
extern int resWalkleft();
extern int resWalkright();
extern int resWalkup();
/* Macros */
#define InitializeResNode(node,x,y,why) \
{\
(node)->rn_te = NULL;\
(node)->rn_id=0;\
(node)->rn_float.rn_area = 0.0;\
(node)->rn_name = NULL;\
(node)->rn_client = (ClientData)NULL;\
(node)->rn_noderes = RES_INFINITY;\
(node)->rn_je = NULL;\
(node)->rn_status = FALSE;\
(node)->rn_loc.p_x = (x);\
(node)->rn_loc.p_y = (y);\
(node)->rn_why = (why);\
(node)->rn_ce = (cElement *) NULL;\
(node)->rn_re = (resElement *) NULL;\
}
#define ResInfoInit(Info) \
{ \
Info->contactList = (cElement *) NULL; \
Info->deviceList = (resDevice *) NULL; \
Info->junctionList = (ResJunction *) NULL; \
Info->breakList = (Breakpoint *) NULL; \
Info->portList = (resPort *) NULL; \
Info->ri_status = FALSE; \
Info->sourceEdge = 0 ; \
}
#define NEWBREAK(node,tile,px,py,crect)\
{\
Breakpoint *bp;\
resInfo *jX_ = (resInfo *)((tile)->ti_client); \
bp = (Breakpoint *) mallocMagic((unsigned)(sizeof(Breakpoint))); \
bp->br_next= jX_->breakList; \
bp->br_this = (node); \
bp->br_loc.p_x = px; \
bp->br_loc.p_y = py; \
bp->br_crect = (Rect *) (crect); \
jX_->breakList = bp; \
}
#define NEWPORT(node,tile)\
{\
resPort *rp;\
resInfo *pX_ = (resInfo *)((tile)->ti_client); \
rp = (resPort *) mallocMagic((unsigned)(sizeof(resPort))); \
rp->rp_nextPort = pX_->portList; \
rp->rp_bbox = node->rs_bbox; \
rp->rp_loc = node->drivepoint; \
rp->rp_nodename = node->name; \
pX_->portList = rp; \
}
#endif /* _MAGIC__RESIS__RESIS_H */