diff --git a/resis/ResBasic.c b/resis/ResBasic.c index 378f3048..45b91c5a 100644 --- a/resis/ResBasic.c +++ b/resis/ResBasic.c @@ -76,101 +76,6 @@ resMakePortBreakpoints(tile, list) freeMagic1_end(&mm1); } -/* - * Structure used by ResEachTile for the callback to ResMultiPlaneFunc() - * to pass a pointer to the tile being processed, and the terminal being - * searched. - */ - -typedef struct tile_and_term -{ - Tile *tat_tile; - int tat_term; -} TileAndTerm; - -/* - *-------------------------------------------------------------------------- - * - * ResMultiPlaneFunc--- - * - * If device is found overlapping one of its source/drain types, then - * generate a new device at the center of the tile and add to ResNodeQueue. - * - * Results: - * Always 0 to keep the search going. - * - * Side effects: - * Adds to ResNodeQueue - * - *-------------------------------------------------------------------------- - */ - -int -ResMultiPlaneFunc(tile, dinfo, tat) - Tile *tile; - TileType dinfo; /* Not used, but needs to be handled */ - TileAndTerm *tat; -{ - Tile *tp = tat->tat_tile; - int term = tat->tat_term; - int xj, yj; - - /* Simplified split tile handling---Ignore the right side of - * tiles that have non-space types on both sides. - */ - if (IsSplit(tile)) - if (TiGetLeftType(tile) != TT_SPACE && TiGetRightType(tile) != TT_SPACE) - if (dinfo & TT_SIDE) - return 0; - - xj = (LEFT(tile) + RIGHT(tile)) / 2; - yj = (TOP(tile) + BOTTOM(tile)) / 2; - ResNewTermDevice(tp, tile, term, xj, yj, OTHERPLANE, &ResNodeQueue); - - return 0; -} - -/* - *-------------------------------------------------------------------------- - * - * ResSubstrateFunc--- - * - * If device is found overlapping its substrate type, then generate a new - * device at the center of the tile and add to ResNodeQueue. - * - * Results: - * Always 0 to keep the search going. - * - * Side effects: - * Adds to ResNodeQueue - * - *-------------------------------------------------------------------------- - */ - -int -ResSubstrateFunc(tile, dinfo, tpptr) - Tile *tile; - TileType dinfo; - Tile **tpptr; -{ - Tile *tp = *tpptr; - int xj, yj; - - /* Simplified split tile handling---Ignore the right side of - * tiles that have non-space types on both sides. - */ - if (IsSplit(tile)) - if (TiGetLeftType(tile) != TT_SPACE && TiGetRightType(tile) != TT_SPACE) - if (dinfo & TT_SIDE) - return 0; - - xj = (LEFT(tile) + RIGHT(tile)) / 2; - yj = (TOP(tile) + BOTTOM(tile)) / 2; - ResNewSubDevice(tp, tile, xj, yj, OTHERPLANE, &ResNodeQueue); - - return 0; -} - /* *-------------------------------------------------------------------------- * diff --git a/resis/ResJunct.c b/resis/ResJunct.c index 14df60a2..03f9d2fe 100644 --- a/resis/ResJunct.c +++ b/resis/ResJunct.c @@ -50,7 +50,9 @@ static char rcsid[] __attribute__ ((unused)) = "$Header: /usr/cvsroot/magic-8.0/ void ResNewTermDevice(tile, tp, n, xj, yj, direction, PendingList) Tile *tile, *tp; - int n, xj, yj, direction; + int n; /* Terminal index */ + int xj, yj; /* Location of connection */ + int direction; /* Direction of current */ resNode **PendingList; { resNode *resptr = NULL; @@ -70,29 +72,39 @@ ResNewTermDevice(tile, tp, n, xj, yj, direction, PendingList) ri = (resInfo *) TiGetClientPTR(tp); resDev = ri->deviceList; if (resDev == NULL) return; /* Shouldn't happen? */ - if ((((ri->sourceEdge & direction) != 0) && (resDev->rd_nterms == 4)) - || (resDev->rd_nterms > 2)) + + /* Set the terminal indicated (source or drain). If the terminal + * indicated is already set, then create a new breakpoint on the + * terminal. However, to handle cases where a device may have + * source and drain tied to the same net, if there is an existing + * entry and the edge direction is opposite of "direction", then + * create a new terminal on the other side (i.e., permute source + * and drain). + */ + + if (resDev->rd_terminals[2 + n] == (resNode *)NULL) { - 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; + resptr = (resNode *) mallocMagic((unsigned)(sizeof(resNode))); + newnode = TRUE; + resDev->rd_terminals[2 + n] = resptr; } - else if (resDev->rd_nterms > 3) + else if (((ri->sourceEdge & direction) != 0) || (resDev->rd_nterms < 4)) { - 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; + resptr = resDev->rd_terminals[2 + n]; } + else if ((n == 0) && (resDev->rd_terminals[3] == (resNode *)NULL)) + { + resptr = (resNode *) mallocMagic((unsigned)(sizeof(resNode))); + newnode = TRUE; + resDev->rd_terminals[3] = resptr; + } + else if ((n == 1) && (resDev->rd_terminals[2] == (resNode *)NULL)) + { + resptr = (resNode *) mallocMagic((unsigned)(sizeof(resNode))); + newnode = TRUE; + resDev->rd_terminals[2] = resptr; + } + if (newnode) { tcell = (tElement *) mallocMagic((unsigned)(sizeof(tElement))); diff --git a/resis/ResMain.c b/resis/ResMain.c index e99905ee..405f2280 100644 --- a/resis/ResMain.c +++ b/resis/ResMain.c @@ -937,6 +937,7 @@ resMakeDevFunc(tile, dinfo, cx) { if (DBPlane(ttype) != DBPlane(thisDev->type)) return 0; /* Completely different device? */ + thisDev->type = ttype; } @@ -1362,6 +1363,27 @@ ResExtractNet(node, resisdata, cellname) freeMagic(thisDev); continue; } + else if (thisDev->type != tptr->thisDev->rs_ttype) + { + /* The type changed. Note that when reading the .ext file, only + * the device name is given. If the device name maps to multiple + * entries, then it may point to the wrong type. Regardless of + * the reason, rewrite the tptr->thisDev and local thisDev records + * to match the actual device at the location. + */ + thisDev->type = tptr->thisDev->rs_ttype; + for (devptr = ExtCurStyle->exts_device[thisDev->type]; devptr; + devptr = devptr->exts_next) + { + if (!strcmp(devptr->exts_deviceName, + tptr->thisDev->rs_devptr->exts_deviceName)) + { + tptr->thisDev->rs_devptr = devptr; + thisDev->devptr = devptr; + break; + } + } + } thisDev->nextDev = DevTiles; DevTiles = thisDev;