/* 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 */