#ifndef lint static char rcsid[] __attribute__ ((unused)) = "$Header: /usr/cvsroot/magic-8.0/resis/ResJunct.c,v 1.1.1.1 2008/02/03 20:43:50 tim Exp $"; #endif /* not lint */ #include #include #include #include #include "utils/magic.h" #include "utils/geometry.h" #include "utils/geofast.h" #include "tiles/tile.h" #include "utils/hash.h" #include "database/database.h" #include "database/databaseInt.h" #include "utils/malloc.h" #include "textio/textio.h" #include "extract/extract.h" #include "extract/extractInt.h" #include "windows/windows.h" #include "dbwind/dbwind.h" #include "utils/stack.h" #include "utils/tech.h" #include "textio/txcommands.h" #include "resis/resis.h" /* *------------------------------------------------------------------------- * * ResNewSDDevice -- called when a device is reached via a piece of * diffusion. (Devices reached via poly, i.e. * gates, are handled by ResEachTile.) * * Results:none * * Side Effects: determines to which terminal (source or drain) node * is connected. Makes new node if node hasn't already been created . * Allocates breakpoint in current tile for device. * *------------------------------------------------------------------------- */ void ResNewSDDevice(tile, tp, xj, yj, direction, PendingList) Tile *tile, *tp; int xj, yj, direction; resNode **PendingList; { resNode *resptr; resDevice *resDev; tElement *tcell; int newnode; tileJunk *j; newnode = FALSE; j = (tileJunk *) tp->ti_client; resDev = j->deviceList; if ((j->sourceEdge & direction) != 0) { if (resDev->rd_fet_source == (resNode *) NULL) { resptr = (resNode *) mallocMagic((unsigned)(sizeof(resNode))); newnode = TRUE; resDev->rd_fet_source = resptr; } else { resptr = resDev->rd_fet_source; } } else { if (resDev->rd_fet_drain == (resNode *) NULL) { resptr = (resNode *) mallocMagic((unsigned)(sizeof(resNode))); newnode = TRUE; resDev->rd_fet_drain = resptr; } else { resptr = resDev->rd_fet_drain; } } if (newnode) { tcell = (tElement *) mallocMagic((unsigned)(sizeof(tElement))); tcell->te_nextt = NULL; tcell->te_thist = j->deviceList; InitializeNode(resptr, xj, yj, RES_NODE_DEVICE); resptr->rn_te = tcell; ResAddToQueue(resptr, PendingList); } NEWBREAK(resptr, tile, xj, yj, NULL); } /* *------------------------------------------------------------------------- * * ResNewSubDevice -- called when a device is reached via a substrate. * * Results:none * * Side Effects: Makes new node if node hasn't already been created. * Allocates breakpoint in current tile for device. * *------------------------------------------------------------------------- */ void ResNewSubDevice(tile, tp, xj, yj, direction, PendingList) Tile *tile, *tp; int xj, yj, direction; resNode **PendingList; { resNode *resptr; resDevice *resDev; tElement *tcell; int newnode; tileJunk *j; newnode = FALSE; j = (tileJunk *) tp->ti_client; resDev = j->deviceList; /* Arrived at a device that has a terminal connected to substrate */ /* that is not a FET bulk terminal (e.g., varactor, diode). */ if (resDev->rd_nterms < 4) return; if (resDev->rd_fet_subs == (resNode *) NULL) { resptr = (resNode *) mallocMagic((unsigned)(sizeof(resNode))); newnode = TRUE; resDev->rd_fet_subs = resptr; } else { resptr = resDev->rd_fet_subs; } if (newnode) { tcell = (tElement *) mallocMagic((unsigned)(sizeof(tElement))); tcell->te_nextt = NULL; tcell->te_thist = j->deviceList; InitializeNode(resptr, xj, yj, RES_NODE_DEVICE); resptr->rn_te = tcell; ResAddToQueue(resptr, PendingList); } NEWBREAK(resptr, tile, xj, yj, NULL); } /* *------------------------------------------------------------------------- * * ResProcessJunction-- Called whenever a tile connecting to the tile being * worked on is found. If a junction is already present, its address is * returned. Otherwise, a new junction is made. * * Results: None. * * Side Effects: Junctions may be created. * *------------------------------------------------------------------------- */ void ResProcessJunction(tile, tp, xj, yj, NodeList) Tile *tile, *tp; int xj, yj; resNode **NodeList; { ResJunction *junction; resNode *resptr; jElement *jcell; tileJunk *j0 = (tileJunk *)tile->ti_client; tileJunk *j2 = (tileJunk *)tp->ti_client; #ifdef PARANOID if (tile == tp) { TxError("Junction being made between tile and itself \n"); return; } #endif if (j2->tj_status & RES_TILE_DONE) return; resptr = (resNode *) mallocMagic((unsigned)(sizeof(resNode))); resptr->rn_te = (tElement *) NULL; junction = (ResJunction *) mallocMagic((unsigned)(sizeof(ResJunction))); jcell = (jElement *) mallocMagic((unsigned)(sizeof(jElement))); InitializeNode(resptr, xj, yj, RES_NODE_JUNCTION); resptr->rn_je = jcell; ResAddToQueue(resptr, NodeList); jcell->je_thisj = junction; jcell->je_nextj = NULL; junction->rj_status = FALSE; junction->rj_jnode = resptr; junction->rj_Tile[0] = tile; junction->rj_Tile[1] = tp; junction->rj_loc.p_x =xj; junction->rj_loc.p_y =yj; junction->rj_nextjunction[0] = j0->junctionList; j0->junctionList = junction; junction->rj_nextjunction[1] = j2->junctionList; j2->junctionList = junction; NEWBREAK(junction->rj_jnode,tile, junction->rj_loc.p_x, junction->rj_loc.p_y, NULL); NEWBREAK(junction->rj_jnode,tp, junction->rj_loc.p_x, junction->rj_loc.p_y, NULL); }