diff --git a/VERSION b/VERSION index 8b702771..1d110651 100644 --- a/VERSION +++ b/VERSION @@ -1 +1 @@ -8.3.164 +8.3.182 diff --git a/calma/CalmaRdcl.c b/calma/CalmaRdcl.c index 71be0d79..ee80b888 100644 --- a/calma/CalmaRdcl.c +++ b/calma/CalmaRdcl.c @@ -882,7 +882,8 @@ calmaElementSref(filename) if (rtype == CALMA_PROPATTR) { READI2(propAttrType); - if (propAttrType == CALMA_PROP_USENAME) + if (propAttrType == CALMA_PROP_USENAME || + propAttrType == CALMA_PROP_USENAME_STD) { char *s; @@ -1262,7 +1263,19 @@ calmaFindCell(name, was_called, predefined) if (was_called) *was_called = FALSE; } else - if (was_called) *was_called = TRUE; + { + if (was_called) + { + if (*was_called == TRUE) + { + def = DBCellLookDef(name); + if ((def != NULL) && (def->cd_flags & CDAVAILABLE)) + if (CalmaNoDuplicates) + if (predefined) *predefined = TRUE; + } + *was_called = TRUE; + } + } return (CellDef *) HashGetValue(h); } diff --git a/calma/CalmaRead.c b/calma/CalmaRead.c index 9857f8d0..c9b300d2 100644 --- a/calma/CalmaRead.c +++ b/calma/CalmaRead.c @@ -46,6 +46,7 @@ static char rcsid[] __attribute__ ((unused)) = "$Header: /usr/cvsroot/magic-8.0/ #include "textio/textio.h" #include "calma/calmaInt.h" #include "commands/commands.h" /* for CmdGetRootPoint */ +#include "utils/main.h" /* for EditCellUse */ #include "utils/undo.h" /* Globals for Calma reading */ @@ -164,6 +165,12 @@ CalmaReadFile(file, filename) static int skipBeforeLib[] = { CALMA_LIBDIRSIZE, CALMA_SRFNAME, CALMA_LIBSECUR, -1 }; + if (EditCellUse == (CellUse *)NULL) + { + TxError("Cannot read GDS: There is no edit cell.\n"); + return; + } + /* We will use full cell names as keys in this hash table */ CIFReadCellInit(0); diff --git a/calma/CalmaWrite.c b/calma/CalmaWrite.c index cb1857cd..c4eb4127 100644 --- a/calma/CalmaWrite.c +++ b/calma/CalmaWrite.c @@ -26,6 +26,7 @@ static char rcsid[] __attribute__ ((unused)) ="$Header: /usr/cvsroot/magic-8.0/c #include #include #include +#include /* for htons() */ #ifdef SYSV #include #else @@ -146,6 +147,7 @@ int calmaPaintLayerType; */ HashTable calmaLibHash; HashTable calmaPrefixHash; +HashTable calmaUndefHash; /* Imports */ extern time_t time(); @@ -285,6 +287,8 @@ CalmaWrite(rootDef, f) int oldCount = DBWFeedbackCount, problems; bool good; CellUse dummy; + HashEntry *he; + HashSearch hs; /* * Do not attempt to write anything if a CIF/GDS output style @@ -298,6 +302,7 @@ CalmaWrite(rootDef, f) HashInit(&calmaLibHash, 32, 0); HashInit(&calmaPrefixHash, 32, 0); + HashInit(&calmaUndefHash, 32, 0); /* * Make sure that the entire hierarchy rooted at rootDef is @@ -337,7 +342,31 @@ CalmaWrite(rootDef, f) * to insure that each child cell is output before it is used. The * root cell is output last. */ - (void) calmaProcessDef(rootDef, f, CalmaDoLibrary); + calmaProcessDef(rootDef, f, CalmaDoLibrary); + + /* + * Check for any cells that were instanced in the output definition + * (by dumping a GDS file from a read-only view) but were never + * defined (because the dumped GDS contained undefined references). + * If these are in the database but were not part of the tree of + * rootDef, then output them at the end. + */ + HashStartSearch(&hs); + while ((he = HashNext(&calmaUndefHash, &hs)) != NULL) + { + char *refname = (char *)HashGetValue(he); + if (refname && (refname[0] == '0')) + { + CellDef *extraDef; + + extraDef = DBCellLookDef((char *)he->h_key.h_name); + if (extraDef != NULL) + calmaProcessDef(extraDef, f, FALSE); + else + TxError("Error: Cell %s is not defined in the output file!\n", + refname + 1); + } + } /* Finish up by outputting the end-of-library marker */ calmaOutRH(4, CALMA_ENDLIB, CALMA_NODATA, f); @@ -355,6 +384,7 @@ CalmaWrite(rootDef, f) HashFreeKill(&calmaLibHash); HashKill(&calmaPrefixHash); + HashFreeKill(&calmaUndefHash); return (good); } @@ -409,14 +439,47 @@ calmaDumpStructure(def, outf, calmaDefHash, filename) calmaOutDate(def->cd_timestamp, outf); calmaOutDate(time((time_t *) 0), outf); - /* Find the structure's unique prefix, in case structure calls subcells */ - /* that are not yet defined. */ + /* Do a quick check of the calmaUndefHash table to see if this cell */ + /* was previously used in a GDS file that does not define it (a GDS */ + /* addendum library). */ - he2 = HashFind(&calmaLibHash, filename); - if (he2 == NULL) - TxError("Fatal error: Library %s not recorded!\n", filename); + he = HashLookOnly(&calmaUndefHash, strname); + if (he != NULL) + { + HashSearch hs; + char *undefname = (char *)HashGetValue(he); + + HashStartSearch(&hs); + while ((he2 = HashNext(&calmaLibHash, &hs)) != NULL) + { + prefix = (char *)HashGetValue(he2); + if (!strncmp(prefix, undefname + 1, strlen(prefix))) + break; + } + if (he2 == NULL) + { + prefix = (char *)NULL; + TxError("Error: Unreferenced cell %s prefix is unrecorded!\n", + undefname); + } + else + { + /* Remove this entry from the hash table */ + freeMagic(undefname); + HashRemove(&calmaUndefHash, strname); + } + } else - prefix = (char *)HashGetValue(he2); + { + /* Find the structure's unique prefix, in case structure calls */ + /* subcells that are not yet defined. */ + + he2 = HashFind(&calmaLibHash, filename); + if (he2 == NULL) + TxError("Fatal error: Library %s not recorded!\n", filename); + else + prefix = (char *)HashGetValue(he2); + } /* Prefix structure name with def name, and output new structure name */ he = HashFind(calmaDefHash, strname); @@ -456,16 +519,20 @@ calmaDumpStructure(def, outf, calmaDefHash, filename) if (edef != NULL) { bool isAbstract, isReadOnly; - char *chklibname, *dotptr; + char *chklibname, *filenamesubbed = NULL; /* Is view abstract? */ DBPropGet(edef, "LEFview", &isAbstract); chklibname = (char *)DBPropGet(edef, "GDS_FILE", &isReadOnly); - dotptr = strrchr(filename, '.'); - if (dotptr) *dotptr = '\0'; - /* Is the library name the same as the filename (less extension)? */ - if (isAbstract && isReadOnly && !strcmp(filename, chklibname)) + if (isAbstract && isReadOnly) + { + filenamesubbed = StrDup(NULL, filename); + DBPathSubstitute(filename, filenamesubbed, edef); + } + + /* Is the library name the same as the filename? */ + if (isAbstract && isReadOnly && !strcmp(filenamesubbed, chklibname)) { /* Same library, so keep the cellname and mark the cell */ /* as having been written to GDS. */ @@ -487,7 +554,7 @@ calmaDumpStructure(def, outf, calmaDefHash, filename) HashSetValue(he, (char *)newnameptr); } } - if (dotptr) *dotptr = '.'; + if (filenamesubbed) freeMagic(filenamesubbed); } else { @@ -614,11 +681,12 @@ calmaFullDump(def, fi, outf, filename) char *filename; { int version, rval; - char *libname = NULL, uniqlibname[4]; + char *libname = NULL, *testlib, uniqlibname[4]; char *sptr, *viewopts; bool isAbstract; HashTable calmaDefHash; - HashEntry *he; + HashSearch hs; + HashEntry *he, *he2; static int hdrSkip[] = { CALMA_FORMAT, CALMA_MASK, CALMA_ENDMASKS, CALMA_REFLIBS, CALMA_FONTS, CALMA_ATTRTABLE, @@ -645,6 +713,11 @@ calmaFullDump(def, fi, outf, filename) // Record the GDS library so it will not be processed again. he = HashFind(&calmaLibHash, filename); + if ((char *)HashGetValue(he) != NULL) + { + TxPrintf("Library %s has already been processed\n", libname); + return; + } /* If property LEFview is defined as "no_prefix" instead of "TRUE", * then do not create a unique prefix for subcells. This is generally @@ -672,8 +745,6 @@ calmaFullDump(def, fi, outf, filename) */ while (TRUE) { - HashEntry *he2; - rval = random() % 26; rval = 'A' + rval; uniqlibname[0] = (char)(rval & 127); @@ -700,6 +771,24 @@ calmaFullDump(def, fi, outf, filename) calmaSkipExact(CALMA_ENDLIB); done: + + /* Check that all references were resolved. If not, then it is + * probably because a library was an "addendum"-type library + * referencing things in other libraries. Move those cell + * references to the calmaUndefHash before killing calmaDefHash. + */ + + HashStartSearch(&hs); + while ((he = HashNext(&calmaDefHash, &hs)) != NULL) + { + char *refname = (char *)HashGetValue(he); + if (refname[0] == '0') + { + he2 = HashFind(&calmaUndefHash, (char *)he->h_key.h_name); + HashSetValue(he2, StrDup(NULL, refname)); + } + } + HashFreeKill(&calmaDefHash); if (libname != NULL) freeMagic(libname); return; @@ -1346,7 +1435,7 @@ calmaWriteUseFunc(use, f) if (!calmaIsUseNameDefault(use->cu_def->cd_name, use->cu_id)) { calmaOutRH(6, CALMA_PROPATTR, CALMA_I2, f); - calmaOutI2(CALMA_PROP_USENAME, f); + calmaOutI2(CALMA_PROP_USENAME_STD, f); calmaOutStringRecord(CALMA_PROPVALUE, use->cu_id, f); } diff --git a/calma/calmaInt.h b/calma/calmaInt.h index 297ceb4d..3271c106 100644 --- a/calma/calmaInt.h +++ b/calma/calmaInt.h @@ -99,6 +99,7 @@ #define CALMA_NUMRECORDTYPES 60 /* Number of above types */ /* Property types defined for magic */ +#define CALMA_PROP_USENAME_STD 61 /* To record non-default cell use ids */ #define CALMA_PROP_USENAME 98 /* To record non-default cell use ids */ #define CALMA_PROP_ARRAY_LIMITS 99 /* To record non-default array limits */ diff --git a/cif/CIFgen.c b/cif/CIFgen.c index db9f7609..da5875be 100644 --- a/cif/CIFgen.c +++ b/cif/CIFgen.c @@ -4896,13 +4896,14 @@ CIFGenLayer(op, area, cellDef, origDef, temps, hier, clientdata) TxError("%s: Cannot read rectangle values.\n", propname); break; } + cifPlane = curPlane; cifScale = (CIFCurStyle) ? CIFCurStyle->cs_scaleFactor : 1; bbox.r_xbot *= cifScale; bbox.r_xtop *= cifScale; bbox.r_ybot *= cifScale; bbox.r_ytop *= cifScale; cifScale = 1; - DBNMPaintPlane(cifPlane, CIF_SOLIDTYPE, &bbox, + DBNMPaintPlane(curPlane, CIF_SOLIDTYPE, &bbox, CIFPaintTable, (PaintUndoInfo *)NULL); for (j = 0; j < 4; j++) { diff --git a/cif/CIFhier.c b/cif/CIFhier.c index 9d2860e5..e7219ed5 100644 --- a/cif/CIFhier.c +++ b/cif/CIFhier.c @@ -911,6 +911,52 @@ CIFGenSubcells(def, area, output) UndoEnable(); } +/* + * ---------------------------------------------------------------------------- + * + * ---------------------------------------------------------------------------- + */ + +int +cifHierElementFuncLow(use, transform, x, y, checkArea) + CellUse *use; /* CellUse being array-checked. */ + Transform *transform; /* Transform from this instance to + * the parent. + */ + int x, y; /* Indices of this instance. */ + Rect *checkArea; /* Area (in parent coords) to be + * CIF-generated. + */ +{ + if (((x - use->cu_xlo) < 2) && ((y - use->cu_ylo) < 2)) + return cifHierElementFunc(use, transform, x, y, checkArea); + else + return 0; +} + +/* + * ---------------------------------------------------------------------------- + * + * ---------------------------------------------------------------------------- + */ + +int +cifHierElementFuncHigh(use, transform, x, y, checkArea) + CellUse *use; /* CellUse being array-checked. */ + Transform *transform; /* Transform from this instance to + * the parent. + */ + int x, y; /* Indices of this instance. */ + Rect *checkArea; /* Area (in parent coords) to be + * CIF-generated. + */ +{ + if (((use->cu_xhi - x) < 2) && ((use->cu_yhi - y) < 2)) + return cifHierElementFunc(use, transform, x, y, checkArea); + else + return 0; +} + /* * ---------------------------------------------------------------------------- * @@ -1139,7 +1185,6 @@ cifHierArrayFunc(scx, output) Rect childArea, parentArea, A, B, C, D, expandedArea; CellUse *use; int radius, xsep, ysep, xsize, ysize, nx, ny, i, oldTileOps; - int xhi, yhi; bool anyInteractions = FALSE; use = scx->scx_use; @@ -1147,17 +1192,9 @@ cifHierArrayFunc(scx, output) if ((use->cu_xlo == use->cu_xhi) && (use->cu_ylo == use->cu_yhi)) return 2; - /* We only want interactions between neighboring cells, so reduce */ - /* the array size to at most 2x2, process, then restore the */ - /* original array count. */ - - xhi = use->cu_xhi; - yhi = use->cu_yhi; - - if (use->cu_xlo != use->cu_xhi) - use->cu_xhi = use->cu_xlo + ((use->cu_xlo < use->cu_xhi) ? 1 : -1); - if (use->cu_ylo != use->cu_yhi) - use->cu_yhi = use->cu_ylo + ((use->cu_ylo < use->cu_yhi) ? 1 : -1); + /* We only want interactions between neighboring cells, so only */ + /* look at the bottom-left 2x2 set when calculating A and B, and */ + /* only look at the top-right 2x2 set when calculating C and D. */ /* Compute the sizes and separations of elements, in coordinates * of the parent. If the array is 1-dimensional, we set the @@ -1200,6 +1237,12 @@ cifHierArrayFunc(scx, output) * into CIFTotalPlanes. Note: in each case we have to yank a larger * area than we check, in order to include material that will be * bloated or shrunk. + * + * (Updated 6/7/2021) A and B should be calculated and processed + * completely independently of C and D, or else if the array is + * small and the radius is large, then results from one will get + * picked up when making copies of the other, resulting in things + * getting painted out-of-bounds. */ /* A */ @@ -1211,7 +1254,7 @@ cifHierArrayFunc(scx, output) A.r_ybot = use->cu_bbox.r_ybot + ysep - radius; A.r_ytop = use->cu_bbox.r_ybot + ysize + radius; GEO_EXPAND(&A, CIFCurStyle->cs_radius, &expandedArea); - (void) DBArraySr(use, &expandedArea, cifHierElementFunc, + (void) DBArraySr(use, &expandedArea, cifHierElementFuncLow, (ClientData) &A); CIFErrorDef = use->cu_parent; CIFGen(CIFTotalDef, use->cu_def, &A, CIFTotalPlanes, @@ -1220,24 +1263,6 @@ cifHierArrayFunc(scx, output) anyInteractions = TRUE; } - /* C */ - - if (xsep < xsize + radius) - { - C.r_xbot = use->cu_bbox.r_xtop - xsize - radius; - C.r_xtop = use->cu_bbox.r_xtop - xsep + radius; - C.r_ybot = use->cu_bbox.r_ytop - ysize - radius; - C.r_ytop = use->cu_bbox.r_ytop + radius; - GEO_EXPAND(&C, CIFCurStyle->cs_radius, &expandedArea); - (void) DBArraySr(use, &expandedArea, cifHierElementFunc, - (ClientData) &C); - CIFErrorDef = use->cu_parent; - CIFGen(CIFTotalDef, use->cu_def, &C, CIFTotalPlanes, - &CIFCurStyle->cs_hierLayers, FALSE, TRUE, TRUE, - (ClientData)NULL); - anyInteractions = TRUE; - } - if ((xsep < xsize + radius) && (ysep < ysize + radius)) { /* B */ @@ -1247,31 +1272,16 @@ cifHierArrayFunc(scx, output) B.r_ybot = use->cu_bbox.r_ybot - radius; B.r_ytop = use->cu_bbox.r_ybot + ysep - radius; GEO_EXPAND(&B, CIFCurStyle->cs_radius, &expandedArea); - (void) DBArraySr(use, &expandedArea, cifHierElementFunc, + (void) DBArraySr(use, &expandedArea, cifHierElementFuncLow, (ClientData) &B); CIFErrorDef = use->cu_parent; CIFGen(CIFTotalDef, use->cu_def, &B, CIFTotalPlanes, &CIFCurStyle->cs_hierLayers, FALSE, TRUE, TRUE, (ClientData)NULL); - - /* D */ - - D.r_xbot = use->cu_bbox.r_xtop - xsep + radius; - D.r_xtop = use->cu_bbox.r_xtop + radius; - D.r_ybot = use->cu_bbox.r_ytop - ysize - radius; - D.r_ytop = use->cu_bbox.r_ytop - ysep + radius; - GEO_EXPAND(&D, CIFCurStyle->cs_radius, &expandedArea); - (void) DBArraySr(use, &expandedArea, cifHierElementFunc, - (ClientData) &D); - CIFErrorDef = use->cu_parent; - CIFGen(CIFTotalDef, use->cu_def, &D, CIFTotalPlanes, - &CIFCurStyle->cs_hierLayers, FALSE, TRUE, TRUE, - (ClientData)NULL); } if (anyInteractions) { - /* Remove redundant CIF that's already in the children, and * make sure everything in the kids is in the parent too. */ @@ -1308,6 +1318,155 @@ cifHierArrayFunc(scx, output) (ClientData) NULL); } + if ((nx > 1) && (ny > 1) && (xsep < xsize + radius) + && (ysep < ysize + radius)) + { + /* The bottom edge of the array (from B). */ + + cifHierXSpacing = xsep * scale; + cifHierYSpacing = 0; + cifHierXCount = nx-1; + cifHierYCount = 1; + SCALE(&B, scale, &cifArea); + (void) DBSrPaintArea((Tile *) NULL, CIFTotalPlanes[i], + &cifArea, &CIFSolidBits, cifHierPaintArrayFunc, + (ClientData) NULL); + + /* The core of the array (copied from A and B). Copy area + * from A, but not to exceed 1/2 Y array separation, into the + * inside area of the array. If the expanded area is > 1/2 + * the array separation, then there is no need to copy from + * area B. Otherwise, copy area from B, extending up to + * the bottom of the area just copied, and not to exceed + * 1/2 the X array separation. + */ + + cifHierXSpacing = xsep * scale; + cifHierYSpacing = ysep * scale; + cifHierXCount = nx-1; + cifHierYCount = ny-1; + + /* Find top edge of cell */ + A.r_xbot = use->cu_bbox.r_xbot; + A.r_xtop = use->cu_bbox.r_xbot + xsep; + A.r_ybot = use->cu_bbox.r_ybot + ysep; + A.r_ytop = use->cu_bbox.r_ybot + ysize; + /* Expand up/down but not by more than 1/2 ysep */ + if ((2 * radius) > ysep) + { + A.r_ybot -= (ysep >> 1); + A.r_ytop += (ysep >> 1); + } + else + { + A.r_ybot -= radius; + A.r_ytop += radius; + } + SCALE(&A, scale, &cifArea); + (void) DBSrPaintArea((Tile *) NULL, CIFTotalPlanes[i], + &cifArea, &CIFSolidBits, cifHierPaintArrayFunc, + (ClientData) NULL); + + /* If the radius is more than half of ysep then there */ + /* is nothing left that needs to be copied. */ + + if ((2 * radius) < ysep) + { + /* Find right edge of cell */ + B.r_ybot = use->cu_bbox.r_ybot; + B.r_ytop = use->cu_bbox.r_ybot + ysep; + + if (B.r_ytop > A.r_ybot) B.r_ytop = A.r_ybot; + + B.r_xbot = use->cu_bbox.r_xbot + xsep; + B.r_xtop = use->cu_bbox.r_xbot + xsize; + /* Expand left/right but not by more than 1/2 xsep */ + if ((2 * radius) > xsep) + { + B.r_xbot -= (xsep >> 1); + B.r_xtop += (xsep >> 1); + } + else + { + B.r_xbot -= radius; + B.r_xtop += radius; + } + SCALE(&B, scale, &cifArea); + (void) DBSrPaintArea((Tile *) NULL, CIFTotalPlanes[i], + &cifArea, &CIFSolidBits, cifHierPaintArrayFunc, + (ClientData) NULL); + } + } + } + CIFHierRects += CIFTileOps - oldTileOps; + } + + /* Clean up from areas A and B */ + cifHierCleanup(); + anyInteractions = FALSE; + + /* Now do areas C and D */ + + /* C */ + + if (xsep < xsize + radius) + { + C.r_xbot = use->cu_bbox.r_xtop - xsize - radius; + C.r_xtop = use->cu_bbox.r_xtop - xsep + radius; + C.r_ybot = use->cu_bbox.r_ytop - ysize - radius; + C.r_ytop = use->cu_bbox.r_ytop + radius; + GEO_EXPAND(&C, CIFCurStyle->cs_radius, &expandedArea); + (void) DBArraySr(use, &expandedArea, cifHierElementFuncHigh, + (ClientData) &C); + CIFErrorDef = use->cu_parent; + CIFGen(CIFTotalDef, use->cu_def, &C, CIFTotalPlanes, + &CIFCurStyle->cs_hierLayers, FALSE, TRUE, TRUE, + (ClientData)NULL); + anyInteractions = TRUE; + } + + if ((xsep < xsize + radius) && (ysep < ysize + radius)) + { + /* D */ + + D.r_xbot = use->cu_bbox.r_xtop - xsep + radius; + D.r_xtop = use->cu_bbox.r_xtop + radius; + D.r_ybot = use->cu_bbox.r_ytop - ysize - radius; + D.r_ytop = use->cu_bbox.r_ytop - ysep + radius; + GEO_EXPAND(&D, CIFCurStyle->cs_radius, &expandedArea); + (void) DBArraySr(use, &expandedArea, cifHierElementFuncHigh, + (ClientData) &D); + CIFErrorDef = use->cu_parent; + CIFGen(CIFTotalDef, use->cu_def, &D, CIFTotalPlanes, + &CIFCurStyle->cs_hierLayers, FALSE, TRUE, TRUE, + (ClientData)NULL); + } + + if (anyInteractions) + { + + /* Remove redundant CIF that's already in the children, and + * make sure everything in the kids is in the parent too. + */ + + CIFErrorDef = use->cu_parent; + cifCheckAndErase(CIFCurStyle); + + /* Lastly, paint everything back from our local planes into + * the planes of the caller. In doing this, stuff has to + * be replicated many times over to cover each of the array + * interaction areas. + */ + + oldTileOps = CIFTileOps; + for (i=0; ics_nLayers; i++) + { + int scale = CIFCurStyle->cs_scaleFactor; + Rect cifArea; + + cifHierCurPlane = output[i]; + CurCifLayer = CIFCurStyle->cs_layers[i]; /* for growSliver */ + /* The top edge of the array (from C). */ if ((nx > 1) && (xsep < xsize + radius)) @@ -1325,17 +1484,6 @@ cifHierArrayFunc(scx, output) if ((nx > 1) && (ny > 1) && (xsep < xsize + radius) && (ysep < ysize + radius)) { - /* The bottom edge of the array (from B). */ - - cifHierXSpacing = xsep * scale; - cifHierYSpacing = 0; - cifHierXCount = nx-1; - cifHierYCount = 1; - SCALE(&B, scale, &cifArea); - (void) DBSrPaintArea((Tile *) NULL, CIFTotalPlanes[i], - &cifArea, &CIFSolidBits, cifHierPaintArrayFunc, - (ClientData) NULL); - /* The right edge of the array (from D). */ cifHierXSpacing = 0; @@ -1346,36 +1494,12 @@ cifHierArrayFunc(scx, output) (void) DBSrPaintArea((Tile *) NULL, CIFTotalPlanes[i], &cifArea, &CIFSolidBits, cifHierPaintArrayFunc, (ClientData) NULL); - - /* The core of the array (from A and B). This code is a bit - * tricky in order to work correctly even for arrays where - * radius < ysep. The "if" statement handles this case. - */ - - cifHierXSpacing = xsep * scale; - cifHierYSpacing = ysep * scale; - cifHierXCount = nx-1; - cifHierYCount = ny-1; - parentArea.r_xbot = A.r_xtop - xsep; - parentArea.r_ybot = A.r_ytop - ysep; - if (parentArea.r_ybot > B.r_ytop) parentArea.r_ybot = B.r_ytop; - parentArea.r_xtop = A.r_xtop; - parentArea.r_ytop = A.r_ytop; - SCALE(&parentArea, scale, &cifArea); - (void) DBSrPaintArea((Tile *) NULL, CIFTotalPlanes[i], - &cifArea, &CIFSolidBits, cifHierPaintArrayFunc, - (ClientData) NULL); } } CIFHierRects += CIFTileOps - oldTileOps; } cifHierCleanup(); - - /* Restore the array bounds of the array */ - use->cu_xhi = xhi; - use->cu_yhi = yhi; - return 2; } diff --git a/commands/CmdCD.c b/commands/CmdCD.c index 1ba9e472..9b64a4f7 100644 --- a/commands/CmdCD.c +++ b/commands/CmdCD.c @@ -4261,6 +4261,11 @@ cmdDumpParseArgs(cmdName, w, cmd, dummy, scx) cellnameptr++; fullpathname = (char *)mallocMagic(strlen(cmd->tx_argv[1]) + 2); strcpy(fullpathname, cmd->tx_argv[1]); + + /* If the name still has ".mag" attached, then strip it. */ + clen = strlen(fullpathname); + if ((clen > 4) && !strcmp(fullpathname + clen - 4, ".mag")) + *(fullpathname + clen - 4) = '\0'; } else { @@ -4307,8 +4312,8 @@ cmdDumpParseArgs(cmdName, w, cmd, dummy, scx) def = DBCellLookDef(newcellname); uniqchar++; } - TxError("Renaming cell to \"%s\" to avoid conflict.", newcellname); - def = DBCellNewDef(cellnameptr); + TxError("Renaming cell to \"%s\" to avoid conflict.\n", newcellname); + def = DBCellNewDef(newcellname); StrDup(&def->cd_file, fullpathname); freeMagic(newcellname); } @@ -4396,15 +4401,10 @@ cmdDumpParseArgs(cmdName, w, cmd, dummy, scx) TxError("Keyword must be followed by a reference point\n"); goto usage; } - if (StrIsInt(av[1])) + else if (ac == 3) { - childPoint.p_x = atoi(av[1]); - if (ac < 3 || !StrIsInt(av[2])) - { - TxError("Must provide two coordinates\n"); - goto usage; - } - childPoint.p_y = atoi(av[2]); + childPoint.p_x = cmdParseCoord(w, av[1], TRUE, TRUE); + childPoint.p_y = cmdParseCoord(w, av[2], TRUE, FALSE); av += 3; ac -= 3; } @@ -4455,15 +4455,10 @@ cmdDumpParseArgs(cmdName, w, cmd, dummy, scx) TxError("Keyword must be followed by a reference point\n"); goto usage; } - if (StrIsInt(av[1])) + else if (ac == 3) { - editPoint.p_x = atoi(av[1]); - if (ac < 3 || !StrIsInt(av[2])) - { - TxError("Must provide two coordinates\n"); - goto usage; - } - editPoint.p_y = atoi(av[2]); + editPoint.p_x = cmdParseCoord(w, av[1], TRUE, TRUE); + editPoint.p_y = cmdParseCoord(w, av[2], TRUE, FALSE); av += 3; ac -= 3; GeoTransPoint(&EditToRootTransform, &editPoint, diff --git a/commands/CmdFI.c b/commands/CmdFI.c index 80bdd153..2441c3e7 100644 --- a/commands/CmdFI.c +++ b/commands/CmdFI.c @@ -2008,14 +2008,18 @@ CmdFlatten(w, cmd) return; } /* create the new def */ - if (newdef = DBCellLookDef(destname)) + newdef = DBCellLookDef(destname); + if ((newdef != NULL) && (dobox == FALSE)) { TxError("%s already exists\n",destname); return; } - newdef = DBCellNewDef(destname); - ASSERT(newdef, "CmdFlatten"); - DBCellSetAvail(newdef); + else if (newdef == NULL) + { + newdef = DBCellNewDef(destname); + ASSERT(newdef, "CmdFlatten"); + DBCellSetAvail(newdef); + } newuse = DBCellNewUse(newdef, (char *) NULL); (void) StrDup(&(newuse->cu_id), "Flattened cell"); DBSetTrans(newuse, &GeoIdentityTransform); @@ -2063,5 +2067,6 @@ CmdFlatten(w, cmd) if (xMask != CU_DESCEND_ALL) DBCellCopyAllCells(&scx, xMask, flatDestUse, (Rect *)NULL); + DBCellDeleteUse(flatDestUse); UndoEnable(); } diff --git a/database/DBcellname.c b/database/DBcellname.c index e6ee0b14..a0dd4d80 100644 --- a/database/DBcellname.c +++ b/database/DBcellname.c @@ -1612,8 +1612,9 @@ DBCellLookDef(cellName) { HashEntry *entry; - entry = HashFind(&dbCellDefTable, cellName); - return ((CellDef *) HashGetValue(entry)); + entry = HashLookOnly(&dbCellDefTable, cellName); + if (entry == (HashEntry *)NULL) return (CellDef *)NULL; + return (CellDef *)HashGetValue(entry); } diff --git a/database/database.h.in b/database/database.h.in index 1ef2d9fd..0a2ea89c 100644 --- a/database/database.h.in +++ b/database/database.h.in @@ -816,6 +816,7 @@ extern void DBTechInitContact(); extern void DBTechFinalContact(); extern void DBTechFinalConnect(); extern void DBTechInitConnect(); +extern bool DBIsContact(); /* Cell symbol table */ extern void DBCellInit(); diff --git a/dbwind/DBWprocs.c b/dbwind/DBWprocs.c index e1c05368..2d982777 100644 --- a/dbwind/DBWprocs.c +++ b/dbwind/DBWprocs.c @@ -326,6 +326,7 @@ DBWloadWindow(window, name, flags) { deleteDef = ((CellUse *)window->w_surfaceID)->cu_def; if (strcmp(deleteDef->cd_name, "(UNNAMED)") || + (GrDisplayStatus == DISPLAY_SUSPEND) || deleteDef->cd_flags & (CDMODIFIED|CDBOXESCHANGED|CDSTAMPSCHANGED)) deleteDef = NULL; } @@ -497,7 +498,7 @@ DBWloadWindow(window, name, flags) if (newEdit) { - if (EditCellUse && EditRootDef) + if ((EditCellUse && EditRootDef) && (deleteDef == NULL)) { DBWUndoOldEdit(EditCellUse, EditRootDef, &EditToRootTransform, &RootToEditTransform); @@ -549,6 +550,11 @@ DBWloadWindow(window, name, flags) /* If the cell before loading was (UNNAMED) and it was */ /* never modified, then delete it now. */ + /* Caveat: The (UNNAMED) cell could be on a push stack; */ + /* that is not fatal but should be avoided. Since the most */ + /* common use is from the toolkit scripts, then make sure */ + /* this doesn't happen within suspendall ... resumeall. */ + if (deleteDef != NULL) DBCellDelete(deleteDef->cd_name, TRUE); } diff --git a/drc/DRCcif.c b/drc/DRCcif.c index a06d8d0d..af6264d0 100644 --- a/drc/DRCcif.c +++ b/drc/DRCcif.c @@ -613,6 +613,14 @@ drcCifTile (tile, arg) if (SigInterruptPending) return 1; DRCstatTiles++; + /* For non-Manhattan tiles, if the left side of tile is not the */ + /* type that is declared by the rule, then skip the left-right */ + /* check. */ + + if (IsSplit(tile)) + if (SplitSide(tile)) + goto tbcheck; + /* * Check design rules along a vertical boundary between two tiles. * @@ -801,6 +809,15 @@ drcCifTile (tile, arg) } } +tbcheck: + + /* For non-Manhattan tiles, if the bottom side of tile is not */ + /* the type that is declared by the rule, then skip the top- */ + /* bottom check. */ + + if (IsSplit(tile)) + if (SplitSide(tile) == SplitDirection(tile)) + return 0; /* * Check design rules along a horizontal boundary between two tiles. diff --git a/drc/DRCtech.c b/drc/DRCtech.c index c61c68a8..5a8aa999 100644 --- a/drc/DRCtech.c +++ b/drc/DRCtech.c @@ -1836,6 +1836,7 @@ drcMaskSpacing(set1, set2, pmask1, pmask2, wwidth, distance, adjacency, bool needtrigger = FALSE; bool touchingok = TRUE; bool cornerok = FALSE; + bool surroundok = FALSE; if (!strcmp(adjacency, "surround_ok")) { @@ -1858,6 +1859,7 @@ drcMaskSpacing(set1, set2, pmask1, pmask2, wwidth, distance, adjacency, needtrigger = TRUE; touchingok = FALSE; needReverse = TRUE; + surroundok = TRUE; } else { @@ -2077,10 +2079,11 @@ drcMaskSpacing(set1, set2, pmask1, pmask2, wwidth, distance, adjacency, /* * Now, if set1 and set2 are distinct apply the rule for LHS in set1 - * and RHS in set2. + * and RHS in set2. HOWEVER, "surround_ok" rules are asymmetrically + * triggered and cannot be reversed between set1 and set2. */ - if (pset = (DBTypesOnSamePlane(i, j) & pmask2)) + if ((!surroundok) && (pset = (DBTypesOnSamePlane(i, j) & pmask2))) { plane = LowestMaskBit(pset); diff --git a/ext2sim/ext2sim.c b/ext2sim/ext2sim.c index ce0ad59b..507dd1ea 100644 --- a/ext2sim/ext2sim.c +++ b/ext2sim/ext2sim.c @@ -97,39 +97,39 @@ struct { short resClassSub ; /* The resistance class of the substrate of the dev */ TileType devType ; /* Magic tile type of the device */ char *defSubs ; /* The default substrate node */ -} fetInfo[MAXDEVTYPES]; +} fetInfo[TT_MAXTYPES]; typedef struct { - long visitMask:MAXDEVTYPES; + TileTypeBitMask visitMask; } nodeClient; typedef struct { HierName *lastPrefix; - long visitMask:MAXDEVTYPES; + TileTypeBitMask visitMask; } nodeClientHier; #define NO_RESCLASS -1 #define markVisited(client, rclass) \ - { (client)->visitMask |= (1<visitMask), rclass); } #define clearVisited(client) \ - { (client)->visitMask = (long)0; } + { TTMaskZero(&((client)->visitMask)); } #define beenVisited(client, rclass) \ - ( (client)->visitMask & (1<visitMask), rclass) ) #define initNodeClient(node) \ { \ (node)->efnode_client = (ClientData) mallocMagic((unsigned) (sizeof(nodeClient))); \ - (( nodeClient *)(node)->efnode_client)->visitMask = (long) 0; \ + TTMaskZero(&(( nodeClient *)(node)->efnode_client)->visitMask); \ } #define initNodeClientHier(node) \ { \ (node)->efnode_client = (ClientData) mallocMagic((unsigned) (sizeof(nodeClientHier))); \ - ((nodeClientHier *) (node)->efnode_client)->visitMask = (long) 0; \ + TTMaskZero(&(( nodeClientHier *)(node)->efnode_client)->visitMask); \ } @@ -572,7 +572,7 @@ runexttosim: /* create default fetinfo entries (MOSIS) which can be overriden by the command line arguments */ - for ( i = 0 ; i < MAXDEVTYPES ; i++ ) + for ( i = 0 ; i < TT_MAXTYPES ; i++ ) { fetInfo[i].resClassSource = NO_RESCLASS; fetInfo[i].resClassDrain = NO_RESCLASS; @@ -589,12 +589,12 @@ runexttosim: while (ExtGetDevInfo(idx++, &devname, &devtype, &s_rclass, &d_rclass, &sub_rclass, &subname)) { - if (idx == MAXDEVTYPES) + if (idx == TT_MAXTYPES) { TxError("Error: Ran out of space for device types!\n"); break; } - i = efBuildAddStr(EFDevTypes, &EFDevNumTypes, MAXDEVTYPES, devname); + i = efBuildAddStr(EFDevTypes, &EFDevNumTypes, TT_MAXTYPES, devname); if (EFStyle != NULL) { @@ -676,26 +676,26 @@ main(argc, argv) EFInit(); /* create default fetinfo entries (MOSIS) which can be overriden by the command line arguments */ - for ( i = 0 ; i < MAXDEVTYPES ; i++ ) { + for ( i = 0 ; i < TT_MAXTYPES ; i++ ) { fetInfo[i].resClassSource = NO_RESCLASS; fetInfo[i].resClassDrain = NO_RESCLASS; fetInfo[i].resClassSub = NO_RESCLASS; fetInfo[i].defSubs = NULL; fetInfo[i].devType = TT_SPACE; } - i = efBuildAddStr(EFDevTypes, &EFDevNumTypes, MAXDEVTYPES, "nfet"); + i = efBuildAddStr(EFDevTypes, &EFDevNumTypes, TT_MAXTYPES, "nfet"); fetInfo[i].resClassSource = fetInfo[i].resClassDrain = 0 ; fetInfo[i].resClassSub = NO_RESCLASS ; fetInfo[i].defSubs = "Gnd!"; - i = efBuildAddStr(EFDevTypes, &EFDevNumTypes, MAXDEVTYPES, "pfet"); + i = efBuildAddStr(EFDevTypes, &EFDevNumTypes, TT_MAXTYPES, "pfet"); fetInfo[i].resClassSource = fetInfo[i].resClassDrain = 1 ; fetInfo[i].resClassSub = 6 ; fetInfo[i].defSubs = "Vdd!"; - i = efBuildAddStr(EFDevTypes, &EFDevNumTypes, MAXDEVTYPES, "nmos"); + i = efBuildAddStr(EFDevTypes, &EFDevNumTypes, TT_MAXTYPES, "nmos"); fetInfo[i].resClassSource = fetInfo[i].resClassDrain = 0 ; fetInfo[i].resClassSub = NO_RESCLASS ; fetInfo[i].defSubs = "Gnd!"; - i = efBuildAddStr(EFDevTypes, &EFDevNumTypes, MAXDEVTYPES, "pmos"); + i = efBuildAddStr(EFDevTypes, &EFDevNumTypes, TT_MAXTYPES, "pmos"); fetInfo[i].resClassSource = fetInfo[i].resClassDrain = 1 ; fetInfo[i].resClassSub = 6 ; fetInfo[i].defSubs = "Vdd!"; @@ -896,7 +896,7 @@ simmainArgs(pargc, pargv) rClassSub = NO_RESCLASS ; if ( sscanf(rp, "%d/%s", &rClass, subsNode) != 2 ) goto usage; } - ndx = efBuildAddStr(EFDevTypes, &EFDevNumTypes, MAXDEVTYPES, cp); + ndx = efBuildAddStr(EFDevTypes, &EFDevNumTypes, TT_MAXTYPES, cp); fetInfo[ndx].resClassSource = rClass; fetInfo[ndx].resClassDrain = rClass; fetInfo[ndx].resClassSub = rClassSub; @@ -1206,9 +1206,6 @@ simdevVisit(dev, hc, scale, trans) /* Output length, width, and position as attributes */ fprintf(esSimF, " l=%g w=%g x=%g y=%g", l * scale, w * scale, r.r_xbot * scale, r.r_ybot * scale); - - /* Output tile type as an attribute for quick lookup by ResReadSim */ - fprintf(esSimF, " t=%d", fetInfo[dev->dev_type].devType); } else if ((dev->dev_class != DEV_DIODE) && (dev->dev_class != DEV_PDIODE) && (dev->dev_class != DEV_NDIODE)) { @@ -1402,7 +1399,7 @@ bool simnAPHier(dterm, hierName, resClass, scale, outf) initNodeClientHier(node); nc = (nodeClientHier *)node->efnode_client; if ( nc->lastPrefix != hierName ) { - nc->visitMask = 0; + TTMaskZero(&(nc->visitMask)); nc->lastPrefix = hierName; } if ( resClass == NO_RESCLASS || diff --git a/ext2spice/ext2hier.c b/ext2spice/ext2hier.c index 2373bb7b..717dadc9 100644 --- a/ext2spice/ext2hier.c +++ b/ext2spice/ext2hier.c @@ -1264,10 +1264,10 @@ spcnodeHierVisit(hc, node, res, cap) if (node->efnode_client) { - isConnected = (esDistrJunct) ? - (((nodeClient *)node->efnode_client)->m_w.widths != NULL) : - ((((nodeClient *)node->efnode_client)->m_w.visitMask - & DEV_CONNECT_MASK) != 0); + if (esDistrJunct) + isConnected = (((nodeClient *)node->efnode_client)->m_w.widths != NULL); + else + isConnected = !TTMaskIsZero(&((nodeClient *)node->efnode_client)->m_w.visitMask); } if (!isConnected && esDevNodesOnly) return 0; diff --git a/ext2spice/ext2spice.c b/ext2spice/ext2spice.c index b3c96123..d79a97fe 100644 --- a/ext2spice/ext2spice.c +++ b/ext2spice/ext2spice.c @@ -79,7 +79,7 @@ int esNoModelType; /* index for device type "None" (model-less device) */ HashTable subcktNameTable ; /* the hash table itself */ DQueue subcktNameQueue ; /* q used to print it sorted at the end*/ -fetInfoList esFetInfo[MAXDEVTYPES]; +fetInfoList esFetInfo[TT_MAXTYPES]; /* Record for keeping a list of global names */ @@ -90,7 +90,7 @@ typedef struct GLL { char *gll_name; } globalList; -unsigned long initMask = 0; +TileTypeBitMask initMask; /* Used for device types, not tile types */ bool esMergeDevsA = FALSE; /* aggressive merging of devs L1=L2 merge them */ bool esMergeDevsC = FALSE; /* conservative merging of devs L1=L2 and W1=W2 */ @@ -728,7 +728,7 @@ runexttospice: /* create default devinfo entries (MOSIS) which can be overridden by the command line arguments */ - for ( i = 0 ; i < MAXDEVTYPES ; i++ ) { + for ( i = 0 ; i < TT_MAXTYPES ; i++ ) { esFetInfo[i].resClassSource = NO_RESCLASS; esFetInfo[i].resClassDrain = NO_RESCLASS; esFetInfo[i].resClassSub = NO_RESCLASS; @@ -743,12 +743,12 @@ runexttospice: while (ExtGetDevInfo(idx++, &devname, &devtype, &s_rclass, &d_rclass, &sub_rclass, &subname)) { - if (idx == MAXDEVTYPES) + if (idx == TT_MAXTYPES) { TxError("Error: Ran out of space for device types!\n"); break; } - i = efBuildAddStr(EFDevTypes, &EFDevNumTypes, MAXDEVTYPES, devname); + i = efBuildAddStr(EFDevTypes, &EFDevNumTypes, TT_MAXTYPES, devname); if (!strcmp(devname, "None")) esNoModelType = i; if (EFStyle != NULL) @@ -908,7 +908,9 @@ runexttospice: if (!esDoPorts) EFVisitSubcircuits(subcktUndef, (ClientData) NULL); - initMask = ( esDistrJunct ) ? (unsigned long)0 : DEV_CONNECT_MASK; + TTMaskZero(&initMask); + if (!esDistrJunct) + TTMaskCom(&initMask); if (esMergeDevsA || esMergeDevsC) { @@ -924,7 +926,7 @@ runexttospice: else if (esDistrJunct) EFVisitDevs(devDistJunctVisit, (ClientData) NULL); EFVisitDevs(spcdevVisit, (ClientData) NULL); - initMask = (unsigned long) 0; + TTMaskZero(&initMask); if (flatFlags & EF_FLATCAPS) { (void) sprintf( esSpiceCapFormat, "C%%d %%s %%s %%.%dlffF\n", @@ -994,25 +996,25 @@ main(argc, argv) EFResistThreshold = INFINITE_THRESHOLD ; /* create default devinfo entries (MOSIS) which can be overriden by the command line arguments */ - for ( i = 0 ; i < MAXDEVTYPES ; i++ ) { + for ( i = 0 ; i < TT_MAXTYPES ; i++ ) { esFetInfo[i].resClassSource = NO_RESCLASS; esFetInfo[i].resClassDrain = NO_RESCLASS; esFetInfo[i].resClassSub = NO_RESCLASS; esFetInfo[i].defSubs = NULL; } - i = efBuildAddStr(EFDevTypes, &EFDevNumTypes, MAXDEVTYPES, "ndev"); + i = efBuildAddStr(EFDevTypes, &EFDevNumTypes, TT_MAXTYPES, "ndev"); esFetInfo[i].resClassSource = esFetInfo[i].resClassDrain = 0 ; esFetInfo[i].resClassSub = NO_RESCLASS ; esFetInfo[i].defSubs = "Gnd!"; - i = efBuildAddStr(EFDevTypes, &EFDevNumTypes, MAXDEVTYPES, "pdev"); + i = efBuildAddStr(EFDevTypes, &EFDevNumTypes, TT_MAXTYPES, "pdev"); esFetInfo[i].resClassSource = esFetInfo[i].resClassDrain = 1 ; esFetInfo[i].resClassSub = 8 ; esFetInfo[i].defSubs = "Vdd!"; - i = efBuildAddStr(EFDevTypes, &EFDevNumTypes, MAXDEVTYPES, "nmos"); + i = efBuildAddStr(EFDevTypes, &EFDevNumTypes, TT_MAXTYPES, "nmos"); esFetInfo[i].resClassSource = esFetInfo[i].resClassDrain = 0 ; esFetInfo[i].resClassSub = NO_RESCLASS ; esFetInfo[i].defSubs = "Gnd!"; - i = efBuildAddStr(EFDevTypes, &EFDevNumTypes, MAXDEVTYPES, "pmos"); + i = efBuildAddStr(EFDevTypes, &EFDevNumTypes, TT_MAXTYPES, "pmos"); esFetInfo[i].resClassSource = esFetInfo[i].resClassDrain = 1 ; esFetInfo[i].resClassSub = 8 ; esFetInfo[i].defSubs = "Vdd!"; @@ -1078,7 +1080,9 @@ main(argc, argv) if (!esDoPorts) EFVisitSubcircuits(subcktUndef, (ClientData) NULL); - initMask = ( esDistrJunct ) ? (unsigned long)0 : DEV_CONNECT_MASK ; + TTMaskZero(&initMask); + if (!esDistrJunct) + TTMaskCom(&initMask); if ( esMergeDevsA || esMergeDevsC ) { EFVisitDevs(devMergeVisit, (ClientData) NULL); @@ -1092,7 +1096,7 @@ main(argc, argv) } else if ( esDistrJunct ) EFVisitDevs(devDistJunctVisit, (ClientData) NULL); EFVisitDevs(spcdevVisit, (ClientData) NULL); - initMask = (unsigned long) 0; + TTMaskZero(&initMask); if (flatFlags & EF_FLATCAPS) { (void) sprintf( esSpiceCapFormat, "C%%d %%s %%s %%.%dlffF\n",esCapAccuracy); EFVisitCaps(spccapVisit, (ClientData) NULL); @@ -1240,17 +1244,9 @@ spcmainArgs(pargc, pargv) rClassSub = -1 ; if ( sscanf(rp, "%d/%s", &rClass, subsNode) != 2 ) goto usage; } - ndx = efBuildAddStr(EFDevTypes, &EFDevNumTypes, MAXDEVTYPES, cp); + ndx = efBuildAddStr(EFDevTypes, &EFDevNumTypes, TT_MAXTYPES, cp); esFetInfo[ndx].resClassSource = esFetInfo[ndx].resClassDrain = rClass; esFetInfo[ndx].resClassSub = rClassSub; - if ( ((1<efnn_node); if (!esDistrJunct) - ((nodeClient *)nn->efnn_node->efnode_client)->m_w.visitMask |= - DEV_CONNECT_MASK; + { + TTMaskZero(&((nodeClient *)nn->efnn_node->efnode_client)->m_w.visitMask); + TTMaskCom(&((nodeClient *)nn->efnn_node->efnode_client)->m_w.visitMask); + } return nn->efnn_node; } } @@ -3126,7 +3124,10 @@ spcdevOutNode(prefix, suffix, name, outf) /* Mark node as visited */ if (!esDistrJunct) - ((nodeClient *)nn->efnn_node->efnode_client)->m_w.visitMask |= DEV_CONNECT_MASK; + { + TTMaskZero(&((nodeClient *)nn->efnn_node->efnode_client)->m_w.visitMask); + TTMaskCom(&((nodeClient *)nn->efnn_node->efnode_client)->m_w.visitMask); + } return (1 + strlen(nname)); } @@ -3279,8 +3280,7 @@ spcnodeVisit(node, res, cap) { isConnected = (esDistrJunct) ? (((nodeClient *)node->efnode_client)->m_w.widths != NULL) : - ((((nodeClient *)node->efnode_client)->m_w.visitMask - & DEV_CONNECT_MASK) != 0); + (!TTMaskIsZero(&((nodeClient *)node->efnode_client)->m_w.visitMask)); } if (!isConnected && esDevNodesOnly) return 0; diff --git a/ext2spice/ext2spice.h b/ext2spice/ext2spice.h index e21e6acd..4a30d847 100644 --- a/ext2spice/ext2spice.h +++ b/ext2spice/ext2spice.h @@ -60,7 +60,7 @@ extern FILE *esSpiceF; extern float esScale; /* negative if hspice the EFScale/100 otherwise */ extern unsigned short esFormat; -extern unsigned long initMask; +extern TileTypeBitMask initMask; extern int esCapNum, esDevNum, esResNum, esDiodeNum; extern int esNodeNum; /* just in case we're extracting spice2 */ @@ -96,19 +96,15 @@ typedef struct { char *defSubs ; /* the default substrate node */ } fetInfoList; -extern fetInfoList esFetInfo[MAXDEVTYPES]; +extern fetInfoList esFetInfo[TT_MAXTYPES]; #define MAX_STR_SIZE (1<<11) /* 2K should be enough for keeping temp names even of the most complicated design */ /* Node clients for figuring out areas and perimeters of sources and drains */ -typedef struct { - long _duml:MAXDEVTYPES; -} _dum; /* if you get an error here you should change - the data structures and visitMask */ typedef union { - long visitMask; /* mask for normal visits */ + TileTypeBitMask visitMask; /* mask for normal visits */ float *widths; /* width used for distributing area perim */ } maskOrWidth ; @@ -125,32 +121,27 @@ typedef struct { #define NO_RESCLASS -1 #define markVisited(client, rclass) \ - { (client)->m_w.visitMask |= (1<m_w.visitMask), rclass); } #define clearVisited(client) \ - { (client)->m_w.visitMask = (long)0; } + { TTMaskZero(&((client)->m_w.visitMask)); } #define beenVisited(client, rclass) \ - ( (client)->m_w.visitMask & (1<m_w.visitMask), rclass) ) #define initNodeClient(node) \ { \ (node)->efnode_client = (ClientData) mallocMagic((unsigned) (sizeof(nodeClient))); \ - (( nodeClient *)(node)->efnode_client)->spiceNodeName = NULL; \ - (( nodeClient *)(node)->efnode_client)->m_w.visitMask = (unsigned long)initMask; \ + (( nodeClient *)(node)->efnode_client)->spiceNodeName = NULL; \ + TTMaskZero (&((nodeClient *) (node)->efnode_client)->m_w.visitMask); \ + TTMaskSetMask(&(((nodeClient *)(node)->efnode_client)->m_w.visitMask), &initMask);\ } #define initNodeClientHier(node) \ { \ (node)->efnode_client = (ClientData) mallocMagic((unsigned)(sizeof(nodeClientHier))); \ - ((nodeClientHier *) (node)->efnode_client)->m_w.visitMask = (unsigned long) 0; \ + TTMaskZero (&((nodeClientHier *) (node)->efnode_client)->m_w.visitMask); \ } diff --git a/extflat/EFantenna.c b/extflat/EFantenna.c index 480d6f90..63d94493 100644 --- a/extflat/EFantenna.c +++ b/extflat/EFantenna.c @@ -42,36 +42,36 @@ int antennacheckArgs(); int antennacheckVisit(); typedef struct { - long visitMask:MAXDEVTYPES; + TileTypeBitMask visitMask; } nodeClient; typedef struct { HierName *lastPrefix; - long visitMask:MAXDEVTYPES; + TileTypeBitMask visitMask; } nodeClientHier; #define NO_RESCLASS -1 #define markVisited(client, rclass) \ - { (client)->visitMask |= (1<visitMask), rclass); } #define clearVisited(client) \ - { (client)->visitMask = (long)0; } + { TTMaskZero(&((client)->visitMask); } #define beenVisited(client, rclass) \ - ( (client)->visitMask & (1<visitMask), rclass) ) #define initNodeClient(node) \ { \ (node)->efnode_client = (ClientData) mallocMagic((unsigned) (sizeof(nodeClient))); \ - (( nodeClient *)(node)->efnode_client)->visitMask = (long) 0; \ + TTMaskZero(&(( nodeClient *)(node)->efnode_client)->visitMask); \ } #define initNodeClientHier(node) \ { \ (node)->efnode_client = (ClientData) mallocMagic((unsigned) (sizeof(nodeClientHier))); \ - ((nodeClientHier *) (node)->efnode_client)->visitMask = (long) 0; \ + TTMaskZero(&(( nodeClientHier *)(node)->efnode_client)->visitMask); \ } /* Diagnostic */ @@ -228,9 +228,21 @@ runantennacheck: TxPrintf("Building flattened netlist.\n"); EFFlatBuild(inName, flatFlags); + /* Get device information from the current extraction style */ + idx = 0; + while (ExtGetDevInfo(idx++, &devname, NULL, NULL, NULL, NULL, NULL)) + { + if (idx == TT_MAXTYPES) + { + TxError("Error: Ran out of space for device types!\n"); + break; + } + efBuildAddStr(EFDevTypes, &EFDevNumTypes, TT_MAXTYPES, devname); + } + /* Build device lookup table */ - EFDeviceTypes = (TileType *)mallocMagic(MAXDEVTYPES * sizeof(TileType)); - for (i = 0; i < MAXDEVTYPES; i++) + EFDeviceTypes = (TileType *)mallocMagic(EFDevNumTypes * sizeof(TileType)); + for (i = 0; i < EFDevNumTypes; i++) if (EFDevTypes[i]) EFDeviceTypes[i] = extGetDevType(EFDevTypes[i]); diff --git a/extflat/EFbuild.c b/extflat/EFbuild.c index 5d0f1530..07d59fdd 100644 --- a/extflat/EFbuild.c +++ b/extflat/EFbuild.c @@ -30,9 +30,10 @@ static char rcsid[] __attribute__ ((unused)) = "$Header$"; #include "utils/hash.h" #include "utils/utils.h" #include "utils/malloc.h" +#include "tiles/tile.h" +#include "database/database.h" /* for TileType definition */ #include "extflat/extflat.h" #include "extflat/EFint.h" -#include "tiles/tile.h" #include "extract/extract.h" /* for device class list */ /* @@ -48,7 +49,7 @@ static char rcsid[] __attribute__ ((unused)) = "$Header$"; #define MAXTYPES 100 /* Table of transistor types */ -char *EFDevTypes[MAXDEVTYPES]; +char *EFDevTypes[TT_MAXTYPES]; int EFDevNumTypes; /* Table of Magic layers */ @@ -656,6 +657,8 @@ efBuildDevice(def, class, type, r, argc, argv) DevTerm *term; Dev *newdev, devtmp; DevParam *newparm, *devp, *sparm; + TileType ttype; + int dev_type; char ptype, *pptr, **av; char devhash[64]; int argstart = 1; /* start of terminal list in argv[] */ @@ -799,9 +802,18 @@ efBuildDevice(def, class, type, r, argc, argv) nterminals = (argc - argstart) / 3; - /* Determine if this device has been seen before */ + dev_type = efBuildAddStr(EFDevTypes, &EFDevNumTypes, TT_MAXTYPES, type); - sprintf(devhash, "%dx%d%s", r->r_xbot, r->r_ybot, type); + /* Determine if this device has been seen before */ + /* NOTE: This is done by tile type, not name, because the extresist + * device extraction is less sophisticated than the standard extraction + * and does not differentiate between different device names belonging + * to the same tile type. The extGetDevType() function is not efficient, + * and all of this needs to be done better. + */ + + ttype = extGetDevType(type); + sprintf(devhash, "%dx%d_%d", r->r_xbot, r->r_ybot, ttype); he = HashFind(&def->def_devs, devhash); newdev = (Dev *)HashGetValue(he); if (newdev) @@ -813,10 +825,14 @@ efBuildDevice(def, class, type, r, argc, argv) * * Check that the device is actually the same device type and number * of terminals. If not, throw an error and abandon the new device. + * + * NOTE: Quick check is made on dev_type, but for the reason stated + * above for the calculation of ttype, only the tile types need to + * match, so make an additional (expensive) check on tile type. */ - if ((newdev->dev_class != class) || - (strcmp(EFDevTypes[newdev->dev_type], type))) + if ((newdev->dev_class != class) || ((newdev->dev_type != dev_type) + && (ttype != extGetDevType(EFDevTypes[newdev->dev_type])))) { TxError("Device %s %s at (%d, %d) overlaps incompatible device %s %s!\n", extDevTable[class], type, r->r_xbot, r->r_ybot, @@ -849,7 +865,7 @@ efBuildDevice(def, class, type, r, argc, argv) newdev->dev_nterm = nterminals; newdev->dev_rect = *r; - newdev->dev_type = efBuildAddStr(EFDevTypes, &EFDevNumTypes, MAXDEVTYPES, type); + newdev->dev_type = dev_type; newdev->dev_class = class; switch (class) diff --git a/extflat/EFdef.c b/extflat/EFdef.c index ecefb3d0..358c6b0d 100644 --- a/extflat/EFdef.c +++ b/extflat/EFdef.c @@ -135,6 +135,7 @@ EFDone() /* Misc cleanup */ for (n = 0; n < EFDevNumTypes; n++) freeMagic(EFDevTypes[n]); + EFDevNumTypes = 0; /* Changed from n = 0 to n = 1; First entry "space" is predefined, */ /* not malloc'd. ---Tim 9/3/02 */ diff --git a/extflat/extflat.h b/extflat/extflat.h index a512e7d8..56cc5554 100644 --- a/extflat/extflat.h +++ b/extflat/extflat.h @@ -342,9 +342,6 @@ extern char *EFHNToStr(); extern int EFGetPortMax(); /* ------------------------- constants used by clients -------------- */ -/* This gives us a 32 or 64 dev types which should be ok */ -#define BITSPERCHAR 8 -#define MAXDEVTYPES (sizeof(long)*BITSPERCHAR) /* * ANSI C definitions of arguments to EFvisit procedures diff --git a/extract/ExtCell.c b/extract/ExtCell.c index d2289dd6..bb470f6a 100644 --- a/extract/ExtCell.c +++ b/extract/ExtCell.c @@ -112,7 +112,7 @@ ExtCell(def, outName, doLength) TxError("Cannot open output file: "); perror(filename); #endif - return; + return NULL; } extNumFatal = extNumWarnings = 0; diff --git a/extract/ExtHier.c b/extract/ExtHier.c index 8056a8e9..83b58587 100644 --- a/extract/ExtHier.c +++ b/extract/ExtHier.c @@ -203,15 +203,32 @@ extHierSubstrate(ha, use, x, y) if (node1 != node2) { - /* - * Both sets of names will now point to node1. - */ - for (nn = node2->node_names; nn->nn_next; nn = nn->nn_next) + if (node1->node_len < node2->node_len) + { + /* + * Both sets of names will now point to node2. + */ + for (nn = node1->node_names; nn->nn_next; nn = nn->nn_next) + nn->nn_node = node2; + nn->nn_node = node2; + nn->nn_next = node2->node_names->nn_next; + node2->node_names->nn_next = node1->node_names; + node2->node_len += node1->node_len; + freeMagic((char *)node1); + } + else + { + /* + * Both sets of names will now point to node1. + */ + for (nn = node2->node_names; nn->nn_next; nn = nn->nn_next) nn->nn_node = node1; - nn->nn_node = node1; - nn->nn_next = node1->node_names; - node1->node_names = node2->node_names; - freeMagic((char *) node2); + nn->nn_node = node1; + nn->nn_next = node1->node_names; + node1->node_names = node2->node_names; + node1->node_len += node2->node_len; + freeMagic((char *)node2); + } } freeMagic(nodeList); } @@ -385,17 +402,36 @@ extHierConnectFunc1(oneTile, ha) if (node1 != node2) { - /* - * Both sets of names will now point to node1. - * We don't need to update node_cap since it - * hasn't been computed yet. - */ - for (nn = node2->node_names; nn->nn_next; nn = nn->nn_next) - nn->nn_node = node1; - nn->nn_node = node1; - nn->nn_next = node1->node_names; - node1->node_names = node2->node_names; - freeMagic((char *) node2); + if (node1->node_len < node2->node_len) + { + /* + * Both sets of names will now point to node2. + * We don't need to update node_cap since it + * hasn't been computed yet. + */ + for (nn = node1->node_names; nn->nn_next; nn = nn->nn_next) + nn->nn_node = node2; + nn->nn_node = node2; + nn->nn_next = node2->node_names->nn_next; + node2->node_names->nn_next = node1->node_names; + node2->node_len += node1->node_len; + freeMagic((char *) node1); + } + else + { + /* + * Both sets of names will now point to node1. + * We don't need to update node_cap since it + * hasn't been computed yet. + */ + for (nn = node2->node_names; nn->nn_next; nn = nn->nn_next) + nn->nn_node = node1; + nn->nn_node = node1; + nn->nn_next = node1->node_names; + node1->node_names = node2->node_names; + node1->node_len += node2->node_len; + freeMagic((char *) node2); + } } } } @@ -470,17 +506,36 @@ extHierConnectFunc2(cum, ha) if (node1 != node2) { - /* - * Both sets of names will now point to node1. - * We don't need to update node_cap since it - * hasn't been computed yet. - */ - for (nn = node2->node_names; nn->nn_next; nn = nn->nn_next) - nn->nn_node = node1; - nn->nn_node = node1; - nn->nn_next = node1->node_names; - node1->node_names = node2->node_names; - freeMagic((char *) node2); + if (node1->node_len < node2->node_len) + { + /* + * Both sets of names will now point to node2. + * We don't need to update node_cap since it + * hasn't been computed yet. + */ + for (nn = node1->node_names; nn->nn_next; nn = nn->nn_next) + nn->nn_node = node2; + nn->nn_node = node2; + nn->nn_next = node2->node_names->nn_next; + node2->node_names->nn_next = node1->node_names; + node2->node_len += node1->node_len; + freeMagic((char *) node1); + } + else + { + /* + * Both sets of names will now point to node1. + * We don't need to update node_cap since it + * hasn't been computed yet. + */ + for (nn = node2->node_names; nn->nn_next; nn = nn->nn_next) + nn->nn_node = node1; + nn->nn_node = node1; + nn->nn_next = node1->node_names; + node1->node_names = node2->node_names; + node1->node_len += node2->node_len; + freeMagic((char *) node2); + } } } else if (r.r_xtop > r.r_xbot && r.r_ytop > r.r_ybot) @@ -553,17 +608,36 @@ extHierConnectFunc3(cum, ha) if (node1 != node2) { - /* - * Both sets of names will now point to node1. - * We don't need to update node_cap since it - * hasn't been computed yet. - */ - for (nn = node2->node_names; nn->nn_next; nn = nn->nn_next) - nn->nn_node = node1; - nn->nn_node = node1; - nn->nn_next = node1->node_names; - node1->node_names = node2->node_names; - freeMagic((char *) node2); + if (node1->node_len < node2->node_len) + { + /* + * Both sets of names will now point to node2. + * We don't need to update node_cap since it + * hasn't been computed yet. + */ + for (nn = node1->node_names; nn->nn_next; nn = nn->nn_next) + nn->nn_node = node2; + nn->nn_node = node2; + nn->nn_next = node2->node_names->nn_next; + node2->node_names->nn_next = node1->node_names; + node2->node_len += node1->node_len; + freeMagic((char *) node1); + } + else + { + /* + * Both sets of names will now point to node1. + * We don't need to update node_cap since it + * hasn't been computed yet. + */ + for (nn = node2->node_names; nn->nn_next; nn = nn->nn_next) + nn->nn_node = node1; + nn->nn_node = node1; + nn->nn_next = node1->node_names; + node1->node_names = node2->node_names; + node1->node_len += node2->node_len; + freeMagic((char *) node2); + } } } else if (r.r_xtop > r.r_xbot && r.r_ytop > r.r_ybot) @@ -810,6 +884,7 @@ extHierNewNode(he) nn->nn_name = he->h_key.h_name; node->node_names = nn; node->node_cap = (CapValue) 0; + node->node_len = 1; for (n = 0; n < nclasses; n++) node->node_pa[n].pa_perim = node->node_pa[n].pa_area = 0; HashSetValue(he, (char *) nn); diff --git a/extract/ExtTech.c b/extract/ExtTech.c index 7445ddb4..731cdf73 100644 --- a/extract/ExtTech.c +++ b/extract/ExtTech.c @@ -354,54 +354,63 @@ ExtGetDevInfo(idx, devnameptr, devtypeptr, s_rclassptr, d_rclassptr, if (t == DBNumTypes) return FALSE; if (devptr == NULL) return FALSE; - *devnameptr = locdname; - *subnameptr = devptr->exts_deviceSubstrateName; - *devtypeptr = t; + if (devnameptr) *devnameptr = locdname; + if (subnameptr) *subnameptr = devptr->exts_deviceSubstrateName; + if (devtypeptr) *devtypeptr = t; tmask = &devptr->exts_deviceSDTypes[0]; - *s_rclassptr = (short)(-1); /* NO_RESCLASS */ - - for (n = 0; n < ExtCurStyle->exts_numResistClasses; n++) + if (s_rclassptr) { - rmask = &ExtCurStyle->exts_typesByResistClass[n]; - if (TTMaskIntersect(rmask, tmask)) - { - *s_rclassptr = (short)n; - break; - } - } - - tmask = &devptr->exts_deviceSDTypes[1]; - if (TTMaskIsZero(tmask)) - { - /* Set source and drain resistance classes to be the same */ - *d_rclassptr = (short)n; - } - else - { - *d_rclassptr = (short)(-1); /* NO_RESCLASS */ + *s_rclassptr = (short)(-1); /* NO_RESCLASS */ for (n = 0; n < ExtCurStyle->exts_numResistClasses; n++) { rmask = &ExtCurStyle->exts_typesByResistClass[n]; if (TTMaskIntersect(rmask, tmask)) { - *d_rclassptr = (short)n; + *s_rclassptr = (short)n; break; } } } - tmask = &devptr->exts_deviceSubstrateTypes; - *sub_rclassptr = (short)(-1); /* NO_RESCLASS */ - - for (n = 0; n < ExtCurStyle->exts_numResistClasses; n++) + if (d_rclassptr) { - rmask = &ExtCurStyle->exts_typesByResistClass[n]; - if (TTMaskIntersect(rmask, tmask)) + tmask = &devptr->exts_deviceSDTypes[1]; + if (TTMaskIsZero(tmask)) { - *sub_rclassptr = (short)(n); - break; + /* Set source and drain resistance classes to be the same */ + *d_rclassptr = (short)n; + } + else + { + *d_rclassptr = (short)(-1); /* NO_RESCLASS */ + + for (n = 0; n < ExtCurStyle->exts_numResistClasses; n++) + { + rmask = &ExtCurStyle->exts_typesByResistClass[n]; + if (TTMaskIntersect(rmask, tmask)) + { + *d_rclassptr = (short)n; + break; + } + } + } + } + + if (sub_rclassptr) + { + tmask = &devptr->exts_deviceSubstrateTypes; + *sub_rclassptr = (short)(-1); /* NO_RESCLASS */ + + for (n = 0; n < ExtCurStyle->exts_numResistClasses; n++) + { + rmask = &ExtCurStyle->exts_typesByResistClass[n]; + if (TTMaskIntersect(rmask, tmask)) + { + *sub_rclassptr = (short)(n); + break; + } } } diff --git a/extract/extractInt.h b/extract/extractInt.h index 82d18d51..ad33cce5 100644 --- a/extract/extractInt.h +++ b/extract/extractInt.h @@ -943,6 +943,7 @@ 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 diff --git a/lef/lefWrite.c b/lef/lefWrite.c index aa12f0e6..68371be4 100644 --- a/lef/lefWrite.c +++ b/lef/lefWrite.c @@ -776,7 +776,7 @@ lefWriteGeometry(tile, cdata) lefClient *lefdata = (lefClient *)cdata; FILE *f = lefdata->file; float scale = lefdata->oscale; - char leffmt[6][10]; + char leffmt[6][16]; TileType ttype, otype = TiGetTypeExact(tile); LefMapping *lefMagicToLefLayer = lefdata->lefMagicMap; diff --git a/resis/Makefile b/resis/Makefile index 9cba56fd..18e0fe40 100644 --- a/resis/Makefile +++ b/resis/Makefile @@ -5,7 +5,7 @@ MODULE = resis MAGICDIR = .. SRCS = ResMain.c ResJunct.c ResMakeRes.c ResSimple.c ResPrint.c \ - ResReadSim.c ResConDCS.c ResRex.c ResBasic.c ResMerge.c ResChecks.c \ + ResReadSim.c ResRex.c ResBasic.c ResMerge.c ResChecks.c \ ResFract.c ResUtils.c ResDebug.c include ${MAGICDIR}/defs.mak diff --git a/resis/ResChecks.c b/resis/ResChecks.c index 6d1954d6..b82747ce 100644 --- a/resis/ResChecks.c +++ b/resis/ResChecks.c @@ -43,111 +43,113 @@ static char rcsid[] __attribute__ ((unused)) = "$Header: /usr/cvsroot/magic-8.0/ */ void -ResSanityChecks(nodename,resistorList,nodeList,devlist) - char *nodename; - resResistor *resistorList; - resNode *nodeList; - resDevice *devlist; +ResSanityChecks(nodename, resistorList, nodeList, devlist) + char *nodename; + resResistor *resistorList; + resNode *nodeList; + resDevice *devlist; { - resResistor *resistor; - resNode *node; - resDevice *dev; - resElement *rcell; - static Stack *resSanityStack = NULL; - int reached,foundorigin; + resResistor *resistor; + resNode *node; + resDevice *dev; + resElement *rcell; + static Stack *resSanityStack = NULL; + int reached, foundorigin; - if (resSanityStack == NULL) - { - resSanityStack = StackNew(64); - } - for (node = nodeList; node != NULL; node=node->rn_more) - { - node->rn_status &= ~RES_REACHED_NODE; - if (node->rn_why == RES_NODE_ORIGIN) + if (resSanityStack == NULL) + { + resSanityStack = StackNew(64); + } + for (node = nodeList; node != NULL; node=node->rn_more) + { + node->rn_status &= ~RES_REACHED_NODE; + if (node->rn_why == RES_NODE_ORIGIN) STACKPUSH((ClientData) node, resSanityStack); - } - for (resistor = resistorList; resistor != NULL; resistor = resistor->rr_nextResistor) - { - resistor->rr_status &= ~RES_REACHED_RESISTOR; - } + } + for (resistor = resistorList; resistor != NULL; resistor = resistor->rr_nextResistor) + { + resistor->rr_status &= ~RES_REACHED_RESISTOR; + } - /* Check 1- Are the resistors and nodes all connected? */ - while (!StackEmpty(resSanityStack)) - { - node = (resNode *)STACKPOP(resSanityStack); - if (node->rn_status & RES_REACHED_NODE) continue; - node->rn_status |= RES_REACHED_NODE; - for (rcell = node->rn_re; rcell != NULL; rcell=rcell->re_nextEl) - { - resistor = rcell->re_thisEl; - if (resistor->rr_status & RES_REACHED_RESISTOR) continue; - resistor->rr_status |= RES_REACHED_RESISTOR; - if (resistor->rr_connection1 != node && + /* Check: Are the resistors and nodes all connected? */ + while (!StackEmpty(resSanityStack)) + { + node = (resNode *)STACKPOP(resSanityStack); + if (node->rn_status & RES_REACHED_NODE) continue; + node->rn_status |= RES_REACHED_NODE; + for (rcell = node->rn_re; rcell != NULL; rcell = rcell->re_nextEl) + { + resistor = rcell->re_thisEl; + if (resistor->rr_status & RES_REACHED_RESISTOR) continue; + resistor->rr_status |= RES_REACHED_RESISTOR; + if (resistor->rr_connection1 != node && resistor->rr_connection2 != node) - { - TxError("Stray resElement pointer- node %s, pointer %d\n",nodename,rcell); - continue; - } - if ((resistor->rr_connection1->rn_status & RES_REACHED_NODE) == 0) - { - STACKPUSH((ClientData)resistor->rr_connection1,resSanityStack); - } - if ((resistor->rr_connection2->rn_status & RES_REACHED_NODE) == 0) - { - STACKPUSH((ClientData)resistor->rr_connection2,resSanityStack); - } - } - } - for (resistor = resistorList; resistor != NULL; resistor = resistor->rr_nextResistor) - { - if ((resistor->rr_status & RES_REACHED_RESISTOR) == 0) - { - TxError("Unreached resistor in %s\n",nodename); - } - resistor->rr_status &= ~RES_REACHED_RESISTOR; + { + TxError("Stray resElement pointer- node %s, pointer %d\n", + nodename, rcell); + continue; + } + if ((resistor->rr_connection1->rn_status & RES_REACHED_NODE) == 0) + { + STACKPUSH((ClientData)resistor->rr_connection1, resSanityStack); + } + if ((resistor->rr_connection2->rn_status & RES_REACHED_NODE) == 0) + { + STACKPUSH((ClientData)resistor->rr_connection2, resSanityStack); + } + } + } + for (resistor = resistorList; resistor != NULL; resistor = resistor->rr_nextResistor) + { + if ((resistor->rr_status & RES_REACHED_RESISTOR) == 0) + { + TxError("Unreached resistor in %s\n", nodename); + } + resistor->rr_status &= ~RES_REACHED_RESISTOR; } for (dev = devlist; dev != NULL; dev = dev->rd_nextDev) { - int i; + int i; - if (dev->rd_status & RES_DEV_PLUG) continue; - reached = FALSE; - for (i=0;i != dev->rd_nterms;i++) - { - if (dev->rd_terminals[i] != NULL) - { - reached = TRUE; - if ((dev->rd_terminals[i]->rn_status & RES_REACHED_NODE) == 0) - { - TxError("Device node %d unreached in %s\n",i,nodename); - } - } - } - if (reached == 0) - { - TxError("Unreached device in %s at %d %d\n", - nodename, - dev->rd_inside.r_xbot, - dev->rd_inside.r_ybot); - } - } - foundorigin = 0; - for (node = nodeList; node != NULL; node=node->rn_more) - { - if ((node->rn_status & RES_REACHED_NODE) == 0) - { - TxError("Unreached node in %s at %d, %d\n",nodename,node->rn_loc.p_x,node->rn_loc.p_y); - } - node->rn_status &= ~RES_REACHED_NODE; - if (node->rn_why & RES_NODE_ORIGIN) - { - foundorigin = 1; - } - } - if (foundorigin == 0) - { - TxError("Starting node not found in %s\n",nodename); - } + if (dev->rd_status & RES_DEV_PLUG) continue; + reached = FALSE; + for (i = 0; i != dev->rd_nterms; i++) + { + if (dev->rd_terminals[i] != NULL) + { + reached = TRUE; + if ((dev->rd_terminals[i]->rn_status & RES_REACHED_NODE) == 0) + { + TxError("Device node %d unreached in %s\n", i, nodename); + } + } + } + if (reached == 0) + { + TxError("Unreached device in %s at %d %d\n", + nodename, + dev->rd_inside.r_xbot, + dev->rd_inside.r_ybot); + } + } + foundorigin = 0; + for (node = nodeList; node != NULL; node=node->rn_more) + { + if ((node->rn_status & RES_REACHED_NODE) == 0) + { + TxError("Unreached node in %s at %d, %d\n", nodename, + node->rn_loc.p_x, node->rn_loc.p_y); + } + node->rn_status &= ~RES_REACHED_NODE; + if (node->rn_why & RES_NODE_ORIGIN) + { + foundorigin = 1; + } + } + if (foundorigin == 0) + { + TxError("Starting node not found in %s\n", nodename); + } } #endif diff --git a/resis/ResConDCS.c b/resis/ResConDCS.c deleted file mode 100644 index c1cca55b..00000000 --- a/resis/ResConDCS.c +++ /dev/null @@ -1,547 +0,0 @@ -/* ResConnectDCS.c -- - * - * This contains a slightly modified version of DBTreeCopyConnect. - */ - -#ifndef lint -static char rcsid[] __attribute__ ((unused)) = "$Header: /usr/cvsroot/magic-8.0/resis/ResConDCS.c,v 1.5 2010/06/24 12:37:56 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 "utils/stack.h" -#include "database/database.h" -#include "utils/malloc.h" -#include "textio/textio.h" -#include "extract/extract.h" -#include "extract/extractInt.h" -#include "utils/signals.h" -#include "windows/windows.h" -#include "dbwind/dbwind.h" -#include "utils/tech.h" -#include "textio/txcommands.h" -#include "resis/resis.h" - -extern int dbcUnconnectFunc(); -extern int dbcConnectLabelFunc(); -extern int dbcConnectFuncDCS(); -#ifdef ARIEL -extern int resSubSearchFunc(); -#endif - -static ResDevTile *DevList = NULL; -static TileTypeBitMask DiffTypeBitMask; -TileTypeBitMask ResSubsTypeBitMask; - -/* Forward declarations */ -extern void ResCalcPerimOverlap(); - -/* - * ---------------------------------------------------------------------------- - * - * dbcConnectFuncDCS -- the same as dbcConnectFunc, except that it does - * some extra searching around diffusion tiles looking for - * devices. - * - * Results: - * Always returns 0 to keep the search from aborting. - * - * Side effects: - * Adds a new record to the current check list. May also add new - * ResDevTile structures. - * - * ---------------------------------------------------------------------------- - */ - -int -dbcConnectFuncDCS(tile, cx) - Tile *tile; - TreeContext *cx; - -{ - struct conSrArg2 *csa2; - Rect tileArea, *srArea, devArea, newarea; - ResDevTile *thisDev; - TileTypeBitMask notConnectMask, *connectMask; - Tile *tp; - TileType t2, t1, loctype, ctype; - TileType dinfo = 0; - SearchContext *scx = cx->tc_scx; - SearchContext scx2; - int i, pNum; - CellDef *def; - ExtDevice *devptr; - TerminalPath tpath; - char pathstring[FLATTERMSIZE]; - - TiToRect(tile, &tileArea); - srArea = &scx->scx_area; - - if (((tileArea.r_xbot >= srArea->r_xtop-1) || - (tileArea.r_xtop <= srArea->r_xbot+1)) && - ((tileArea.r_ybot >= srArea->r_ytop-1) || - (tileArea.r_ytop <= srArea->r_ybot+1))) - return 0; - - t1 = TiGetType(tile); - if TTMaskHasType(&DiffTypeBitMask,t1) - { - /* left */ - for (tp = BL(tile); BOTTOM(tp) < TOP(tile); tp=RT(tp)) - { - t2 = TiGetType(tp); - devptr = ExtCurStyle->exts_device[t2]; - if (TTMaskHasType(&(ExtCurStyle->exts_deviceMask),t2) && - TTMaskHasType(&(devptr->exts_deviceSDTypes[0]),t1)) - { - TiToRect(tp, &devArea); - thisDev = (ResDevTile *) mallocMagic((unsigned)(sizeof(ResDevTile))); - ResCalcPerimOverlap(thisDev,tp); - GeoTransRect(&scx->scx_trans, &devArea, &thisDev->area); - thisDev->type = TiGetType(tp); - thisDev->nextDev = DevList; - DevList = thisDev; - } - } - /*right*/ - for (tp = TR(tile); TOP(tp) > BOTTOM(tile); tp=LB(tp)) - { - t2 = TiGetType(tp); - devptr = ExtCurStyle->exts_device[t2]; - if (TTMaskHasType(&(ExtCurStyle->exts_deviceMask),t2) && - TTMaskHasType(&(devptr->exts_deviceSDTypes[0]),t1)) - { - TiToRect(tp, &devArea); - thisDev = (ResDevTile *) mallocMagic((unsigned)(sizeof(ResDevTile))); - GeoTransRect(&scx->scx_trans, &devArea, &thisDev->area); - thisDev->type = TiGetType(tp); - thisDev->nextDev = DevList; - DevList = thisDev; - ResCalcPerimOverlap(thisDev,tp); - } - } - /*top*/ - for (tp = RT(tile); RIGHT(tp) > LEFT(tile); tp=BL(tp)) - { - t2 = TiGetType(tp); - devptr = ExtCurStyle->exts_device[t2]; - if (TTMaskHasType(&(ExtCurStyle->exts_deviceMask),t2) && - TTMaskHasType(&(devptr->exts_deviceSDTypes[0]),t1)) - { - TiToRect(tp, &devArea); - thisDev = (ResDevTile *) mallocMagic((unsigned)(sizeof(ResDevTile))); - GeoTransRect(&scx->scx_trans, &devArea, &thisDev->area); - thisDev->type = TiGetType(tp); - thisDev->nextDev = DevList; - DevList = thisDev; - ResCalcPerimOverlap(thisDev,tp); - } - } - /*bottom */ - for (tp = LB(tile); LEFT(tp) < RIGHT(tile); tp=TR(tp)) - { - t2 = TiGetType(tp); - devptr = ExtCurStyle->exts_device[t2]; - if (TTMaskHasType(&(ExtCurStyle->exts_deviceMask),t2) && - TTMaskHasType(&(devptr->exts_deviceSDTypes[0]),t1)) - { - TiToRect(tp, &devArea); - thisDev = (ResDevTile *) mallocMagic((unsigned)(sizeof(ResDevTile))); - GeoTransRect(&scx->scx_trans, &devArea, &thisDev->area); - thisDev->type = TiGetType(tp); - thisDev->nextDev = DevList; - DevList = thisDev; - ResCalcPerimOverlap(thisDev,tp); - } - } - } - else if TTMaskHasType(&(ExtCurStyle->exts_deviceMask),t1) - { - TiToRect(tile, &devArea); - thisDev = (ResDevTile *) mallocMagic((unsigned)(sizeof(ResDevTile))); - ResCalcPerimOverlap(thisDev,tile); - GeoTransRect(&scx->scx_trans, &devArea, &thisDev->area); - thisDev->type = TiGetType(tile); - thisDev->nextDev = DevList; - DevList = thisDev; - } - /* in some cases (primarily bipolar technology), we'll want to extract - devices whose substrate terminals are part of the given region. - The following does that check. (10-11-88) - */ -#ifdef ARIEL - if (TTMaskHasType(&ResSubsTypeBitMask,t1) && (ResOptionsFlags & ResOpt_DoSubstrate)) - { - TileTypeBitMask *mask = &ExtCurStyle->exts_subsTransistorTypes[t1]; - - for (pNum = PL_TECHDEPBASE; pNum < DBNumPlanes; pNum++) - { - if (TTMaskIntersect(&DBPlaneTypes[pNum], mask)) - { - (void)DBSrPaintArea((Tile *) NULL, - scx->scx_use->cu_def->cd_planes[pNum], - &tileArea,mask,resSubSearchFunc, (ClientData) cx); - } - } - } -#endif - GeoTransRect(&scx->scx_trans, &tileArea, &newarea); - - csa2 = (struct conSrArg2 *)cx->tc_filter->tf_arg; - GeoClip(&newarea, csa2->csa2_bounds); - if (GEO_RECTNULL(&newarea)) return 0; - - loctype = TiGetTypeExact(tile); - - /* Resolve geometric transformations on diagonally-split tiles */ - - if (IsSplit(tile)) - { - dinfo = DBTransformDiagonal(loctype, &scx->scx_trans); - loctype = (SplitSide(tile)) ? SplitRightType(tile) : SplitLeftType(tile); - } - - pNum = cx->tc_plane; - connectMask = &csa2->csa2_connect[loctype]; - - if (DBIsContact(loctype)) - { - /* The mask of contact types must include all stacked contacts */ - - TTMaskZero(¬ConnectMask); - TTMaskSetMask(¬ConnectMask, &DBNotConnectTbl[loctype]); - } - else - { - TTMaskCom2(¬ConnectMask, connectMask); - } - - def = csa2->csa2_use->cu_def; - - if (DBSrPaintNMArea((Tile *) NULL, def->cd_planes[pNum], - dinfo, &newarea, ¬ConnectMask, dbcUnconnectFunc, - (ClientData)NULL) == 0) - return 0; - - DBNMPaintPlane(def->cd_planes[pNum], dinfo, - &newarea, DBStdPaintTbl(loctype, pNum), - (PaintUndoInfo *) NULL); - - /* Check the source def for any labels belonging to this */ - /* tile area and plane, and add them to the destination */ - - scx2 = *csa2->csa2_topscx; - scx2.scx_area = newarea; - - pathstring[0] = '\0'; - tpath.tp_first = tpath.tp_next = pathstring; - tpath.tp_last = pathstring + FLATTERMSIZE; - - DBTreeSrLabels(&scx2, connectMask, csa2->csa2_xMask, &tpath, - TF_LABEL_ATTACH, dbcConnectLabelFunc, - (ClientData)csa2); - // DBCellCopyLabels(&scx2, connectMask, csa2->csa2_xMask, csa2->csa2_use, NULL); - - /* Only extend those sides bordering the diagonal tile */ - - if (dinfo & TT_DIAGONAL) - { - if (dinfo & TT_SIDE) /* right */ - newarea.r_xtop += 1; - else /* left */ - newarea.r_xbot -= 1; - if (((dinfo & TT_SIDE) >> 1) - == (dinfo & TT_DIRECTION)) /* top */ - newarea.r_ytop += 1; - else /* bottom */ - newarea.r_ybot -= 1; - } - else - { - newarea.r_xbot -= 1; - newarea.r_ybot -= 1; - newarea.r_xtop += 1; - newarea.r_ytop += 1; - } - - /* Check if any of the last 5 entries has the same type and */ - /* area. If so, don't duplicate the existing entry. */ - /* (NOTE: Connect masks are all from the same table, so */ - /* they can be compared by address, no need for TTMaskEqual)*/ - - for (i = csa2->csa2_lasttop; (i >= 0) && (i > csa2->csa2_lasttop - 5); i--) - if (connectMask == csa2->csa2_list[i].connectMask) - if (GEO_SURROUND(&csa2->csa2_list[i].area, &newarea)) - return 0; - - /* Register the area and connection mask as needing to be processed */ - - if (++csa2->csa2_top == CSA2_LIST_SIZE) - { - /* Reached list size limit---need to enlarge the list */ - /* Double the size of the list every time we hit the limit */ - - conSrArea *newlist; - - newlist = (conSrArea *)mallocMagic(CSA2_LIST_SIZE * sizeof(conSrArea)); - StackPush((ClientData)csa2->csa2_list, csa2->csa2_stack); - csa2->csa2_list = newlist; - csa2->csa2_top = 0; - } - - csa2->csa2_list[csa2->csa2_top].area = newarea; - csa2->csa2_list[csa2->csa2_top].connectMask = connectMask; - csa2->csa2_list[csa2->csa2_top].dinfo = dinfo; - - return 0; -} - - -/* - *------------------------------------------------------------------------- - * - * ResCalcPerimOverlap-- - * - * Results: - * None. - * - * Side Effects: - * - *------------------------------------------------------------------------- - */ - -void -ResCalcPerimOverlap(dev, tile) - ResDevTile *dev; - Tile *tile; - -{ - Tile *tp; - int t1; - int overlap; - - dev->perim = (TOP(tile)-BOTTOM(tile)-LEFT(tile)+RIGHT(tile))<<1; - overlap =0; - - t1 = TiGetType(tile); - /* left */ - for (tp = BL(tile); BOTTOM(tp) < TOP(tile); tp=RT(tp)) - { - if TTMaskHasType(&(ExtCurStyle->exts_nodeConn[t1]),TiGetType(tp)) - { - overlap += MIN(TOP(tile),TOP(tp))- - MAX(BOTTOM(tile),BOTTOM(tp)); - } - - } - /*right*/ - for (tp = TR(tile); TOP(tp) > BOTTOM(tile); tp=LB(tp)) - { - if TTMaskHasType(&(ExtCurStyle->exts_nodeConn[t1]),TiGetType(tp)) - { - overlap += MIN(TOP(tile),TOP(tp))- - MAX(BOTTOM(tile),BOTTOM(tp)); - } - - } - /*top*/ - for (tp = RT(tile); RIGHT(tp) > LEFT(tile); tp=BL(tp)) - { - if TTMaskHasType(&(ExtCurStyle->exts_nodeConn[t1]),TiGetType(tp)) - { - overlap += MIN(RIGHT(tile),RIGHT(tp))- - MAX(LEFT(tile),LEFT(tp)); - } - - } - /*bottom */ - for (tp = LB(tile); LEFT(tp) < RIGHT(tile); tp=TR(tp)) - { - if TTMaskHasType(&(ExtCurStyle->exts_nodeConn[t1]),TiGetType(tp)) - { - overlap += MIN(RIGHT(tile),RIGHT(tp))- - MAX(LEFT(tile),LEFT(tp)); - } - - } - dev->overlap = overlap; -} - - -/* - * ---------------------------------------------------------------------------- - * - * DBTreeCopyConnectDCS -- - * - * Basically the same as DBTreeCopyConnect, except it calls - * dbcConnectFuncDCS. - * - * Results: - * Linked list of devices. - * - * Side effects: - * The contents of the result cell are modified. - * - * ---------------------------------------------------------------------------- - */ - -ResDevTile * -DBTreeCopyConnectDCS(scx, mask, xMask, connect, area, destUse) - SearchContext *scx; - TileTypeBitMask *mask; - int xMask; - TileTypeBitMask *connect; - Rect *area; - CellUse *destUse; - -{ - static int first = 1; - struct conSrArg2 csa2; - int dev, pNum; - char *dev_name; - TileTypeBitMask *newmask; - ResDevTile *CurrentT; - CellDef *def = destUse->cu_def; - TileType newtype; - ExtDevice *devptr; - - csa2.csa2_use = destUse; - csa2.csa2_xMask = xMask; - csa2.csa2_bounds = area; - csa2.csa2_connect = connect; - csa2.csa2_topscx = scx; - - csa2.csa2_list = (conSrArea *)mallocMagic(CSA2_LIST_SIZE * sizeof(conSrArea)); - csa2.csa2_top = -1; - csa2.csa2_lasttop = -1; - - csa2.csa2_stack = StackNew(100); - - if (first) - { - TTMaskZero(&DiffTypeBitMask); - TTMaskZero(&ResSubsTypeBitMask); - for (dev = TT_TECHDEPBASE; dev < TT_MAXTYPES; dev++) - { - devptr = ExtCurStyle->exts_device[dev]; - if ((devptr != NULL) && ((dev_name = devptr->exts_deviceName) != NULL) - && (strcmp(dev_name, "None"))) - { - TTMaskSetMask(&DiffTypeBitMask, - &(devptr->exts_deviceSDTypes[0])); - TTMaskSetMask(&ResSubsTypeBitMask, - &(devptr->exts_deviceSubstrateTypes)); - } - } - first = 0; - } - - DevList = NULL; - DBTreeSrTiles(scx, mask, xMask, dbcConnectFuncDCS, (ClientData) &csa2); - while (csa2.csa2_top >= 0) - { - newmask = csa2.csa2_list[csa2.csa2_top].connectMask; - scx->scx_area = csa2.csa2_list[csa2.csa2_top].area; - newtype = csa2.csa2_list[csa2.csa2_top].dinfo; - if (csa2.csa2_top == 0) - { - if (StackLook(csa2.csa2_stack) != (ClientData)NULL) - { - freeMagic(csa2.csa2_list); - csa2.csa2_list = (conSrArea *)StackPop(csa2.csa2_stack); - csa2.csa2_top = CSA2_LIST_SIZE - 1; - } - else - csa2.csa2_top--; - } - else - csa2.csa2_top--; - - csa2.csa2_lasttop = csa2.csa2_top; - - if (newtype & TT_DIAGONAL) - DBTreeSrNMTiles(scx, newtype, newmask, xMask, dbcConnectFuncDCS, - (ClientData) &csa2); - else - DBTreeSrTiles(scx, newmask, xMask, dbcConnectFuncDCS, (ClientData) &csa2); - } - freeMagic((char *)csa2.csa2_list); - StackFree(csa2.csa2_stack); - - for (CurrentT = DevList; CurrentT != NULL; CurrentT=CurrentT->nextDev) - { - TileType t = CurrentT->type; - TileType nt; - TileTypeBitMask *residues = DBResidueMask(t); - - for (nt = TT_TECHDEPBASE; nt < DBNumTypes; nt++) - { - if (TTMaskHasType(residues, nt)) - { - pNum = DBPlane(nt); - DBPaintPlane(def->cd_planes[pNum], &CurrentT->area, - DBStdPaintTbl(nt, pNum), (PaintUndoInfo *) NULL); - } - } - } - - DBReComputeBbox(def); - return(DevList); -} - - -#ifdef ARIEL -/* - *------------------------------------------------------------------------- - * - * resSubSearchFunc -- - * - * called when DBSrPaintArea finds a device within - * a substrate area. - * - * Results: - * Always return 0 to keep the search alive. - * - * Side Effects: - * - *------------------------------------------------------------------------- - */ - -int -resSubSearchFunc(tile,cx) - Tile *tile; - TreeContext *cx; - - -{ - ResDevTile *thisDev; - Rect devArea; - TileType t = TiGetType(tile); - ExtDevice *devptr; - - /* Right now, we're only going to extract substrate terminals for - devices with only one diffusion terminal, principally bipolar - devices. - */ - devptr = ExtCurStyle->exts_device[t] - if (devptr->exts_deviceSDCount >1) return 0; - TiToRect(tile, &devArea); - thisDev = (ResDevTile *) mallocMagic((unsigned)(sizeof(ResDevTile))); - GeoTransRect(&cx->tc_scx->scx_trans, &devArea, &thisDev->area); - thisDev->type = t; - thisDev->nextDev = DevList; - DevList = thisDev; - ResCalcPerimOverlap(thisDev,tile); - - return 0; -} - -#endif /* ARIEL */ diff --git a/resis/ResDebug.c b/resis/ResDebug.c index 4453eed7..2eb210cc 100644 --- a/resis/ResDebug.c +++ b/resis/ResDebug.c @@ -46,17 +46,16 @@ static char rcsid[] __attribute__ ((unused)) = "$Header: /usr/cvsroot/magic-8.0/ */ void -ResPrintNodeList(fp,list) - FILE *fp; - resNode *list; - +ResPrintNodeList(fp, list) + FILE *fp; + resNode *list; { - for (; list != NULL; list = list->rn_more) - { - fprintf(fp, "node %p: (%d %d) r= %d\n", - list,list->rn_loc.p_x,list->rn_loc.p_y,list->rn_noderes); - } + for (; list != NULL; list = list->rn_more) + { + fprintf(fp, "node %p: (%d %d) r= %d\n", + list, list->rn_loc.p_x, list->rn_loc.p_y, list->rn_noderes); + } } /* @@ -73,7 +72,7 @@ ResPrintNodeList(fp,list) *------------------------------------------------------------------------- */ void -ResPrintResistorList(fp,list) +ResPrintResistorList(fp, list) FILE *fp; resResistor *list; @@ -112,9 +111,9 @@ ResPrintResistorList(fp,list) */ void -ResPrintDeviceList(fp,list) - FILE *fp; - resDevice *list; +ResPrintDeviceList(fp, list) + FILE *fp; + resDevice *list; { static char termtype[] = {'g','s','d','c'}; diff --git a/resis/ResFract.c b/resis/ResFract.c index 3dd9fcf0..1061c6ea 100644 --- a/resis/ResFract.c +++ b/resis/ResFract.c @@ -81,31 +81,30 @@ enumerate: if (SigInterruptPending) return (1); - if ((tt=TiGetType(resSrTile)) != TT_SPACE) + if ((tt = TiGetType(resSrTile)) != TT_SPACE) { - resTopTile = RT(resSrTile); - while (RIGHT(resTopTile) > LEFT(resSrTile)) - { - TileType ntt = TiGetType(resTopTile); - - if (ntt != tt) - { - resTopTile=BL(resTopTile); - continue; - } - /* ok, we may have found a concave corner */ - ResCheckConcavity(resSrTile,resTopTile,tt); - if (resTopTile == NULL) break; - if (BOTTOM(resTopTile) != TOP(resSrTile)) - { - resTopTile = RT(resSrTile); - } - else - { - resTopTile=BL(resTopTile); - } - } + resTopTile = RT(resSrTile); + while (RIGHT(resTopTile) > LEFT(resSrTile)) + { + TileType ntt = TiGetType(resTopTile); + if (ntt != tt) + { + resTopTile = BL(resTopTile); + continue; + } + /* ok, we may have found a concave corner */ + ResCheckConcavity(resSrTile, resTopTile, tt); + if (resTopTile == NULL) break; + if (BOTTOM(resTopTile) != TOP(resSrTile)) + { + resTopTile = RT(resSrTile); + } + else + { + resTopTile=BL(resTopTile); + } + } } tpnew = TR(resSrTile); @@ -134,7 +133,8 @@ enumerate: } /* At left edge -- walk down to next tile along the left edge */ - for (resSrTile = LB(resSrTile); RIGHT(resSrTile) <= rect->r_xbot; resSrTile = TR(resSrTile)) + for (resSrTile = LB(resSrTile); RIGHT(resSrTile) <= rect->r_xbot; + resSrTile = TR(resSrTile)) /* Nothing */; } return (0); @@ -157,88 +157,96 @@ enumerate: */ void -ResCheckConcavity(bot,top,tt) - Tile *bot,*top; - TileType tt; +ResCheckConcavity(bot, top, tt) + Tile *bot, *top; + TileType tt; { - Tile *tp; - int xlen,ylen; - /* corner #1: - XXXXXXX - YYYYYYY - ^--here - */ - if (RIGHT(top) > RIGHT(bot) && TiGetType(TR(bot)) != tt) - { - int xpos = RIGHT(bot); - int ypos = BOTTOM(top); - xlen = xpos - resWalkleft(top,tt,xpos,ypos,NULL); - ylen = resWalkup(top,tt,xpos,ypos,NULL) - ypos; - if (xlen > ylen) - { - (void) resWalkup(top,tt,xpos,ypos,ResSplitX); - } - } - if (resTopTile == NULL) return; - /* corner #2: - v--here - XXXXXXX - YYYYYYY - */ - if (RIGHT(top) < RIGHT(bot)) - { - for (tp = TR(top);BOTTOM(tp) > BOTTOM(top);tp=LB(tp)); - if (TiGetType(tp) != tt) - { - int xpos = RIGHT(top); - int ypos = BOTTOM(top); - xlen = xpos-resWalkleft(top,tt,xpos,ypos,NULL); - ylen = ypos-resWalkdown(bot,tt,xpos,ypos,NULL); - if (xlen > ylen) - { - (void) resWalkdown(bot,tt,xpos,ypos,ResSplitX); - } - } - } - if (resTopTile == NULL) return; - /* corner #3: - XXXXXXX - YYYYYYY - ^--here - */ - if (LEFT(top) < LEFT(bot)) - { - for (tp = BL(bot);TOP(tp) < TOP(bot);tp=RT(tp)); - if (TiGetType(tp) != tt) - { - int xpos = LEFT(bot); - int ypos = BOTTOM(top); - xlen = resWalkright(top,tt,xpos,ypos,NULL)- xpos; - ylen = resWalkup(top,tt,xpos,ypos,NULL) - ypos; - if (xlen > ylen) - { - (void) resWalkup(top,tt,xpos,ypos,ResSplitX); - } - } - } - if (resTopTile == NULL) return; - /* corner #4: - v--here - XXXXXXX - YYYYYYY + Tile *tp; + int xlen, ylen; + + /* corner #1: + * XXXXXXX + * YYYYYYY + * ^--here */ - if (LEFT(top) > LEFT(bot) && TiGetType(BL(top)) != tt) - { - int xpos = LEFT(top); - int ypos = BOTTOM(top); - xlen = resWalkright(top,tt,xpos,ypos,NULL)- xpos; - ylen = ypos-resWalkdown(bot,tt,xpos,ypos,NULL); - if (xlen > ylen) - { - (void) resWalkdown(bot,tt,xpos,ypos,ResSplitX); - } - } + + if (RIGHT(top) > RIGHT(bot) && TiGetType(TR(bot)) != tt) + { + int xpos = RIGHT(bot); + int ypos = BOTTOM(top); + xlen = xpos - resWalkleft(top, tt, xpos, ypos, NULL); + ylen = resWalkup(top, tt, xpos, ypos, NULL) - ypos; + if (xlen > ylen) + { + (void) resWalkup(top, tt, xpos, ypos, ResSplitX); + } + } + if (resTopTile == NULL) return; + + /* corner #2: + * v--here + * XXXXXXX + * YYYYYYY + */ + + if (RIGHT(top) < RIGHT(bot)) + { + for (tp = TR(top); BOTTOM(tp) > BOTTOM(top); tp = LB(tp)); + if (TiGetType(tp) != tt) + { + int xpos = RIGHT(top); + int ypos = BOTTOM(top); + xlen = xpos - resWalkleft(top, tt, xpos, ypos, NULL); + ylen = ypos - resWalkdown(bot, tt, xpos, ypos, NULL); + if (xlen > ylen) + { + (void) resWalkdown(bot,tt,xpos,ypos,ResSplitX); + } + } + } + if (resTopTile == NULL) return; + + /* corner #3: + * XXXXXXX + * YYYYYYY + * ^--here + */ + + if (LEFT(top) < LEFT(bot)) + { + for (tp = BL(bot); TOP(tp) < TOP(bot); tp = RT(tp)); + if (TiGetType(tp) != tt) + { + int xpos = LEFT(bot); + int ypos = BOTTOM(top); + xlen = resWalkright(top, tt, xpos, ypos, NULL) - xpos; + ylen = resWalkup(top, tt, xpos, ypos, NULL) - ypos; + if (xlen > ylen) + { + (void) resWalkup(top, tt, xpos, ypos, ResSplitX); + } + } + } + if (resTopTile == NULL) return; + + /* corner #4: + * v--here + * XXXXXXX + * YYYYYYY + */ + + if (LEFT(top) > LEFT(bot) && TiGetType(BL(top)) != tt) + { + int xpos = LEFT(top); + int ypos = BOTTOM(top); + xlen = resWalkright(top, tt, xpos, ypos, NULL) - xpos; + ylen = ypos - resWalkdown(bot, tt, xpos, ypos, NULL); + if (xlen > ylen) + { + (void) resWalkdown(bot, tt, xpos, ypos, ResSplitX); + } + } } /* @@ -259,151 +267,151 @@ ResCheckConcavity(bot,top,tt) */ int -resWalkup(tile,tt,xpos,ypos,func) - Tile *tile; - TileType tt; - int xpos,ypos; - Tile * (*func)(); +resWalkup(tile, tt, xpos, ypos, func) + Tile *tile; + TileType tt; + int xpos,ypos; + Tile * (*func)(); { - Point pt; - Tile *tp; + Point pt; + Tile *tp; - pt.p_x = xpos; - while (TiGetType(tile) == tt) - { - if (xpos == LEFT(tile)) - { - /* walk up left edge */ - for (tp = BL(tile);TOP(tp) <= ypos;tp=RT(tp)); - for (;BOTTOM(tp) < TOP(tile);tp=RT(tp)) - { - if (TiGetType(tp) != tt) return(BOTTOM(tp)); - } - } - else - { - if (func) tile = (*func)(tile,xpos); - } - pt.p_y = TOP(tile); - GOTOPOINT(tile,&pt); - } - return(BOTTOM(tile)); + pt.p_x = xpos; + while (TiGetType(tile) == tt) + { + if (xpos == LEFT(tile)) + { + /* walk up left edge */ + for (tp = BL(tile); TOP(tp) <= ypos; tp = RT(tp)); + for (; BOTTOM(tp) < TOP(tile); tp = RT(tp)) + { + if (TiGetType(tp) != tt) return(BOTTOM(tp)); + } + } + else + { + if (func) tile = (*func)(tile,xpos); + } + pt.p_y = TOP(tile); + GOTOPOINT(tile, &pt); + } + return(BOTTOM(tile)); } int -resWalkdown(tile,tt,xpos,ypos,func) - Tile *tile; - TileType tt; - int xpos,ypos; - Tile * (*func)(); +resWalkdown(tile, tt, xpos, ypos, func) + Tile *tile; + TileType tt; + int xpos, ypos; + Tile * (*func)(); { - Point pt; - Tile *tp; - Tile *endt; + Point pt; + Tile *tp; + Tile *endt; - pt.p_x = xpos; - while (TiGetType(tile) == tt) - { - if (xpos == LEFT(tile)) - { - /* walk up left edge */ - endt = NULL; - for (tp = BL(tile);BOTTOM(tp) < TOP(tile);tp=RT(tp)) - { - if (TiGetType(tp) != tt) - { - if (BOTTOM(tp) < ypos) endt = tp; - } - } - if (endt) - { - return TOP(endt); - } - } - else - { - if (func) tile = (*func)(tile,xpos); - } - pt.p_y = BOTTOM(tile)-1; - GOTOPOINT(tile,&pt); - } - return(TOP(tile)); + pt.p_x = xpos; + while (TiGetType(tile) == tt) + { + if (xpos == LEFT(tile)) + { + /* walk up left edge */ + endt = NULL; + for (tp = BL(tile); BOTTOM(tp) < TOP(tile); tp = RT(tp)) + { + if (TiGetType(tp) != tt) + { + if (BOTTOM(tp) < ypos) endt = tp; + } + } + if (endt) + { + return TOP(endt); + } + } + else + { + if (func) tile = (*func)(tile, xpos); + } + pt.p_y = BOTTOM(tile) - 1; + GOTOPOINT(tile, &pt); + } + return(TOP(tile)); } int -resWalkright(tile,tt,xpos,ypos,func) - Tile *tile; - TileType tt; - int xpos,ypos; - Tile * (*func)(); +resWalkright(tile, tt, xpos, ypos, func) + Tile *tile; + TileType tt; + int xpos, ypos; + Tile * (*func)(); { - Point pt; - Tile *tp; + Point pt; + Tile *tp; - pt.p_y = ypos; - while (TiGetType(tile) == tt) - { - if (ypos == BOTTOM(tile)) - { - /* walk along bottom edge */ - for (tp = LB(tile);LEFT(tp) < xpos;tp=TR(tp)); - for (;LEFT(tp) < RIGHT(tile);tp=TR(tp)) - { - if (TiGetType(tp) != tt) return(LEFT(tp)); - } - } - else - { - if (func) tile = (*func)(tile,ypos); - } - pt.p_x = RIGHT(tile); - GOTOPOINT(tile,&pt); - } - return(LEFT(tile)); + pt.p_y = ypos; + while (TiGetType(tile) == tt) + { + if (ypos == BOTTOM(tile)) + { + /* walk along bottom edge */ + for (tp = LB(tile); LEFT(tp) < xpos; tp = TR(tp)); + for (; LEFT(tp) < RIGHT(tile); tp = TR(tp)) + { + if (TiGetType(tp) != tt) return(LEFT(tp)); + } + } + else + { + if (func) tile = (*func)(tile, ypos); + } + pt.p_x = RIGHT(tile); + GOTOPOINT(tile, &pt); + } + return(LEFT(tile)); } int -resWalkleft(tile,tt,xpos,ypos,func) - Tile *tile; - TileType tt; - int xpos,ypos; - Tile * (*func)(); +resWalkleft(tile, tt, xpos, ypos, func) + Tile *tile; + TileType tt; + int xpos, ypos; + Tile * (*func)(); { - Point pt; - Tile *tp; - Tile *endt; + Point pt; + Tile *tp; + Tile *endt; - pt.p_y = ypos; - while (TiGetType(tile) == tt) - { - if (ypos == BOTTOM(tile)) - { - /* walk along bottom edge */ - endt = NULL; - for (tp = LB(tile);LEFT(tp) < RIGHT(tile);tp=TR(tp)) - { - if (TiGetType(tp) != tt) - { - if (LEFT(tp) < xpos) endt = tp; - } - } - if (endt) - { - return RIGHT(endt); - } - } - else - { - if (func) tile = (*func)(tile,ypos); - } - pt.p_x = LEFT(tile)-1; - GOTOPOINT(tile,&pt); - } - return(RIGHT(tile)); + pt.p_y = ypos; + while (TiGetType(tile) == tt) + { + if (ypos == BOTTOM(tile)) + { + /* walk along bottom edge */ + endt = NULL; + for (tp = LB(tile); LEFT(tp) < RIGHT(tile); tp = TR(tp)) + { + if (TiGetType(tp) != tt) + { + if (LEFT(tp) < xpos) endt = tp; + } + } + if (endt) + { + return RIGHT(endt); + } + } + else + { + if (func) tile = (*func)(tile, ypos); + } + pt.p_x = LEFT(tile) - 1; + GOTOPOINT(tile, &pt); + } + return(RIGHT(tile)); } /* @@ -419,59 +427,60 @@ resWalkleft(tile,tt,xpos,ypos,func) * *------------------------------------------------------------------------- */ + Tile * -ResSplitX(tile,x) - Tile *tile; - int x; +ResSplitX(tile, x) + Tile *tile; + int x; { - TileType tt = TiGetType(tile); - Tile *tp = TiSplitX(tile,x); - Tile *tp2; + TileType tt = TiGetType(tile); + Tile *tp = TiSplitX(tile, x); + Tile *tp2; - TiSetBody(tp,tt); - /* check to see if we can combine with the tiles above or below us */ - tp2 = RT(tile); - if (TiGetType(tp2) == tt && LEFT(tp2) == LEFT(tile) && RIGHT(tp2) == RIGHT(tile)) - { - if (tp2 == resSrTile) - { - if (resTopTile == tile) resTopTile = NULL; - TiJoinY(tp2,tile,resFracPlane); - tile = tp2; - } - else - { - if (resTopTile == tp2) resTopTile = NULL; - TiJoinY(tile,tp2,resFracPlane); - } - } - tp2 = LB(tile); - if (TiGetType(tp2) == tt && LEFT(tp2) == LEFT(tile) && RIGHT(tp2) == RIGHT(tile)) - { - if (tp2 == resSrTile) - { - if (resTopTile == tile) resTopTile = NULL; - TiJoinY(tp2,tile,resFracPlane); - tile = tp2; - } - else - { - if (resTopTile == tp2) resTopTile = NULL; - TiJoinY(tile,tp2,resFracPlane); - } - } - /* do the same checks with the newly created tile */ - tp2 = RT(tp); - if (TiGetType(tp2) == tt && LEFT(tp2) == LEFT(tp) && RIGHT(tp2) == RIGHT(tp)) - { - TiJoinY(tp2,tp,resFracPlane); - tp = tp2; - } - tp2 = LB(tp); - if (TiGetType(tp2) == tt && LEFT(tp2) == LEFT(tp) && RIGHT(tp2) == RIGHT(tp)) - { - TiJoinY(tp2,tp,resFracPlane); - } - return tile; + TiSetBody(tp,tt); + /* check to see if we can combine with the tiles above or below us */ + tp2 = RT(tile); + if (TiGetType(tp2) == tt && LEFT(tp2) == LEFT(tile) && RIGHT(tp2) == RIGHT(tile)) + { + if (tp2 == resSrTile) + { + if (resTopTile == tile) resTopTile = NULL; + TiJoinY(tp2, tile, resFracPlane); + tile = tp2; + } + else + { + if (resTopTile == tp2) resTopTile = NULL; + TiJoinY(tile, tp2, resFracPlane); + } + } + tp2 = LB(tile); + if (TiGetType(tp2) == tt && LEFT(tp2) == LEFT(tile) && RIGHT(tp2) == RIGHT(tile)) + { + if (tp2 == resSrTile) + { + if (resTopTile == tile) resTopTile = NULL; + TiJoinY(tp2, tile, resFracPlane); + tile = tp2; + } + else + { + if (resTopTile == tp2) resTopTile = NULL; + TiJoinY(tile, tp2, resFracPlane); + } + } + /* do the same checks with the newly created tile */ + tp2 = RT(tp); + if (TiGetType(tp2) == tt && LEFT(tp2) == LEFT(tp) && RIGHT(tp2) == RIGHT(tp)) + { + TiJoinY(tp2, tp, resFracPlane); + tp = tp2; + } + tp2 = LB(tp); + if (TiGetType(tp2) == tt && LEFT(tp2) == LEFT(tp) && RIGHT(tp2) == RIGHT(tp)) + { + TiJoinY(tp2, tp, resFracPlane); + } + return tile; } diff --git a/resis/ResJunct.c b/resis/ResJunct.c index 3d19089a..79328983 100644 --- a/resis/ResJunct.c +++ b/resis/ResJunct.c @@ -26,8 +26,6 @@ static char rcsid[] __attribute__ ((unused)) = "$Header: /usr/cvsroot/magic-8.0/ #include "textio/txcommands.h" #include "resis/resis.h" - - /* *------------------------------------------------------------------------- * @@ -45,56 +43,56 @@ static char rcsid[] __attribute__ ((unused)) = "$Header: /usr/cvsroot/magic-8.0/ */ void -ResNewSDDevice(tile,tp,xj,yj,direction,PendingList) - Tile *tile,*tp; - int xj,yj,direction; - resNode **PendingList; +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; + 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) + newnode = FALSE; + j = (tileJunk *) tp->ti_client; + resDev = j->deviceList; + if ((j->sourceEdge & direction) != 0) + { + if (resDev->rd_fet_source == (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_fet_source = resptr; } 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; - } + resptr = resDev->rd_fet_source; } - if (newnode) + } + else + { + if (resDev->rd_fet_drain == (resNode *) NULL) { - 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); + resptr = (resNode *) mallocMagic((unsigned)(sizeof(resNode))); + newnode = TRUE; + resDev->rd_fet_drain = resptr; } - NEWBREAK(resptr,tile,xj,yj,NULL); + 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); } /* @@ -113,49 +111,49 @@ ResNewSDDevice(tile,tp,xj,yj,direction,PendingList) void ResProcessJunction(tile, tp, xj, yj, NodeList) - Tile *tile, *tp; - int xj,yj; - resNode **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; + 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; - } + 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); + 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; + 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,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); + NEWBREAK(junction->rj_jnode,tp, junction->rj_loc.p_x, + junction->rj_loc.p_y, NULL); } diff --git a/resis/ResMain.c b/resis/ResMain.c index d5c6469e..78e32d29 100644 --- a/resis/ResMain.c +++ b/resis/ResMain.c @@ -20,23 +20,24 @@ static char rcsid[] __attribute__ ((unused)) = "$Header: /usr/cvsroot/magic-8.0/ #include "windows/windows.h" #include "dbwind/dbwind.h" #include "utils/tech.h" +#include "select/select.h" #include "textio/txcommands.h" #include "resis/resis.h" -CellUse *ResUse=NULL; /* Our use and def */ -CellDef *ResDef=NULL; +CellUse *ResUse = NULL; /* Our use and def */ +CellDef *ResDef = NULL; TileTypeBitMask ResConnectWithSD[NT]; /* A mask that goes from */ /* SD's to devices. */ TileTypeBitMask ResCopyMask[NT]; /* Indicates which tiles */ /* are to be copied. */ -resResistor *ResResList=NULL; /* Resistor list */ -resNode *ResNodeList=NULL; /* Processed Nodes */ -resDevice *ResDevList=NULL; /* Devices */ -ResContactPoint *ResContactList=NULL; /* Contacts */ -resNode *ResNodeQueue=NULL; /* Pending nodes */ -resNode *ResOriginNode=NULL; /* node where R=0 */ +resResistor *ResResList = NULL; /* Resistor list */ +resNode *ResNodeList = NULL; /* Processed Nodes */ +resDevice *ResDevList = NULL; /* Devices */ +ResContactPoint *ResContactList = NULL; /* Contacts */ +resNode *ResNodeQueue = NULL; /* Pending nodes */ +resNode *ResOriginNode = NULL; /* node where R=0 */ resNode *resCurrentNode; -int ResTileCount=0; /* Number of tiles rn_status */ +int ResTileCount = 0; /* Number of tiles rn_status */ extern Region *ResFirst(); extern Tile *FindStartTile(); extern int ResEachTile(); @@ -45,8 +46,6 @@ extern ResSimNode *ResInitializeNode(); extern HashTable ResNodeTable; - - /* *-------------------------------------------------------------------------- * @@ -78,13 +77,13 @@ ResInitializeConn() for (diff = TT_TECHDEPBASE; diff < TT_MAXTYPES; diff++) { if TTMaskHasType(&(devptr->exts_deviceSDTypes[0]), diff) - TTMaskSetType(&ResConnectWithSD[diff],dev); + TTMaskSetType(&ResConnectWithSD[diff], dev); - if TTMaskHasType(&(devptr->exts_deviceSubstrateTypes),diff) - TTMaskSetType(&ResConnectWithSD[diff],dev); + if TTMaskHasType(&(devptr->exts_deviceSubstrateTypes), diff) + TTMaskSetType(&ResConnectWithSD[diff], dev); } } - TTMaskSetMask(&ResConnectWithSD[dev],&DBConnectTbl[dev]); + TTMaskSetMask(&ResConnectWithSD[dev], &DBConnectTbl[dev]); } } @@ -121,7 +120,6 @@ ResGetReCell() ResUse = DBCellNewUse(ResDef, (char *) NULL); DBSetTrans(ResUse, &GeoIdentityTransform); ResUse->cu_expandMask = CU_DESCEND_SPECIAL; - } /* @@ -172,7 +170,7 @@ ResDissolveContacts(contacts) } tp = ResDef->cd_planes[DBPlane(contacts->cp_type)]->pl_hint; - GOTOPOINT(tp,&(contacts->cp_rect.r_ll)); + GOTOPOINT(tp, &(contacts->cp_rect.r_ll)); #ifdef PARANOID if (TiGetTypeExact(tp) == contacts->cp_type) { @@ -325,46 +323,46 @@ ResAddBreakpointFunc(tile, node) void ResFindNewContactTiles(contacts) - ResContactPoint *contacts; + ResContactPoint *contacts; { - int pNum; - Tile *tile; - TileTypeBitMask mask; + int pNum; + Tile *tile; + TileTypeBitMask mask; - for (; contacts != (ResContactPoint *) NULL; contacts = contacts->cp_nextcontact) - { - DBFullResidueMask(contacts->cp_type, &mask); - for (pNum=PL_TECHDEPBASE; pNumcd_planes[pNum]->pl_hint; - GOTOPOINT(tile, &(contacts->cp_center)); + for (; contacts != (ResContactPoint *) NULL; contacts = contacts->cp_nextcontact) + { + DBFullResidueMask(contacts->cp_type, &mask); + for (pNum = PL_TECHDEPBASE; pNum < DBNumPlanes; pNum++) + { + tile = ResDef->cd_planes[pNum]->pl_hint; + GOTOPOINT(tile, &(contacts->cp_center)); #ifdef PARANOID - if (tile == (Tile *) NULL) - { - TxError("Error: setting contact tile to null\n"); - } + if (tile == (Tile *) NULL) + { + TxError("Error: setting contact tile to null\n"); + } #endif - if ((IsSplit(tile) && TTMaskHasType(&mask, TiGetRightType(tile))) + if ((IsSplit(tile) && TTMaskHasType(&mask, TiGetRightType(tile))) || TTMaskHasType(&mask, TiGetType(tile))) - { - tileJunk *j = (tileJunk *)tile->ti_client; - cElement *ce; + { + tileJunk *j = (tileJunk *)tile->ti_client; + cElement *ce; - ce = (cElement *) mallocMagic((unsigned) (sizeof(cElement))); - contacts->cp_tile[contacts->cp_currentcontact] = tile; - ce->ce_thisc = contacts; - ce->ce_nextc = j->contactList; - (contacts->cp_currentcontact) += 1; - j->contactList = ce; - } - } + ce = (cElement *) mallocMagic((unsigned) (sizeof(cElement))); + contacts->cp_tile[contacts->cp_currentcontact] = tile; + ce->ce_thisc = contacts; + ce->ce_nextc = j->contactList; + (contacts->cp_currentcontact) += 1; + j->contactList = ce; + } + } #ifdef PARANOID - if (contacts->cp_currentcontact > LAYERS_PER_CONTACT) - { - TxError("Error: Not enough space allocated for contact nodes\n"); - } + if (contacts->cp_currentcontact > LAYERS_PER_CONTACT) + { + TxError("Error: Not enough space allocated for contact nodes\n"); + } #endif - } + } } /* @@ -388,78 +386,77 @@ ResProcessTiles(goodies, origin) ResGlobalParams *goodies; { - Tile *startTile; - int tilenum,merged; - resNode *resptr2; - jElement *workingj; - cElement *workingc; - ResFixPoint *fix; - resNode *resptr; - int (*tilefunc)(); + Tile *startTile; + int tilenum, merged; + resNode *resptr2; + jElement *workingj; + cElement *workingc; + ResFixPoint *fix; + resNode *resptr; + int (*tilefunc)(); #ifdef LAPLACE - tilefunc = (ResOptionsFlags & ResOpt_DoLaplace)?ResLaplaceTile:ResEachTile; + tilefunc = (ResOptionsFlags & ResOpt_DoLaplace) ? ResLaplaceTile : ResEachTile; #else - tilefunc = ResEachTile; + tilefunc = ResEachTile; #endif if (ResOptionsFlags & ResOpt_Signal) { - startTile = FindStartTile(goodies, origin); - if (startTile == NULL) return(1); - resCurrentNode = NULL; - (void) (*tilefunc)(startTile, origin); + startTile = FindStartTile(goodies, origin); + if (startTile == NULL) return(1); + resCurrentNode = NULL; + (void) (*tilefunc)(startTile, origin); } #ifdef ARIEL else if (ResOptionsFlags & ResOpt_Power) { - for (fix = ResFixList; fix != NULL;fix=fix->fp_next) - { - Tile *tile = fix->fp_tile; - if (tile == NULL) - { + for (fix = ResFixList; fix != NULL; fix = fix->fp_next) + { + Tile *tile = fix->fp_tile; + if (tile == NULL) + { + tile = ResDef->cd_planes[DBPlane(fix->fp_ttype)]->pl_hint; + GOTOPOINT(tile, &(fix->fp_loc)); + if (TiGetTypeExact(tile) != TT_SPACE) + { + fix->fp_tile = tile; + } + else + { + tile = NULL; + } + } + if (tile != NULL) + { + int x = fix->fp_loc.p_x; + int y = fix->fp_loc.p_y; + resptr = (resNode *) mallocMagic((unsigned)(sizeof(resNode))); + InitializeNode(resptr, x, y, RES_NODE_ORIGIN); + resptr->rn_status = TRUE; + resptr->rn_noderes = 0; + ResAddToQueue(resptr, &ResNodeQueue); + fix->fp_node = resptr; + NEWBREAK(resptr, tile, x, y, NULL); + } + } + for (fix = ResFixList; fix != NULL; fix = fix->fp_next) + { + Tile *tile = fix->fp_tile; - tile = ResDef->cd_planes[DBPlane(fix->fp_ttype)]->pl_hint; - GOTOPOINT(tile, &(fix->fp_loc)); - if (TiGetTypeExact(tile) != TT_SPACE) - { - fix->fp_tile = tile; - } - else - { - tile = NULL; - } - } - if (tile != NULL) - { - int x = fix->fp_loc.p_x; - int y = fix->fp_loc.p_y; - resptr = (resNode *) mallocMagic((unsigned)(sizeof(resNode))); - InitializeNode(resptr, x, y, RES_NODE_ORIGIN); - resptr->rn_status = TRUE; - resptr->rn_noderes = 0; - ResAddToQueue(resptr, &ResNodeQueue); - fix->fp_node = resptr; - NEWBREAK(resptr, tile, x, y, NULL); - } - } - for (fix = ResFixList; fix != NULL; fix = fix->fp_next) - { - Tile *tile = fix->fp_tile; - - if (tile != NULL && (((tileJunk *)tile->ti_client)->tj_status & + if (tile != NULL && (((tileJunk *)tile->ti_client)->tj_status & RES_TILE_DONE) == 0) - { - resCurrentNode = fix->fp_node; - (void) (*tilefunc)(tile, (Point *)NULL); - } - } + { + resCurrentNode = fix->fp_node; + (void) (*tilefunc)(tile, (Point *)NULL); + } + } } #endif #ifdef PARANOID else { - TxError("Unknown analysis type in ResProcessTiles\n"); + TxError("Unknown analysis type in ResProcessTiles\n"); } #endif @@ -467,103 +464,199 @@ ResProcessTiles(goodies, origin) while (ResNodeQueue != NULL) { - /* - * merged keeps track of whether another node gets merged into - * the current one. If it does, then the node must be processed - * because additional junctions or contacts were added - */ + /* + * merged keeps track of whether another node gets merged into + * the current one. If it does, then the node must be processed + * because additional junctions or contacts were added + */ - resptr2 = ResNodeQueue; - merged = FALSE; + resptr2 = ResNodeQueue; + merged = FALSE; - /* Process all junctions associated with node */ + /* Process all junctions associated with node */ - for (workingj = resptr2->rn_je; workingj != NULL; workingj = workingj->je_nextj) - { - ResJunction *rj = workingj->je_thisj; - if (rj->rj_status == FALSE) - { - for (tilenum = 0; tilenum < TILES_PER_JUNCTION; tilenum++) - { - Tile *tile = rj->rj_Tile[tilenum]; - tileJunk *j = (tileJunk *) tile->ti_client; + for (workingj = resptr2->rn_je; workingj != NULL; workingj = workingj->je_nextj) + { + ResJunction *rj = workingj->je_thisj; + if (rj->rj_status == FALSE) + { + for (tilenum = 0; tilenum < TILES_PER_JUNCTION; tilenum++) + { + Tile *tile = rj->rj_Tile[tilenum]; + tileJunk *j = (tileJunk *)tile->ti_client; - if ((j->tj_status & RES_TILE_DONE) == 0) + if ((j->tj_status & RES_TILE_DONE) == 0) + { + resCurrentNode = resptr2; + merged |= (*tilefunc)(tile,(Point *)NULL); + } + if (merged & ORIGIN) break; + } + if (merged & ORIGIN) break; + rj->rj_status = TRUE; + } + } + + /* Next, Process all contacts. */ + + for (workingc = resptr2->rn_ce;workingc != NULL;workingc = workingc->ce_nextc) + { + ResContactPoint *cp = workingc->ce_thisc; + + if (merged & ORIGIN) break; + if (cp->cp_status == FALSE) + { + int newstatus = TRUE; + for (tilenum = 0; tilenum < cp->cp_currentcontact; tilenum++) + { + Tile *tile = cp->cp_tile[tilenum]; + tileJunk *j = (tileJunk *) tile->ti_client; + + if ((j->tj_status & RES_TILE_DONE) == 0) + { + if (cp->cp_cnode[tilenum] == resptr2) { - resCurrentNode = resptr2; - merged |= (*tilefunc)(tile,(Point *)NULL); + resCurrentNode = resptr2; + merged |= (*tilefunc)(tile,(Point *)NULL); } - if (merged & ORIGIN) break; - } - if (merged & ORIGIN) break; - rj->rj_status = TRUE; - } - } - - /* Next, Process all contacts. */ - - for (workingc = resptr2->rn_ce;workingc != NULL;workingc = workingc->ce_nextc) - { - ResContactPoint *cp = workingc->ce_thisc; - - if (merged & ORIGIN) break; - if (cp->cp_status == FALSE) - { - int newstatus = TRUE; - for (tilenum = 0; tilenum < cp->cp_currentcontact; tilenum++) - { - Tile *tile = cp->cp_tile[tilenum]; - tileJunk *j = (tileJunk *) tile->ti_client; - - if ((j->tj_status & RES_TILE_DONE) == 0) + else { - if (cp->cp_cnode[tilenum] == resptr2) - { - resCurrentNode = resptr2; - merged |= (*tilefunc)(tile,(Point *)NULL); - } - else - { - newstatus = FALSE; - } + newstatus = FALSE; } - if (merged & ORIGIN) break; - } - if (merged & ORIGIN) break; - cp->cp_status = newstatus; - } - } + } + if (merged & ORIGIN) break; + } + if (merged & ORIGIN) break; + cp->cp_status = newstatus; + } + } - /* - * If nothing new has been added via a merge, then the node is - * finished. It is removed from the pending queue, added to the - * done list, cleaned up, and passed to ResDoneWithNode - */ + /* + * If nothing new has been added via a merge, then the node is + * finished. It is removed from the pending queue, added to the + * done list, cleaned up, and passed to ResDoneWithNode + */ - if (merged == FALSE) - { - ResRemoveFromQueue(resptr2,&ResNodeQueue); - resptr2->rn_more = ResNodeList; - resptr2->rn_less = NULL; - resptr2->rn_status &= ~PENDING; - resptr2->rn_status |= FINISHED | MARKED; - if (ResNodeList != NULL) - { - ResNodeList->rn_less = resptr2; - } - if (resptr2->rn_noderes == 0) - { - ResOriginNode=resptr2; - } - ResNodeList = resptr2; - ResCleanNode(resptr2, FALSE, &ResNodeList, &ResNodeQueue); - ResDoneWithNode(resptr2); - } - } - return(0); + if (merged == FALSE) + { + ResRemoveFromQueue(resptr2, &ResNodeQueue); + resptr2->rn_more = ResNodeList; + resptr2->rn_less = NULL; + resptr2->rn_status &= ~PENDING; + resptr2->rn_status |= FINISHED | MARKED; + if (ResNodeList != NULL) + { + ResNodeList->rn_less = resptr2; + } + if (resptr2->rn_noderes == 0) + { + ResOriginNode=resptr2; + } + ResNodeList = resptr2; + ResCleanNode(resptr2, FALSE, &ResNodeList, &ResNodeQueue); + ResDoneWithNode(resptr2); + } + } + return(0); } -/*------------------------------------------------------------------------- +/* + *------------------------------------------------------------------------- + * + * ResCalcPerimOverlap --- + * + * Given a device tile, compute simple perimeter and overlap of the device + * by the net under consideration. + * + * Results: + * None. + * + * Side Effects: + * The ResDevTile structure is updated with the overlap and perimeter + * values. + * + *------------------------------------------------------------------------- + */ + +void +ResCalcPerimOverlap(tile, dev) + Tile *tile; + ResDevTile *dev; +{ + Tile *tp; + int t1; + int overlap; + TileTypeBitMask *omask; + + dev->perim = (TOP(tile) - BOTTOM(tile) - LEFT(tile) + RIGHT(tile)) << 1; + overlap = 0; + + t1 = TiGetType(tile); + omask = &(ExtCurStyle->exts_nodeConn[t1]); + + /* left */ + for (tp = BL(tile); BOTTOM(tp) < TOP(tile); tp = RT(tp)) + { + if TTMaskHasType(omask, TiGetType(tp)) + overlap += MIN(TOP(tile), TOP(tp)) - MAX(BOTTOM(tile), BOTTOM(tp)); + } + + /* right */ + for (tp = TR(tile); TOP(tp) > BOTTOM(tile); tp=LB(tp)) + { + if TTMaskHasType(omask, TiGetType(tp)) + overlap += MIN(TOP(tile), TOP(tp)) - MAX(BOTTOM(tile), BOTTOM(tp)); + } + + /* top */ + for (tp = RT(tile); RIGHT(tp) > LEFT(tile); tp = BL(tp)) + { + if TTMaskHasType(omask, TiGetType(tp)) + overlap += MIN(RIGHT(tile), RIGHT(tp)) - MAX(LEFT(tile), LEFT(tp)); + } + + /* bottom */ + for (tp = LB(tile); LEFT(tp) < RIGHT(tile); tp=TR(tp)) + { + if TTMaskHasType(omask, TiGetType(tp)) + overlap += MIN(RIGHT(tile), RIGHT(tp)) - MAX(LEFT(tile), LEFT(tp)); + } + dev->overlap = overlap; +} +/* + *------------------------------------------------------------------------- + * + * resMakeDevFunc -- + * + * Callback function from ResExtractNet. For each device in a node's + * device list pulled from the .sim file, find the tile corresponding + * to the device in the source tree, and fill out the complete device + * record (namely the full device area). + * + * Result: + * Return 1 to stop the search because the device has been found. + * + *------------------------------------------------------------------------- + */ + +int +resMakeDevFunc(tile, cx) + Tile *tile; + TreeContext *cx; +{ + ResDevTile *thisDev = (ResDevTile *)cx->tc_filter->tf_arg; + Rect devArea; + + TiToRect(tile, &devArea); + GeoTransRect(&cx->tc_scx->scx_trans, &devArea, &thisDev->area); + ResCalcPerimOverlap(tile, thisDev); + + return 1; +} + + +/* + *------------------------------------------------------------------------- * * ResExtractNet-- extracts the resistance net at the specified * rn_loc. If the resulting net is greater than the tolerance, @@ -577,18 +670,20 @@ ResProcessTiles(goodies, origin) */ bool -ResExtractNet(startlist, goodies, cellname) - ResFixPoint *startlist; +ResExtractNet(node, goodies, cellname) + ResSimNode *node; ResGlobalParams *goodies; char *cellname; { SearchContext scx; int pNum; - ResDevTile *DevTiles, *lasttile; TileTypeBitMask FirstTileMask; Point startpoint; - ResFixPoint *fix; static int first = 1; + ResDevTile *DevTiles, *thisDev; + ResFixPoint *fix; + devPtr *tptr; + int resMakeDevFunc(); /* Make sure all global network variables are reset */ @@ -599,18 +694,18 @@ ResExtractNet(startlist, goodies, cellname) ResContactList = NULL; ResOriginNode = NULL; - /* Pass back network pointers */ + /* Pass back network pointers */ goodies->rg_maxres = 0; goodies->rg_tilecount = 0; - /*set up internal stuff if this is the first time through */ + /* Set up internal stuff if this is the first time through */ if (first) { - ResInitializeConn(); - first = 0; - ResGetReCell(); + ResInitializeConn(); + first = 0; + ResGetReCell(); } /* Initialize Cell */ @@ -618,7 +713,7 @@ ResExtractNet(startlist, goodies, cellname) if (cellname) { CellDef *def = DBCellLookDef(cellname); - if (def == (CellDef *) NULL) + if (def == (CellDef *)NULL) { TxError("Error: No such cell \"%s\"\n", cellname); return TRUE; @@ -629,8 +724,8 @@ ResExtractNet(startlist, goodies, cellname) } else { - MagWindow *w = ToolGetBoxWindow(&scx.scx_area, (int *) NULL); - if (w == (MagWindow *) NULL) + MagWindow *w = ToolGetBoxWindow(&scx.scx_area, (int *)NULL); + if (w == (MagWindow *)NULL) { TxError("Sorry, the box must appear in one of the windows.\n"); return TRUE; @@ -641,49 +736,59 @@ ResExtractNet(startlist, goodies, cellname) DBCellClearDef(ResUse->cu_def); - /* Copy Paint */ - DevTiles = NULL; - lasttile = NULL; - for (fix = startlist; fix != NULL; fix = fix->fp_next) - { - ResDevTile *newdevtiles, *tmp; - #ifdef ARIEL - if ((ResOptionsFlags & ResOpt_Power) && - strcmp(fix->fp_name, goodies->rg_name) != 0) continue; + if ((ResOptionsFlags & ResOpt_Power) && + strcmp(node->name, goodies->rg_name) != 0) continue; #endif - scx.scx_area.r_ll.p_x = fix->fp_loc.p_x-2; - scx.scx_area.r_ll.p_y = fix->fp_loc.p_y-2; - scx.scx_area.r_ur.p_x = fix->fp_loc.p_x+2; - scx.scx_area.r_ur.p_y = fix->fp_loc.p_y+2; - startpoint = fix->fp_loc; + /* Copy Paint */ - /* Because fix->fp_ttype might come from a label with a sticky type - * that does not correspond exactly to the layer underneath, include - * all connecting types. - */ - TTMaskSetMask(&FirstTileMask, &DBConnectTbl[fix->fp_ttype]); + scx.scx_area.r_ll.p_x = node->location.p_x - 2; + scx.scx_area.r_ll.p_y = node->location.p_y - 2; + scx.scx_area.r_ur.p_x = node->location.p_x + 2; + scx.scx_area.r_ur.p_y = node->location.p_y + 2; + startpoint = node->location; - newdevtiles = DBTreeCopyConnectDCS(&scx, &FirstTileMask, 0, - ResCopyMask, &TiPlaneRect, ResUse); + /* Because node->type might come from a label with a sticky type + * that does not correspond exactly to the layer underneath, include + * all connecting types. + */ + TTMaskZero(&FirstTileMask); + TTMaskSetMask(&FirstTileMask, &DBConnectTbl[node->type]); - for (tmp = newdevtiles; tmp && tmp->nextDev; tmp = tmp->nextDev); - if (newdevtiles) - { - if (DevTiles) - lasttile->nextDev = newdevtiles; - else - DevTiles = newdevtiles; - lasttile = tmp; - } + DBTreeCopyConnect(&scx, &FirstTileMask, 0, ResCopyMask, &TiPlaneRect, + SEL_DO_LABELS, ResUse); + + /* Add devices to ResUse from list in node */ + DevTiles = NULL; + for (tptr = node->firstDev; tptr; tptr = tptr->nextDev) + { + TileTypeBitMask devMask; + + TTMaskSetOnlyType(&devMask, tptr->thisDev->rs_ttype); + thisDev = (ResDevTile *)mallocMagic(sizeof(ResDevTile)); + thisDev->devptr = tptr->thisDev->rs_devptr; + thisDev->type = tptr->thisDev->rs_ttype; + scx.scx_area.r_ll.p_x = tptr->thisDev->location.p_x; + scx.scx_area.r_ll.p_y = tptr->thisDev->location.p_y; + scx.scx_area.r_xtop = scx.scx_area.r_xbot + 1; + scx.scx_area.r_ytop = scx.scx_area.r_ybot + 1; + DBTreeSrTiles(&scx, &devMask, 0, resMakeDevFunc, (ClientData)thisDev); + thisDev->nextDev = DevTiles; + DevTiles = thisDev; + + /* Paint the type into ResUse */ + pNum = DBPlane(thisDev->type); + DBPaintPlane(ResUse->cu_def->cd_planes[pNum], &thisDev->area, + DBStdPaintTbl(thisDev->type, pNum), (PaintUndoInfo *)NULL); } + DBReComputeBbox(ResUse->cu_def); ExtResetTiles(scx.scx_use->cu_def, extUnInit); - /* find all contacts in design and note their position */ + /* Find all contacts in design and note their position */ - ResContactList = (ResContactPoint *) ExtFindRegions(ResUse->cu_def, + ResContactList = (ResContactPoint *)ExtFindRegions(ResUse->cu_def, &(ResUse->cu_def->cd_bbox), &DBAllButSpaceAndDRCBits, ResConnectWithSD, extUnInit, ResFirst, @@ -701,16 +806,16 @@ ResExtractNet(startlist, goodies, cellname) for (pNum = PL_TECHDEPBASE; pNum < DBNumPlanes; pNum++) { - Plane *plane = ResUse->cu_def->cd_planes[pNum]; - Rect *rect = &ResUse->cu_def->cd_bbox; - ResFracture(plane, rect); - (void) DBSrPaintClient((Tile *) NULL,plane,rect, + Plane *plane = ResUse->cu_def->cd_planes[pNum]; + Rect *rect = &ResUse->cu_def->cd_bbox; + ResFracture(plane, rect); + (void) DBSrPaintClient((Tile *) NULL, plane, rect, &DBAllButSpaceAndDRCBits, (ClientData) CLIENTDEFAULT, ResAddPlumbing, (ClientData) &ResDevList); } - /* Finish preprocessing. */ + /* Finish preprocessing. */ ResMakePortBreakpoints(ResUse->cu_def); ResMakeLabelBreakpoints(ResUse->cu_def); @@ -720,24 +825,24 @@ ResExtractNet(startlist, goodies, cellname) #ifdef LAPLACE if (ResOptionsFlags & ResOpt_DoLaplace) { - for (pNum = PL_TECHDEPBASE; pNum < DBNumPlanes; pNum++) - { - Plane *plane = ResUse->cu_def->cd_planes[pNum]; - Rect *rect = &ResUse->cu_def->cd_bbox; - Res1d(plane,rect); - } + for (pNum = PL_TECHDEPBASE; pNum < DBNumPlanes; pNum++) + { + Plane *plane = ResUse->cu_def->cd_planes[pNum]; + Rect *rect = &ResUse->cu_def->cd_bbox; + Res1d(plane, rect); + } } #endif #ifdef ARIEL if (ResOptionsFlags & ResOpt_Power) { - for (fix = startlist; fix != NULL;fix=fix->fp_next) - { - fix->fp_tile = ResUse->cu_def->cd_planes[DBPlane(fix->fp_ttype)]->pl_hint; - GOTOPOINT(fix->fp_tile,&fix->fp_loc); - if (TiGetTypeExact(fix->fp_tile) == TT_SPACE) fix->fp_tile = NULL; - } + for (fix = startlist; fix != NULL; fix = fix->fp_next) + { + fix->fp_tile = ResUse->cu_def->cd_planes[DBPlane(fix->fp_ttype)]->pl_hint; + GOTOPOINT(fix->fp_tile, &fix->fp_loc); + if (TiGetTypeExact(fix->fp_tile) == TT_SPACE) fix->fp_tile = NULL; + } } #endif @@ -765,25 +870,24 @@ void ResCleanUpEverything() { - int pNum; - resResistor *oldRes; - resDevice *oldDev; - ResContactPoint *oldCon; + int pNum; + resResistor *oldRes; + resDevice *oldDev; + ResContactPoint *oldCon; - /* check integrity of internal database. Free up lists. */ + /* Check integrity of internal database. Free up lists. */ for (pNum = PL_TECHDEPBASE; pNum < DBNumPlanes; pNum++) { - (void) DBSrPaintClient((Tile *) NULL,ResUse->cu_def->cd_planes[pNum], - &(ResUse->cu_def->cd_bbox),&DBAllButSpaceAndDRCBits, - (ClientData) CLIENTDEFAULT,ResRemovePlumbing, - (ClientData) NULL); - + (void) DBSrPaintClient((Tile *)NULL, ResUse->cu_def->cd_planes[pNum], + &(ResUse->cu_def->cd_bbox), &DBAllButSpaceAndDRCBits, + (ClientData)CLIENTDEFAULT, ResRemovePlumbing, + (ClientData)NULL); } while (ResNodeList != NULL) { - ResCleanNode(ResNodeList,TRUE,&ResNodeList,&ResNodeQueue); + ResCleanNode(ResNodeList, TRUE, &ResNodeList, &ResNodeQueue); } while (ResContactList != NULL) { @@ -807,12 +911,9 @@ ResCleanUpEverything() freeMagic((char *)oldDev); } } - DBCellClearDef(ResUse->cu_def); } - - /* *------------------------------------------------------------------------- * @@ -849,10 +950,10 @@ FindStartTile(goodies, SourcePoint) TileType savtype = goodies->rg_ttype; TileType rtype; - savtype = goodies->rg_ttype; for (rtype = TT_TECHDEPBASE; rtype < DBNumUserLayers; rtype++) if (TTMaskHasType(rmask, rtype)) { + goodies->rg_ttype = rtype; if ((tile = FindStartTile(goodies, SourcePoint)) != NULL) { goodies->rg_ttype = savtype; @@ -934,54 +1035,55 @@ FindStartTile(goodies, SourcePoint) t1 = TiGetType(tile); devptr = ExtCurStyle->exts_device[t1]; + /* left */ - for (tp = BL(tile); BOTTOM(tp) < TOP(tile); tp=RT(tp)) + for (tp = BL(tile); BOTTOM(tp) < TOP(tile); tp = RT(tp)) { t2 = TiGetRightType(tp); - if (TTMaskHasType(&(devptr->exts_deviceSDTypes[0]),t2)) + if (TTMaskHasType(&(devptr->exts_deviceSDTypes[0]), t2)) { SourcePoint->p_x = LEFT(tile); - SourcePoint->p_y = (MIN(TOP(tile),TOP(tp))+ - MAX(BOTTOM(tile),BOTTOM(tp)))>>1; + SourcePoint->p_y = (MIN(TOP(tile),TOP(tp)) + + MAX(BOTTOM(tile), BOTTOM(tp))) >> 1; return(tp); } } /* right */ - for (tp = TR(tile); TOP(tp) > BOTTOM(tile); tp=LB(tp)) + for (tp = TR(tile); TOP(tp) > BOTTOM(tile); tp = LB(tp)) { t2 = TiGetLeftType(tp); - if (TTMaskHasType(&(devptr->exts_deviceSDTypes[0]),t2)) + if (TTMaskHasType(&(devptr->exts_deviceSDTypes[0]), t2)) { SourcePoint->p_x = RIGHT(tile); - SourcePoint->p_y = (MIN(TOP(tile),TOP(tp))+ - MAX(BOTTOM(tile),BOTTOM(tp)))>>1; + SourcePoint->p_y = (MIN(TOP(tile), TOP(tp))+ + MAX(BOTTOM(tile), BOTTOM(tp))) >> 1; return(tp); } } /* top */ - for (tp = RT(tile); RIGHT(tp) > LEFT(tile); tp=BL(tp)) + for (tp = RT(tile); RIGHT(tp) > LEFT(tile); tp = BL(tp)) { t2 = TiGetBottomType(tp); - if (TTMaskHasType(&(devptr->exts_deviceSDTypes[0]),t2)) + if (TTMaskHasType(&(devptr->exts_deviceSDTypes[0]), t2)) { SourcePoint->p_y = TOP(tile); - SourcePoint->p_x = (MIN(RIGHT(tile),RIGHT(tp))+ - MAX(LEFT(tile),LEFT(tp)))>>1; + SourcePoint->p_x = (MIN(RIGHT(tile),RIGHT(tp)) + + MAX(LEFT(tile), LEFT(tp))) >> 1; return(tp); } } /* bottom */ - for (tp = LB(tile); LEFT(tp) < RIGHT(tile); tp=TR(tp)) + for (tp = LB(tile); LEFT(tp) < RIGHT(tile); tp = TR(tp)) { t2 = TiGetTopType(tp); - if (TTMaskHasType(&(devptr->exts_deviceSDTypes[0]),t2)) + if (TTMaskHasType(&(devptr->exts_deviceSDTypes[0]), t2)) { SourcePoint->p_y = BOTTOM(tile); - SourcePoint->p_x = (MIN(RIGHT(tile),RIGHT(tp))+ - MAX(LEFT(tile),LEFT(tp)))>>1; + SourcePoint->p_x = (MIN(RIGHT(tile), RIGHT(tp)) + + MAX(LEFT(tile), LEFT(tp))) >> 1; return(tp); } } @@ -1005,36 +1107,36 @@ FindStartTile(goodies, SourcePoint) resDevice * ResGetDevice(pt) - Point *pt; + Point *pt; { - Point workingPoint; - Tile *tile; - int pnum; + Point workingPoint; + Tile *tile; + int pnum; - workingPoint.p_x = (*pt).p_x; - workingPoint.p_y = (*pt).p_y; + workingPoint.p_x = (*pt).p_x; + workingPoint.p_y = (*pt).p_y; - for (pnum= PL_TECHDEPBASE; pnum < DBNumPlanes; pnum++) - { - if (TTMaskIntersect(&ExtCurStyle->exts_deviceMask,&DBPlaneTypes[pnum]) == 0) - { - continue; - } - /*start at hint tile for device plane */ - tile = ResUse->cu_def->cd_planes[pnum]->pl_hint; - GOTOPOINT(tile,&workingPoint); + for (pnum = PL_TECHDEPBASE; pnum < DBNumPlanes; pnum++) + { + if (TTMaskIntersect(&ExtCurStyle->exts_deviceMask, &DBPlaneTypes[pnum]) == 0) + continue; - if (IsSplit(tile)) - { - if (TTMaskHasType(&ExtCurStyle->exts_deviceMask, TiGetLeftType(tile)) + /* Start at hint tile for device plane */ + + tile = ResUse->cu_def->cd_planes[pnum]->pl_hint; + GOTOPOINT(tile, &workingPoint); + + if (IsSplit(tile)) + { + if (TTMaskHasType(&ExtCurStyle->exts_deviceMask, TiGetLeftType(tile)) || TTMaskHasType(&ExtCurStyle->exts_deviceMask, TiGetRightType(tile))) - return(((tileJunk *)tile->ti_client)->deviceList); - } - else if (TTMaskHasType(&ExtCurStyle->exts_deviceMask, TiGetType(tile))) - { - return(((tileJunk *)tile->ti_client)->deviceList); - } - } - return (NULL); + return (((tileJunk *)tile->ti_client)->deviceList); + } + else if (TTMaskHasType(&ExtCurStyle->exts_deviceMask, TiGetType(tile))) + { + return (((tileJunk *)tile->ti_client)->deviceList); + } + } + return NULL; } diff --git a/resis/ResMakeRes.c b/resis/ResMakeRes.c index 6f15b3ee..b16d889d 100644 --- a/resis/ResMakeRes.c +++ b/resis/ResMakeRes.c @@ -311,7 +311,7 @@ ResCalcNorthSouth(tile, pendingList, doneList, resList) */ p1 = junk->breakList; - if (p1->br_next == NULL) + if (p1->br_next == NULL) { p1->br_this->rn_float.rn_area += width * (TOP(tile) - BOTTOM(tile)); freeMagic((char *)p1); diff --git a/resis/ResMerge.c b/resis/ResMerge.c index db328065..4650d52e 100644 --- a/resis/ResMerge.c +++ b/resis/ResMerge.c @@ -13,6 +13,7 @@ static char rcsid[] __attribute__ ((unused)) = "$Header: /usr/cvsroot/magic-8.0/ #include "database/database.h" #include "utils/malloc.h" #include "textio/textio.h" +#include "extract/extractInt.h" #include "resis/resis.h" TileTypeBitMask ResNoMergeMask[NT]; @@ -29,9 +30,10 @@ extern void ResFixBreakPoint(); /* *------------------------------------------------------------------------- * - * ResDoneWithNode--After all connections to node are made, ResDoneWithNode - * is called. It checks for parallel, series, loop, triangle, - * and single conections, and simplifies the network where possible. + * ResDoneWithNode-- + * After all connections to node are made, ResDoneWithNode is + * called. It checks for parallel, series, loop, triangle, and + * single conections, and simplifies the network where possible. * * Results: none * @@ -56,10 +58,7 @@ ResDoneWithNode(resptr) /* are there any resistors? */ - if (resptr->rn_re == NULL) - { - return; - } + if (resptr->rn_re == NULL) return; /* Special handling for geometry option */ @@ -73,10 +72,10 @@ ResDoneWithNode(resptr) rr1 = rcell1->re_thisEl; if (rr1->rr_connection1 == rr1->rr_connection2) { - ResDeleteResPointer(resptr,rr1); - ResDeleteResPointer(resptr,rr1); + ResDeleteResPointer(resptr, rr1); + ResDeleteResPointer(resptr, rr1); resptr->rn_float.rn_area += rr1->rr_float.rr_area; - ResEliminateResistor(rr1,&ResResList); + ResEliminateResistor(rr1, &ResResList); status = LOOP; ResDoneWithNode(resptr); break; @@ -84,8 +83,8 @@ ResDoneWithNode(resptr) } else if (rr1->rr_value == 0) { - ResDeleteResPointer(rr1->rr_connection1,rr1); - ResDeleteResPointer(rr1->rr_connection2,rr1); + ResDeleteResPointer(rr1->rr_connection1, rr1); + ResDeleteResPointer(rr1->rr_connection2, rr1); if (rr1->rr_connection1 == resptr) { resptr2 = rr1->rr_connection2; @@ -93,9 +92,9 @@ ResDoneWithNode(resptr) { resptr2 = rr1->rr_connection1; } - ResMergeNodes(resptr2,resptr,&ResNodeQueue,&ResNodeList); + ResMergeNodes(resptr2, resptr, &ResNodeQueue, &ResNodeList); resptr2->rn_float.rn_area += rr1->rr_float.rr_area; - ResEliminateResistor(rr1,&ResResList); + ResEliminateResistor(rr1, &ResResList); if ((resptr2->rn_status & TRUE) == TRUE) { resptr2->rn_status &= ~TRUE; @@ -106,23 +105,20 @@ ResDoneWithNode(resptr) break; } } + if (status != UNTOUCHED) return; /* resptr may be invalid */ /* Eliminations that can be only if there are no devices connected */ - /* to node. Series and dangling connections fall in this group. */ + /* to node. Series and dangling connections fall in this group. */ if ((resptr->rn_te == NULL) && (resptr->rn_why != RES_NODE_ORIGIN) && (status == UNTOUCHED)) - { status = ResSeriesCheck(resptr); - } + if ((status == UNTOUCHED) && (resptr->rn_why != RES_NODE_ORIGIN)) - { status = ResParallelCheck(resptr); - } + if ((status == UNTOUCHED) && (resptr->rn_why != RES_NODE_ORIGIN)) - { status = ResTriangleCheck(resptr); - } } @@ -141,20 +137,24 @@ ResDoneWithNode(resptr) */ void -ResFixRes(resptr,resptr2,resptr3,elimResis,newResis) - resNode *resptr,*resptr2,*resptr3; - resResistor *elimResis, *newResis; +ResFixRes(resptr, resptr2, resptr3, elimResis, newResis) + resNode *resptr, *resptr2, *resptr3; + resResistor *elimResis, *newResis; { resElement *thisREl; - resptr3->rn_float.rn_area += newResis->rr_value*resptr->rn_float.rn_area/((float)(newResis->rr_value+elimResis->rr_value)); - resptr2->rn_float.rn_area += elimResis->rr_value*resptr->rn_float.rn_area/((float)(newResis->rr_value+elimResis->rr_value)); + resptr3->rn_float.rn_area += newResis->rr_value*resptr->rn_float.rn_area + / ((float)(newResis->rr_value + elimResis->rr_value)); + resptr2->rn_float.rn_area += elimResis->rr_value*resptr->rn_float.rn_area + / ((float)(newResis->rr_value + elimResis->rr_value)); newResis->rr_value += elimResis->rr_value; - ASSERT(newResis->rr_value > 0,"series"); + ASSERT(newResis->rr_value > 0, "series"); newResis->rr_float.rr_area += elimResis->rr_float.rr_area; + #ifdef ARIEL - if (elimResis->rr_csArea && elimResis->rr_csArea < newResis->rr_csArea || newResis->rr_csArea == 0) + if (elimResis->rr_csArea && elimResis->rr_csArea < newResis->rr_csArea + || newResis->rr_csArea == 0) { newResis->rr_csArea = elimResis->rr_csArea; newResis->rr_tt = elimResis->rr_tt; @@ -170,10 +170,10 @@ ResFixRes(resptr,resptr2,resptr3,elimResis,newResis) } if (thisREl == NULL) TxError("Resistor not found in duo\n"); - ResDeleteResPointer(resptr,elimResis); - ResDeleteResPointer(resptr,newResis); + ResDeleteResPointer(resptr, elimResis); + ResDeleteResPointer(resptr, newResis); ResEliminateResistor(elimResis, &ResResList); - ResCleanNode(resptr, TRUE,&ResNodeList,&ResNodeQueue); + ResCleanNode(resptr, TRUE, &ResNodeList, &ResNodeQueue); } /* @@ -191,36 +191,36 @@ ResFixRes(resptr,resptr2,resptr3,elimResis,newResis) */ void -ResFixParallel(elimResis,newResis) - resResistor *elimResis,*newResis; +ResFixParallel(elimResis, newResis) + resResistor *elimResis, *newResis; { - if ((newResis->rr_value+elimResis->rr_value) != 0) + if ((newResis->rr_value + elimResis->rr_value) != 0) { - newResis->rr_value = (((float) newResis->rr_value)* - ((float)elimResis->rr_value))/ - ((float)(newResis->rr_value+ + newResis->rr_value = (((float) newResis->rr_value) * + ((float)elimResis->rr_value)) / + ((float)(newResis->rr_value + elimResis->rr_value)); - ASSERT(newResis->rr_value >= 0,"parallel"); + ASSERT(newResis->rr_value >= 0, "parallel"); } else { - newResis->rr_value =0; + newResis->rr_value = 0; } newResis->rr_float.rr_area += elimResis->rr_float.rr_area; #ifdef ARIEL newResis->rr_csArea += elimResis->rr_csArea; #endif - ResDeleteResPointer(elimResis->rr_connection1,elimResis); - ResDeleteResPointer(elimResis->rr_connection2,elimResis); - ResEliminateResistor(elimResis,&ResResList); + ResDeleteResPointer(elimResis->rr_connection1, elimResis); + ResDeleteResPointer(elimResis->rr_connection2, elimResis); + ResEliminateResistor(elimResis, &ResResList); } /* *------------------------------------------------------------------------- * * ResSeriesCheck -- for nodes with no devices, sees if a series - or loop combination is possible. + * or loop combination is possible. * * Results: returns SINGLE,LOOP,or SERIES if succesful. * @@ -231,175 +231,177 @@ ResFixParallel(elimResis,newResis) int ResSeriesCheck(resptr) - resNode *resptr; + resNode *resptr; { - resResistor *rr1,*rr2; - resNode *resptr2,*resptr3; - int status=UNTOUCHED; - resElement *res_next; + resResistor *rr1,*rr2; + resNode *resptr2, *resptr3; + int status = UNTOUCHED; + resElement *res_next; - rr1 = resptr->rn_re->re_thisEl; - res_next = resptr->rn_re->re_nextEl; + rr1 = resptr->rn_re->re_thisEl; + res_next = resptr->rn_re->re_nextEl; - if (res_next == NULL) - /* node with only one connection */ - { - resptr2 = (rr1->rr_connection1 == resptr)?rr1->rr_connection2: + if (res_next == NULL) + /* node with only one connection */ + { + resptr2 = (rr1->rr_connection1 == resptr) ? rr1->rr_connection2: rr1->rr_connection1; - ResDeleteResPointer(rr1->rr_connection1,rr1); - ResDeleteResPointer(rr1->rr_connection2,rr1); - resptr2->rn_float.rn_area += rr1->rr_float.rr_area+ + ResDeleteResPointer(rr1->rr_connection1, rr1); + ResDeleteResPointer(rr1->rr_connection2, rr1); + resptr2->rn_float.rn_area += rr1->rr_float.rr_area + resptr->rn_float.rn_area; - ResEliminateResistor(rr1,&ResResList); - ResCleanNode(resptr,TRUE,&ResNodeList,&ResNodeQueue); - status = SINGLE; - if (resptr2->rn_status & TRUE) - { - resptr2->rn_status &= ~TRUE; - ResDoneWithNode(resptr2); - } - resptr2 = NULL; - } - else if (res_next->re_nextEl == NULL) - { - rr2 = res_next->re_thisEl; - if (!TTMaskHasType(ResNoMergeMask+rr1->rr_tt,rr2->rr_tt)) - { - if (rr1->rr_connection1 == resptr) + ResEliminateResistor(rr1, &ResResList); + ResCleanNode(resptr, TRUE, &ResNodeList, &ResNodeQueue); + status = SINGLE; + if (resptr2->rn_status & TRUE) + { + resptr2->rn_status &= ~TRUE; + ResDoneWithNode(resptr2); + } + resptr2 = NULL; + } + else if (res_next->re_nextEl == NULL) + { + rr2 = res_next->re_thisEl; + if (!TTMaskHasType(ResNoMergeMask + rr1->rr_tt, rr2->rr_tt)) + { + if (rr1->rr_connection1 == resptr) + { + if (rr2->rr_connection1 == resptr) { - - if (rr2->rr_connection1 == resptr) - { - resptr2 = rr1->rr_connection2; - if (rr1->rr_connection2 == - rr2->rr_connection2) - { - status = LOOP; - ResDeleteResPointer(rr1->rr_connection1,rr1); - ResDeleteResPointer(rr1->rr_connection2,rr1); - ResDeleteResPointer(rr2->rr_connection1,rr2); - ResDeleteResPointer(rr2->rr_connection2,rr2); - resptr2->rn_float.rn_area += rr1->rr_float.rr_area + resptr2 = rr1->rr_connection2; + if (rr1->rr_connection2 == rr2->rr_connection2) + { + status = LOOP; + ResDeleteResPointer(rr1->rr_connection1, rr1); + ResDeleteResPointer(rr1->rr_connection2, rr1); + ResDeleteResPointer(rr2->rr_connection1, rr2); + ResDeleteResPointer(rr2->rr_connection2, rr2); + resptr2->rn_float.rn_area += rr1->rr_float.rr_area + rr2->rr_float.rr_area + resptr->rn_float.rn_area; - ResEliminateResistor(rr1,&ResResList); - ResEliminateResistor(rr2,&ResResList); - ResCleanNode(resptr,TRUE,&ResNodeList,&ResNodeQueue); - }else - { - status = SERIES; - resptr3 = rr2->rr_connection2; - rr1->rr_connection1 = rr2->rr_connection2; - ResFixRes(resptr,resptr2,resptr3,rr2,rr1); - } - if ((resptr2->rn_status & TRUE) == TRUE) - { - resptr2->rn_status &= ~TRUE; - ResDoneWithNode(resptr2); - } - resptr2 = NULL; - }else - { - resptr2 = rr1->rr_connection2; - if (rr1->rr_connection2 == rr2->rr_connection1) - { - status = LOOP; - ResDeleteResPointer(rr1->rr_connection1,rr1); - ResDeleteResPointer(rr1->rr_connection2,rr1); - ResDeleteResPointer(rr2->rr_connection1,rr2); - ResDeleteResPointer(rr2->rr_connection2,rr2); - resptr2->rn_float.rn_area += rr1->rr_float.rr_area - + rr2->rr_float.rr_area - + resptr->rn_float.rn_area; - ResEliminateResistor(rr1,&ResResList); - ResEliminateResistor(rr2,&ResResList); - ResCleanNode(resptr,TRUE,&ResNodeList,&ResNodeQueue); - }else - { - status = SERIES; - resptr3 = rr2->rr_connection1; - rr1->rr_connection1 = rr2->rr_connection1; - ResFixRes(resptr,resptr2,resptr3,rr2,rr1); - } - if ((resptr2->rn_status & TRUE) == TRUE) - { - resptr2->rn_status &= ~TRUE; - ResDoneWithNode(resptr2); - } - resptr2 = NULL; - } - }else - { - if (rr2->rr_connection1 == resptr) - { - resptr2 = rr1->rr_connection1; - if (rr1->rr_connection1 == rr2->rr_connection2) - { - status = LOOP; - ResDeleteResPointer(rr1->rr_connection1,rr1); - ResDeleteResPointer(rr1->rr_connection2,rr1); - ResDeleteResPointer(rr2->rr_connection1,rr2); - ResDeleteResPointer(rr2->rr_connection2,rr2); - resptr2->rn_float.rn_area += rr1->rr_float.rr_area - + rr2->rr_float.rr_area - + resptr->rn_float.rn_area; - ResEliminateResistor(rr1,&ResResList); - ResEliminateResistor(rr2,&ResResList); - ResCleanNode(resptr,TRUE,&ResNodeList,&ResNodeQueue); - }else - { - status = SERIES; - resptr3 = rr2->rr_connection2; - rr1->rr_connection2 = - rr2->rr_connection2; - ResFixRes(resptr,resptr2,resptr3,rr2,rr1); - } - if ((resptr2->rn_status & TRUE) == TRUE) - { - resptr2->rn_status &= ~TRUE; - ResDoneWithNode(resptr2); - } - resptr2 = NULL; - }else - { - resptr2 = rr1->rr_connection1; - if (rr1->rr_connection1 == rr2->rr_connection1) - { - status = LOOP; - ResDeleteResPointer(rr1->rr_connection1,rr1); - ResDeleteResPointer(rr1->rr_connection2,rr1); - ResDeleteResPointer(rr2->rr_connection1,rr2); - ResDeleteResPointer(rr2->rr_connection2,rr2); - resptr2->rn_float.rn_area += rr1->rr_float.rr_area - + rr2->rr_float.rr_area - + resptr->rn_float.rn_area; - ResEliminateResistor(rr1,&ResResList); - ResEliminateResistor(rr2,&ResResList); - ResCleanNode(resptr,TRUE,&ResNodeList,&ResNodeQueue); - }else - { - status = SERIES; - resptr3 = rr2->rr_connection1; - rr1->rr_connection2 = - rr2->rr_connection1; - ResFixRes(resptr,resptr2,resptr3,rr2,rr1); - } - if ((resptr2->rn_status & TRUE) == TRUE) - { - resptr2->rn_status &= ~TRUE; - ResDoneWithNode(resptr2); - } - resptr2 = NULL; - } + ResEliminateResistor(rr1, &ResResList); + ResEliminateResistor(rr2, &ResResList); + ResCleanNode(resptr, TRUE, &ResNodeList, &ResNodeQueue); + } + else + { + status = SERIES; + resptr3 = rr2->rr_connection2; + rr1->rr_connection1 = rr2->rr_connection2; + ResFixRes(resptr, resptr2, resptr3, rr2, rr1); + } + if ((resptr2->rn_status & TRUE) == TRUE) + { + resptr2->rn_status &= ~TRUE; + ResDoneWithNode(resptr2); + } + resptr2 = NULL; } - } - } - return status; + else + { + resptr2 = rr1->rr_connection2; + if (rr1->rr_connection2 == rr2->rr_connection1) + { + status = LOOP; + ResDeleteResPointer(rr1->rr_connection1, rr1); + ResDeleteResPointer(rr1->rr_connection2, rr1); + ResDeleteResPointer(rr2->rr_connection1, rr2); + ResDeleteResPointer(rr2->rr_connection2, rr2); + resptr2->rn_float.rn_area += rr1->rr_float.rr_area + + rr2->rr_float.rr_area + + resptr->rn_float.rn_area; + ResEliminateResistor(rr1, &ResResList); + ResEliminateResistor(rr2, &ResResList); + ResCleanNode(resptr, TRUE, &ResNodeList, &ResNodeQueue); + } + else + { + status = SERIES; + resptr3 = rr2->rr_connection1; + rr1->rr_connection1 = rr2->rr_connection1; + ResFixRes(resptr, resptr2, resptr3, rr2, rr1); + } + if ((resptr2->rn_status & TRUE) == TRUE) + { + resptr2->rn_status &= ~TRUE; + ResDoneWithNode(resptr2); + } + resptr2 = NULL; + } + } + else + { + if (rr2->rr_connection1 == resptr) + { + resptr2 = rr1->rr_connection1; + if (rr1->rr_connection1 == rr2->rr_connection2) + { + status = LOOP; + ResDeleteResPointer(rr1->rr_connection1, rr1); + ResDeleteResPointer(rr1->rr_connection2, rr1); + ResDeleteResPointer(rr2->rr_connection1, rr2); + ResDeleteResPointer(rr2->rr_connection2, rr2); + resptr2->rn_float.rn_area += rr1->rr_float.rr_area + + rr2->rr_float.rr_area + + resptr->rn_float.rn_area; + ResEliminateResistor(rr1, &ResResList); + ResEliminateResistor(rr2, &ResResList); + ResCleanNode(resptr, TRUE, &ResNodeList, &ResNodeQueue); + } + else + { + status = SERIES; + resptr3 = rr2->rr_connection2; + rr1->rr_connection2 = rr2->rr_connection2; + ResFixRes(resptr, resptr2, resptr3, rr2, rr1); + } + if ((resptr2->rn_status & TRUE) == TRUE) + { + resptr2->rn_status &= ~TRUE; + ResDoneWithNode(resptr2); + } + resptr2 = NULL; + } + else + { + resptr2 = rr1->rr_connection1; + if (rr1->rr_connection1 == rr2->rr_connection1) + { + status = LOOP; + ResDeleteResPointer(rr1->rr_connection1, rr1); + ResDeleteResPointer(rr1->rr_connection2, rr1); + ResDeleteResPointer(rr2->rr_connection1, rr2); + ResDeleteResPointer(rr2->rr_connection2, rr2); + resptr2->rn_float.rn_area += rr1->rr_float.rr_area + + rr2->rr_float.rr_area + + resptr->rn_float.rn_area; + ResEliminateResistor(rr1, &ResResList); + ResEliminateResistor(rr2, &ResResList); + ResCleanNode(resptr, TRUE, &ResNodeList, &ResNodeQueue); + } + else + { + status = SERIES; + resptr3 = rr2->rr_connection1; + rr1->rr_connection2 = rr2->rr_connection1; + ResFixRes(resptr, resptr2, resptr3, rr2, rr1); + } + if ((resptr2->rn_status & TRUE) == TRUE) + { + resptr2->rn_status &= ~TRUE; + ResDoneWithNode(resptr2); + } + resptr2 = NULL; + } + } + } + } + return status; } - /* *------------------------------------------------------------------------- * @@ -414,49 +416,49 @@ ResSeriesCheck(resptr) int ResParallelCheck(resptr) - resNode *resptr; + resNode *resptr; { - resResistor *r1,*r2; - resNode *resptr2,*resptr3; - int status=UNTOUCHED; - resElement *rcell1,*rcell2; + resResistor *r1,*r2; + resNode *resptr2,*resptr3; + int status = UNTOUCHED; + resElement *rcell1, *rcell2; - for (rcell1 = resptr->rn_re; - rcell1->re_nextEl != NULL; rcell1 = rcell1->re_nextEl) - { - r1 = rcell1->re_thisEl; + for (rcell1 = resptr->rn_re; rcell1->re_nextEl != NULL; + rcell1 = rcell1->re_nextEl) + { + r1 = rcell1->re_thisEl; - for (rcell2 = rcell1->re_nextEl; - rcell2 != NULL; rcell2 = rcell2->re_nextEl) + for (rcell2 = rcell1->re_nextEl; rcell2 != NULL; + rcell2 = rcell2->re_nextEl) - { - r2 = rcell2->re_thisEl; - if (TTMaskHasType(ResNoMergeMask+r1->rr_tt,r2->rr_tt)) continue; - if (((r1->rr_connection1 == r2->rr_connection1) && - (r1->rr_connection2 == r2->rr_connection2))|| + { + r2 = rcell2->re_thisEl; + if (TTMaskHasType(ResNoMergeMask+r1->rr_tt,r2->rr_tt)) continue; + if (((r1->rr_connection1 == r2->rr_connection1) && + (r1->rr_connection2 == r2->rr_connection2))|| ((r1->rr_connection1 == r2->rr_connection2) && - (r1->rr_connection2 == r2->rr_connection1))) - { - resptr3 = (r1->rr_connection1 == resptr) ? + (r1->rr_connection2 == r2->rr_connection1))) + { + resptr3 = (r1->rr_connection1 == resptr) ? r1->rr_connection2 : r1->rr_connection1; - ResFixParallel(r1,r2); - status = PARALLEL; - resptr2 = NULL; - if (resptr3->rn_status & TRUE) - { - resptr2 = resptr3; - resptr2->rn_status &= ~TRUE; - } - ResDoneWithNode(resptr); - if (resptr2 != NULL) ResDoneWithNode(resptr2); - break; - } - } - if (status == PARALLEL) break; - } - return status; + ResFixParallel(r1, r2); + status = PARALLEL; + resptr2 = NULL; + if (resptr3->rn_status & TRUE) + { + resptr2 = resptr3; + resptr2->rn_status &= ~TRUE; + } + ResDoneWithNode(resptr); + if (resptr2 != NULL) ResDoneWithNode(resptr2); + break; + } + } + if (status == PARALLEL) break; + } + return status; } @@ -474,151 +476,143 @@ ResParallelCheck(resptr) int ResTriangleCheck(resptr) - resNode *resptr; + resNode *resptr; { - resResistor *rr1,*rr2,*rr3; - int status=UNTOUCHED; - float r1,r2,r3,denom; - resNode *n1,*n2,*n3; - resElement *rcell1,*rcell2,*rcell3,*element; + resResistor *rr1, *rr2, *rr3; + int status = UNTOUCHED; + float r1, r2, r3, denom; + resNode *n1, *n2, *n3; + resElement *rcell1, *rcell2, *rcell3, *element; - for (rcell1 = resptr->rn_re; - rcell1->re_nextEl != NULL; rcell1 = rcell1->re_nextEl) - { - rr1 = rcell1->re_thisEl; - n1 = (rr1->rr_connection1 == resptr)?rr1->rr_connection2: - rr1->rr_connection1; + for (rcell1 = resptr->rn_re; rcell1->re_nextEl != NULL; + rcell1 = rcell1->re_nextEl) + { + rr1 = rcell1->re_thisEl; + n1 = (rr1->rr_connection1 == resptr) ? rr1->rr_connection2: + rr1->rr_connection1; - for (rcell2 = rcell1->re_nextEl; - rcell2 != NULL; rcell2 = rcell2->re_nextEl) - { - rr2 = rcell2->re_thisEl; - if (TTMaskHasType(ResNoMergeMask + rr1->rr_tt, rr2->rr_tt)) - continue; - n2 = (rr2->rr_connection1 == resptr) ? rr2->rr_connection2 : + for (rcell2 = rcell1->re_nextEl; rcell2 != NULL; + rcell2 = rcell2->re_nextEl) + { + rr2 = rcell2->re_thisEl; + if (TTMaskHasType(ResNoMergeMask + rr1->rr_tt, rr2->rr_tt)) + continue; + n2 = (rr2->rr_connection1 == resptr) ? rr2->rr_connection2 : rr2->rr_connection1; - for (rcell3 = n1->rn_re; - rcell3 != NULL; rcell3 = rcell3->re_nextEl) - { - rr3 = rcell3->re_thisEl; - if (TTMaskHasType(ResNoMergeMask+rr1->rr_tt,rr3->rr_tt)) - continue; - if (TTMaskHasType(ResNoMergeMask+rr2->rr_tt,rr3->rr_tt)) - continue; + for (rcell3 = n1->rn_re; rcell3 != NULL; + rcell3 = rcell3->re_nextEl) + { + rr3 = rcell3->re_thisEl; + if (TTMaskHasType(ResNoMergeMask + rr1->rr_tt, rr3->rr_tt)) + continue; + if (TTMaskHasType(ResNoMergeMask + rr2->rr_tt, rr3->rr_tt)) + continue; - if (((rr3->rr_connection1 != n1) || - (rr3->rr_connection2 != n2)) && + if (((rr3->rr_connection1 != n1) || + (rr3->rr_connection2 != n2)) && ((rr3->rr_connection2 != n1) || - (rr3->rr_connection1 != n2))) continue; + (rr3->rr_connection1 != n2))) continue; - status = TRIANGLE; - if ((denom=rr1->rr_value+rr2->rr_value+rr3->rr_value) != 0.0) - { - denom = 1.0/denom; - /*calculate new values for resistors */ - r1 = (((float) rr1->rr_value)* - ((float) rr2->rr_value))*denom; + status = TRIANGLE; + if ((denom = rr1->rr_value + rr2->rr_value + rr3->rr_value) != 0.0) + { + denom = 1.0 /denom; + /* calculate new values for resistors */ + r1 = (((float)rr1->rr_value) * ((float)rr2->rr_value)) * denom; - r2 = (((float) rr2->rr_value)* - ((float) rr3->rr_value))*denom; + r2 = (((float)rr2->rr_value) * ((float)rr3->rr_value)) * denom; - r3 = (((float) rr1->rr_value)* - ((float) rr3->rr_value))*denom; + r3 = (((float)rr1->rr_value) * ((float)rr3->rr_value)) * denom; - rr1->rr_value = r1+0.5; - rr2->rr_value = r2+0.5; - rr3->rr_value = r3+0.5; - ASSERT(rr1->rr_value >= 0,"Triangle"); - ASSERT(rr2->rr_value >= 0,"Triangle"); - ASSERT(rr3->rr_value >= 0,"Triangle"); - } - else - { - rr1->rr_value = 0; - rr2->rr_value = 0; - rr3->rr_value = 0; - } - n3 = (resNode *) mallocMagic((unsigned) (sizeof(resNode))); - /* Where should the new node be `put'? It */ - /* is arbitrarily assigned to the location */ - /* occupied by the first node. */ + rr1->rr_value = r1 + 0.5; + rr2->rr_value = r2 + 0.5; + rr3->rr_value = r3 + 0.5; + ASSERT(rr1->rr_value >= 0, "Triangle"); + ASSERT(rr2->rr_value >= 0, "Triangle"); + ASSERT(rr3->rr_value >= 0, "Triangle"); + } + else + { + rr1->rr_value = 0; + rr2->rr_value = 0; + rr3->rr_value = 0; + } + n3 = (resNode *)mallocMagic((unsigned)(sizeof(resNode))); - InitializeNode(n3,resptr->rn_loc.p_x,resptr->rn_loc.p_y,TRIANGLE); - n3->rn_status = FINISHED | TRUE | MARKED; + /* Where should the new node be `put'? It */ + /* is arbitrarily assigned to the location */ + /* occupied by the first node. */ - n3->rn_less = NULL; - n3->rn_more = ResNodeList; - ResNodeList->rn_less = n3; - ResNodeList = n3; - if (resptr == rr1->rr_connection1) - { - ResDeleteResPointer(rr1->rr_connection2,rr1); - rr1->rr_connection2 = n3; - } - else - { - ResDeleteResPointer(rr1->rr_connection1,rr1); - rr1->rr_connection1 = n3; - } - if (n2 == rr2->rr_connection1) - { - ResDeleteResPointer(rr2->rr_connection2,rr2); - rr2->rr_connection2 = n3; - } - else - { - ResDeleteResPointer(rr2->rr_connection1,rr2); - rr2->rr_connection1 = n3; - } - if (n1 == rr3->rr_connection1) - { - ResDeleteResPointer(rr3->rr_connection2,rr3); - rr3->rr_connection2 = n3; - } - else - { - ResDeleteResPointer(rr3->rr_connection1,rr3); - rr3->rr_connection1 = n3; - } - element = (resElement *) mallocMagic((unsigned)(sizeof(resElement))); - element->re_nextEl = NULL; - element->re_thisEl = rr1; - n3->rn_re = element; - element = (resElement *) mallocMagic((unsigned)(sizeof(resElement))); - element->re_nextEl = n3->rn_re; - element->re_thisEl = rr2; - n3->rn_re = element; - element = (resElement *) mallocMagic((unsigned)(sizeof(resElement))); - element->re_nextEl = n3->rn_re; - element->re_thisEl = rr3; - n3->rn_re = element; - if ((n1->rn_status & TRUE) == TRUE) - { - n1->rn_status &= ~TRUE; - } - else - { - n1 = NULL; - } - if ((n2->rn_status & TRUE) == TRUE) - { - n2->rn_status &= ~TRUE; - } - else - { - n2 = NULL; - } - ResDoneWithNode(resptr); - if (n1 != NULL) ResDoneWithNode(n1); - if (n2 != NULL) ResDoneWithNode(n2); - break; - } - if (status == TRIANGLE) break; - } - if (status == TRIANGLE) break; - } - return status; + InitializeNode(n3, resptr->rn_loc.p_x, resptr->rn_loc.p_y, TRIANGLE); + n3->rn_status = FINISHED | TRUE | MARKED; + + n3->rn_less = NULL; + n3->rn_more = ResNodeList; + ResNodeList->rn_less = n3; + ResNodeList = n3; + if (resptr == rr1->rr_connection1) + { + ResDeleteResPointer(rr1->rr_connection2, rr1); + rr1->rr_connection2 = n3; + } + else + { + ResDeleteResPointer(rr1->rr_connection1, rr1); + rr1->rr_connection1 = n3; + } + if (n2 == rr2->rr_connection1) + { + ResDeleteResPointer(rr2->rr_connection2, rr2); + rr2->rr_connection2 = n3; + } + else + { + ResDeleteResPointer(rr2->rr_connection1, rr2); + rr2->rr_connection1 = n3; + } + if (n1 == rr3->rr_connection1) + { + ResDeleteResPointer(rr3->rr_connection2, rr3); + rr3->rr_connection2 = n3; + } + else + { + ResDeleteResPointer(rr3->rr_connection1, rr3); + rr3->rr_connection1 = n3; + } + element = (resElement *)mallocMagic((unsigned)(sizeof(resElement))); + element->re_nextEl = NULL; + element->re_thisEl = rr1; + n3->rn_re = element; + element = (resElement *)mallocMagic((unsigned)(sizeof(resElement))); + element->re_nextEl = n3->rn_re; + element->re_thisEl = rr2; + n3->rn_re = element; + element = (resElement *)mallocMagic((unsigned)(sizeof(resElement))); + element->re_nextEl = n3->rn_re; + element->re_thisEl = rr3; + n3->rn_re = element; + if ((n1->rn_status & TRUE) == TRUE) + n1->rn_status &= ~TRUE; + else + n1 = NULL; + + if ((n2->rn_status & TRUE) == TRUE) + n2->rn_status &= ~TRUE; + else + n2 = NULL; + + ResDoneWithNode(resptr); + if (n1 != NULL) ResDoneWithNode(n1); + if (n2 != NULL) ResDoneWithNode(n2); + break; + } + if (status == TRIANGLE) break; + } + if (status == TRIANGLE) break; + } + return status; } /* @@ -636,174 +630,156 @@ ResTriangleCheck(resptr) */ void -ResMergeNodes(node1,node2,pendingList,doneList) - resNode *node1,*node2,**pendingList,**doneList; +ResMergeNodes(node1, node2, pendingList, doneList) + resNode *node1, *node2; + resNode **pendingList, **doneList; +{ + resElement *workingRes, *tRes; + tElement *workingDev, *tDev; + jElement *workingJunc, *tJunc; + cElement *workingCon, *tCon; + Tile *tile; + int i; - { - resElement *workingRes,*tRes; - tElement *workingDev,*tDev; - jElement *workingJunc,*tJunc; - cElement *workingCon,*tCon; - Tile *tile; - int i; + /* sanity check */ + if (node1 == node2) return; - /* sanity check */ - if (node1 == node2) return; - if (node1 == NULL || node2 == NULL) - { - TxError("Attempt to merge NULL node\n"); - return; - } + if (node1 == NULL || node2 == NULL) + { + TxError("Attempt to merge NULL node\n"); + return; + } - /* don't want to merge away startpoint */ - if (node2->rn_why & RES_NODE_ORIGIN) - { - node1->rn_why = RES_NODE_ORIGIN; - } + /* don't want to merge away startpoint */ + if (node2->rn_why & RES_NODE_ORIGIN) + node1->rn_why = RES_NODE_ORIGIN; - /* set node resistance */ - if (node1->rn_noderes >node2->rn_noderes) - { - node1->rn_noderes = node2->rn_noderes; - if ((node1->rn_status & FINISHED) != FINISHED) - { - ResRemoveFromQueue(node1,pendingList); - ResAddToQueue(node1,pendingList); - } - } - node1->rn_float.rn_area += node2->rn_float.rn_area; + /* set node resistance */ + if (node1->rn_noderes > node2->rn_noderes) + { + node1->rn_noderes = node2->rn_noderes; + if ((node1->rn_status & FINISHED) != FINISHED) + { + ResRemoveFromQueue(node1, pendingList); + ResAddToQueue(node1, pendingList); + } + } + node1->rn_float.rn_area += node2->rn_float.rn_area; + /* combine relevant flags */ + node1->rn_status |= (node2->rn_status & RN_MAXTDI); - /* combine relevant flags */ - node1->rn_status |= (node2->rn_status & RN_MAXTDI); + /* merge device lists */ + workingDev = node2->rn_te; + while (workingDev != NULL) + { + if (workingDev->te_thist->rd_status & RES_DEV_PLUG) + { + ResPlug *plug = (ResPlug *) workingDev->te_thist; + if (plug->rpl_node == node2) + plug->rpl_node = node1; + else + { + TxError("Bad plug node: is (%d %d), should be (%d %d)\n", + plug->rpl_node->rn_loc, node2->rn_loc); + plug->rpl_node = NULL; + } + } + else + { + int j; - /*merge device lists */ - workingDev = node2->rn_te; - while (workingDev != NULL) - { - if (workingDev->te_thist->rd_status & RES_DEV_PLUG) - { - ResPlug *plug = (ResPlug *) workingDev->te_thist; - if (plug->rpl_node == node2) - { - plug->rpl_node = node1; - } - else - { - TxError("Bad plug node: is (%d %d), should be (%d %d)\n", - plug->rpl_node->rn_loc,node2->rn_loc); - plug->rpl_node = NULL; - } - } - else - { - int j; - - for (j = 0; j != workingDev->te_thist->rd_nterms; j++) + for (j = 0; j != workingDev->te_thist->rd_nterms; j++) if (workingDev->te_thist->rd_terminals[j] == node2) - { - workingDev->te_thist->rd_terminals[j] = node1; - } - } - tDev = workingDev; - workingDev = workingDev->te_nextt; - tDev->te_nextt = node1->rn_te; - node1->rn_te = tDev; - } + workingDev->te_thist->rd_terminals[j] = node1; + } + tDev = workingDev; + workingDev = workingDev->te_nextt; + tDev->te_nextt = node1->rn_te; + node1->rn_te = tDev; + } - /* append junction lists */ - workingJunc = node2->rn_je; - while (workingJunc != NULL) - { - tJunc = workingJunc; - for (i=0; irn_je; + while (workingJunc != NULL) + { + tJunc = workingJunc; + for (i = 0; i < TILES_PER_JUNCTION; i++) + { + tileJunk *junk; + + tile = tJunc->je_thisj->rj_Tile[i]; + junk = (tileJunk *) tile->ti_client; + + if ((junk->tj_status & RES_TILE_DONE) == FALSE) + ResFixBreakPoint(&junk->breakList, node2, node1); + } + tJunc->je_thisj->rj_jnode = node1; + workingJunc = workingJunc->je_nextj; + tJunc->je_nextj = node1->rn_je; + node1->rn_je = tJunc; + } + + /* Append connection lists */ + workingCon = node2->rn_ce; + while (workingCon != NULL) + { + tCon = workingCon; + for (i = 0; i < workingCon->ce_thisc->cp_currentcontact; i++) + { + if (workingCon->ce_thisc->cp_cnode[i] == node2) + { tileJunk *junk; - tile =tJunc->je_thisj->rj_Tile[i]; + workingCon->ce_thisc->cp_cnode[i] = node1; + tile =tCon->ce_thisc->cp_tile[i]; junk = (tileJunk *) tile->ti_client; - if ((junk->tj_status & RES_TILE_DONE) == FALSE) - { - ResFixBreakPoint(&junk->breakList,node2,node1); - } - } - tJunc->je_thisj->rj_jnode = node1; - workingJunc = workingJunc->je_nextj; - tJunc->je_nextj = node1->rn_je; - node1->rn_je = tJunc; - } + ResFixBreakPoint(&junk->breakList, node2, node1); + } + } + workingCon = workingCon->ce_nextc; + tCon->ce_nextc = node1->rn_ce; + node1->rn_ce = tCon; + } - /* Append connection lists */ - workingCon = node2->rn_ce; - while (workingCon != NULL) - { - tCon = workingCon; - for (i=0; i ce_thisc->cp_currentcontact;i++) - { - if (workingCon->ce_thisc->cp_cnode[i] == node2) - { - tileJunk *junk; + /* Moves resistors to new node */ - workingCon->ce_thisc->cp_cnode[i] = node1; - tile =tCon->ce_thisc->cp_tile[i]; - junk = (tileJunk *) tile->ti_client; - if ((junk->tj_status & RES_TILE_DONE) == FALSE) - { - ResFixBreakPoint(&junk->breakList,node2,node1); - } - } - } - workingCon = workingCon->ce_nextc; - tCon->ce_nextc = node1->rn_ce; - node1->rn_ce = tCon; - } + workingRes = node2->rn_re; + while (workingRes != NULL) + { + if (workingRes->re_thisEl->rr_connection1 == node2) + workingRes->re_thisEl->rr_connection1 = node1; + else if (workingRes->re_thisEl->rr_connection2 == node2) + workingRes->re_thisEl->rr_connection2 = node1; + else + TxError("Resistor not found.\n"); - /* Moves resistors to new node */ - workingRes = node2->rn_re; - while (workingRes != NULL) - { - if (workingRes->re_thisEl->rr_connection1 == node2) - { - workingRes->re_thisEl->rr_connection1 = node1; - } - else if (workingRes->re_thisEl->rr_connection2 == node2) - { - workingRes->re_thisEl->rr_connection2 = node1; - } - else - { - TxError("Resistor not found.\n"); - } - tRes = workingRes; - workingRes = workingRes->re_nextEl; - tRes->re_nextEl = node1->rn_re; - node1->rn_re = tRes; - } - if ((node2->rn_status & FINISHED) == FINISHED) - { - ResRemoveFromQueue(node2,doneList); - } - else - { - ResRemoveFromQueue(node2,pendingList); - } - if (node2->rn_client != (ClientData)NULL) - { - freeMagic((char *)node2->rn_client); - node2->rn_client = (ClientData)NULL; - } - { - node2->rn_re = (resElement *) CLIENTDEFAULT; - node2->rn_ce = (cElement *) CLIENTDEFAULT; - node2->rn_je = (jElement *) CLIENTDEFAULT; - node2->rn_te = (tElement *) CLIENTDEFAULT; - node2->rn_more = (resNode *) CLIENTDEFAULT; - node2->rn_less = (resNode *) CLIENTDEFAULT; - } - freeMagic((char *)node2); - } + tRes = workingRes; + workingRes = workingRes->re_nextEl; + tRes->re_nextEl = node1->rn_re; + node1->rn_re = tRes; + } + if ((node2->rn_status & FINISHED) == FINISHED) + ResRemoveFromQueue(node2, doneList); + else + ResRemoveFromQueue(node2, pendingList); + if (node2->rn_client != (ClientData)NULL) + { + freeMagic((char *)node2->rn_client); + node2->rn_client = (ClientData)NULL; + } + + node2->rn_re = (resElement *)CLIENTDEFAULT; + node2->rn_ce = (cElement *)CLIENTDEFAULT; + node2->rn_je = (jElement *)CLIENTDEFAULT; + node2->rn_te = (tElement *)CLIENTDEFAULT; + node2->rn_more = (resNode *)CLIENTDEFAULT; + node2->rn_less = (resNode *)CLIENTDEFAULT; + freeMagic((char *)node2); +} /* *------------------------------------------------------------------------- @@ -820,42 +796,38 @@ ResMergeNodes(node1,node2,pendingList,doneList) void ResDeleteResPointer(node,resistor) - resNode *node; - resResistor *resistor; + resNode *node; + resResistor *resistor; { - resElement *rcell1,*rcell2; - int notfound=TRUE; + resElement *rcell1, *rcell2; + int notfound = TRUE; - rcell1 = NULL; - rcell2 = node->rn_re; - while (rcell2 != NULL) - { - if (rcell2->re_thisEl == resistor) - { - notfound=FALSE; - if (rcell1 != NULL) - { - rcell1->re_nextEl = rcell2->re_nextEl; - }else - { - node->rn_re = rcell2->re_nextEl; - } - /* Set fields to null just in case there are any stray */ - /* pointers to structure. */ - rcell2->re_thisEl = NULL; - rcell2->re_nextEl = NULL; - freeMagic((char *)rcell2); - break; - } - rcell1 = rcell2; - rcell2 = rcell2->re_nextEl; - } - if (notfound) - { - TxError("Missing rptr at (%d %d).\n", - node->rn_loc.p_x,node->rn_loc.p_y); - } + rcell1 = NULL; + rcell2 = node->rn_re; + while (rcell2 != NULL) + { + if (rcell2->re_thisEl == resistor) + { + notfound = FALSE; + if (rcell1 != NULL) + rcell1->re_nextEl = rcell2->re_nextEl; + else + node->rn_re = rcell2->re_nextEl; + + /* Set fields to null just in case there are any stray */ + /* pointers to structure. */ + rcell2->re_thisEl = NULL; + rcell2->re_nextEl = NULL; + freeMagic((char *)rcell2); + break; + } + rcell1 = rcell2; + rcell2 = rcell2->re_nextEl; + } + if (notfound) + TxError("Missing rptr at (%d %d).\n", + node->rn_loc.p_x, node->rn_loc.p_y); } @@ -873,32 +845,28 @@ ResDeleteResPointer(node,resistor) */ void -ResEliminateResistor(resistor,homelist) - resResistor *resistor,**homelist; +ResEliminateResistor(resistor, homelist) + resResistor *resistor, **homelist; { - if (resistor->rr_lastResistor == NULL) - { - *homelist = resistor->rr_nextResistor; - }else - { - resistor->rr_lastResistor->rr_nextResistor = resistor->rr_nextResistor; - } - if (resistor->rr_nextResistor != NULL) - { - resistor->rr_nextResistor->rr_lastResistor = resistor->rr_lastResistor; - } + if (resistor->rr_lastResistor == NULL) + *homelist = resistor->rr_nextResistor; + else + resistor->rr_lastResistor->rr_nextResistor = resistor->rr_nextResistor; - /* set everything to null so that any stray pointers will cause */ - /* immediate death instead of a slow lingering one. */ - resistor->rr_nextResistor = NULL; - resistor->rr_lastResistor = NULL; - resistor->rr_connection1 = NULL; - resistor->rr_connection2 = NULL; - freeMagic((char *)resistor); + if (resistor->rr_nextResistor != NULL) + resistor->rr_nextResistor->rr_lastResistor = resistor->rr_lastResistor; + + /* set everything to null so that any stray pointers will cause */ + /* immediate death instead of a slow lingering one. */ + + resistor->rr_nextResistor = NULL; + resistor->rr_lastResistor = NULL; + resistor->rr_connection1 = NULL; + resistor->rr_connection2 = NULL; + freeMagic((char *)resistor); } - /* *------------------------------------------------------------------------- * @@ -915,83 +883,73 @@ ResEliminateResistor(resistor,homelist) */ void -ResCleanNode(resptr,junk,homelist1,homelist2) - resNode *resptr; - int junk; - resNode **homelist1; - resNode **homelist2; +ResCleanNode(resptr, junk, homelist1, homelist2) + resNode *resptr; + int junk; + resNode **homelist1; + resNode **homelist2; { - resElement *rcell; - cElement *ccell; - jElement *jcell; - tElement *tcell; + resElement *rcell; + cElement *ccell; + jElement *jcell; + tElement *tcell; - /* free up contact and junction lists */ - while (resptr->rn_ce != NULL) - { - ccell = resptr->rn_ce; - resptr->rn_ce = resptr->rn_ce->ce_nextc; - freeMagic((char *)ccell); - } - while (resptr->rn_je != NULL) - { - jcell = resptr->rn_je; - resptr->rn_je = resptr->rn_je->je_nextj; - freeMagic((char *)jcell->je_thisj); - freeMagic((char *)jcell); - } - if (junk == TRUE) - { - if (resptr->rn_client != (ClientData)NULL) - { - freeMagic((char *)resptr->rn_client); - resptr->rn_client = (ClientData)NULL; - } - while (resptr->rn_te != NULL) - { - tcell = resptr->rn_te; - resptr->rn_te = resptr->rn_te->te_nextt; - freeMagic((char *)tcell); - } - while (resptr->rn_re != NULL) - { - rcell = resptr->rn_re; - resptr->rn_re = resptr->rn_re->re_nextEl; - freeMagic((char *)rcell); - } - if (resptr->rn_less != NULL) - { - resptr->rn_less->rn_more = resptr->rn_more; - }else - { - if (*homelist1 == resptr) - { - *homelist1 = resptr->rn_more; - } - else if (*homelist2 == resptr) - { - *homelist2 = resptr->rn_more; - } - else - { - TxError("Error: Attempted to eliminate node from wrong list.\n"); - } - } - if (resptr->rn_more != NULL) - { - resptr->rn_more->rn_less = resptr->rn_less; - } + /* free up contact and junction lists */ + while (resptr->rn_ce != NULL) + { + ccell = resptr->rn_ce; + resptr->rn_ce = resptr->rn_ce->ce_nextc; + freeMagic((char *)ccell); + } + while (resptr->rn_je != NULL) + { + jcell = resptr->rn_je; + resptr->rn_je = resptr->rn_je->je_nextj; + freeMagic((char *)jcell->je_thisj); + freeMagic((char *)jcell); + } + if (junk == TRUE) + { + if (resptr->rn_client != (ClientData)NULL) + { + freeMagic((char *)resptr->rn_client); + resptr->rn_client = (ClientData)NULL; + } + while (resptr->rn_te != NULL) + { + tcell = resptr->rn_te; + resptr->rn_te = resptr->rn_te->te_nextt; + freeMagic((char *)tcell); + } + while (resptr->rn_re != NULL) + { + rcell = resptr->rn_re; + resptr->rn_re = resptr->rn_re->re_nextEl; + freeMagic((char *)rcell); + } + if (resptr->rn_less != NULL) + resptr->rn_less->rn_more = resptr->rn_more; + else + { + if (*homelist1 == resptr) + *homelist1 = resptr->rn_more; + else if (*homelist2 == resptr) + *homelist2 = resptr->rn_more; + else + TxError("Error: Attempted to eliminate node from wrong list.\n"); + } + if (resptr->rn_more != NULL) + resptr->rn_more->rn_less = resptr->rn_less; - { - resptr->rn_re = (resElement *) CLIENTDEFAULT; - resptr->rn_ce = (cElement *) CLIENTDEFAULT; - resptr->rn_je = (jElement *) CLIENTDEFAULT; - resptr->rn_te = (tElement *) CLIENTDEFAULT; - resptr->rn_more = (resNode *) CLIENTDEFAULT; - resptr->rn_less = (resNode *) CLIENTDEFAULT; - } - freeMagic((char *)resptr); - } + resptr->rn_re = (resElement *) CLIENTDEFAULT; + resptr->rn_ce = (cElement *) CLIENTDEFAULT; + resptr->rn_je = (jElement *) CLIENTDEFAULT; + resptr->rn_te = (tElement *) CLIENTDEFAULT; + resptr->rn_more = (resNode *) CLIENTDEFAULT; + resptr->rn_less = (resNode *) CLIENTDEFAULT; + + freeMagic((char *)resptr); + } } @@ -1010,54 +968,49 @@ ResCleanNode(resptr,junk,homelist1,homelist2) */ void -ResFixBreakPoint(sourcelist,origNode,newNode) - Breakpoint **sourcelist; - resNode *origNode,*newNode; +ResFixBreakPoint(sourcelist, origNode, newNode) + Breakpoint **sourcelist; + resNode *origNode, *newNode; { - Breakpoint *bp,*bp2,*bp3,*bp4; - int alreadypresent; + Breakpoint *bp, *bp2, *bp3, *bp4; + int alreadypresent; - alreadypresent = FALSE; - for (bp4 = *sourcelist; bp4 != NULL; bp4 = bp4->br_next) - { - if (bp4->br_this == newNode) - { - alreadypresent = TRUE; - break; - } - } - bp2 = NULL; - bp = *sourcelist; - while (bp != NULL) - { - if (bp->br_this == origNode) - { - if (alreadypresent) - { - if (bp2 == NULL) - { - *sourcelist = bp->br_next; - }else - { - bp2->br_next = bp->br_next; - } - bp3 = bp; - bp = bp->br_next; + alreadypresent = FALSE; + for (bp4 = *sourcelist; bp4 != NULL; bp4 = bp4->br_next) + { + if (bp4->br_this == newNode) + { + alreadypresent = TRUE; + break; + } + } + bp2 = NULL; + bp = *sourcelist; + while (bp != NULL) + { + if (bp->br_this == origNode) + { + if (alreadypresent) + { + if (bp2 == NULL) + *sourcelist = bp->br_next; + else + bp2->br_next = bp->br_next; - if (bp3->br_crect != NULL && bp4->br_crect == NULL) - { - bp4->br_crect = bp3->br_crect; - } - freeMagic((char *)bp3); - continue; - }else - { - (bp->br_this = newNode); - } - } - bp2 = bp; - bp = bp->br_next; - } + bp3 = bp; + bp = bp->br_next; + if (bp3->br_crect != NULL && bp4->br_crect == NULL) + bp4->br_crect = bp3->br_crect; + + freeMagic((char *)bp3); + continue; + } + else + bp->br_this = newNode; + } + bp2 = bp; + bp = bp->br_next; + } } diff --git a/resis/ResPrint.c b/resis/ResPrint.c index a2dc6b8e..48eb8192 100644 --- a/resis/ResPrint.c +++ b/resis/ResPrint.c @@ -171,16 +171,25 @@ ResPrintExtDev(outextfile, devices) else fprintf(outextfile, " \"%s\"", subsName); - fprintf(outextfile, " \"%s\" %d %s \"%s\" %d %s \"%s\" %d %s\n", - devices->gate->name, - devices->layout->rd_length * 2, - devices->rs_gattr, - devices->source->name, - devices->layout->rd_width, - devices->rs_sattr, - devices->drain->name, - devices->layout->rd_width, - devices->rs_dattr); + if (devices->gate != NULL) + fprintf(outextfile, " \"%s\" %d %s", + devices->gate->name, + devices->layout->rd_length * 2, + devices->rs_gattr); + + if (devices->source != NULL) + fprintf(outextfile, " \"%s\" %d %s", + devices->source->name, + devices->layout->rd_width, + devices->rs_sattr); + + if (devices->drain != NULL) + fprintf(outextfile, " \"%s\" %d %s", + devices->drain->name, + devices->layout->rd_width, + devices->rs_dattr); + + fprintf(outextfile, "\n"); } } } diff --git a/resis/ResReadSim.c b/resis/ResReadSim.c index cb663a0b..74ccd7e3 100644 --- a/resis/ResReadSim.c +++ b/resis/ResReadSim.c @@ -92,12 +92,12 @@ ResFixPoint *ResFixList; ResNodeList = n;\ (n)->rn_te = NULL;\ (n)->rn_re = NULL;\ - (n)->rn_je=NULL;\ - (n)->rn_ce=NULL;\ - (n)->rn_noderes=RES_INFINITY;\ - (n)->location.p_x=MINFINITY;\ - (n)->location.p_y=MINFINITY;\ - (n)->rn_why=0;\ + (n)->rn_je = NULL;\ + (n)->rn_ce = NULL;\ + (n)->rn_noderes = RES_INFINITY;\ + (n)->location.p_x = MINFINITY;\ + (n)->location.p_y = MINFINITY;\ + (n)->rn_why = 0;\ (n)->rn_status = TRUE;\ } @@ -105,7 +105,6 @@ ResFixPoint *ResFixList; extern void ResSimProcessDrivePoints(); - /* *------------------------------------------------------------------------- * @@ -120,93 +119,104 @@ extern void ResSimProcessDrivePoints(); int ResReadSim(simfile, fetproc, capproc, resproc, attrproc, mergeproc, subproc) - char *simfile; - int (*fetproc)(), (*capproc)(), (*resproc)(); - int (*attrproc)(), (*mergeproc)(), (*subproc)(); + char *simfile; + int (*fetproc)(), (*capproc)(), (*resproc)(); + int (*attrproc)(), (*mergeproc)(), (*subproc)(); { - char line[MAXLINE][MAXTOKEN]; - int result,fettype,extfile; - FILE *fp, *fopen(); + char line[MAXLINE][MAXTOKEN]; + int result, fettype, extfile; + FILE *fp, *fopen(); - fp = PaOpen(simfile,"r",".sim",".",(char *) NULL, (char **) NULL); - if (fp == NULL) - { - TxError("Cannot open file %s%s\n",simfile,".sim"); - return(1); - } - extfile = 0; + fp = PaOpen(simfile, "r", ".sim", ".", (char *)NULL, (char **)NULL); + if (fp == NULL) + { + TxError("Cannot open file %s%s\n", simfile, ".sim"); + return 1; + } + extfile = 0; - /*read in file */ - while (gettokens(line,fp) != 0) - { - fettype = MINFINITY; - switch(line[0][0]) - { - case '|': - if (strcmp(line[NODEUNITS],"units:") == 0) - { - resscale = (float)atof(line[NODELAMBDA]); - if (resscale == 0.0) resscale = 1.0; - } - result=0; - break; - case 'e': fettype = DBTechNameType("efet"); - break; - case 'd': fettype = DBTechNameType("dfet"); - break; - case 'n': fettype = DBTechNameType("nfet"); - break; - case 'p': fettype = DBTechNameType("pfet"); - break; - case 'b': fettype = DBTechNameType("bnpn"); - break; - case 'C': if (capproc) result = (*capproc)(line); - break; - case 'R': if (resproc)result = (*resproc)(line); - break; - case '=': if (mergeproc)result = (*mergeproc)(line); - break; - case 'A': if (attrproc) result = - (*attrproc)(line[ATTRIBUTENODENAME], - line[ATTRIBUTEVALUE], - simfile, &extfile); - break; - case 'x': fettype = DBNumTypes; - break; - case 'D': - case 'c': - case 'r': break; - default: result = 1; - (void)fclose(fp); - break; - } - if (fettype == -1) - { - TxError("Error in Reading device line of sim file.\n"); - result = 1; - } - else if (fettype == DBNumTypes) - { - result = (*subproc)(line); - } - else if (fettype != MINFINITY) - { - float sheetr; - ExtDevice *devptr; + /* Read in file */ + while (gettokens(line, fp) != 0) + { + fettype = MINFINITY; + switch(line[0][0]) + { + case '|': + if (strcmp(line[NODEUNITS],"units:") == 0) + { + resscale = (float)atof(line[NODELAMBDA]); + if (resscale == 0.0) resscale = 1.0; + } + result=0; + break; + case 'e': + fettype = DBTechNameType("efet"); + break; + case 'd': + fettype = DBTechNameType("dfet"); + break; + case 'n': + fettype = DBTechNameType("nfet"); + break; + case 'p': + fettype = DBTechNameType("pfet"); + break; + case 'b': + fettype = DBTechNameType("bnpn"); + break; + case 'C': + if (capproc) result = (*capproc)(line); + break; + case 'R': + if (resproc) result = (*resproc)(line); + break; + case '=': + if (mergeproc) result = (*mergeproc)(line); + break; + case 'A': + if (attrproc) + result = (*attrproc)(line[ATTRIBUTENODENAME], + line[ATTRIBUTEVALUE], simfile, &extfile); + break; + case 'x': + fettype = DBNumTypes; + break; + case 'D': + case 'c': + case 'r': + break; + default: + result = 1; + fclose(fp); + break; + } + if (fettype == -1) + { + TxError("Error in Reading device line of sim file.\n"); + result = 1; + } + else if (fettype == DBNumTypes) + { + result = (*subproc)(line); + } + else if (fettype != MINFINITY) + { + float sheetr; + ExtDevice *devptr; - devptr = ExtCurStyle->exts_device[fettype]; - sheetr=(float)devptr->exts_linearResist; - result = (*fetproc)(line,sheetr,fettype); - } - if (result != 0) - { - TxError("Error in sim file %s\n",line[0]); - return(1); - } - } - (void)fclose(fp); - return(result); + devptr = ExtCurStyle->exts_device[fettype]; + sheetr = (float)devptr->exts_linearResist; + result = (*fetproc)(line, sheetr, devptr); + } + if (result != 0) + { + TxError("Error in sim file %s\n", line[0]); + return 1; + } + } + fclose(fp); + return(result); } @@ -225,8 +235,7 @@ ResReadSim(simfile, fetproc, capproc, resproc, attrproc, mergeproc, subproc) int ResReadNode(nodefile) - char *nodefile; - + char *nodefile; { char line[MAXLINE][MAXTOKEN]; FILE *fp, *fopen(); @@ -235,15 +244,15 @@ ResReadNode(nodefile) char *cp; float lambda; - fp = PaOpen(nodefile,"r",".nodes",".", (char *) NULL, (char **) NULL); + fp = PaOpen(nodefile, "r", ".nodes", ".", (char *)NULL, (char **)NULL); if (fp == NULL) { - TxError("Cannot open file %s%s\n",nodefile,".nodes"); - return(1); + TxError("Cannot open file %s%s\n", nodefile, ".nodes"); + return 1; } while (gettokens(line,fp) != 0) { - entry = HashFind(&ResNodeTable,line[NODES_NODENAME]); + entry = HashFind(&ResNodeTable, line[NODES_NODENAME]); node = ResInitializeNode(entry); node->location.p_x = atoi(line[NODES_NODEX]); @@ -259,14 +268,15 @@ ResReadNode(nodefile) if (node->type == -1) { - TxError("Bad tile type name in %s.nodes file for node %s\n",nodefile,node->name); + TxError("Bad tile type name in %s.nodes file for node %s\n", + nodefile, node->name); TxError("Did you use the newest version of ext2sim?\n"); - (void)fclose(fp); - return(1); + fclose(fp); + return 1; } } - (void)fclose(fp); - return(0); + fclose(fp); + return 0; } /* @@ -283,39 +293,38 @@ ResReadNode(nodefile) */ int -gettokens(line,fp) - char line[][MAXTOKEN]; - FILE *fp; - +gettokens(line, fp) + char line[][MAXTOKEN]; + FILE *fp; { - int i=0,j=0; - int c; + int i = 0, j = 0; + int c; - while ((c = getc(fp)) != EOF && c != '\n') - { - switch(c) - { - case ' ': - case ' ' : line[i++][j] = '\0'; - j=0; - break; - default: line[i][j++] = c; - break; - } - } - if (c == '\n') - { - line[i++][j] = '\0'; - j=0; - } - for(j=i;j < MAXLINE;j++) - { - line[j][0] = '\0'; - } - return(i); + while ((c = getc(fp)) != EOF && c != '\n') + { + switch(c) + { + case ' ': + case ' ' : + line[i++][j] = '\0'; + j = 0; + break; + default: + line[i][j++] = c; + break; + } + } + if (c == '\n') + { + line[i++][j] = '\0'; + j = 0; + } + for (j = i; j < MAXLINE; j++) + line[j][0] = '\0'; + + return i; } - /* *------------------------------------------------------------------------- * @@ -342,6 +351,7 @@ ResSimSubckt(line) float lambda; TileType ttype = TT_SPACE; char *lptr = NULL, *wptr = NULL; + ExtDevice *devptr; device = (RDev *) mallocMagic((unsigned) (sizeof(RDev))); @@ -358,11 +368,14 @@ ResSimSubckt(line) ResRDevList = device; device->layout = NULL; + device->source = device->drain = device->gate = device->subs = NULL; /* The last argument is the name of the device */ for (i = 1; line[i][0] != '\0'; i++); i--; + /* To do: Replace this search with a pre-prepared hash */ + /* table to key off of the device name. */ for (j = 0; j < EFDevNumTypes; j++) if (!strcmp(EFDevTypes[j], line[i])) break; @@ -391,35 +404,36 @@ ResSimSubckt(line) case 'y': device->location.p_y = (int)((float)atof(eqptr) / lambda); break; - case 't': - ttype = (int)(atoi(eqptr)); - break; } } } - /* This should not be needed, as ext2sim should encode device type */ - /* in the attributes list. */ - if (ttype == TT_SPACE) + if (j == EFDevNumTypes) { - if (j == EFDevNumTypes) - { - TxError("Failure to find device type %s\n", line[i]); - return 1; - } - ttype = extGetDevType(EFDevTypes[j]); + TxError("Failure to find device type %s\n", line[i]); + return 1; } + ttype = extGetDevType(EFDevTypes[j]); + /* Find the device record that corresponds to the device name */ + for (devptr = ExtCurStyle->exts_device[ttype]; devptr; devptr = devptr->exts_next) + if (!strcmp(devptr->exts_deviceName, EFDevTypes[j])) + break; + + device->rs_devptr = devptr; device->rs_ttype = ttype; if (lptr != NULL && wptr != NULL) { float rpersquare; - ExtDevice *devptr; - devptr = ExtCurStyle->exts_device[ttype]; rpersquare =(float)devptr->exts_linearResist; - device->resistance = MagAtof(lptr) * rpersquare/MagAtof(wptr); + /* Subcircuit types may not have a length or width value, in which */ + /* case it is zero. Don't induce a divide-by-zero error. */ + if (MagAtof(wptr) == 0) + device->resistance = 0; + else + device->resistance = MagAtof(lptr) * rpersquare/MagAtof(wptr); } else device->resistance = 0; @@ -438,8 +452,6 @@ ResSimSubckt(line) return rvalue; } - - /* *------------------------------------------------------------------------- * @@ -453,95 +465,107 @@ ResSimSubckt(line) */ int -ResSimDevice(line, rpersquare, ttype) - char line[][MAXTOKEN]; - float rpersquare; - TileType ttype; +ResSimDevice(line, rpersquare, devptr) + char line[][MAXTOKEN]; + float rpersquare; + ExtDevice *devptr; { - RDev *device; - int rvalue,i,j,k; - char *newattr,tmpattr[MAXTOKEN]; - static int nowarning = TRUE; - float lambda; + RDev *device; + int rvalue, i, j, k; + char *newattr, tmpattr[MAXTOKEN]; + static int nowarning = TRUE; + float lambda; - device = (RDev *) mallocMagic((unsigned) (sizeof(RDev))); - if ((line[RDEV_WIDTH][0] == '\0') || (line[RDEV_LENGTH][0] == '\0')) - { + if ((line[RDEV_WIDTH][0] == '\0') || (line[RDEV_LENGTH][0] == '\0')) + { TxError("error in input file:\n"); - return(1); - } - else - { - if (nowarning && rpersquare == 0) - { - TxError("Warning- FET resistance not included or set to zero in technology file-\n"); - TxError("All driven nodes will be extracted\n"); - nowarning = FALSE; - } - device->resistance = MagAtof(line[RDEV_LENGTH]) * rpersquare/MagAtof(line[RDEV_WIDTH]); - } - device->status = FALSE; - device->nextDev = ResRDevList; + return 1; + } - lambda = (float)ExtCurStyle->exts_unitsPerLambda / resscale; - device->location.p_x = (int)((float)atof(line[RDEV_DEVX]) / lambda); - device->location.p_y = (int)((float)atof(line[RDEV_DEVY]) / lambda); + device = (RDev *)mallocMagic((unsigned)(sizeof(RDev))); + if (nowarning && rpersquare == 0) + { + TxError("Warning: FET resistance not included or " + "set to zero in technology file-\n"); + TxError("All driven nodes will be extracted\n"); + nowarning = FALSE; + } + if (MagAtof(line[RDEV_WIDTH]) != 0) + device->resistance = MagAtof(line[RDEV_LENGTH]) * rpersquare / + MagAtof(line[RDEV_WIDTH]); + else + device->resistance = 0; - device->rs_gattr=RDEV_NOATTR; - device->rs_sattr=RDEV_NOATTR; - device->rs_dattr=RDEV_NOATTR; - device->rs_ttype = ttype; + device->status = FALSE; + device->nextDev = ResRDevList; - /* sim attributes look like g=a1,a2 */ - /* ext attributes are "a1","a2" */ - /* do conversion from one to the other here */ + lambda = (float)ExtCurStyle->exts_unitsPerLambda / resscale; + device->location.p_x = (int)((float)atof(line[RDEV_DEVX]) / lambda); + device->location.p_y = (int)((float)atof(line[RDEV_DEVY]) / lambda); - for (i=RDEV_ATTR;i < RDEV_ATTR+RDEV_NUM_ATTR;i++) - { - if (line[i][0] == '\0') break; - k=0; - tmpattr[k++]='"'; - for (j=2;line[i][j] != '\0';j++) - { - if (line[i][j] == ',') - { - tmpattr[k++] = '"'; - tmpattr[k++] = ','; - tmpattr[k++] = '"'; - } - else - { - tmpattr[k++] = line[i][j]; - } - } - tmpattr[k++]='"'; - tmpattr[k++]='\0'; - newattr = (char *) mallocMagic((unsigned) k); - strncpy(newattr,tmpattr,k); - switch (line[i][0]) - { - case 'g': device->rs_gattr = newattr; break; - case 's': device->rs_sattr = newattr; break; - case 'd': device->rs_dattr = newattr; break; - default: TxError("Bad fet attribute\n"); - break; - } - } - ResRDevList = device; - device->layout = NULL; - rvalue = ResSimNewNode(line[GATE],GATE,device) + - ResSimNewNode(line[SOURCE],SOURCE,device) + - ResSimNewNode(line[DRAIN],DRAIN,device); + device->rs_gattr=RDEV_NOATTR; + device->rs_sattr=RDEV_NOATTR; + device->rs_dattr=RDEV_NOATTR; + device->rs_devptr = devptr; - return(rvalue); + device->gate = device->source = device->drain = device->subs = NULL; + + /* sim attributes look like g=a1,a2 */ + /* ext attributes are "a1","a2" */ + /* do conversion from one to the other here */ + + for (i = RDEV_ATTR; i < RDEV_ATTR + RDEV_NUM_ATTR; i++) + { + if (line[i][0] == '\0') break; + k = 0; + tmpattr[k++] = '"'; + for (j = 2; line[i][j] != '\0'; j++) + { + if (line[i][j] == ',') + { + tmpattr[k++] = '"'; + tmpattr[k++] = ','; + tmpattr[k++] = '"'; + } + else + { + tmpattr[k++] = line[i][j]; + } + } + tmpattr[k++] = '"'; + tmpattr[k++] = '\0'; + newattr = (char *)mallocMagic((unsigned)k); + strncpy(newattr, tmpattr, k); + switch (line[i][0]) + { + case 'g': + device->rs_gattr = newattr; + break; + case 's': + device->rs_sattr = newattr; + break; + case 'd': + device->rs_dattr = newattr; + break; + default: + TxError("Bad fet attribute\n"); + break; + } + } + ResRDevList = device; + device->layout = NULL; + rvalue = ResSimNewNode(line[GATE], GATE, device) + + ResSimNewNode(line[SOURCE], SOURCE, device) + + ResSimNewNode(line[DRAIN], DRAIN, device); + + return rvalue; } - /* *------------------------------------------------------------------------- * - * ResSimNewNode-- Adds a new node to the Node Hash Table. + * ResSimNewNode-- Adds a new node to the Node Hash Table. * * Results: returns zero if node is added correctly, one otherwise. * @@ -552,44 +576,48 @@ ResSimDevice(line, rpersquare, ttype) int ResSimNewNode(line, type, device) - char line[]; - int type; - RDev *device; + char line[]; + int type; + RDev *device; { - HashEntry *entry; - ResSimNode *node; - devPtr *tptr; + HashEntry *entry; + ResSimNode *node; + devPtr *tptr; - if (line[0] == '\0') - { - TxError("Missing device connection\n"); - return(1); - } - entry = HashFind(&ResNodeTable, line); - node = ResInitializeNode(entry); - tptr = (devPtr *) mallocMagic((unsigned) (sizeof(devPtr))); - tptr->thisDev = device; - tptr->nextDev = node->firstDev; - node->firstDev = tptr; - tptr->terminal = type; - switch(type) - { - case GATE: device->gate = node; - break; - case SOURCE: device->source = node; - break; - case DRAIN: device->drain = node; - break; - case SUBS: device->subs = node; - break; - default: TxError("Bad Terminal Specifier\n"); - break; - } - return(0); + if (line[0] == '\0') + { + TxError("Missing device connection\n"); + return 1; + } + entry = HashFind(&ResNodeTable, line); + node = ResInitializeNode(entry); + tptr = (devPtr *)mallocMagic((unsigned)(sizeof(devPtr))); + tptr->thisDev = device; + tptr->nextDev = node->firstDev; + node->firstDev = tptr; + tptr->terminal = type; + switch(type) + { + case GATE: + device->gate = node; + break; + case SOURCE: + device->source = node; + break; + case DRAIN: + device->drain = node; + break; + case SUBS: + device->subs = node; + break; + default: + TxError("Bad Terminal Specifier\n"); + break; + } + return 0; } - /* *------------------------------------------------------------------------- * @@ -607,58 +635,57 @@ ResSimNewNode(line, type, device) int ResSimCapacitor(line) - char line[][MAXTOKEN]; + char line[][MAXTOKEN]; { - HashEntry *entry1,*entry2; - ResSimNode *node1,*node2; - - if (line[COUPLETERMINAL1][0] == 0 || line[COUPLETERMINAL2][0] == 0) - { - TxError("Bad Capacitor\n"); - return(1); - } - entry1 = HashFind(&ResNodeTable,line[COUPLETERMINAL1]); - node1 = ResInitializeNode(entry1); - if (ResOptionsFlags & ResOpt_Signal) - { - node1->capacitance += MagAtof(line[COUPLEVALUE]); - if (strcmp(line[COUPLETERMINAL2],"GND") == 0 || - strcmp(line[COUPLETERMINAL2],"Vdd") == 0) - { - return(0); - } - entry2 = HashFind(&ResNodeTable,line[COUPLETERMINAL2]); - node2 = ResInitializeNode(entry2); - node2->capacitance += MagAtof(line[COUPLEVALUE]); - return(0); - } - if (strcmp(line[COUPLETERMINAL2],"GND") == 0 ) - { - node1->capacitance += MagAtof(line[COUPLEVALUE]); - return(0); - } - if (strcmp(line[COUPLETERMINAL2],"Vdd") == 0 ) - { - node1->cap_vdd += MagAtof(line[COUPLEVALUE]); - return(0); - } - entry2 = HashFind(&ResNodeTable,line[COUPLETERMINAL2]); - node2 = ResInitializeNode(entry2); - if (strcmp(line[COUPLETERMINAL1],"GND") == 0 ) - { - node2->capacitance += MagAtof(line[COUPLEVALUE]); - return(0); - } - if (strcmp(line[COUPLETERMINAL1],"Vdd") == 0 ) - { - node2->cap_vdd += MagAtof(line[COUPLEVALUE]); - return(0); - } - node1->cap_couple += MagAtof(line[COUPLEVALUE]); - node2->cap_couple += MagAtof(line[COUPLEVALUE]); - return(0); + HashEntry *entry1, *entry2; + ResSimNode *node1, *node2; + if (line[COUPLETERMINAL1][0] == 0 || line[COUPLETERMINAL2][0] == 0) + { + TxError("Bad Capacitor\n"); + return(1); + } + entry1 = HashFind(&ResNodeTable, line[COUPLETERMINAL1]); + node1 = ResInitializeNode(entry1); + if (ResOptionsFlags & ResOpt_Signal) + { + node1->capacitance += MagAtof(line[COUPLEVALUE]); + if (strcmp(line[COUPLETERMINAL2], "GND") == 0 || + strcmp(line[COUPLETERMINAL2], "Vdd") == 0) + { + return 0; + } + entry2 = HashFind(&ResNodeTable, line[COUPLETERMINAL2]); + node2 = ResInitializeNode(entry2); + node2->capacitance += MagAtof(line[COUPLEVALUE]); + return 0; + } + if (strcmp(line[COUPLETERMINAL2], "GND") == 0) + { + node1->capacitance += MagAtof(line[COUPLEVALUE]); + return 0; + } + if (strcmp(line[COUPLETERMINAL2], "Vdd") == 0) + { + node1->cap_vdd += MagAtof(line[COUPLEVALUE]); + return 0; + } + entry2 = HashFind(&ResNodeTable, line[COUPLETERMINAL2]); + node2 = ResInitializeNode(entry2); + if (strcmp(line[COUPLETERMINAL1], "GND") == 0) + { + node2->capacitance += MagAtof(line[COUPLEVALUE]); + return 0; + } + if (strcmp(line[COUPLETERMINAL1], "Vdd") == 0) + { + node2->cap_vdd += MagAtof(line[COUPLEVALUE]); + return 0; + } + node1->cap_couple += MagAtof(line[COUPLEVALUE]); + node2->cap_couple += MagAtof(line[COUPLEVALUE]); + return 0; } @@ -678,30 +705,27 @@ ResSimCapacitor(line) int ResSimResistor(line) - char line[][MAXTOKEN]; - + char line[][MAXTOKEN]; { - HashEntry *entry; - ResSimNode *node; + HashEntry *entry; + ResSimNode *node; - if (line[RESNODENAME][0] == 0) - { - TxError("Bad Resistor\n"); - return(1); - } - entry = HashFind(&ResNodeTable,line[RESNODENAME]); - node = ResInitializeNode(entry); - if (node->resistance != 0) - { + if (line[RESNODENAME][0] == 0) + { + TxError("Bad Resistor\n"); + return 1; + } + entry = HashFind(&ResNodeTable, line[RESNODENAME]); + node = ResInitializeNode(entry); + if (node->resistance != 0) + { TxError("Duplicate Resistance Entries\n"); - return(1); - } - node->resistance = MagAtof(line[NODERESISTANCE]); - return(0); + return 1; + } + node->resistance = MagAtof(line[NODERESISTANCE]); + return(0); } - - /* *------------------------------------------------------------------------- * @@ -718,95 +742,95 @@ ResSimResistor(line) */ int -ResSimAttribute(aname,avalue,rootname,readextfile) - char *aname,*avalue,*rootname; - int *readextfile; +ResSimAttribute(aname, avalue, rootname, readextfile) + char *aname, *avalue, *rootname; + int *readextfile; { - HashEntry *entry; - ResSimNode *node; - char digit[MAXDIGIT]; - int i; - static int notwarned=TRUE; + HashEntry *entry; + ResSimNode *node; + char digit[MAXDIGIT]; + int i; + static int notwarned=TRUE; - if (aname[0] == 0) - { - TxError("Bad Resistor\n"); - return(1); - } - entry = HashFind(&ResNodeTable,aname); - node = ResInitializeNode(entry); - if (strncmp(avalue,"res:skip",8) == 0) - { - if (node->status & FORCE) - { - TxError("Warning: Node %s is both forced and skipped\n",aname); - } - else - { - node->status |= SKIP; - } - } - else if (strncmp(avalue,"res:force",9) == 0) - { - if (node->status & SKIP) - { - TxError("Warning: Node %s is both skipped and forced \n",aname); - } - else - { - node->status |= FORCE; - } - } - else if (strncmp(avalue,"res:min=",8) == 0) - { - node->status |= MINSIZE; - for(i=0,avalue += 8; *avalue != '\0' && *avalue != ','; avalue++) - { - digit[i++] = *avalue; - } - digit[i++]='\0'; - node->minsizeres=MagAtof(digit); - } - else if (strncmp(avalue,"res:drive",9) == 0 && + if (aname[0] == 0) + { + TxError("Bad Resistor\n"); + return 1; + } + entry = HashFind(&ResNodeTable, aname); + node = ResInitializeNode(entry); + if (strncmp(avalue, "res:skip", 8) == 0) + { + if (node->status & FORCE) + { + TxError("Warning: Node %s is both forced and skipped\n", aname); + } + else + { + node->status |= SKIP; + } + } + else if (strncmp(avalue, "res:force", 9) == 0) + { + if (node->status & SKIP) + { + TxError("Warning: Node %s is both skipped and forced \n", aname); + } + else + { + node->status |= FORCE; + } + } + else if (strncmp(avalue, "res:min=", 8) == 0) + { + node->status |= MINSIZE; + for (i = 0, avalue += 8; *avalue != '\0' && *avalue != ','; avalue++) + { + digit[i++] = *avalue; + } + digit[i++] = '\0'; + node->minsizeres = MagAtof(digit); + } + else if (strncmp(avalue, "res:drive", 9) == 0 && (ResOptionsFlags & ResOpt_Signal)) - { - if (*readextfile == 0) - { - ResSimProcessDrivePoints(rootname); - *readextfile = 1; - } - /* is the attribute in root.ext? */ - if (node->drivepoint.p_x != INFINITY) - { - node->status |= DRIVELOC; - } - else - { - if (notwarned) - TxError("Drivepoint for %s not defined in %s.ext; is it defined in a child cell?\n",node->name,rootname); - notwarned = FALSE; - } - } + { + if (*readextfile == 0) + { + ResSimProcessDrivePoints(rootname); + *readextfile = 1; + } + /* is the attribute in root.ext? */ + if (node->drivepoint.p_x != INFINITY) + { + node->status |= DRIVELOC; + } + else + { + if (notwarned) + TxError("Drivepoint for %s not defined in %s.ext; is it " + "defined in a child cell?\n", node->name, rootname); + notwarned = FALSE; + } + } #ifdef ARIEL - else if (strncmp(avalue,"res:fix",7) == 0 && + else if (strncmp(avalue, "res:fix", 7) == 0 && (ResOptionsFlags & ResOpt_Power)) - { - if (*readextfile == 0) - { - ResSimProcessFixPoints(rootname); - *readextfile = 1; - } - } + { + if (*readextfile == 0) + { + ResSimProcessFixPoints(rootname); + *readextfile = 1; + } + } #endif - if (avalue = strchr(avalue,',')) - { - (void) ResSimAttribute(aname,avalue+1,rootname,readextfile); - } - return(0); + if (avalue = strchr(avalue, ',')) + { + ResSimAttribute(aname, avalue + 1, rootname, readextfile); + } + return 0; } - /* *------------------------------------------------------------------------- * @@ -827,34 +851,34 @@ ResSimAttribute(aname,avalue,rootname,readextfile) void ResSimProcessDrivePoints(filename) - char *filename; + char *filename; { - char line[MAXLINE][MAXTOKEN]; - FILE *fp; - HashEntry *entry; - ResSimNode *node; + char line[MAXLINE][MAXTOKEN]; + FILE *fp; + HashEntry *entry; + ResSimNode *node; - fp = PaOpen(filename,"r",".ext",".",(char *) NULL,(char **) NULL); - if (fp == NULL) - { - TxError("Cannot open file %s%s\n",filename,".ext"); - return; - } - while (gettokens(line,fp) != 0) - { - if (strncmp(line[RES_EXT_ATTR],"attr",4) != 0 || - strncmp(line[RES_EXT_ATTR_TEXT],"\"res:drive\"",11) != 0) continue; + fp = PaOpen(filename, "r", ".ext", ".", (char *)NULL, (char **)NULL); + if (fp == NULL) + { + TxError("Cannot open file %s%s\n", filename, ".ext"); + return; + } + while (gettokens(line,fp) != 0) + { + if (strncmp(line[RES_EXT_ATTR], "attr", 4) != 0 || + strncmp(line[RES_EXT_ATTR_TEXT], "\"res:drive\"", 11) != 0) + continue; - entry = HashFind(&ResNodeTable,line[RES_EXT_ATTR_NAME]); - node = ResInitializeNode(entry); - node->drivepoint.p_x = atoi(line[RES_EXT_ATTR_X]); - node->drivepoint.p_y = atoi(line[RES_EXT_ATTR_Y]); - node->rs_ttype = DBTechNoisyNameType(line[RES_EXT_ATTR_TILE]); - } + entry = HashFind(&ResNodeTable, line[RES_EXT_ATTR_NAME]); + node = ResInitializeNode(entry); + node->drivepoint.p_x = atoi(line[RES_EXT_ATTR_X]); + node->drivepoint.p_y = atoi(line[RES_EXT_ATTR_Y]); + node->rs_ttype = DBTechNoisyNameType(line[RES_EXT_ATTR_TILE]); + } } - /* *------------------------------------------------------------------------- * @@ -875,46 +899,47 @@ ResSimProcessDrivePoints(filename) void ResSimProcessFixPoints(filename) - char *filename; + char *filename; { - char line[MAXLINE][MAXTOKEN],*label,*c; - FILE *fp; - ResFixPoint *thisfix; + char line[MAXLINE][MAXTOKEN], *label, *c; + FILE *fp; + ResFixPoint *thisfix; - fp = PaOpen(filename,"r",".ext",".",(char *) NULL,(char **) NULL); - if (fp == NULL) - { - TxError("Cannot open file %s%s\n",filename,".ext"); - return; - } - while (gettokens(line,fp) != 0) - { - if (strncmp(line[RES_EXT_ATTR],"attr",4) != 0 || - strncmp(line[RES_EXT_ATTR_TEXT],"\"res:fix",8) != 0) continue; - label = line[RES_EXT_ATTR_TEXT]; - label += 8; - if (*label == ':') label++; - if ((c=strrchr(label,'"')) != NULL) *c='\0'; - else if (*label == '\0'); - else - { - TxError("Bad res:fix attribute label %s\n", + fp = PaOpen(filename, "r", ".ext", ".", (char *)NULL, (char **)NULL); + if (fp == NULL) + { + TxError("Cannot open file %s%s\n", filename, ".ext"); + return; + } + while (gettokens(line, fp) != 0) + { + if (strncmp(line[RES_EXT_ATTR], "attr", 4) != 0 || + strncmp(line[RES_EXT_ATTR_TEXT], "\"res:fix", 8) != 0) + continue; + label = line[RES_EXT_ATTR_TEXT]; + label += 8; + if (*label == ':') label++; + if ((c=strrchr(label, '"')) != NULL) *c = '\0'; + else if (*label != '\0') + { + TxError("Bad res:fix attribute label %s\n", line[RES_EXT_ATTR_TEXT]); - *label ='\0'; - } - thisfix = (ResFixPoint *) mallocMagic((unsigned) (sizeof(ResFixPoint)+strlen(label))); - thisfix->fp_next = ResFixList; - ResFixList = thisfix; - thisfix->fp_loc.p_x = atoi(line[RES_EXT_ATTR_X]); - thisfix->fp_loc.p_y = atoi(line[RES_EXT_ATTR_Y]); - thisfix->fp_ttype = DBTechNoisyNameType(line[RES_EXT_ATTR_TILE]); - thisfix->fp_tile=NULL; - strcpy(thisfix->fp_name,label); - } + *label ='\0'; + } + thisfix = (ResFixPoint *)mallocMagic((unsigned)(sizeof(ResFixPoint) + + strlen(label))); + thisfix->fp_next = ResFixList; + ResFixList = thisfix; + thisfix->fp_loc.p_x = atoi(line[RES_EXT_ATTR_X]); + thisfix->fp_loc.p_y = atoi(line[RES_EXT_ATTR_Y]); + thisfix->fp_ttype = DBTechNoisyNameType(line[RES_EXT_ATTR_TILE]); + thisfix->fp_tile = NULL; + strcpy(thisfix->fp_name, label); + } } - /* +/* *------------------------------------------------------------------------- * * ResSimMerge-- Processes = line in sim file @@ -930,30 +955,30 @@ ResSimProcessFixPoints(filename) int ResSimMerge(line) - char line[][MAXTOKEN]; + char line[][MAXTOKEN]; { - ResSimNode *node; - devPtr *ptr; + ResSimNode *node; + devPtr *ptr; - if ((line[ALIASNAME][0] == '\0') || (line[REALNAME][0] == '\0')) - { - TxError("Bad node alias line\n"); - return(1); - } - node = ResInitializeNode(HashFind(&ResNodeTable,line[ALIASNAME])); - node->status |= FORWARD; - node->forward = ResInitializeNode(HashFind(&ResNodeTable,line[REALNAME])); - node->forward->resistance += node->resistance; - node->forward->capacitance += node->capacitance; - while (node->firstDev != NULL) - { - ptr=node->firstDev; - node->firstDev = node->firstDev->nextDev; - ptr->nextDev = node->forward->firstDev; - node->forward->firstDev = ptr; - } - return(0); + if ((line[ALIASNAME][0] == '\0') || (line[REALNAME][0] == '\0')) + { + TxError("Bad node alias line\n"); + return(1); + } + node = ResInitializeNode(HashFind(&ResNodeTable, line[ALIASNAME])); + node->status |= FORWARD; + node->forward = ResInitializeNode(HashFind(&ResNodeTable, line[REALNAME])); + node->forward->resistance += node->resistance; + node->forward->capacitance += node->capacitance; + while (node->firstDev != NULL) + { + ptr = node->firstDev; + node->firstDev = node->firstDev->nextDev; + ptr->nextDev = node->forward->firstDev; + node->forward->firstDev = ptr; + } + return 0; } /* @@ -971,36 +996,36 @@ ResSimMerge(line) ResSimNode * ResInitializeNode(entry) - HashEntry *entry; + HashEntry *entry; { - ResSimNode *node; + ResSimNode *node; - if ((node = (ResSimNode *) HashGetValue(entry)) == NULL) - { - node = (ResSimNode *) mallocMagic((unsigned)(sizeof(ResSimNode))); - HashSetValue(entry,(char *) node); - node->nextnode = ResOriginalNodes; - ResOriginalNodes = node; - node->status = FALSE; - node->forward = (ResSimNode *) NULL; - node->capacitance = 0; - node->cap_vdd = 0; - node->cap_couple = 0; - node->resistance = 0; - node->type = 0; - node->firstDev = NULL; - node->name = entry->h_key.h_name; - node->oldname = NULL; - node->drivepoint.p_x = INFINITY; - node->drivepoint.p_y = INFINITY; - node->location.p_x = INFINITY; - node->location.p_y = INFINITY; - node->rs_sublist[0]=NULL; - node->rs_sublist[1]=NULL; - } - while (node->status & FORWARD) - { - node = node->forward; - } - return(node); + if ((node = (ResSimNode *) HashGetValue(entry)) == NULL) + { + node = (ResSimNode *)mallocMagic((unsigned)(sizeof(ResSimNode))); + HashSetValue(entry, (char *) node); + node->nextnode = ResOriginalNodes; + ResOriginalNodes = node; + node->status = FALSE; + node->forward = (ResSimNode *) NULL; + node->capacitance = 0; + node->cap_vdd = 0; + node->cap_couple = 0; + node->resistance = 0; + node->type = 0; + node->firstDev = NULL; + node->name = entry->h_key.h_name; + node->oldname = NULL; + node->drivepoint.p_x = INFINITY; + node->drivepoint.p_y = INFINITY; + node->location.p_x = INFINITY; + node->location.p_y = INFINITY; + node->rs_sublist[0] = NULL; + node->rs_sublist[1] = NULL; + } + while (node->status & FORWARD) + { + node = node->forward; + } + return node; } diff --git a/resis/ResRex.c b/resis/ResRex.c index bc67e95d..64caa1a4 100644 --- a/resis/ResRex.c +++ b/resis/ResRex.c @@ -22,6 +22,7 @@ static char rcsid[] __attribute__ ((unused)) = "$Header: /usr/cvsroot/magic-8.0/ #include "textio/textio.h" #include "extract/extract.h" #include "extract/extractInt.h" +#include "extflat/extflat.h" #include "windows/windows.h" #include "dbwind/dbwind.h" #include "utils/utils.h" @@ -52,9 +53,10 @@ extern ResSimNode *ResOriginalNodes; /*Linked List of Nodes */ int resNodeNum; #ifdef LAPLACE -int ResOptionsFlags = ResOpt_Simplify|ResOpt_Tdi|ResOpt_DoExtFile|ResOpt_CacheLaplace; +int ResOptionsFlags = ResOpt_Simplify | ResOpt_Tdi | ResOpt_DoExtFile + | ResOpt_CacheLaplace; #else -int ResOptionsFlags = ResOpt_Simplify|ResOpt_Tdi|ResOpt_DoExtFile; +int ResOptionsFlags = ResOpt_Simplify | ResOpt_Tdi | ResOpt_DoExtFile; #endif char *ResCurrentNode; @@ -97,17 +99,34 @@ ExtResisForDef(celldef, resisdata) HashEntry *entry; devPtr *tptr,*oldtptr; ResSimNode *node; - int result; + int result, idx; + char *devname; ResRDevList = NULL; ResOriginalNodes = NULL; + /* Get device information from the current extraction style */ + idx = 0; + while (ExtGetDevInfo(idx++, &devname, NULL, NULL, NULL, NULL, NULL)) + { + if (idx == TT_MAXTYPES) + { + TxError("Error: Ran out of space for device types!\n"); + break; + } + efBuildAddStr(EFDevTypes, &EFDevNumTypes, TT_MAXTYPES, devname); + } + HashInit(&ResNodeTable, INITFLATSIZE, HT_STRINGKEYS); /* read in .sim file */ result = (ResReadSim(celldef->cd_name, ResSimDevice, ResSimCapacitor, ResSimResistor, ResSimAttribute, ResSimMerge, ResSimSubckt) == 0); + /* Clean up the EFDevTypes table */ + for (idx = 0; idx < EFDevNumTypes; idx++) freeMagic(EFDevTypes[idx]); + EFDevNumTypes = 0; + if (result) /* read in .nodes file */ result = (ResReadNode(celldef->cd_name) == 0); @@ -185,7 +204,7 @@ CmdExtResis(win, cmd) TxCommand *cmd; { int i, j, k, option, value, saveFlags; - static int init=1; + static int init = 1; static float tolerance, tdiTolerance, fhFrequency; CellDef *mainDef; CellUse *selectedUse; @@ -246,6 +265,17 @@ typedef enum { init = 0; } + /* Initialize ResGlobalParams */ + gparams.rg_ttype = TT_SPACE; + gparams.rg_Tdi = 0.0; + gparams.rg_nodecap = 0.0; + gparams.rg_maxres = 0.0; + gparams.rg_bigdevres = 0; + gparams.rg_tilecount = 0; + gparams.rg_status = 0; + gparams.rg_devloc = NULL; + gparams.rg_name = NULL; + option = (cmd->tx_argc > 1) ? Lookup(cmd->tx_argv[1], cmdExtresisCmd) : RES_RUN; @@ -434,7 +464,7 @@ typedef enum { CellDef *def; Rect rect; int oldoptions; - ResFixPoint fp; + ResSimNode lnode; if (ToolGetBoxWindow((Rect *) NULL, (int *) NULL) == NULL) { @@ -449,23 +479,23 @@ typedef enum { gparams.rg_ttype = tt; gparams.rg_status = DRIVEONLY; oldoptions = ResOptionsFlags; - ResOptionsFlags = ResOpt_DoSubstrate|ResOpt_Signal|ResOpt_Box; + ResOptionsFlags = ResOpt_DoSubstrate | ResOpt_Signal | ResOpt_Box; #ifdef LAPLACE - ResOptionsFlags |= (oldoptions & (ResOpt_CacheLaplace|ResOpt_DoLaplace)); + ResOptionsFlags |= (oldoptions & + (ResOpt_CacheLaplace | ResOpt_DoLaplace)); LaplaceMatchCount = 0; LaplaceMissCount = 0; #endif - fp.fp_ttype = tt; - fp.fp_loc = rect.r_ll; - fp.fp_next = NULL; - if (ResExtractNet(&fp, &gparams, NULL) != 0) return; - ResPrintResistorList(stdout,ResResList); - ResPrintDeviceList(stdout,ResRDevList); + lnode.location = rect.r_ll; + lnode.type = tt; + if (ResExtractNet(&lnode, &gparams, NULL) != 0) return; + ResPrintResistorList(stdout, ResResList); + ResPrintDeviceList(stdout, ResRDevList); #ifdef LAPLACE if (ResOptionsFlags & ResOpt_DoLaplace) { TxPrintf("Laplace solved: %d matched %d\n", - LaplaceMissCount,LaplaceMatchCount); + LaplaceMissCount, LaplaceMatchCount); } #endif @@ -492,11 +522,11 @@ typedef enum { return; #endif case RES_AMBIG: - TxPrintf("Ambiguous option: %s\n",cmd->tx_argv[1]); + TxPrintf("Ambiguous option: %s\n", cmd->tx_argv[1]); TxFlushOut(); return; case RES_BAD: - TxPrintf("Unknown option: %s\n",cmd->tx_argv[1]); + TxPrintf("Unknown option: %s\n", cmd->tx_argv[1]); TxFlushOut(); return; default: @@ -519,7 +549,7 @@ typedef enum { } ResOptionsFlags |= ResOpt_Signal; #ifdef ARIEL - ResOptionsFlags &= ~ResOpt_Power; + ResOptionsFlags &= ~ResOpt_Power; #endif resisdata.tolerance = tolerance; @@ -581,8 +611,6 @@ resSubcircuitFunc(cellDef, rdata) return 0; } - - /* *------------------------------------------------------------------------- * @@ -841,7 +869,7 @@ ResCheckSimNodes(celldef, resisdata) } if (ResOptionsFlags & ResOpt_DoLumpFile) { - ResLumpFile = PaOpen(outfile,"w",".res.lump",".",(char *) NULL, (char **) NULL); + ResLumpFile = PaOpen(outfile, "w", ".res.lump", ".", (char *)NULL, (char **)NULL); } else { @@ -850,7 +878,7 @@ ResCheckSimNodes(celldef, resisdata) if (ResOptionsFlags & ResOpt_FastHenry) { char *geofilename; - ResFHFile = PaOpen(outfile,"w",".fh",".",(char *) NULL, &geofilename); + ResFHFile = PaOpen(outfile, "w", ".fh", ".", (char *)NULL, &geofilename); TxPrintf("Writing FastHenry-format geometry file \"%s\"\n", geofilename); ResPortIndex = 0; } @@ -961,7 +989,7 @@ ResCheckSimNodes(celldef, resisdata) t1->drain != t2->source)) break; /* do parallel combination */ - if (cumRes != 0.0 && t2->resistance != 0.0) + if ((cumRes != 0.0) && (t2->resistance != 0.0)) { cumRes = (cumRes * t2->resistance) / (cumRes + t2->resistance); @@ -998,32 +1026,32 @@ ResCheckSimNodes(celldef, resisdata) gparams.rg_devloc = &node->drivepoint; gparams.rg_status |= DRIVEONLY; } - if (node->status & PORTNODE) + if (node->status & PORTNODE) { /* The node is a port, not a device, so make */ - /* sure rg_ttype is set accordingly. */ + /* sure rg_ttype is set accordingly. */ gparams.rg_ttype = node->rs_ttype; } } - if (gparams.rg_devloc == NULL && node->status & FORCE) + if ((gparams.rg_devloc == NULL) && (node->status & FORCE)) { TxError("Node %s has force label but no drive point or " "driving device\n",node->name); } - if (minRes == FLT_MAX || gparams.rg_devloc == NULL) + if ((minRes == FLT_MAX) || (gparams.rg_devloc == NULL)) { continue; } - gparams.rg_bigdevres = (int)minRes*OHMSTOMILLIOHMS; - if (rctol == 0.0 || tol == 0.0) + gparams.rg_bigdevres = (int)minRes * OHMSTOMILLIOHMS; + if ((rctol == 0.0) || (tol == 0.0)) { ftolerance = 0.0; rctolerance = 0.0; } else { - ftolerance = minRes/tol; - rctolerance = minRes/rctol; + ftolerance = minRes / tol; + rctolerance = minRes / rctol; } /* @@ -1031,19 +1059,16 @@ ResCheckSimNodes(celldef, resisdata) * resistance? If so, extract net. */ - if (node->resistance > ftolerance || node->status & FORCE || + if ((node->resistance > ftolerance) || (node->status & FORCE) || (ResOpt_ExtractAll & ResOptionsFlags)) { ResFixPoint fp; failed1++; - fp.fp_loc = node->location; - fp.fp_ttype = node->type; - fp.fp_next = NULL; - if (ResExtractNet(&fp, &gparams, outfile) != 0) + if (ResExtractNet(node, &gparams, outfile) != 0) { - TxError("Error in extracting node %s\n",node->name); - // break; // Don't stop for one error. . . + /* On error, don't output this net, but keep going */ + TxError("Error in extracting node %s\n", node->name); } else { @@ -1062,7 +1087,7 @@ ResCheckSimNodes(celldef, resisdata) } } #ifdef PARANOID - ResSanityChecks(node->name,ResResList,ResNodeList,ResDevList); + ResSanityChecks(node->name, ResResList, ResNodeList, ResDevList); #endif ResCleanUpEverything(); } @@ -1075,7 +1100,7 @@ ResCheckSimNodes(celldef, resisdata) if (ResOptionsFlags & ResOpt_DoExtFile) { - ResPrintExtDev(ResExtFile,ResRDevList); + ResPrintExtDev(ResExtFile, ResRDevList); } /* @@ -1182,7 +1207,7 @@ ResFixUpConnections(simDev, layoutDev, simNode, nodename) if (simDev->gate == simNode) { - if ((gate=layoutDev->rd_fet_gate) != NULL) + if ((gate = layoutDev->rd_fet_gate) != NULL) { /* Cosmetic addition: If the layout device already has a */ /* name, the new one won't be used, so we decrement resNodeNum */ @@ -1398,9 +1423,10 @@ void ResSortByGate(DevpointerList) devPtr **DevpointerList; { - int changed=TRUE; - int localchange=TRUE; - devPtr *working, *last=NULL, *current, *gatelist=NULL; + int changed = TRUE; + int localchange = TRUE; + devPtr *working, *current; + devPtr *last = NULL, *gatelist = NULL; working = *DevpointerList; while (working != NULL) @@ -1526,7 +1552,7 @@ ResWriteLumpFile(node) { lumpedres = gparams.rg_maxres; } - fprintf(ResLumpFile,"R %s %d\n", node->name, lumpedres); + fprintf(ResLumpFile, "R %s %d\n", node->name, lumpedres); } diff --git a/resis/ResSimple.c b/resis/ResSimple.c index 0011125d..698ba573 100644 --- a/resis/ResSimple.c +++ b/resis/ResSimple.c @@ -40,16 +40,14 @@ static char rcsid[] __attribute__ ((unused)) = "$Header: /usr/cvsroot/magic-8.0/ void ResSetPathRes(); void resPathNode(); void resPathRes(); -Heap ResistorHeap; -int resRemoveLoops = FALSE; +Heap ResistorHeap; +int resRemoveLoops = FALSE; /* Forward declarations */ extern void ResMoveDevices(); extern void ResAddResistorToList(); - - /* *------------------------------------------------------------------------- * @@ -65,318 +63,301 @@ extern void ResAddResistorToList(); */ void -ResSimplifyNet(nodelist,biglist,reslist,tolerance) - resNode **nodelist,**biglist; - resResistor **reslist; - float tolerance; +ResSimplifyNet(nodelist, biglist, reslist, tolerance) + resNode **nodelist, **biglist; + resResistor **reslist; + float tolerance; { - resElement *resisptr; - resNode *node,*otherNode,*node1,*node2; - resResistor *resistor1 = NULL,*resistor2 = NULL; - int numdrive = 0, numreceive = 0; - int MarkedReceivers,UnMarkedReceivers,NumberOfDrivers,PendingReceivers; + resElement *resisptr; + resNode *node, *otherNode, *node1, *node2; + resResistor *resistor1 = NULL, *resistor2 = NULL; + int numdrive = 0, numreceive = 0; + int MarkedReceivers, UnMarkedReceivers; + int NumberOfDrivers, PendingReceivers; - if (*nodelist == NULL) return; - node = *nodelist; - node->rn_status |= MARKED | FINISHED; - *nodelist = node->rn_more; - if (node->rn_more != NULL) - { - node->rn_more->rn_less = (resNode *) NULL; - } - node->rn_more = *biglist; - if (*biglist != (resNode *) NULL) - { - (*biglist)->rn_less = node; - } - *biglist = node; + if (*nodelist == NULL) return; + node = *nodelist; + node->rn_status |= MARKED | FINISHED; + *nodelist = node->rn_more; + if (node->rn_more != NULL) + node->rn_more->rn_less = (resNode *) NULL; - /* - Walk though resistors. Mark uninitialized ones and assign them - A direction. Keep track of the number of resistors pointing in - each direction. + node->rn_more = *biglist; + if (*biglist != (resNode *) NULL) + (*biglist)->rn_less = node; + + *biglist = node; + + /* + * Walk though resistors. Mark uninitialized ones and assign them + * a direction. Keep track of the number of resistors pointing in + * each direction. */ - for (resisptr = node->rn_re; resisptr != NULL; resisptr = resisptr->re_nextEl) - { + for (resisptr = node->rn_re; resisptr != NULL; resisptr = resisptr->re_nextEl) + { if (((resisptr->re_thisEl->rr_status & RES_MARKED) == RES_MARKED) && - (resisptr->re_thisEl->rr_connection2 == node)) + (resisptr->re_thisEl->rr_connection2 == node)) { - if (resistor1 == NULL) - { - resistor1 = resisptr->re_thisEl; - } - else - { - resistor2 = resisptr->re_thisEl; - } - numdrive++; + if (resistor1 == NULL) + resistor1 = resisptr->re_thisEl; + else + resistor2 = resisptr->re_thisEl; + + numdrive++; } else { - /* - Resistor direction is from node1 to node2. If the resistor - is not marked, mark it and make sure the direction is - set properly. + /* + * Resistor direction is from node1 to node2. If the resistor + * is not marked, mark it and make sure the direction is + * set properly. */ - if ((resisptr->re_thisEl->rr_status & RES_MARKED) != RES_MARKED) - { - if (resisptr->re_thisEl->rr_connection2 == node) - { - resisptr->re_thisEl->rr_connection2 = resisptr->re_thisEl->rr_connection1; - resisptr->re_thisEl->rr_connection1 = node; - } - resisptr->re_thisEl->rr_status |= RES_MARKED; - } - if (resistor1 == NULL) - { - resistor1 = resisptr->re_thisEl; - } - else - { - resistor2 = resisptr->re_thisEl; - } - numreceive++; - } - } + if ((resisptr->re_thisEl->rr_status & RES_MARKED) != RES_MARKED) + { + if (resisptr->re_thisEl->rr_connection2 == node) + { + resisptr->re_thisEl->rr_connection2 = + resisptr->re_thisEl->rr_connection1; + resisptr->re_thisEl->rr_connection1 = node; + } + resisptr->re_thisEl->rr_status |= RES_MARKED; + } + if (resistor1 == NULL) + resistor1 = resisptr->re_thisEl; + else + resistor2 = resisptr->re_thisEl; - /* - Is the node reached by one resistor? If it is, check the resistor's - other end. Check the number of drivers at the other end. If it is - more than 1, delete the current resistor to break the deadlock. + numreceive++; + } + } + + /* + * Is the node reached by one resistor? If it is, check the resistor's + * other end. Check the number of drivers at the other end. If it is + * more than 1, delete the current resistor to break the deadlock. */ - if (numreceive == 0 && numdrive == 1 && node->rn_why != RES_NODE_ORIGIN) - { + + if (numreceive == 0 && numdrive == 1 && node->rn_why != RES_NODE_ORIGIN) + { resistor1->rr_status |= RES_DEADEND; if (resistor1->rr_value < tolerance) { - otherNode = (resistor1->rr_connection1 == node) ? resistor1->rr_connection2 : resistor1->rr_connection1; - MarkedReceivers = 0; - UnMarkedReceivers = 0; - NumberOfDrivers = 0; - PendingReceivers = 0; - resistor2 = resistor1; - for (resisptr = otherNode->rn_re; resisptr != NULL; resisptr=resisptr->re_nextEl) - { - if (resisptr->re_thisEl->rr_connection1 == otherNode) - { - if ((resisptr->re_thisEl->rr_connection2->rn_status & MARKED) != MARKED) - { - PendingReceivers++; - } - if (resisptr->re_thisEl->rr_status & RES_DEADEND || - resisptr->re_thisEl->rr_value > tolerance) - { - MarkedReceivers++; - resistor2 = (resisptr->re_thisEl->rr_value >= resistor2->rr_value) ? resisptr->re_thisEl : resistor2; - } - else - { - UnMarkedReceivers++; - } - } - else - { - NumberOfDrivers++; - } - } - /* other recievers at far end? If so, reschedule other node; - deadlock will be settled from that node. + otherNode = (resistor1->rr_connection1 == node) ? + resistor1->rr_connection2 : resistor1->rr_connection1; + MarkedReceivers = 0; + UnMarkedReceivers = 0; + NumberOfDrivers = 0; + PendingReceivers = 0; + resistor2 = resistor1; + for (resisptr = otherNode->rn_re; resisptr != NULL; + resisptr = resisptr->re_nextEl) + { + if (resisptr->re_thisEl->rr_connection1 == otherNode) + { + if ((resisptr->re_thisEl->rr_connection2->rn_status & MARKED) + != MARKED) + { + PendingReceivers++; + } + if (resisptr->re_thisEl->rr_status & RES_DEADEND || + resisptr->re_thisEl->rr_value > tolerance) + { + MarkedReceivers++; + resistor2 = (resisptr->re_thisEl->rr_value >= + resistor2->rr_value) ? resisptr->re_thisEl : resistor2; + } + else + UnMarkedReceivers++; + } + else + NumberOfDrivers++; + } + /* other recievers at far end? If so, reschedule other node; + * deadlock will be settled from that node. */ - if ((MarkedReceivers+UnMarkedReceivers+NumberOfDrivers == 2) || - (UnMarkedReceivers == 0 && MarkedReceivers > 1 && resistor2 == resistor1 && PendingReceivers == 0)) - { - if (otherNode->rn_status & MARKED) - { - otherNode->rn_status &= ~MARKED; - ResRemoveFromQueue(otherNode,biglist); - otherNode->rn_less= NULL; - otherNode->rn_more = *nodelist; - if (*nodelist != NULL) - { - (*nodelist)->rn_less = otherNode; - } - *nodelist = otherNode; - } - return; - } + if ((MarkedReceivers+UnMarkedReceivers+NumberOfDrivers == 2) || + (UnMarkedReceivers == 0 && MarkedReceivers > 1 && + resistor2 == resistor1 && PendingReceivers == 0)) + { + if (otherNode->rn_status & MARKED) + { + otherNode->rn_status &= ~MARKED; + ResRemoveFromQueue(otherNode, biglist); + otherNode->rn_less = NULL; + otherNode->rn_more = *nodelist; + if (*nodelist != NULL) + (*nodelist)->rn_less = otherNode; - /* - Break loop here. More than one driver indicates a loop; - remove deadend, allowing drivers to be merged + *nodelist = otherNode; + } + return; + } + + /* + * Break loop here. More than one driver indicates a loop; + * remove deadend, allowing drivers to be merged */ - else if (UnMarkedReceivers == 0 && (MarkedReceivers == 1 && NumberOfDrivers > 1 || resistor2 != resistor1)) + else if (UnMarkedReceivers == 0 && (MarkedReceivers == 1 && + NumberOfDrivers > 1 || resistor2 != resistor1)) - { - otherNode->rn_float.rn_area += resistor1->rr_float.rr_area; - otherNode->rn_status &= ~RES_DONE_ONCE; - ResDeleteResPointer(resistor1->rr_connection1,resistor1); - ResDeleteResPointer(resistor1->rr_connection2,resistor1); - ResEliminateResistor(resistor1,reslist); - ResMergeNodes(otherNode,node,nodelist,biglist); - if (otherNode->rn_status & MARKED) - { - otherNode->rn_status &= ~MARKED; - ResRemoveFromQueue(otherNode,biglist); - otherNode->rn_less= NULL; - otherNode->rn_more = *nodelist; - if (*nodelist != NULL) - { - (*nodelist)->rn_less = otherNode; - } - *nodelist = otherNode; - } - ResDoneWithNode(otherNode); - } + { + otherNode->rn_float.rn_area += resistor1->rr_float.rr_area; + otherNode->rn_status &= ~RES_DONE_ONCE; + ResDeleteResPointer(resistor1->rr_connection1, resistor1); + ResDeleteResPointer(resistor1->rr_connection2, resistor1); + ResEliminateResistor(resistor1, reslist); + ResMergeNodes(otherNode, node, nodelist, biglist); + if (otherNode->rn_status & MARKED) + { + otherNode->rn_status &= ~MARKED; + ResRemoveFromQueue(otherNode, biglist); + otherNode->rn_less= NULL; + otherNode->rn_more = *nodelist; + if (*nodelist != NULL) + (*nodelist)->rn_less = otherNode; + + *nodelist = otherNode; + } + ResDoneWithNode(otherNode); + } } - - } - /* - Two resistors in series? Combine them and move devices to - appropriate end. + } + /* + * Two resistors in series? Combine them and move devices to + * appropriate end. */ - else if (numdrive+numreceive == 2 && - (resistor1->rr_value < tolerance && resistor2->rr_value < tolerance)) - { - if ((resistor1->rr_status & RES_MARKED) == 0 && (resistor1->rr_connection2 == node)) - { - resistor1->rr_connection2 = resistor1->rr_connection1; - resistor1->rr_connection1 = node; - } - resistor1->rr_status |= RES_MARKED; - if ((resistor2->rr_status & RES_MARKED) == 0 && (resistor2->rr_connection2 == node)) - { - resistor2->rr_connection2 = resistor2->rr_connection1; - resistor2->rr_connection1 = node; - } - resistor2->rr_status |= RES_MARKED; - node1 = (resistor1->rr_connection1 == node) ? resistor1->rr_connection2 : resistor1->rr_connection1; - node2 = (resistor2->rr_connection1 == node) ? resistor2->rr_connection2 : resistor2->rr_connection1; - otherNode = (resistor1->rr_status & RES_DEADEND && + else if (numdrive+numreceive == 2 && (resistor1->rr_value < tolerance && + resistor2->rr_value < tolerance)) + { + if ((resistor1->rr_status & RES_MARKED) == 0 && + (resistor1->rr_connection2 == node)) + { + resistor1->rr_connection2 = resistor1->rr_connection1; + resistor1->rr_connection1 = node; + } + resistor1->rr_status |= RES_MARKED; + if ((resistor2->rr_status & RES_MARKED) == 0 && + (resistor2->rr_connection2 == node)) + { + resistor2->rr_connection2 = resistor2->rr_connection1; + resistor2->rr_connection1 = node; + } + resistor2->rr_status |= RES_MARKED; + node1 = (resistor1->rr_connection1 == node) ? resistor1->rr_connection2 : + resistor1->rr_connection1; + node2 = (resistor2->rr_connection1 == node) ? resistor2->rr_connection2 : + resistor2->rr_connection1; + otherNode = (resistor1->rr_status & RES_DEADEND && resistor1->rr_value < tolerance / 2) || ((resistor2->rr_status & RES_DEADEND) == 0 && resistor1->rr_value < resistor2->rr_value) ? node1 : node2; + /* + * Make one big resistor out of two little ones, eliminating + * the current node. Devices connected to this node are + * moved to either end depending on their resistance. + */ + ResMoveDevices(node,otherNode); + otherNode->rn_noderes = MIN(node->rn_noderes, otherNode->rn_noderes); + node2->rn_float.rn_area += resistor1->rr_value * node->rn_float.rn_area / + (resistor1->rr_value + resistor2->rr_value); + node1->rn_float.rn_area += resistor2->rr_value * node->rn_float.rn_area / + (resistor1->rr_value + resistor2->rr_value); + resistor1->rr_value += resistor2->rr_value; + resistor1->rr_float.rr_area +=resistor2->rr_float.rr_area; + if (resistor1 == *reslist) + *reslist = resistor1->rr_nextResistor; + else + resistor1->rr_lastResistor->rr_nextResistor = resistor1->rr_nextResistor; - /* - make one big resistor out of two little ones, eliminating - the current node. Devices connected to this node are - moved to either end depending on their resistance. - */ - ResMoveDevices(node,otherNode); - otherNode->rn_noderes = MIN(node->rn_noderes,otherNode->rn_noderes); - node2->rn_float.rn_area += resistor1->rr_value*node->rn_float.rn_area/(resistor1->rr_value+resistor2->rr_value); - node1->rn_float.rn_area += resistor2->rr_value*node->rn_float.rn_area/(resistor1->rr_value+resistor2->rr_value); - resistor1->rr_value += resistor2->rr_value; - resistor1->rr_float.rr_area +=resistor2->rr_float.rr_area; - if (resistor1 == *reslist) - { - *reslist = resistor1->rr_nextResistor; - } - else - { - resistor1->rr_lastResistor->rr_nextResistor = resistor1->rr_nextResistor; - } - if (resistor1->rr_nextResistor != NULL) - { - resistor1->rr_nextResistor->rr_lastResistor = resistor1->rr_lastResistor; - } - ResAddResistorToList(resistor1,reslist); - ResDeleteResPointer(node,resistor1); - ResDeleteResPointer(node,resistor2); - ResDeleteResPointer(node2,resistor2); - if (resistor1->rr_connection1 == node) - { - resistor1->rr_connection1 = node2; - } - else - { - resistor1->rr_connection2 = node2; - } - resisptr = (resElement *) mallocMagic((unsigned)(sizeof(resElement))); - resisptr->re_thisEl = resistor1; - resisptr->re_nextEl = node2->rn_re; - node2->rn_re = resisptr; - ResEliminateResistor(resistor2,reslist); - otherNode->rn_status |= (node->rn_status & RN_MAXTDI); - ResCleanNode(node,TRUE,biglist,nodelist); - node1->rn_status &= ~RES_DONE_ONCE; - if (node1->rn_status & MARKED) - { - node1->rn_status &= ~MARKED; - ResRemoveFromQueue(node1,biglist); - node1->rn_less= NULL; - node1->rn_more = *nodelist; - if (*nodelist != NULL) - { - (*nodelist)->rn_less = node1; - } - *nodelist = node1; - } - node2->rn_status &= ~RES_DONE_ONCE; - if (node2->rn_status & MARKED) - { - node2->rn_status &= ~MARKED; - ResRemoveFromQueue(node2,biglist); - node2->rn_less= NULL; - node2->rn_more = *nodelist; - if (*nodelist != NULL) - { - (*nodelist)->rn_less = node2; - } - *nodelist = node2; - } - ResDoneWithNode(node1); - } + if (resistor1->rr_nextResistor != NULL) + resistor1->rr_nextResistor->rr_lastResistor = resistor1->rr_lastResistor; - /* - Last resort- keep propagating down the tree. To avoid looping, - mark each node when it is reached. Don't reschedule node if - none of the connections to it have changed since it was marked + ResAddResistorToList(resistor1, reslist); + ResDeleteResPointer(node, resistor1); + ResDeleteResPointer(node, resistor2); + ResDeleteResPointer(node2, resistor2); + if (resistor1->rr_connection1 == node) + resistor1->rr_connection1 = node2; + else + resistor1->rr_connection2 = node2; + + resisptr = (resElement *)mallocMagic((unsigned)(sizeof(resElement))); + resisptr->re_thisEl = resistor1; + resisptr->re_nextEl = node2->rn_re; + node2->rn_re = resisptr; + ResEliminateResistor(resistor2, reslist); + otherNode->rn_status |= (node->rn_status & RN_MAXTDI); + ResCleanNode(node, TRUE, biglist, nodelist); + node1->rn_status &= ~RES_DONE_ONCE; + if (node1->rn_status & MARKED) + { + node1->rn_status &= ~MARKED; + ResRemoveFromQueue(node1, biglist); + node1->rn_less = NULL; + node1->rn_more = *nodelist; + if (*nodelist != NULL) + (*nodelist)->rn_less = node1; + *nodelist = node1; + } + node2->rn_status &= ~RES_DONE_ONCE; + if (node2->rn_status & MARKED) + { + node2->rn_status &= ~MARKED; + ResRemoveFromQueue(node2, biglist); + node2->rn_less = NULL; + node2->rn_more = *nodelist; + if (*nodelist != NULL) + (*nodelist)->rn_less = node2; + *nodelist = node2; + } + ResDoneWithNode(node1); + } + + /* + * Last resort- keep propagating down the tree. To avoid looping, + * mark each node when it is reached. Don't reschedule node if + * none of the connections to it have changed since it was marked */ - else if (numreceive > 0 && (node->rn_status & RES_DONE_ONCE) == 0) - { - node->rn_status |= RES_DONE_ONCE; - for (resisptr = node->rn_re; resisptr != NULL; resisptr = resisptr->re_nextEl) - { - if (resisptr->re_thisEl->rr_connection1 == node) + else if (numreceive > 0 && (node->rn_status & RES_DONE_ONCE) == 0) + { + node->rn_status |= RES_DONE_ONCE; + for (resisptr = node->rn_re; resisptr != NULL; resisptr = resisptr->re_nextEl) + { + if (resisptr->re_thisEl->rr_connection1 == node) + { + /* + * Elements with a resistance greater than the + * tolerance should only be propagated past once- + * loops may occur otherwise. + */ + if (resisptr->re_thisEl->rr_status & RES_DONE_ONCE) + continue; + + if (resisptr->re_thisEl->rr_connection2->rn_status & MARKED) { - /* - elements with a resistance greater than the - tolerance should only be propagated past once- - loops may occur otherwise. - */ - if (resisptr->re_thisEl->rr_status & RES_DONE_ONCE) - { - continue; - } - if (resisptr->re_thisEl->rr_connection2->rn_status & MARKED) - { - /* - mark big resistors so we only process them - once. - */ - if (resisptr->re_thisEl->rr_value > tolerance) - { - resisptr->re_thisEl->rr_status |= RES_DONE_ONCE; - } - resisptr->re_thisEl->rr_connection2->rn_status &= ~MARKED; - ResRemoveFromQueue(resisptr->re_thisEl->rr_connection2,biglist); - resisptr->re_thisEl->rr_connection2->rn_less= NULL; - resisptr->re_thisEl->rr_connection2->rn_more = *nodelist; - if (*nodelist != NULL) - { - (*nodelist)->rn_less = resisptr->re_thisEl->rr_connection2; - } - *nodelist = resisptr->re_thisEl->rr_connection2; - } + /* + * Mark big resistors so we only process them + * once. + */ + if (resisptr->re_thisEl->rr_value > tolerance) + resisptr->re_thisEl->rr_status |= RES_DONE_ONCE; + + resisptr->re_thisEl->rr_connection2->rn_status &= ~MARKED; + ResRemoveFromQueue(resisptr->re_thisEl->rr_connection2, biglist); + resisptr->re_thisEl->rr_connection2->rn_less= NULL; + resisptr->re_thisEl->rr_connection2->rn_more = *nodelist; + if (*nodelist != NULL) + (*nodelist)->rn_less = resisptr->re_thisEl->rr_connection2; + + *nodelist = resisptr->re_thisEl->rr_connection2; } - } - } + } + } + } } - - /* *------------------------------------------------------------------------- * @@ -390,56 +371,44 @@ ResSimplifyNet(nodelist,biglist,reslist,tolerance) */ void -ResMoveDevices(node1,node2) - resNode *node1,*node2; +ResMoveDevices(node1, node2) + resNode *node1, *node2; { - tElement *devptr,*oldptr; - resDevice *device; + tElement *devptr, *oldptr; + resDevice *device; - devptr = node1->rn_te; - while (devptr != NULL) - { - device = devptr->te_thist; - oldptr = devptr; - devptr = devptr->te_nextt; - if (device->rd_status & RES_DEV_PLUG) - { - if (((ResPlug *)(device))->rpl_node == node1) - { - ((ResPlug *)(device))->rpl_node = node2; - } - else - { - TxError("Bad node connection in plug\n"); - } - } - else - { - if (device->rd_fet_gate == node1) - { - device->rd_fet_gate = node2; - } - else if (device->rd_fet_source == node1) - { - device->rd_fet_source = node2; - } - else if (device->rd_fet_drain == node1) - { - device->rd_fet_drain = node2; - } - else - { - TxError("Missing Device connection in squish routines at %d, %d\n",node1->rn_loc.p_x,node1->rn_loc.p_y); - } - } - oldptr->te_nextt = node2->rn_te; - node2->rn_te = oldptr; - } - node1->rn_te = NULL; + devptr = node1->rn_te; + while (devptr != NULL) + { + device = devptr->te_thist; + oldptr = devptr; + devptr = devptr->te_nextt; + if (device->rd_status & RES_DEV_PLUG) + { + if (((ResPlug *)(device))->rpl_node == node1) + ((ResPlug *)(device))->rpl_node = node2; + else + TxError("Bad node connection in plug\n"); + } + else + { + if (device->rd_fet_gate == node1) + device->rd_fet_gate = node2; + else if (device->rd_fet_source == node1) + device->rd_fet_source = node2; + else if (device->rd_fet_drain == node1) + device->rd_fet_drain = node2; + else + TxError("Missing Device connection in squish routines" + " at %d, %d\n", node1->rn_loc.p_x, node1->rn_loc.p_y); + } + oldptr->te_nextt = node2->rn_te; + node2->rn_te = oldptr; + } + node1->rn_te = NULL; } - /* *------------------------------------------------------------------------- * @@ -457,146 +426,137 @@ ResMoveDevices(node1,node2) */ void -ResScrunchNet(reslist,pendingList,biglist,tolerance) - resResistor **reslist; - resNode **pendingList,**biglist; - float tolerance; +ResScrunchNet(reslist, pendingList, biglist, tolerance) + resResistor **reslist; + resNode **pendingList, **biglist; + float tolerance; { - resResistor *locallist=NULL,*current,*working; - resNode *node1,*node2; - resElement *rcell1; - int c1,c2; + resResistor *locallist = NULL, *current, *working; + resNode *node1, *node2; + resElement *rcell1; + int c1, c2; - /* sort resistors by size */ - current = *reslist; - while (current != NULL) - { - working = current; - current = current->rr_nextResistor; - if (working == *reslist) - { - *reslist = current; - } - else - { - working->rr_lastResistor->rr_nextResistor = current; - } - if (current != NULL) - { - current->rr_lastResistor = working->rr_lastResistor; - } - ResAddResistorToList(working,&locallist); - } + /* Sort resistors by size */ + current = *reslist; + while (current != NULL) + { + working = current; + current = current->rr_nextResistor; + if (working == *reslist) + *reslist = current; + else + working->rr_lastResistor->rr_nextResistor = current; + if (current != NULL) + current->rr_lastResistor = working->rr_lastResistor; - *reslist = locallist; - while (*reslist != NULL && (*reslist)->rr_value < tolerance) - { - current = *reslist; - if (current->rr_nextResistor == NULL) - { - break; - } - working = NULL; - c1=0; - c2=0; + ResAddResistorToList(working, &locallist); + } - /* search for next smallest adjoining resistor */ - for (rcell1 = current->rr_connection1->rn_re; rcell1 != NULL; rcell1 = rcell1->re_nextEl) - { - if (rcell1->re_thisEl != current) - { - c1++; - if (working == NULL) + *reslist = locallist; + while (*reslist != NULL && (*reslist)->rr_value < tolerance) + { + current = *reslist; + if (current->rr_nextResistor == NULL) + break; + + working = NULL; + c1 = 0; + c2 = 0; + + /* Search for next smallest adjoining resistor */ + for (rcell1 = current->rr_connection1->rn_re; rcell1 != NULL; + rcell1 = rcell1->re_nextEl) + { + if (rcell1->re_thisEl != current) + { + c1++; + if (working == NULL) + { + working = rcell1->re_thisEl; + node1 = current->rr_connection1; + } + else + { + if (working->rr_value > rcell1->re_thisEl->rr_value) { - working = rcell1->re_thisEl; - node1 = current->rr_connection1; + node1 = current->rr_connection1; + working = rcell1->re_thisEl; } - else + } + } + } + for (rcell1 = current->rr_connection2->rn_re; rcell1 != NULL; + rcell1 = rcell1->re_nextEl) + { + if (rcell1->re_thisEl != current) + { + c2++; + if (working == NULL) + { + working = rcell1->re_thisEl; + node1 = current->rr_connection2; + } + else + { + if (working->rr_value > rcell1->re_thisEl->rr_value) { - if (working->rr_value > rcell1->re_thisEl->rr_value) - { - node1 = current->rr_connection1; - working = rcell1->re_thisEl; - } - } - } - } - for (rcell1 = current->rr_connection2->rn_re; rcell1 != NULL; rcell1 = rcell1->re_nextEl) - { - if (rcell1->re_thisEl != current) - { - c2++; - if (working == NULL) - { - working = rcell1->re_thisEl; - node1 = current->rr_connection2; - } - else - { - if (working->rr_value > rcell1->re_thisEl->rr_value) - { - node1 = current->rr_connection2; - working = rcell1->re_thisEl; - } - } - } - } - /* - if the current resistor isn't a deadend, add its value and - area to that of the next smallest one. If it is a deadend, - simply add its area to its node. - */ - if (c1 != 0 && c2 != 0) - { - working->rr_value += current->rr_value; - working->rr_float.rr_area += current->rr_float.rr_area; - } - else - { - node1->rn_float.rn_area += current->rr_float.rr_area; - } - /* - Move everything from from one end of the ressistor to the - other and eliminate the resistor. - */ - node2 = (current->rr_connection1 == node1) ? current->rr_connection2 : current->rr_connection1; - ResDeleteResPointer(current->rr_connection1,current); - ResDeleteResPointer(current->rr_connection2,current); - working->rr_lastResistor->rr_nextResistor = working->rr_nextResistor; - if (working->rr_nextResistor != NULL) - { - working->rr_nextResistor->rr_lastResistor = working->rr_lastResistor; - } - ResEliminateResistor(current,reslist); - ResAddResistorToList(working,reslist); - if (node2->rn_why & RES_NODE_ORIGIN) - { - ResMergeNodes(node2,node1,pendingList,biglist); - node1 = node2; - } - else - { - ResMergeNodes(node1,node2,pendingList,biglist); - } + node1 = current->rr_connection2; + working = rcell1->re_thisEl; + } + } + } + } + /* + * If the current resistor isn't a deadend, add its value and + * area to that of the next smallest one. If it is a deadend, + * simply add its area to its node. + */ + if (c1 != 0 && c2 != 0) + { + working->rr_value += current->rr_value; + working->rr_float.rr_area += current->rr_float.rr_area; + } + else + { + node1->rn_float.rn_area += current->rr_float.rr_area; + } + /* + * Move everything from from one end of the ressistor to the + * other and eliminate the resistor. + */ + node2 = (current->rr_connection1 == node1) ? current->rr_connection2 : + current->rr_connection1; + ResDeleteResPointer(current->rr_connection1, current); + ResDeleteResPointer(current->rr_connection2, current); + working->rr_lastResistor->rr_nextResistor = working->rr_nextResistor; + if (working->rr_nextResistor != NULL) + working->rr_nextResistor->rr_lastResistor = working->rr_lastResistor; - /* - Try further simplification on net using ResDoneWithNode and - ResSimplifyNet. - */ - ResRemoveFromQueue(node1,biglist); - ResAddToQueue(node1,pendingList); - node1->rn_status &= ~(RES_DONE_ONCE | FINISHED); - ResDoneWithNode(node1); - while (*pendingList != NULL) - { - ResSimplifyNet(pendingList,biglist,reslist,tolerance); - } - } + ResEliminateResistor(current, reslist); + ResAddResistorToList(working, reslist); + if (node2->rn_why & RES_NODE_ORIGIN) + { + ResMergeNodes(node2, node1, pendingList, biglist); + node1 = node2; + } + else + ResMergeNodes(node1,node2,pendingList,biglist); + + /* + * Try further simplification on net using ResDoneWithNode and + * ResSimplifyNet. + */ + ResRemoveFromQueue(node1, biglist); + ResAddToQueue(node1, pendingList); + node1->rn_status &= ~(RES_DONE_ONCE | FINISHED); + ResDoneWithNode(node1); + while (*pendingList != NULL) + ResSimplifyNet(pendingList,biglist,reslist,tolerance); + } } - /* *------------------------------------------------------------------------- * @@ -611,52 +571,46 @@ ResScrunchNet(reslist,pendingList,biglist,tolerance) */ void -ResAddResistorToList(resistor,locallist) - resResistor *resistor,**locallist; +ResAddResistorToList(resistor, locallist) + resResistor *resistor, **locallist; { - resResistor *local,*last=NULL; + resResistor *local,*last=NULL; - for (local = *locallist; local != NULL; local = local->rr_nextResistor) - { - if (local->rr_value >= resistor->rr_value) - { - break; - } - last = local; - } - if (local != NULL) - { - resistor->rr_nextResistor = local; - resistor->rr_lastResistor = local->rr_lastResistor; - if (local->rr_lastResistor == NULL) - { - *locallist = resistor; - } - else - { - local->rr_lastResistor->rr_nextResistor = resistor; - } - local->rr_lastResistor = resistor; + for (local = *locallist; local != NULL; local = local->rr_nextResistor) + { + if (local->rr_value >= resistor->rr_value) + break; + last = local; + } + if (local != NULL) + { + resistor->rr_nextResistor = local; + resistor->rr_lastResistor = local->rr_lastResistor; + if (local->rr_lastResistor == NULL) + *locallist = resistor; + else + local->rr_lastResistor->rr_nextResistor = resistor; + + local->rr_lastResistor = resistor; } else { - if (last != NULL) - { - last->rr_nextResistor = resistor; - resistor->rr_lastResistor = last; - resistor->rr_nextResistor = NULL; - } - else - { - resistor->rr_nextResistor = NULL; - resistor->rr_lastResistor = NULL; - *locallist = resistor; + if (last != NULL) + { + last->rr_nextResistor = resistor; + resistor->rr_lastResistor = last; + resistor->rr_nextResistor = NULL; + } + else + { + resistor->rr_nextResistor = NULL; + resistor->rr_lastResistor = NULL; + *locallist = resistor; } } } - /* *------------------------------------------------------------------------- * @@ -673,40 +627,34 @@ ResAddResistorToList(resistor,locallist) */ void -ResDistributeCapacitance(nodelist,totalcap) - resNode *nodelist; - float totalcap; +ResDistributeCapacitance(nodelist, totalcap) + resNode *nodelist; + float totalcap; { - float totalarea=0,capperarea; - resNode *workingNode; - resElement *rptr; + float totalarea = 0, capperarea; + resNode *workingNode; + resElement *rptr; - for (workingNode = nodelist; workingNode != NULL; workingNode=workingNode->rn_more) - { - for (rptr = workingNode->rn_re; rptr != NULL; rptr=rptr->re_nextEl) - { - if (rptr->re_thisEl->rr_float.rr_area != 0.0) - { - TxError("Nonnull resistor area\n"); - } -/* workingNode->rn_float.rn_area += rptr->re_thisEl->rr_float.rr_area/2; */ - } - totalarea += workingNode->rn_float.rn_area; - } - if (totalarea == 0) - { - TxError("Error: Node with no area.\n"); - return; - } - capperarea = FEMTOTOATTO*totalcap/totalarea; - for (workingNode = nodelist; workingNode != NULL; workingNode=workingNode->rn_more) - { - workingNode->rn_float.rn_area *= capperarea; - } + for (workingNode = nodelist; workingNode != NULL; workingNode = workingNode->rn_more) + { + for (rptr = workingNode->rn_re; rptr != NULL; rptr=rptr->re_nextEl) + if (rptr->re_thisEl->rr_float.rr_area != 0.0) + TxError("Nonnull resistor area\n"); + + totalarea += workingNode->rn_float.rn_area; + } + if (totalarea == 0) + { + TxError("Error: Node with no area.\n"); + return; + } + capperarea = FEMTOTOATTO * totalcap / totalarea; + + for (workingNode = nodelist; workingNode != NULL; workingNode=workingNode->rn_more) + workingNode->rn_float.rn_area *= capperarea; } - /* *------------------------------------------------------------------------- * @@ -723,74 +671,69 @@ ResDistributeCapacitance(nodelist,totalcap) float ResCalculateChildCapacitance(me) - resNode *me; + resNode *me; { - RCDelayStuff *myC; - resElement *workingRes; - resDevice *dev; - float childcap; - tElement *tptr; - int t; - ExtDevice *devptr; + RCDelayStuff *myC; + resElement *workingRes; + resDevice *dev; + float childcap; + tElement *tptr; + int t; + ExtDevice *devptr; + if (me->rn_client != (ClientData) NULL) /* we have a loop */ + return(-1); - if (me->rn_client != (ClientData) NULL) /* we have a loop */ - { - return(-1); - } - myC = (RCDelayStuff *) mallocMagic((unsigned) (sizeof(RCDelayStuff))); - me->rn_client = (ClientData) myC; + myC = (RCDelayStuff *) mallocMagic((unsigned) (sizeof(RCDelayStuff))); + me->rn_client = (ClientData) myC; - /* This following assumes that ResDistributeCapacitance has been run */ - /* and the the resulting capacitance value is stored in the area field */ - myC->rc_Cdownstream = me->rn_float.rn_area; + /* This following assumes that ResDistributeCapacitance has been run */ + /* and the the resulting capacitance value is stored in the area field */ + myC->rc_Cdownstream = me->rn_float.rn_area; + myC->rc_Tdi = 0.0; - /* get capacitance for all connected gates */ - for (tptr = me->rn_te; tptr != NULL; tptr = tptr->te_nextt) - { - dev = tptr->te_thist; - /* Hack for non-Manhattan geometry. Only one side of a split */ - /* tile should correspond to a device type. */ - if (IsSplit(dev->rd_tile)) - { - t = TiGetLeftType(dev->rd_tile); - if (ExtCurStyle->exts_device[t] == NULL) - t = TiGetRightType(dev->rd_tile); - } - else - t = TiGetType(dev->rd_tile); - if (dev->rd_fet_gate == me) - { - devptr = ExtCurStyle->exts_device[t]; - myC->rc_Cdownstream += - dev->rd_length* - dev->rd_width* - devptr->exts_deviceGateCap+ - (dev->rd_width+dev->rd_width)* + /* get capacitance for all connected gates */ + for (tptr = me->rn_te; tptr != NULL; tptr = tptr->te_nextt) + { + dev = tptr->te_thist; + /* Hack for non-Manhattan geometry. Only one side of a split */ + /* tile should correspond to a device type. */ + if (IsSplit(dev->rd_tile)) + { + t = TiGetLeftType(dev->rd_tile); + if (ExtCurStyle->exts_device[t] == NULL) + t = TiGetRightType(dev->rd_tile); + } + else + t = TiGetType(dev->rd_tile); + if (dev->rd_fet_gate == me) + { + devptr = ExtCurStyle->exts_device[t]; + myC->rc_Cdownstream += dev->rd_length * dev->rd_width * + devptr->exts_deviceGateCap + + (dev->rd_width + dev->rd_width) * devptr->exts_deviceSDCap; - } - } + } + } - /* Calculate child Capacitance */ - for (workingRes = me->rn_re; workingRes != NULL; workingRes=workingRes->re_nextEl) - { - if (workingRes->re_thisEl->rr_connection1 == me && - (workingRes->re_thisEl->rr_status & RES_TDI_IGNORE) == 0) - { - childcap = ResCalculateChildCapacitance(workingRes->re_thisEl->rr_connection2); - if (childcap == -1) - { - return(-1); - } - myC->rc_Cdownstream +=childcap; - } - } - return(myC->rc_Cdownstream); + /* Calculate child Capacitance */ + for (workingRes = me->rn_re; workingRes != NULL; workingRes=workingRes->re_nextEl) + { + if (workingRes->re_thisEl->rr_connection1 == me && + (workingRes->re_thisEl->rr_status & RES_TDI_IGNORE) == 0) + { + childcap = ResCalculateChildCapacitance(workingRes->re_thisEl->rr_connection2); + if (childcap == -1) + return(-1); + + myC->rc_Cdownstream += childcap; + } + } + return (myC->rc_Cdownstream); } - /* *------------------------------------------------------------------------- * @@ -805,40 +748,35 @@ ResCalculateChildCapacitance(me) */ void -ResCalculateTDi(node,resistor,resistorvalue) - resNode *node; - resResistor *resistor; - int resistorvalue; +ResCalculateTDi(node, resistor, resistorvalue) + resNode *node; + resResistor *resistor; + int resistorvalue; { - resElement *workingRes; - RCDelayStuff *rcd = (RCDelayStuff *)node->rn_client; - RCDelayStuff *rcd2; + resElement *workingRes; + RCDelayStuff *rcd = (RCDelayStuff *)node->rn_client; + RCDelayStuff *rcd2; - ASSERT(rcd != NULL,"ResCalculateTdi"); - if (resistor == NULL) - { - rcd->rc_Tdi = rcd->rc_Cdownstream*(float)resistorvalue; - } - else - { - rcd2 = (RCDelayStuff *)resistor->rr_connection1->rn_client; - ASSERT(rcd2 != NULL,"ResCalculateTdi"); - rcd->rc_Tdi=rcd->rc_Cdownstream*(float)resistor->rr_value + - rcd2->rc_Tdi; + ASSERT(rcd != NULL, "ResCalculateTdi"); + if (resistor == NULL) + rcd->rc_Tdi = rcd->rc_Cdownstream*(float)resistorvalue; + else + { + rcd2 = (RCDelayStuff *)resistor->rr_connection1->rn_client; + ASSERT(rcd2 != NULL,"ResCalculateTdi"); + rcd->rc_Tdi = rcd->rc_Cdownstream * (float)resistor->rr_value + + rcd2->rc_Tdi; + } - } - - for (workingRes = node->rn_re; workingRes != NULL; workingRes=workingRes->re_nextEl) - { - if (workingRes->re_thisEl->rr_connection1 == node && - (workingRes->re_thisEl->rr_status & RES_TDI_IGNORE) == 0) - { - ResCalculateTDi(workingRes->re_thisEl->rr_connection2, - workingRes->re_thisEl, - workingRes->re_thisEl->rr_value); - } - } + for (workingRes = node->rn_re; workingRes != NULL; workingRes = workingRes->re_nextEl) + { + if (workingRes->re_thisEl->rr_connection1 == node && + (workingRes->re_thisEl->rr_status & RES_TDI_IGNORE) == 0) + ResCalculateTDi(workingRes->re_thisEl->rr_connection2, + workingRes->re_thisEl, + workingRes->re_thisEl->rr_value); + } } /* @@ -856,71 +794,77 @@ ResCalculateTDi(node,resistor,resistorvalue) */ void -ResPruneTree(node,minTdi,nodelist1,nodelist2,resistorlist) - resNode *node,**nodelist1,**nodelist2; - float minTdi; - resResistor **resistorlist; +ResPruneTree(node, minTdi, nodelist1, nodelist2, resistorlist) + resNode *node, **nodelist1, **nodelist2; + float minTdi; + resResistor **resistorlist; { - resResistor *currentRes; - resElement *current; + resResistor *currentRes; + resElement *current; - current = node->rn_re; - while(current != NULL) - { - currentRes = current->re_thisEl; - current = current->re_nextEl; - /* if branch points outward, call routine on subtrees */ - if (currentRes->rr_connection1 == node) - { - ResPruneTree(currentRes->rr_connection2, minTdi,nodelist1,nodelist2,resistorlist); - } - } - /* We eliminate this branch if */ - /* 1. It is a terminal node, i.e. it is the connected */ - /* to only one resistor. */ - /* 2. The direction of this resistor is toward the node */ - /* (This prevents the root from being eliminated */ - /* 3. The time constant TDI is less than the tolerance. */ - if (node->rn_re != NULL && - node->rn_re->re_nextEl == NULL && - node->rn_re->re_thisEl->rr_connection2 == node) - { - if (node->rn_client == (ClientData)NULL) - { - TxError("Internal Error in Tree Pruning: Missing TDi value.\n"); - } - else if (((RCDelayStuff *)(node->rn_client))->rc_Tdi < minTdi) - { - currentRes = node->rn_re->re_thisEl; - ResDeleteResPointer(currentRes->rr_connection1,currentRes); - ResDeleteResPointer(currentRes->rr_connection2,currentRes); - ResMergeNodes(currentRes->rr_connection1,currentRes->rr_connection2,nodelist2,nodelist1); /* Patched 7/5/94 */ - ResEliminateResistor(currentRes,resistorlist); - } - } + current = node->rn_re; + while(current != NULL) + { + currentRes = current->re_thisEl; + current = current->re_nextEl; + /* if branch points outward, call routine on subtrees */ + if (currentRes->rr_connection1 == node) + ResPruneTree(currentRes->rr_connection2, minTdi, nodelist1, + nodelist2, resistorlist); + } + + /* We eliminate this branch if: + * 1. It is a terminal node, i.e. it is the connected + * to only one resistor. + * 2. The direction of this resistor is toward the node + * (This prevents the root from being eliminated + * 3. The time constant TDI is less than the tolerance. + */ + + if (node->rn_re != NULL && + node->rn_re->re_nextEl == NULL && + node->rn_re->re_thisEl->rr_connection2 == node) + { + if (node->rn_client == (ClientData)NULL) + { + TxError("Internal Error in Tree Pruning: Missing TDi value.\n"); + } + else if (((RCDelayStuff *)(node->rn_client))->rc_Tdi < minTdi) + { + currentRes = node->rn_re->re_thisEl; + ResDeleteResPointer(currentRes->rr_connection1, currentRes); + ResDeleteResPointer(currentRes->rr_connection2, currentRes); + ResMergeNodes(currentRes->rr_connection1, currentRes->rr_connection2, + nodelist2, nodelist1); + ResEliminateResistor(currentRes, resistorlist); + } + } } +/* + *------------------------------------------------------------------------- + * + *------------------------------------------------------------------------- + */ + int -ResDoSimplify(tolerance,rctol,goodies) - float tolerance; - float rctol; - ResGlobalParams *goodies; +ResDoSimplify(tolerance, rctol, goodies) + float tolerance; + float rctol; + ResGlobalParams *goodies; { - resNode *node,*slownode; + resNode *node, *slownode; float bigres = 0; float millitolerance; float totalcap; resResistor *res; - resRemoveLoops = FALSE; ResSetPathRes(); for (node = ResNodeList; node != NULL; node = node->rn_more) - { bigres = MAX(bigres,node->rn_noderes); - } bigres /= OHMSTOMILLIOHMS; /* convert from milliohms to ohms */ goodies->rg_maxres = bigres; @@ -936,238 +880,237 @@ ResDoSimplify(tolerance,rctol,goodies) (void) ResDistributeCapacitance(ResNodeList,goodies->rg_nodecap); - if ((tolerance > bigres || (ResOptionsFlags &ResOpt_Simplify)==0) && - (ResOptionsFlags &ResOpt_DoLumpFile)==0) - { - return(0); - } + if (((tolerance > bigres) || ((ResOptionsFlags & ResOpt_Simplify) == 0)) && + ((ResOptionsFlags & ResOpt_DoLumpFile) == 0)) + return 0; + res = ResResList; while (res) { - resResistor *oldres = res; + resResistor *oldres = res; - res = res->rr_nextResistor; - oldres->rr_status &= ~RES_HEAP; - if (oldres->rr_status & RES_TDI_IGNORE) - { - ResDeleteResPointer(oldres->rr_node[0],oldres); - ResDeleteResPointer(oldres->rr_node[1],oldres); - ResEliminateResistor(oldres,&ResResList); - } + res = res->rr_nextResistor; + oldres->rr_status &= ~RES_HEAP; + if (oldres->rr_status & RES_TDI_IGNORE) + { + ResDeleteResPointer(oldres->rr_node[0], oldres); + ResDeleteResPointer(oldres->rr_node[1], oldres); + ResEliminateResistor(oldres, &ResResList); + } } - if (ResOptionsFlags & ResOpt_Tdi) - { - if (goodies->rg_nodecap != -1 && + if (ResOptionsFlags & ResOpt_Tdi) + { + if (goodies->rg_nodecap != -1 && (totalcap = ResCalculateChildCapacitance(ResOriginNode)) != -1) - { - RCDelayStuff *rc = (RCDelayStuff *) ResNodeList->rn_client; + { + RCDelayStuff *rc = (RCDelayStuff *) ResNodeList->rn_client; - goodies->rg_nodecap = totalcap; - ResCalculateTDi(ResOriginNode,(resResistor *)NULL, + goodies->rg_nodecap = totalcap; + ResCalculateTDi(ResOriginNode, (resResistor *)NULL, goodies->rg_bigdevres); - if (rc != (RCDelayStuff *)NULL) - goodies->rg_Tdi = rc->rc_Tdi; - else - goodies->rg_Tdi = 0; + if (rc != (RCDelayStuff *)NULL) + goodies->rg_Tdi = rc->rc_Tdi; + else + goodies->rg_Tdi = 0; - slownode = ResNodeList; - for (node = ResNodeList; node != NULL; node = node->rn_more) - { - rc = (RCDelayStuff *)node->rn_client; - if (rc && (goodies->rg_Tdi < rc->rc_Tdi)) - { - slownode = node; - goodies->rg_Tdi = rc->rc_Tdi; - } - } - slownode->rn_status |= RN_MAXTDI; - } - else - { - goodies->rg_Tdi = -1; - } + slownode = ResNodeList; + for (node = ResNodeList; node != NULL; node = node->rn_more) + { + rc = (RCDelayStuff *)node->rn_client; + if ((rc != NULL) && (goodies->rg_Tdi < rc->rc_Tdi)) + { + slownode = node; + goodies->rg_Tdi = rc->rc_Tdi; + } + } + slownode->rn_status |= RN_MAXTDI; + } + else + goodies->rg_Tdi = -1; } else - { goodies->rg_Tdi = 0; - } - if ((rctol+1)*goodies->rg_bigdevres*goodies->rg_nodecap > - rctol*goodies->rg_Tdi && - (ResOptionsFlags & ResOpt_Tdi) && - goodies->rg_Tdi != -1) - { - return(0); - } + + if ((rctol+1) * goodies->rg_bigdevres * goodies->rg_nodecap > + rctol * goodies->rg_Tdi && + (ResOptionsFlags & ResOpt_Tdi) && + goodies->rg_Tdi != -1) + return 0; + /* Simplify network; resistors are still in milliohms, so use - millitolerance. - */ + * millitolerance. + */ if (ResOptionsFlags & ResOpt_Simplify) { + millitolerance = tolerance * MILLIOHMSPEROHM; - millitolerance = tolerance*MILLIOHMSPEROHM; - - /* - Start simplification at driver (R=0). Remove it from the done list - and add it to the pending list. Call ResSimplifyNet as long as nodes - remain in the pending list. + /* + * Start simplification at driver (R=0). Remove it from the done list + * and add it to the pending list. Call ResSimplifyNet as long as + * nodes remain in the pending list. */ - for (node = ResNodeList; node != NULL ;node = node->rn_more) - { - if (node->rn_noderes == 0) - { - ResOriginNode = node; - } - node->rn_status |= FINISHED; - } - if (ResOriginNode != NULL) - { + for (node = ResNodeList; node != NULL; node = node->rn_more) + { + if (node->rn_noderes == 0) + ResOriginNode = node; - /* if Tdi is enabled, prune all branches whose end nodes have */ - /* time constants less than the tolerance. */ + node->rn_status |= FINISHED; + } + if (ResOriginNode != NULL) + { - if ((ResOptionsFlags & ResOpt_Tdi) && + /* if Tdi is enabled, prune all branches whose end nodes */ + /* have time constants less than the tolerance. */ + + if ((ResOptionsFlags & ResOpt_Tdi) && goodies->rg_Tdi != -1 && rctol != 0) - { - ResPruneTree(ResOriginNode, - (rctol+1)*goodies->rg_bigdevres*goodies->rg_nodecap/rctol, - &ResNodeList,&ResNodeQueue,&ResResList); - } - ResOriginNode->rn_status &= ~MARKED; - if (ResOriginNode->rn_less == NULL) - { - ResNodeList = ResOriginNode->rn_more; - } - else - { - ResOriginNode->rn_less->rn_more = ResOriginNode->rn_more; - } - if (ResOriginNode->rn_more != NULL) - { - ResOriginNode->rn_more->rn_less = ResOriginNode->rn_less; - } - ResOriginNode->rn_more = NULL; - ResOriginNode->rn_less = NULL; - ResNodeQueue = ResOriginNode; - while (ResNodeQueue != NULL) - { - ResSimplifyNet(&ResNodeQueue,&ResNodeList,&ResResList,millitolerance); - } + { + ResPruneTree(ResOriginNode, (rctol + 1) * + goodies->rg_bigdevres * goodies->rg_nodecap / rctol, + &ResNodeList, &ResNodeQueue, &ResResList); + } + ResOriginNode->rn_status &= ~MARKED; + if (ResOriginNode->rn_less == NULL) + ResNodeList = ResOriginNode->rn_more; + else + ResOriginNode->rn_less->rn_more = ResOriginNode->rn_more; - /* - Call ResScrunchNet to eliminate any remaining under tolerance - resistors. + if (ResOriginNode->rn_more != NULL) + ResOriginNode->rn_more->rn_less = ResOriginNode->rn_less; + + ResOriginNode->rn_more = NULL; + ResOriginNode->rn_less = NULL; + ResNodeQueue = ResOriginNode; + while (ResNodeQueue != NULL) + ResSimplifyNet(&ResNodeQueue,&ResNodeList,&ResResList,millitolerance); + + /* + * Call ResScrunchNet to eliminate any remaining under tolerance + * resistors. */ - ResScrunchNet(&ResResList,&ResNodeQueue,&ResNodeList,millitolerance); - } - } - return(0); - + ResScrunchNet(&ResResList,&ResNodeQueue,&ResNodeList,millitolerance); + } + } + return 0; } +/* + *------------------------------------------------------------------------- + * + *------------------------------------------------------------------------- + */ + void ResSetPathRes() - { - HeapEntry he; - resNode *node; - static int init=1; + HeapEntry he; + resNode *node; + static int init = 1; - if (init) - { - init = 0; - HeapInit(&ResistorHeap,128,FALSE,FALSE); - } + if (init) + { + init = 0; + HeapInit(&ResistorHeap, 128, FALSE, FALSE); + } - for (node = ResNodeList; node != NULL ;node = node->rn_more) - { - if (node->rn_noderes == 0) - { - ResOriginNode = node; - node->rn_status |= FINISHED; - } - else - { - node->rn_noderes = RES_INFINITY; - node->rn_status &= ~FINISHED; - } - } - if (ResOriginNode == NULL) - { - resDevice *res = ResGetDevice(gparams.rg_devloc); - ResOriginNode = res->rd_fet_source; - ResOriginNode->rn_why = RES_NODE_ORIGIN; - ResOriginNode->rn_noderes = 0; - } - ASSERT(ResOriginNode != NULL,"ResDoSimplify"); - resPathNode(ResOriginNode); - while (HeapRemoveTop(&ResistorHeap,&he)) - { - resPathRes((resResistor *) he.he_id); - } + for (node = ResNodeList; node != NULL; node = node->rn_more) + { + if (node->rn_noderes == 0) + { + ResOriginNode = node; + node->rn_status |= FINISHED; + } + else + { + node->rn_noderes = RES_INFINITY; + node->rn_status &= ~FINISHED; + } + } + if (ResOriginNode == NULL) + { + resDevice *res = ResGetDevice(gparams.rg_devloc); + ResOriginNode = res->rd_fet_source; + ResOriginNode->rn_why = RES_NODE_ORIGIN; + ResOriginNode->rn_noderes = 0; + } + ASSERT(ResOriginNode != NULL, "ResDoSimplify"); + resPathNode(ResOriginNode); + while (HeapRemoveTop(&ResistorHeap,&he)) + resPathRes((resResistor *)he.he_id); } +/* + *------------------------------------------------------------------------- + * + *------------------------------------------------------------------------- + */ + void resPathNode(node) - resNode *node; + resNode *node; { - resElement *re; + resElement *re; - node->rn_status |= FINISHED; - for (re = node->rn_re;re;re=re->re_nextEl) - { - resResistor *res = re->re_thisEl; - resNode *node2; + node->rn_status |= FINISHED; + for (re = node->rn_re; re; re = re->re_nextEl) + { + resResistor *res = re->re_thisEl; + resNode *node2; - if (res->rr_status & RES_HEAP) continue; - if ((node2=res->rr_node[0]) == node) node2 = res->rr_node[1]; - if ((node2->rn_status & FINISHED) == 0) - { - HeapAddInt(&ResistorHeap, node->rn_noderes + res->rr_value, + if (res->rr_status & RES_HEAP) continue; + if ((node2 = res->rr_node[0]) == node) node2 = res->rr_node[1]; + if ((node2->rn_status & FINISHED) == 0) + HeapAddInt(&ResistorHeap, node->rn_noderes + res->rr_value, (char *)res); - } - } + } } +/* + *------------------------------------------------------------------------- + * + *------------------------------------------------------------------------- + */ + void resPathRes(res) - resResistor *res; + resResistor *res; { - resNode *node0,*node1; - int flag0,flag1; + resNode *node0, *node1; + int flag0, flag1; - res->rr_status |= RES_HEAP; - res->rr_status &= ~RES_MARKED; - node0 = res->rr_node[0]; - node1 = res->rr_node[1]; - flag0 = node0->rn_status & FINISHED; - flag1 = node1->rn_status & FINISHED; - if (flag0 && flag1) - { - res->rr_status |= RES_TDI_IGNORE; - if (resRemoveLoops) - { - ResDeleteResPointer(node0,res); - ResDeleteResPointer(node1,res); - ResEliminateResistor(res,&ResResList); - } - } - else if (flag0) - { - node1->rn_noderes = node0->rn_noderes+res->rr_value; - resPathNode(node1); - } - else - { - ASSERT(flag1,"ResPathRes"); - res->rr_node[0] = node1; - res->rr_node[1] = node0; - node0->rn_noderes = node1->rn_noderes+res->rr_value; - resPathNode(node0); - } + res->rr_status |= RES_HEAP; + res->rr_status &= ~RES_MARKED; + node0 = res->rr_node[0]; + node1 = res->rr_node[1]; + flag0 = node0->rn_status & FINISHED; + flag1 = node1->rn_status & FINISHED; + if (flag0 && flag1) + { + res->rr_status |= RES_TDI_IGNORE; + if (resRemoveLoops) + { + ResDeleteResPointer(node0, res); + ResDeleteResPointer(node1, res); + ResEliminateResistor(res, &ResResList); + } + } + else if (flag0) + { + node1->rn_noderes = node0->rn_noderes + res->rr_value; + resPathNode(node1); + } + else + { + ASSERT(flag1, "ResPathRes"); + res->rr_node[0] = node1; + res->rr_node[1] = node0; + node0->rn_noderes = node1->rn_noderes + res->rr_value; + resPathNode(node0); + } } diff --git a/resis/ResUtils.c b/resis/ResUtils.c index 1e305705..be22317d 100644 --- a/resis/ResUtils.c +++ b/resis/ResUtils.c @@ -62,27 +62,27 @@ ResFirst(tile, arg) if (DBIsContact(t)) { - reg = (ResContactPoint *) mallocMagic((unsigned) (sizeof(ResContactPoint))); - reg->cp_center.p_x = (LEFT(tile)+RIGHT(tile))>>1; - reg->cp_center.p_y = (TOP(tile)+BOTTOM(tile))>>1; - reg->cp_status = FALSE; - reg->cp_type = t; - reg->cp_width = RIGHT(tile)-LEFT(tile); - reg->cp_height = TOP(tile)-BOTTOM(tile); - for (i=0; i< LAYERS_PER_CONTACT; i++) - { - reg->cp_tile[i] = (Tile *) NULL; - reg->cp_cnode[i] = (resNode *) NULL; - } - reg->cp_currentcontact = 0; - reg->cp_rect.r_ll.p_x = tile->ti_ll.p_x; - reg->cp_rect.r_ll.p_y = tile->ti_ll.p_y; - reg->cp_rect.r_ur.p_x = RIGHT(tile); - reg->cp_rect.r_ur.p_y = TOP(tile); - reg->cp_contactTile = tile; - /* Prepend it to the region list */ - reg->cp_nextcontact = (ResContactPoint *) arg->fra_region; - arg->fra_region = (Region *) reg; + reg = (ResContactPoint *) mallocMagic((unsigned) (sizeof(ResContactPoint))); + reg->cp_center.p_x = (LEFT(tile) + RIGHT(tile)) >> 1; + reg->cp_center.p_y = (TOP(tile) + BOTTOM(tile)) >> 1; + reg->cp_status = FALSE; + reg->cp_type = t; + reg->cp_width = RIGHT(tile) - LEFT(tile); + reg->cp_height = TOP(tile) - BOTTOM(tile); + for (i = 0; i < LAYERS_PER_CONTACT; i++) + { + reg->cp_tile[i] = (Tile *) NULL; + reg->cp_cnode[i] = (resNode *) NULL; + } + reg->cp_currentcontact = 0; + reg->cp_rect.r_ll.p_x = tile->ti_ll.p_x; + reg->cp_rect.r_ll.p_y = tile->ti_ll.p_y; + reg->cp_rect.r_ur.p_x = RIGHT(tile); + reg->cp_rect.r_ur.p_y = TOP(tile); + reg->cp_contactTile = tile; + /* Prepend it to the region list */ + reg->cp_nextcontact = (ResContactPoint *) arg->fra_region; + arg->fra_region = (Region *) reg; } return((Region *) NULL); } @@ -104,16 +104,16 @@ ResFirst(tile, arg) int ResEach(tile, pNum, arg) - Tile *tile; - int pNum; - FindRegion *arg; + Tile *tile; + int pNum; + FindRegion *arg; { - if ( ((ResContactPoint *)(arg->fra_region))->cp_contactTile != tile) - { - (void) ResFirst(tile, arg); - } - return(0); + if (((ResContactPoint *)(arg->fra_region))->cp_contactTile != tile) + { + ResFirst(tile, arg); + } + return(0); } /* @@ -135,22 +135,21 @@ ResEach(tile, pNum, arg) int ResAddPlumbing(tile, arg) - Tile *tile; - ClientData *arg; - + Tile *tile; + ClientData *arg; { - tileJunk *Junk,*junk2; - static Stack *resDevStack=NULL; - TileType loctype, t1; - Tile *tp1,*tp2,*source; - resDevice *resDev; - ExtDevice *devptr; + tileJunk *Junk, *junk2; + static Stack *resDevStack = NULL; + TileType loctype, t1; + Tile *tp1, *tp2, *source; + resDevice *resDev; + ExtDevice *devptr; - if (resDevStack == NULL) - resDevStack = StackNew(64); + if (resDevStack == NULL) + resDevStack = StackNew(64); - if (tile->ti_client == (ClientData) CLIENTDEFAULT) - { + if (tile->ti_client == (ClientData) CLIENTDEFAULT) + { if (IsSplit(tile)) loctype = (SplitSide(tile)) ? SplitRightType(tile) : SplitLeftType(tile); @@ -165,7 +164,7 @@ ResAddPlumbing(tile, arg) /* Count SD terminals of the device */ nterms = 0; - for (i = 0; ; i++) + for (i = 0;; i++) { if (TTMaskIsZero(&(devptr->exts_deviceSDTypes[i]))) break; nterms++; @@ -181,7 +180,7 @@ ResAddPlumbing(tile, arg) resDev = (resDevice *) mallocMagic((unsigned)(sizeof(resDevice))); resDev->rd_nterms = nterms; resDev->rd_terminals = (resNode **) mallocMagic(nterms * sizeof(resNode *)); - for (i=0; i != nterms;i++) + for (i = 0; i != nterms; i++) resDev->rd_terminals[i] = (resNode *) NULL; resDev->rd_tile = tile; @@ -201,79 +200,91 @@ ResAddPlumbing(tile, arg) junk2->deviceList = resDev; junk2->tj_status |= RES_TILE_DEV; - source = NULL; - /* find diffusion (if present) to be source contact */ - - /* top */ - for (tp2= RT(tile); RIGHT(tp2) > LEFT(tile); tp2 = BL(tp2)) + for (i = 0; i < nterms - 2; i++) { - if TTMaskHasType(&(devptr->exts_deviceSDTypes[0]), + source = NULL; + /* find diffusion (if present) to be source contact */ + + /* top */ + for (tp2 = RT(tile); RIGHT(tp2) > LEFT(tile); tp2 = BL(tp2)) + { + if TTMaskHasType(&(devptr->exts_deviceSDTypes[i]), TiGetBottomType(tp2)) - { - junk2->sourceEdge |= TOPEDGE; - source = tp2; - Junk = resAddField(source); - Junk->tj_status |= RES_TILE_SD; - break; - } - } + { + junk2->sourceEdge |= TOPEDGE; + source = tp2; + Junk = resAddField(source); + Junk->tj_status |= RES_TILE_SD; + break; + } + } - /*bottom*/ - if (source == NULL) - for (tp2= LB(tile); LEFT(tp2) < RIGHT(tile); tp2 = TR(tp2)) - { - if TTMaskHasType(&(devptr->exts_deviceSDTypes[0]), + /* bottom */ + if (source == NULL) + for (tp2 = LB(tile); LEFT(tp2) < RIGHT(tile); tp2 = TR(tp2)) + { + if TTMaskHasType(&(devptr->exts_deviceSDTypes[i]), TiGetTopType(tp2)) - { - junk2->sourceEdge |= BOTTOMEDGE; - source = tp2; - Junk = resAddField(source); - Junk->tj_status |= RES_TILE_SD; - break; + { + junk2->sourceEdge |= BOTTOMEDGE; + source = tp2; + Junk = resAddField(source); + Junk->tj_status |= RES_TILE_SD; + break; + } } - } - /*right*/ - if (source == NULL) - for (tp2= TR(tile); TOP(tp2) > BOTTOM(tile); tp2 = LB(tp2)) - { - if TTMaskHasType(&(devptr->exts_deviceSDTypes[0]), + /* right */ + if (source == NULL) + for (tp2 = TR(tile); TOP(tp2) > BOTTOM(tile); tp2 = LB(tp2)) + { + if TTMaskHasType(&(devptr->exts_deviceSDTypes[i]), TiGetLeftType(tp2)) - { - junk2->sourceEdge |= RIGHTEDGE; - source = tp2; - Junk = resAddField(source); - Junk->tj_status |= RES_TILE_SD; - break; + { + junk2->sourceEdge |= RIGHTEDGE; + source = tp2; + Junk = resAddField(source); + Junk->tj_status |= RES_TILE_SD; + break; + } } - } - /*left*/ - if (source == NULL) - for (tp2= BL(tile); BOTTOM(tp2) < TOP(tile); tp2 = RT(tp2)) - { - if TTMaskHasType(&(devptr->exts_deviceSDTypes[0]), + /* left */ + if (source == NULL) + for (tp2 = BL(tile); BOTTOM(tp2) < TOP(tile); tp2 = RT(tp2)) + { + if TTMaskHasType(&(devptr->exts_deviceSDTypes[i]), TiGetRightType(tp2)) - { - source = tp2; - Junk = resAddField(source); - Junk->tj_status |= RES_TILE_SD; - junk2->sourceEdge |= LEFTEDGE; - break; + { + source = tp2; + Junk = resAddField(source); + Junk->tj_status |= RES_TILE_SD; + junk2->sourceEdge |= LEFTEDGE; + break; + } + } + /* other plane (in ResUse) */ + if (source == NULL) + { + int pNum; + for (pNum = PL_TECHDEPBASE; pNum < DBNumPlanes; pNum++) + { + /* XXX */ + } } - } - /* We need to know whether a given diffusion tile connects to - * the source or to the drain of a device. A single - * diffusion tile is marked, and all connecting diffusion tiles - * are enumerated and called the source. Any other SD tiles - * are assumed to be the drain. BUG: this does not work - * correctly with multi SD structures. - */ + /* We need to know whether a given diffusion tile connects to + * the source or to the drain of a device. A single + * diffusion tile is marked, and all connecting diffusion tiles + * are enumerated and called the source. Any other SD tiles + * are assumed to be the drain. BUG: this does not work + * correctly with multi SD structures. + */ - if (source != (Tile *) NULL) - { - STACKPUSH((ClientData) (source),resDevStack); + if (source != (Tile *) NULL) + { + STACKPUSH((ClientData)source, resDevStack); + } } while (!StackEmpty(resDevStack)) { @@ -287,54 +298,54 @@ ResAddPlumbing(tile, arg) t1 = TiGetTypeExact(tp1); /* top */ - for (tp2= RT(tp1); RIGHT(tp2) > LEFT(tp1); tp2 = BL(tp2)) + for (tp2 = RT(tp1); RIGHT(tp2) > LEFT(tp1); tp2 = BL(tp2)) { if (TiGetBottomType(tp2) == t1) { - tileJunk *j= resAddField(tp2); + tileJunk *j = resAddField(tp2); if ((j->tj_status & RES_TILE_SD) ==0) { j->tj_status |= RES_TILE_SD; - STACKPUSH((ClientData)tp2,resDevStack); + STACKPUSH((ClientData)tp2, resDevStack); } } } - /*bottom*/ - for (tp2= LB(tp1); LEFT(tp2) < RIGHT(tp1); tp2 = TR(tp2)) + /* bottom */ + for (tp2 = LB(tp1); LEFT(tp2) < RIGHT(tp1); tp2 = TR(tp2)) { if (TiGetTopType(tp2) == t1) { - tileJunk *j= resAddField(tp2); + tileJunk *j = resAddField(tp2); if ((j->tj_status & RES_TILE_SD) == 0) { j->tj_status |= RES_TILE_SD; - STACKPUSH((ClientData) (tp2),resDevStack); + STACKPUSH((ClientData)tp2, resDevStack); } } } - /*right*/ - for (tp2= TR(tp1); TOP(tp2) > BOTTOM(tp1); tp2 = LB(tp2)) + /* right */ + for (tp2 = TR(tp1); TOP(tp2) > BOTTOM(tp1); tp2 = LB(tp2)) { if (TiGetLeftType(tp2) == t1) { - tileJunk *j= resAddField(tp2); + tileJunk *j = resAddField(tp2); if ((j->tj_status & RES_TILE_SD) == 0) { j->tj_status |= RES_TILE_SD; - STACKPUSH((ClientData) (tp2),resDevStack); + STACKPUSH((ClientData)tp2, resDevStack); } } } - /*left*/ - for (tp2= BL(tp1); BOTTOM(tp2) < TOP(tp1); tp2 = RT(tp2)) + /* left */ + for (tp2 = BL(tp1); BOTTOM(tp2) < TOP(tp1); tp2 = RT(tp2)) { if (TiGetRightType(tp2) == t1) { - tileJunk *j= resAddField(tp2); + tileJunk *j = resAddField(tp2); if ((j->tj_status & RES_TILE_SD) == 0) { j->tj_status |= RES_TILE_SD; - STACKPUSH((ClientData) (tp2),resDevStack); + STACKPUSH((ClientData)tp2, resDevStack); } } } @@ -342,12 +353,12 @@ ResAddPlumbing(tile, arg) /* find rest of device; search for source edges */ - STACKPUSH((ClientData) (tile), resDevStack); + STACKPUSH((ClientData)tile, resDevStack); while (!StackEmpty(resDevStack)) { - tileJunk *j0; + tileJunk *j0; - tp1= (Tile *) STACKPOP(resDevStack); + tp1 = (Tile *) STACKPOP(resDevStack); if (IsSplit(tp1)) { t1 = (SplitSide(tp1)) ? SplitRightType(tp1) : @@ -359,14 +370,14 @@ ResAddPlumbing(tile, arg) devptr = ExtCurStyle->exts_device[t1]; j0 = (tileJunk *) tp1->ti_client; /* top */ - for (tp2= RT(tp1); RIGHT(tp2) > LEFT(tp1); tp2 = BL(tp2)) + for (tp2 = RT(tp1); RIGHT(tp2) > LEFT(tp1); tp2 = BL(tp2)) { if ((TiGetBottomType(tp2) == t1) && (tp2->ti_client == (ClientData) CLIENTDEFAULT)) { Junk = resAddField(tp2); - STACKPUSH((ClientData)(tp2),resDevStack); - Junk->deviceList = resDev; + STACKPUSH((ClientData)tp2, resDevStack); + Junk->deviceList = resDev; Junk->tj_status |= RES_TILE_DEV; } @@ -378,14 +389,14 @@ ResAddPlumbing(tile, arg) j0->sourceEdge |= TOPEDGE; } } - /*bottom*/ - for (tp2= LB(tp1); LEFT(tp2) < RIGHT(tp1); tp2 = TR(tp2)) + /* bottom */ + for (tp2 = LB(tp1); LEFT(tp2) < RIGHT(tp1); tp2 = TR(tp2)) { if ((TiGetTopType(tp2) == t1) && (tp2->ti_client == (ClientData) CLIENTDEFAULT)) { Junk = resAddField(tp2); - STACKPUSH((ClientData)(tp2),resDevStack); + STACKPUSH((ClientData)tp2, resDevStack); Junk->deviceList = resDev; Junk->tj_status |= RES_TILE_DEV; } @@ -397,33 +408,33 @@ ResAddPlumbing(tile, arg) j0->sourceEdge |= BOTTOMEDGE; } } - /*right*/ - for (tp2= TR(tp1); TOP(tp2) > BOTTOM(tp1); tp2 = LB(tp2)) + /* right */ + for (tp2 = TR(tp1); TOP(tp2) > BOTTOM(tp1); tp2 = LB(tp2)) { if ((TiGetLeftType(tp2) == t1) && (tp2->ti_client == (ClientData) CLIENTDEFAULT)) { Junk = resAddField(tp2); - STACKPUSH((ClientData)(tp2),resDevStack); + STACKPUSH((ClientData)tp2, resDevStack); Junk->deviceList = resDev; Junk->tj_status |= RES_TILE_DEV; } else if TTMaskHasType(&(devptr->exts_deviceSDTypes[0]), TiGetLeftType(tp2)) - { + { Junk = resAddField(tp2); if (Junk->tj_status & RES_TILE_SD) j0->sourceEdge |= RIGHTEDGE; } } - /*left*/ - for (tp2= BL(tp1); BOTTOM(tp2) < TOP(tp1); tp2 = RT(tp2)) + /* left */ + for (tp2 = BL(tp1); BOTTOM(tp2) < TOP(tp1); tp2 = RT(tp2)) { if ((TiGetRightType(tp2) == t1) && (tp2->ti_client == (ClientData) CLIENTDEFAULT)) { Junk = resAddField(tp2); - STACKPUSH((ClientData)(tp2),resDevStack); + STACKPUSH((ClientData)tp2, resDevStack); Junk->deviceList = resDev; Junk->tj_status |= RES_TILE_DEV; } @@ -441,9 +452,9 @@ ResAddPlumbing(tile, arg) if (source != (Tile *) NULL) { - tileJunk *j = (tileJunk *) source->ti_client; + tileJunk *j = (tileJunk *) source->ti_client; - STACKPUSH((ClientData) (source),resDevStack); + STACKPUSH((ClientData)source, resDevStack); j->tj_status &= ~RES_TILE_SD; } while (!StackEmpty(resDevStack)) @@ -458,54 +469,54 @@ ResAddPlumbing(tile, arg) t1 = TiGetTypeExact(tp1); /* top */ - for (tp2= RT(tp1); RIGHT(tp2) > LEFT(tp1); tp2 = BL(tp2)) + for (tp2 = RT(tp1); RIGHT(tp2) > LEFT(tp1); tp2 = BL(tp2)) { - tileJunk *j2 = (tileJunk *) tp2->ti_client; + tileJunk *j2 = (tileJunk *) tp2->ti_client; if (TiGetBottomType(tp2) == t1) { if (j2->tj_status & RES_TILE_SD) { j2->tj_status &= ~RES_TILE_SD; - STACKPUSH((ClientData) tp2,resDevStack); + STACKPUSH((ClientData)tp2, resDevStack); } } } - /*bottom*/ - for(tp2= LB(tp1); LEFT(tp2) < RIGHT(tp1); tp2 = TR(tp2)) + /* bottom */ + for(tp2 = LB(tp1); LEFT(tp2) < RIGHT(tp1); tp2 = TR(tp2)) { - tileJunk *j2 = (tileJunk *) tp2->ti_client; + tileJunk *j2 = (tileJunk *) tp2->ti_client; if (TiGetTopType(tp2) == t1) { if (j2->tj_status & RES_TILE_SD) { j2->tj_status &= ~RES_TILE_SD; - STACKPUSH((ClientData) tp2,resDevStack); + STACKPUSH((ClientData)tp2, resDevStack); } } } - /*right*/ - for (tp2= TR(tp1); TOP(tp2) > BOTTOM(tp1); tp2 = LB(tp2)) + /* right */ + for (tp2 = TR(tp1); TOP(tp2) > BOTTOM(tp1); tp2 = LB(tp2)) { - tileJunk *j2 = (tileJunk *) tp2->ti_client; + tileJunk *j2 = (tileJunk *) tp2->ti_client; if (TiGetLeftType(tp2) == t1) { if (j2->tj_status & RES_TILE_SD) { j2->tj_status &= ~RES_TILE_SD; - STACKPUSH((ClientData) tp2,resDevStack); + STACKPUSH((ClientData)tp2, resDevStack); } } } - /*left*/ - for (tp2= BL(tp1); BOTTOM(tp2) < TOP(tp1); tp2 = RT(tp2)) + /* left */ + for (tp2 = BL(tp1); BOTTOM(tp2) < TOP(tp1); tp2 = RT(tp2)) { - tileJunk *j2 = (tileJunk *) tp2->ti_client; + tileJunk *j2 = (tileJunk *) tp2->ti_client; if (TiGetRightType(tp2) == t1) { if (j2->tj_status & RES_TILE_SD) { j2->tj_status &= ~RES_TILE_SD; - STACKPUSH((ClientData) tp2,resDevStack); + STACKPUSH((ClientData)tp2, resDevStack); } } } @@ -529,24 +540,24 @@ ResAddPlumbing(tile, arg) int ResRemovePlumbing(tile, arg) - Tile *tile; - ClientData *arg; + Tile *tile; + ClientData *arg; { - if (tile->ti_client != (ClientData) CLIENTDEFAULT) - { - freeMagic(((char *)(tile->ti_client))); - tile->ti_client = (ClientData) CLIENTDEFAULT; - } - return(0); + if (tile->ti_client != (ClientData) CLIENTDEFAULT) + { + freeMagic(((char *)(tile->ti_client))); + tile->ti_client = (ClientData) CLIENTDEFAULT; + } + return(0); } /* *------------------------------------------------------------------------- * - * ResPreprocessDevices-- Given a list of all the device tiles and + * ResPreProcessDevices-- Given a list of all the device tiles and * a list of all the devices, this procedure calculates the width and * length. The width is set equal to the sum of all edges that touch * diffusion divided by 2. The length is the remaining perimeter divided by @@ -604,8 +615,9 @@ ResPreProcessDevices(TileList, DeviceList, Def) tt = TiGetType(tile); tstruct = (tileJunk *) tile->ti_client; - if (!TTMaskHasType(&ExtCurStyle->exts_deviceMask, tt) || - tstruct->deviceList == NULL) + if ((tstruct == (tileJunk *)CLIENTDEFAULT) || + (tstruct->deviceList == NULL) || + !TTMaskHasType(&ExtCurStyle->exts_deviceMask, tt)) { TxError("Bad Device Location at %d,%d\n", TileList->area.r_ll.p_x, @@ -627,7 +639,7 @@ ResPreProcessDevices(TileList, DeviceList, Def) freeMagic((char *)oldTile); } - for(; DeviceList != NULL;DeviceList = DeviceList->rd_nextDev) + for (; DeviceList != NULL; DeviceList = DeviceList->rd_nextDev) { int width = DeviceList->rd_perim; int length = DeviceList->rd_length; @@ -666,18 +678,17 @@ ResPreProcessDevices(TileList, DeviceList, Def) * *------------------------------------------------------------------------- */ + void -ResAddToQueue(node,list) - resNode *node,**list; +ResAddToQueue(node, list) + resNode *node, **list; { - - node->rn_more = *list; - node->rn_less = NULL; - if (*list) (*list)->rn_less = node; - *list = node; + node->rn_more = *list; + node->rn_less = NULL; + if (*list) (*list)->rn_less = node; + *list = node; } - /* *------------------------------------------------------------------------- * @@ -692,44 +703,42 @@ ResAddToQueue(node,list) */ void -ResRemoveFromQueue(node,list) - resNode *node,**list; - +ResRemoveFromQueue(node, list) + resNode *node, **list; { - - if (node->rn_less != NULL) - { - node->rn_less->rn_more = node->rn_more; - } - else - { - if (node != (*list)) - { - TxError("Error: Attempt to remove node from wrong list\n"); - } - else - { - *list = node->rn_more; - } - } - if (node->rn_more != NULL) - { - node->rn_more->rn_less = node->rn_less; - } - node->rn_more = NULL; - node->rn_less = NULL; + if (node->rn_less != NULL) + { + node->rn_less->rn_more = node->rn_more; + } + else + { + if (node != (*list)) + { + TxError("Error: Attempt to remove node from wrong list\n"); + } + else + { + *list = node->rn_more; + } + } + if (node->rn_more != NULL) + { + node->rn_more->rn_less = node->rn_less; + } + node->rn_more = NULL; + node->rn_less = NULL; } + tileJunk * resAddField(tile) - Tile *tile; - + Tile *tile; { - tileJunk *Junk; - if ((Junk=(tileJunk *)tile->ti_client) == (tileJunk *) CLIENTDEFAULT) - { - Junk = (tileJunk *) mallocMagic((unsigned) (sizeof(tileJunk))); - ResJunkInit(Junk); - tile->ti_client = (ClientData) Junk; - } - return Junk; + tileJunk *Junk; + if ((Junk = (tileJunk *)tile->ti_client) == (tileJunk *) CLIENTDEFAULT) + { + Junk = (tileJunk *) mallocMagic((unsigned) (sizeof(tileJunk))); + ResJunkInit(Junk); + tile->ti_client = (ClientData) Junk; + } + return Junk; } diff --git a/resis/ResWrite.c b/resis/ResWrite.c index 53313a33..7b40e6d2 100644 --- a/resis/ResWrite.c +++ b/resis/ResWrite.c @@ -47,78 +47,76 @@ ResPrintNetwork(filename, reslist) resResistor *reslist; { - char bigname[255],name1[255],name2[255]; - + char bigname[255], name1[255], name2[255]; FILE *fp; - int i=1; + int i = 1; - sprintf(bigname,"%s.%s",filename,"res"); - fp = fopen(bigname,"w"); + sprintf(bigname, "%s.%s", filename, "res"); + fp = fopen(bigname, "w"); if (fp != NULL) { - for (;reslist;reslist=reslist->rr_nextResistor) - { - if (reslist->rr_connection1->rn_id == 0) - { - reslist->rr_connection1->rn_id = i++; - } - if (reslist->rr_connection2->rn_id == 0) - { - reslist->rr_connection2->rn_id = i++; - } - if (reslist->rr_connection1->rn_why == RES_NODE_ORIGIN) - { - sprintf(name1,"gnd"); - } - else - { - sprintf(name1,"n%d_%d_%d", + for (; reslist; reslist = reslist->rr_nextResistor) + { + if (reslist->rr_connection1->rn_id == 0) + { + reslist->rr_connection1->rn_id = i++; + } + if (reslist->rr_connection2->rn_id == 0) + { + reslist->rr_connection2->rn_id = i++; + } + if (reslist->rr_connection1->rn_why == RES_NODE_ORIGIN) + { + sprintf(name1, "gnd"); + } + else + { + sprintf(name1, "n%d_%d_%d", reslist->rr_connection1->rn_id, reslist->rr_connection1->rn_loc.p_x, reslist->rr_connection1->rn_loc.p_y); - } - if (reslist->rr_connection2->rn_why == RES_NODE_ORIGIN) - { - sprintf(name2,"gnd"); - } - else - { - sprintf(name2,"n%d_%d_%d", + } + if (reslist->rr_connection2->rn_why == RES_NODE_ORIGIN) + { + sprintf(name2,"gnd"); + } + else + { + sprintf(name2, "n%d_%d_%d", reslist->rr_connection2->rn_id, reslist->rr_connection2->rn_loc.p_x, reslist->rr_connection2->rn_loc.p_y); - } - fprintf(fp,"r %s %s %f\n",name1,name2, - (float)(reslist->rr_value)*MILLITOKILO); - } + } + fprintf(fp, "r %s %s %f\n", name1, name2, + (float)(reslist->rr_value) * MILLITOKILO); + } } fclose(fp); } void -ResPrintCurrents(filename,extension,node) - char *filename; - float extension; - resNode *node; +ResPrintCurrents(filename, extension, node) + char *filename; + float extension; + resNode *node; { - char bigname[255]; - FILE *fp; - int resCurrentPrintFunc(); + char bigname[255]; + FILE *fp; + int resCurrentPrintFunc(); - sprintf(bigname,"%s.%d",filename,abs((int)(extension))); + sprintf(bigname, "%s.%d", filename, abs((int)(extension))); - fp = fopen(bigname,"w"); - if (fp != NULL) - { - (void) ResTreeWalk(node,NULL,resCurrentPrintFunc, - RES_DO_FIRST,RES_NO_LOOP,RES_NO_FLAGS,fp); - } - fclose(fp); + fp = fopen(bigname, "w"); + if (fp != NULL) + { + (void) ResTreeWalk(node, NULL, resCurrentPrintFunc, + RES_DO_FIRST, RES_NO_LOOP, RES_NO_FLAGS, fp); + } + fclose(fp); } - /* *------------------------------------------------------------------------- * @@ -130,100 +128,98 @@ ResPrintCurrents(filename,extension,node) */ void -resCurrentPrintFunc(node,resistor,filename) - resNode *node; - resResistor *resistor; - FILE *filename; +resCurrentPrintFunc(node, resistor, filename) + resNode *node; + resResistor *resistor; + FILE *filename; { - tElement *workingDev; - float i_sum=0.0; + tElement *workingDev; + float i_sum = 0.0; - for (workingDev = node->rn_te; workingDev != NULL; - workingDev=workingDev->te_nextt) - { + for (workingDev = node->rn_te; workingDev != NULL; + workingDev = workingDev->te_nextt) + { if ((workingDev->te_thist->rd_status & RES_DEV_PLUG) || workingDev->te_thist->rd_gate != node) i_sum += workingDev->te_thist->rd_i; - } - if (i_sum != 0.0) - { - if (node->rn_why == RES_NODE_ORIGIN) - { - fprintf(filename,"i gnd %f\n",i_sum); - - } - else - { - fprintf(filename,"i n%d_%d %f\n",node->rn_loc.p_x, - node->rn_loc.p_y,i_sum); - } - } - + } + if (i_sum != 0.0) + { + if (node->rn_why == RES_NODE_ORIGIN) + { + fprintf(filename, "i gnd %f\n", i_sum); + } + else + { + fprintf(filename, "i n%d_%d %f\n", node->rn_loc.p_x, + node->rn_loc.p_y, i_sum); + } + } } void ResDeviceCounts() { - int i,j,k; - resNode *n; - resDevice *t; - resResistor *r; + int i,j,k; + resNode *n; + resDevice *t; + resResistor *r; - for (n=ResNodeList,i=0;n!=NULL;n=n->rn_more,i++); - for (t=ResDevList,j=0;t!=NULL;t=t->rd_nextDev,j++); - for (r=ResResList,k=0;r!=NULL;r=r->rr_nextResistor,k++); - TxError("n=%d t=%d r=%d\n",i,j,k); - TxFlushErr(); + for (n = ResNodeList, i = 0; n != NULL; n = n->rn_more, i++); + for (t = ResDevList, j = 0; t != NULL; t = t->rd_nextDev, j++); + for (r = ResResList, k = 0; r != NULL; r = r->rr_nextResistor, k++); + TxError("n=%d t=%d r=%d\n", i, j, k); + TxFlushErr(); } void -ResWriteECLFile(filename,reslist,nodelist) - char *filename; - resResistor *reslist; - resNode *nodelist; +ResWriteECLFile(filename, reslist, nodelist) + char *filename; + resResistor *reslist; + resNode *nodelist; { - char newname[100],*tmpname,*per; - FILE *fp; - int nodenum = 0; + char newname[100], *tmpname, *per; + FILE *fp; + int nodenum = 0; - strcpy(newname,filename); - if (per = strrchr(newname,'.')) *per = '\0'; - strcat(newname,".res"); + strcpy(newname, filename); + if (per = strrchr(newname,'.')) *per = '\0'; + strcat(newname, ".res"); - if ((fp = fopen(newname,"w")) == NULL) - { - TxError("Can't open %s\n",newname); - return; - } - for (;nodelist;nodelist=nodelist->rn_more) - { - if (nodelist->rn_name == NULL) - { - if (nodelist->rn_noderes == 0) - { - strcpy(newname,"gnd"); - } - else - { - (void)sprintf(newname,"n%d_%d_%d",nodelist->rn_loc.p_x, - nodelist->rn_loc.p_y,nodenum++); - } - tmpname = (char *) mallocMagic((unsigned) (strlen(newname)+1)); - strcpy(tmpname,newname); - nodelist->rn_name = tmpname; - } - } - for (;reslist;reslist = reslist->rr_nextResistor) - { - - fprintf(fp,"r %s %s %f %s %d\n", - reslist->rr_node[0]->rn_name,reslist->rr_node[1]->rn_name, + if ((fp = fopen(newname, "w")) == NULL) + { + TxError("Can't open %s\n", newname); + return; + } + for (; nodelist; nodelist = nodelist->rn_more) + { + if (nodelist->rn_name == NULL) + { + if (nodelist->rn_noderes == 0) + { + strcpy(newname, "gnd"); + } + else + { + (void)sprintf(newname, "n%d_%d_%d", nodelist->rn_loc.p_x, + nodelist->rn_loc.p_y, nodenum++); + } + tmpname = (char *)mallocMagic((unsigned) (strlen(newname) + 1)); + strcpy(tmpname, newname); + nodelist->rn_name = tmpname; + } + } + for (; reslist; reslist = reslist->rr_nextResistor) + { + fprintf(fp, "r %s %s %f %s %d\n", + reslist->rr_node[0]->rn_name, + reslist->rr_node[1]->rn_name, /* /1000.0 gets ohms from milliohms */ - (float)(reslist->rr_value)/1000.0, - DBTypeShortName(reslist->rr_tt),reslist->rr_csArea); - } - fclose(fp); + (float)(reslist->rr_value) / 1000.0, + DBTypeShortName(reslist->rr_tt), reslist->rr_csArea); + } + fclose(fp); } diff --git a/resis/resis.h b/resis/resis.h index 9507df0f..0c6d95d3 100644 --- a/resis/resis.h +++ b/resis/resis.h @@ -247,6 +247,7 @@ typedef struct resdevtile struct resdevtile *nextDev; Rect area; TileType type; + ExtDevice *devptr; int perim; int overlap; } ResDevTile; @@ -297,7 +298,8 @@ typedef struct rdev Point location; /* Location of lower left point of */ /* device. */ float resistance; /* "Resistance" of device. */ - int rs_ttype; /* device type */ + 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; @@ -512,6 +514,7 @@ typedef struct capval #define RIGHTEDGE 4 #define TOPEDGE 8 #define BOTTOMEDGE 16 +#define OTHERPLANE 32 #define RN_MAXTDI 0x00001000 diff --git a/utils/geometry.h b/utils/geometry.h index cf482fa5..f16cac42 100644 --- a/utils/geometry.h +++ b/utils/geometry.h @@ -190,7 +190,8 @@ extern int GeoRectPointSide(Rect *, Point *); extern int GeoRectRectSide(Rect *, Rect *); extern void GeoIncludePoint(Point *, Rect *); extern void GeoDecomposeTransform(Transform *, bool *, int *); -extern void GeoIncludeRectInBBox(Rect *, Rect *bbox); +extern void GeoIncludeRectInBBox(Rect *, Rect *); +extern void GeoCanonicalRect(Rect *, Rect *); /* *------------------------------------------------------------------- diff --git a/utils/heap.c b/utils/heap.c index 7666ed94..c2797c54 100644 --- a/utils/heap.c +++ b/utils/heap.c @@ -417,11 +417,12 @@ HeapAdd(heap, pKey, id) { /* If odd then new entry is the right half of a pair */ cmp = i; - if (i & 1) + if ((i & 1) && (i != 1)) KEY_LE_COND(keyType, list, i, i-1, cmp = i-1); /* Find parent. If 0 then at the root so quit */ if ((i >>= 1) == 0) return; + KEY_LE_COND(keyType, list, cmp, i, return); list[0] = list[cmp]; list[cmp] = list[i]; list[i] = list[0]; heapify(heap, cmp); @@ -434,11 +435,12 @@ HeapAdd(heap, pKey, id) { /* If odd then new entry is the right half of a pair */ cmp = i; - if (i & 1) + if ((i & 1) && (i != 1)) KEY_GE_COND(keyType, list, i, i-1, cmp = i-1); /* Find parent. If 0 then at the root so quit */ if ((i >>= 1) == 0) return; + KEY_GE_COND(keyType, list, cmp, i, return); list[0] = list[cmp]; list[cmp] = list[i]; list[i] = list[0]; heapify(heap, cmp); diff --git a/utils/ihash.h b/utils/ihash.h index 9c5d3f34..3efe01cf 100644 --- a/utils/ihash.h +++ b/utils/ihash.h @@ -50,6 +50,7 @@ static __inline__ int IHashAlignedSize(int size) int result; /* Expand size to be double-word (64 bit) aligned */ result = ((size + 7) / 8) * 8; + return result; } /* The IHashTable struct should not be manipulated directly by clients */ diff --git a/utils/tech.c b/utils/tech.c index 6b58cd51..41311980 100644 --- a/utils/tech.c +++ b/utils/tech.c @@ -149,7 +149,7 @@ TechSectionGetMask(sectionName, depend) { invid |= tsp->ts_thisSect; if (tsp->ts_prevSects & thissect->ts_thisSect) - if (depend != NULL) *depend != tsp->ts_thisSect; + if (depend != NULL) *depend = tsp->ts_thisSect; } } return invid; diff --git a/windows/windMain.c b/windows/windMain.c index 852d6ef4..d5568e1e 100644 --- a/windows/windMain.c +++ b/windows/windMain.c @@ -49,6 +49,7 @@ static char rcsid[] __attribute__ ((unused)) = "$Header$"; #include #include +#include /* for isalnum() */ #include "utils/magic.h" #include "utils/geometry.h"