From 1c328dfe15752a0f6f5c561984e9583d9a4f9e79 Mon Sep 17 00:00:00 2001 From: Tim Edwards Date: Mon, 17 May 2021 15:18:05 -0400 Subject: [PATCH 01/30] Corrected an error in the "cifspacing" rule check for non-Manhattan geometry (which had gone unnoticed due to the lack of use of "cifspacing" in any rule decks). The rule was not checking for all synthetic edges, because the tile type was expected to match the rule type when the function is called, but with a non-Manhattan tile, that may or may not be true and needs to be checked. --- drc/DRCcif.c | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) 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. From ff913ddb23f160464e055c22e6ecd449e4303e74 Mon Sep 17 00:00:00 2001 From: Tim Edwards Date: Mon, 17 May 2021 15:22:27 -0400 Subject: [PATCH 02/30] Updated VERSION. --- VERSION | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/VERSION b/VERSION index 8b702771..9273499b 100644 --- a/VERSION +++ b/VERSION @@ -1 +1 @@ -8.3.164 +8.3.165 From 33edee6b425be2bc8aa9999a3820e802126480c7 Mon Sep 17 00:00:00 2001 From: Tim Edwards Date: Wed, 19 May 2021 17:21:59 -0400 Subject: [PATCH 03/30] Modified the condition under which the (UNNAMED) file is deleted on loading a layout to avoid doing so with in a suspendall ... resumeall block. That avoids weird errors occurring when the PDK toolkit scripts are run to generate a new device layout if the top level layout is still (UNNAMED) and empty. --- VERSION | 2 +- dbwind/DBWprocs.c | 8 +++++++- 2 files changed, 8 insertions(+), 2 deletions(-) diff --git a/VERSION b/VERSION index 7d3253ea..8b702771 100644 --- a/VERSION +++ b/VERSION @@ -1 +1 @@ -8.3.163 +8.3.164 diff --git a/dbwind/DBWprocs.c b/dbwind/DBWprocs.c index e1c05368..c9d998a7 100644 --- a/dbwind/DBWprocs.c +++ b/dbwind/DBWprocs.c @@ -549,8 +549,14 @@ 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); + if (GrDisplayStatus != DISPLAY_SUSPEND) + DBCellDelete(deleteDef->cd_name, TRUE); } /* This function is called for each cell whose expansion status changed. From 123219b5f1175b15cb26bc51de28dc6b672c0b53 Mon Sep 17 00:00:00 2001 From: Tim Edwards Date: Fri, 21 May 2021 16:33:20 -0400 Subject: [PATCH 04/30] Corrected an error in the extresist code that will cause an infinite recursive loop and crash magic. Corrected a number of other issues along the way, especially one where routines in EFantenna and extresist make use of array EFDevTypes which was only created by ext2sim and ext2spice, and freed when done. Having run extresist through valgrind, there are still issues in the code. --- VERSION | 2 +- database/database.h.in | 1 + extflat/EFantenna.c | 16 +++++++-- extflat/EFdef.c | 1 + extract/ExtTech.c | 73 ++++++++++++++++++++++++------------------ resis/ResMain.c | 3 +- resis/ResReadSim.c | 12 +++++-- resis/ResRex.c | 20 +++++++++++- 8 files changed, 89 insertions(+), 39 deletions(-) diff --git a/VERSION b/VERSION index 3d283694..581ece37 100644 --- a/VERSION +++ b/VERSION @@ -1 +1 @@ -8.3.166 +8.3.167 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/extflat/EFantenna.c b/extflat/EFantenna.c index 480d6f90..d6e3f500 100644 --- a/extflat/EFantenna.c +++ b/extflat/EFantenna.c @@ -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 == MAXDEVTYPES) + { + TxError("Error: Ran out of space for device types!\n"); + break; + } + efBuildAddStr(EFDevTypes, &EFDevNumTypes, MAXDEVTYPES, 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/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/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/resis/ResMain.c b/resis/ResMain.c index d5c6469e..400e3808 100644 --- a/resis/ResMain.c +++ b/resis/ResMain.c @@ -663,6 +663,7 @@ ResExtractNet(startlist, goodies, cellname) * that does not correspond exactly to the layer underneath, include * all connecting types. */ + TTMaskZero(&FirstTileMask); TTMaskSetMask(&FirstTileMask, &DBConnectTbl[fix->fp_ttype]); newdevtiles = DBTreeCopyConnectDCS(&scx, &FirstTileMask, 0, @@ -849,10 +850,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; diff --git a/resis/ResReadSim.c b/resis/ResReadSim.c index cb663a0b..de1afb51 100644 --- a/resis/ResReadSim.c +++ b/resis/ResReadSim.c @@ -419,7 +419,12 @@ ResSimSubckt(line) 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; @@ -479,7 +484,10 @@ ResSimDevice(line, rpersquare, ttype) TxError("All driven nodes will be extracted\n"); nowarning = FALSE; } - device->resistance = MagAtof(line[RDEV_LENGTH]) * rpersquare/MagAtof(line[RDEV_WIDTH]); + if (MagAtof(line[RDEV_WIDTH]) != 0) + device->resistance = MagAtof(line[RDEV_LENGTH]) * rpersquare/MagAtof(line[RDEV_WIDTH]); + else + device->resistance = 0; } device->status = FALSE; device->nextDev = ResRDevList; diff --git a/resis/ResRex.c b/resis/ResRex.c index bc67e95d..90f90cdc 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" @@ -97,17 +98,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 == MAXDEVTYPES) + { + TxError("Error: Ran out of space for device types!\n"); + break; + } + efBuildAddStr(EFDevTypes, &EFDevNumTypes, MAXDEVTYPES, 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); From 0809dddbe0e4f14389f689f14935291d991807ab Mon Sep 17 00:00:00 2001 From: Tim Edwards Date: Fri, 21 May 2021 22:41:51 -0400 Subject: [PATCH 05/30] Resolved an outstanding issue with extresist, which is that the extresist extractor is less sophisticated than the standard extraction and will not check through the list of device records belonging to a single device type. Therefore a device in the .res.ext may have a different device name. So name hashing and checks are made against the tile type, not the device name, as the tile type + device coordinates is sufficient to uniquely identify the device. However, the extresist extractor does need to be sophisticated enough to find all the terminal types, so that needs to be fixed. --- extflat/EFbuild.c | 28 ++++++++++++++++++++++------ resis/ResReadSim.c | 1 + 2 files changed, 23 insertions(+), 6 deletions(-) diff --git a/extflat/EFbuild.c b/extflat/EFbuild.c index 5d0f1530..21db87ab 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 */ /* @@ -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, MAXDEVTYPES, 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/resis/ResReadSim.c b/resis/ResReadSim.c index de1afb51..3d31f0bb 100644 --- a/resis/ResReadSim.c +++ b/resis/ResReadSim.c @@ -342,6 +342,7 @@ ResSimSubckt(line) float lambda; TileType ttype = TT_SPACE; char *lptr = NULL, *wptr = NULL; + ExtDevice *devptr; device = (RDev *) mallocMagic((unsigned) (sizeof(RDev))); From 5e02726f7f430c85ee1d1c252435556329383c36 Mon Sep 17 00:00:00 2001 From: Tim Edwards Date: Sun, 23 May 2021 12:07:31 -0400 Subject: [PATCH 06/30] Modified the cell load routine to avoid creating an "undo" record for loading a cell after displaying an unmodified "(UNNAMED)" cell, because "(UNNAMED)" will be deleted, leaving the undo record invalid and causing a crash if it is attempted to be invoked. --- VERSION | 2 +- dbwind/DBWprocs.c | 6 +++--- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/VERSION b/VERSION index 581ece37..a11686a4 100644 --- a/VERSION +++ b/VERSION @@ -1 +1 @@ -8.3.167 +8.3.168 diff --git a/dbwind/DBWprocs.c b/dbwind/DBWprocs.c index c9d998a7..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); @@ -555,8 +556,7 @@ DBWloadWindow(window, name, flags) /* this doesn't happen within suspendall ... resumeall. */ if (deleteDef != NULL) - if (GrDisplayStatus != DISPLAY_SUSPEND) - DBCellDelete(deleteDef->cd_name, TRUE); + DBCellDelete(deleteDef->cd_name, TRUE); } /* This function is called for each cell whose expansion status changed. From e6f17735b894d458cb3762734744985e072709a4 Mon Sep 17 00:00:00 2001 From: Tim Edwards Date: Sun, 23 May 2021 14:09:50 -0400 Subject: [PATCH 07/30] Modified the "cmdDumpParseArgs()" routine (used, for instance, by the "getcell" command) so that the "parent" and "child" arguments will accept the standard syntax for coordinates used by most other commands (will accept SI units or trailing suffix i/l for internal or lambda units). --- commands/CmdCD.c | 22 ++++++---------------- 1 file changed, 6 insertions(+), 16 deletions(-) diff --git a/commands/CmdCD.c b/commands/CmdCD.c index 1ba9e472..57c2dd26 100644 --- a/commands/CmdCD.c +++ b/commands/CmdCD.c @@ -4396,15 +4396,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 +4450,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, From 82fada3af69901136a0d0e1edc9641fa09e9594a Mon Sep 17 00:00:00 2001 From: Tim Edwards Date: Sun, 23 May 2021 20:59:00 -0400 Subject: [PATCH 08/30] Corrected two somewhat related errors. When "getcell" finds a name conflict and renames a cell, the name was not pointing to the new name and immediately caused a crash condition. However, it got to that point by believing that cell "path/x" and "path/x.mag" were different files. The name was stripped of the extension but the full file path was not, causing the confusion. --- commands/CmdCD.c | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/commands/CmdCD.c b/commands/CmdCD.c index 57c2dd26..d394264b 100644 --- a/commands/CmdCD.c +++ b/commands/CmdCD.c @@ -4273,6 +4273,11 @@ cmdDumpParseArgs(cmdName, w, cmd, dummy, scx) if ((clen > 4) && !strcmp(cellnameptr + clen - 4, ".mag")) *(cellnameptr + clen - 4) = '\0'; + /* Same for fullpathname */ + clen = strlen(fullpathname); + if ((clen > 4) && !strcmp(fullpathname + clen - 4, ".mag")) + *(fullpathname + clen - 4) = '\0'; + /* Check for illegal characters in the cellname */ if (CmdIllegalChars(cellnameptr, "", "Cell name")) { @@ -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); } From 8d8fe2fe559b8de9555defa257c983cf71e7e11a Mon Sep 17 00:00:00 2001 From: Tim Edwards Date: Sun, 23 May 2021 21:26:02 -0400 Subject: [PATCH 09/30] One correction to the last commit, otherwise segfaults are essentially guaranteed. . . --- commands/CmdCD.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/commands/CmdCD.c b/commands/CmdCD.c index d394264b..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 { @@ -4273,11 +4278,6 @@ cmdDumpParseArgs(cmdName, w, cmd, dummy, scx) if ((clen > 4) && !strcmp(cellnameptr + clen - 4, ".mag")) *(cellnameptr + clen - 4) = '\0'; - /* Same for fullpathname */ - clen = strlen(fullpathname); - if ((clen > 4) && !strcmp(fullpathname + clen - 4, ".mag")) - *(fullpathname + clen - 4) = '\0'; - /* Check for illegal characters in the cellname */ if (CmdIllegalChars(cellnameptr, "", "Cell name")) { From c22d584ac3434505f6247fad1f95bcfcc0648eca Mon Sep 17 00:00:00 2001 From: Tim Edwards Date: Tue, 25 May 2021 11:05:33 -0400 Subject: [PATCH 10/30] Corrected a problem with character array bound overflow when writing values to a LEF file. --- VERSION | 2 +- lef/lefWrite.c | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/VERSION b/VERSION index a11686a4..c946a090 100644 --- a/VERSION +++ b/VERSION @@ -1 +1 @@ -8.3.168 +8.3.169 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; From 9aa39f820fca6b1ab303a61463709726323ac29f Mon Sep 17 00:00:00 2001 From: Tim Edwards Date: Tue, 25 May 2021 22:41:52 -0400 Subject: [PATCH 11/30] A number of fixes to the extresist code (as well as style cleanup). Still tracking down a problem with non-FET devices (e.g., capacitors). So, work in progress. Nothing should be affected outside of extresist. --- resis/ResMain.c | 576 ++++++++-------- resis/ResMerge.c | 1332 +++++++++++++++++------------------- resis/ResPrint.c | 29 +- resis/ResReadSim.c | 1008 +++++++++++++-------------- resis/ResRex.c | 35 +- resis/ResSimple.c | 1625 +++++++++++++++++++++----------------------- utils/heap.c | 6 +- 7 files changed, 2271 insertions(+), 2340 deletions(-) diff --git a/resis/ResMain.c b/resis/ResMain.c index 400e3808..13190c44 100644 --- a/resis/ResMain.c +++ b/resis/ResMain.c @@ -23,20 +23,20 @@ static char rcsid[] __attribute__ ((unused)) = "$Header: /usr/cvsroot/magic-8.0/ #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(); @@ -46,7 +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,100 +464,100 @@ 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); } /*------------------------------------------------------------------------- @@ -599,7 +596,7 @@ ResExtractNet(startlist, goodies, cellname) ResContactList = NULL; ResOriginNode = NULL; - /* Pass back network pointers */ + /* Pass back network pointers */ goodies->rg_maxres = 0; goodies->rg_tilecount = 0; @@ -608,9 +605,9 @@ ResExtractNet(startlist, goodies, cellname) if (first) { - ResInitializeConn(); - first = 0; - ResGetReCell(); + ResInitializeConn(); + first = 0; + ResGetReCell(); } /* Initialize Cell */ @@ -618,7 +615,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 +626,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; @@ -646,45 +643,45 @@ ResExtractNet(startlist, goodies, cellname) lasttile = NULL; for (fix = startlist; fix != NULL; fix = fix->fp_next) { - ResDevTile *newdevtiles, *tmp; + ResDevTile *newdevtiles, *tmp; #ifdef ARIEL - if ((ResOptionsFlags & ResOpt_Power) && + if ((ResOptionsFlags & ResOpt_Power) && strcmp(fix->fp_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; + 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; - /* 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. - */ - TTMaskZero(&FirstTileMask); - TTMaskSetMask(&FirstTileMask, &DBConnectTbl[fix->fp_ttype]); + /* 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. + */ + TTMaskZero(&FirstTileMask); + TTMaskSetMask(&FirstTileMask, &DBConnectTbl[fix->fp_ttype]); - newdevtiles = DBTreeCopyConnectDCS(&scx, &FirstTileMask, 0, + newdevtiles = DBTreeCopyConnectDCS(&scx, &FirstTileMask, 0, ResCopyMask, &TiPlaneRect, ResUse); - for (tmp = newdevtiles; tmp && tmp->nextDev; tmp = tmp->nextDev); - if (newdevtiles) - { - if (DevTiles) - lasttile->nextDev = newdevtiles; - else - DevTiles = newdevtiles; - lasttile = tmp; - } + for (tmp = newdevtiles; tmp && tmp->nextDev; tmp = tmp->nextDev); + if (newdevtiles) + { + if (DevTiles) + lasttile->nextDev = newdevtiles; + else + DevTiles = newdevtiles; + lasttile = tmp; + } } 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, @@ -702,16 +699,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); @@ -721,24 +718,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 @@ -766,25 +763,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) { @@ -808,12 +804,9 @@ ResCleanUpEverything() freeMagic((char *)oldDev); } } - DBCellClearDef(ResUse->cu_def); } - - /* *------------------------------------------------------------------------- * @@ -935,54 +928,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); } } @@ -1006,36 +1000,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/ResMerge.c b/resis/ResMerge.c index db328065..4882dbde 100644 --- a/resis/ResMerge.c +++ b/resis/ResMerge.c @@ -29,9 +29,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 +57,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 +71,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 +82,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 +91,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 +104,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 +136,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 +169,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 +190,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 +230,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 +415,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 +475,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 +629,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 +795,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 +844,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 +882,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 +967,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 3d31f0bb..a969404d 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, fettype); + } + 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; } - /* *------------------------------------------------------------------------- * @@ -359,6 +368,7 @@ 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++); @@ -460,97 +470,106 @@ ResSimSubckt(line) int ResSimDevice(line, rpersquare, ttype) - char line[][MAXTOKEN]; - float rpersquare; - TileType ttype; + char line[][MAXTOKEN]; + float rpersquare; + TileType ttype; { - 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; - } - if (MagAtof(line[RDEV_WIDTH]) != 0) - device->resistance = MagAtof(line[RDEV_LENGTH]) * rpersquare/MagAtof(line[RDEV_WIDTH]); - else - device->resistance = 0; - } - 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_ttype = ttype; - 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. * @@ -561,44 +580,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; } - /* *------------------------------------------------------------------------- * @@ -616,58 +639,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; } @@ -687,30 +709,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); } - - /* *------------------------------------------------------------------------- * @@ -727,95 +746,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; } - /* *------------------------------------------------------------------------- * @@ -836,34 +855,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]); + } } - /* *------------------------------------------------------------------------- * @@ -884,46 +903,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 @@ -939,30 +959,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; } /* @@ -980,36 +1000,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 90f90cdc..8b34acd4 100644 --- a/resis/ResRex.c +++ b/resis/ResRex.c @@ -203,7 +203,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; @@ -264,6 +264,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; @@ -979,7 +990,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); @@ -1016,32 +1027,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; } /* @@ -1049,7 +1060,7 @@ 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; @@ -1200,7 +1211,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 */ 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/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); From 7f11020ab4ee2437deece64a28618e15888b8909 Mon Sep 17 00:00:00 2001 From: Tim Edwards Date: Wed, 26 May 2021 22:34:36 -0400 Subject: [PATCH 12/30] Additional changes, almost all stylistic, to make the resis/ section style conform to the rest of the database. It is difficult to work with code written in a sloppy, random style. --- VERSION | 2 +- resis/ResChecks.c | 194 ++++++++-------- resis/ResConDCS.c | 278 +++++++++++----------- resis/ResDebug.c | 25 +- resis/ResFract.c | 565 +++++++++++++++++++++++---------------------- resis/ResJunct.c | 158 +++++++------ resis/ResMain.c | 51 ++-- resis/ResMakeRes.c | 2 +- resis/ResRex.c | 45 ++-- resis/ResUtils.c | 298 ++++++++++++------------ resis/ResWrite.c | 246 ++++++++++---------- 11 files changed, 919 insertions(+), 945 deletions(-) diff --git a/VERSION b/VERSION index c946a090..367f6320 100644 --- a/VERSION +++ b/VERSION @@ -1 +1 @@ -8.3.169 +8.3.170 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 index c1cca55b..fb8c695f 100644 --- a/resis/ResConDCS.c +++ b/resis/ResConDCS.c @@ -65,7 +65,6 @@ int dbcConnectFuncDCS(tile, cx) Tile *tile; TreeContext *cx; - { struct conSrArg2 *csa2; Rect tileArea, *srArea, devArea, newarea; @@ -85,112 +84,116 @@ dbcConnectFuncDCS(tile, cx) 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))) + 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) + if TTMaskHasType(&DiffTypeBitMask, t1) { - /* left */ - for (tp = BL(tile); BOTTOM(tp) < TOP(tile); tp=RT(tp)) + /* 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))); + GeoTransRect(&scx->scx_trans, &devArea, &thisDev->area); + thisDev->type = TiGetType(tp); + thisDev->nextDev = DevList; + DevList = thisDev; + ResCalcPerimOverlap(thisDev, tp); + } + } + + /* 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) { - 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; + 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) - */ + * 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]; + TileTypeBitMask *mask = &ExtCurStyle->exts_subsTransistorTypes[t1]; - for (pNum = PL_TECHDEPBASE; pNum < DBNumPlanes; pNum++) - { - if (TTMaskIntersect(&DBPlaneTypes[pNum], mask)) - { - (void)DBSrPaintArea((Tile *) NULL, + for (pNum = PL_TECHDEPBASE; pNum < DBNumPlanes; pNum++) + { + if (TTMaskIntersect(&DBPlaneTypes[pNum], mask)) + { + DBSrPaintArea((Tile *) NULL, scx->scx_use->cu_def->cd_planes[pNum], - &tileArea,mask,resSubSearchFunc, (ClientData) cx); - } - } + &tileArea, mask, resSubSearchFunc, (ClientData)cx); + } + } } #endif GeoTransRect(&scx->scx_trans, &tileArea, &newarea); @@ -248,7 +251,6 @@ dbcConnectFuncDCS(tile, cx) 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 */ @@ -256,12 +258,12 @@ dbcConnectFuncDCS(tile, cx) { if (dinfo & TT_SIDE) /* right */ newarea.r_xtop += 1; - else /* left */ + else /* left */ newarea.r_xbot -= 1; if (((dinfo & TT_SIDE) >> 1) == (dinfo & TT_DIRECTION)) /* top */ newarea.r_ytop += 1; - else /* bottom */ + else /* bottom */ newarea.r_ybot -= 1; } else @@ -322,55 +324,43 @@ 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; + 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)); - } + /* 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*/ + + /* 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)); - } - + 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)) + + /* 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)); - } - + if TTMaskHasType(&(ExtCurStyle->exts_nodeConn[t1]), TiGetType(tp)) + overlap += MIN(RIGHT(tile), RIGHT(tp)) - MAX(LEFT(tile), LEFT(tp)); } - /*bottom */ + + /* 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)); - } - + if TTMaskHasType(&(ExtCurStyle->exts_nodeConn[t1]), TiGetType(tp)) + overlap += MIN(RIGHT(tile), RIGHT(tp)) - MAX(LEFT(tile), LEFT(tp)); } dev->overlap = overlap; } @@ -516,30 +506,28 @@ DBTreeCopyConnectDCS(scx, mask, xMask, connect, area, destUse) */ int -resSubSearchFunc(tile,cx) - Tile *tile; - TreeContext *cx; - - +resSubSearchFunc(tile, cx) + Tile *tile; + TreeContext *cx; { - ResDevTile *thisDev; - Rect devArea; - TileType t = TiGetType(tile); - ExtDevice *devptr; + 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. + /* 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; + 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); + ResCalcPerimOverlap(thisDev, tile); return 0; } 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 13190c44..2ceaefb6 100644 --- a/resis/ResMain.c +++ b/resis/ResMain.c @@ -574,18 +574,18 @@ ResProcessTiles(goodies, origin) */ bool -ResExtractNet(startlist, goodies, cellname) - ResFixPoint *startlist; +ResExtractNet(fix, goodies, cellname) + ResFixPoint *fix; ResGlobalParams *goodies; char *cellname; { SearchContext scx; int pNum; - ResDevTile *DevTiles, *lasttile; + ResDevTile *DevTiles; TileTypeBitMask FirstTileMask; Point startpoint; - ResFixPoint *fix; static int first = 1; + ResDevTile *newdevtiles, *tmp; /* Make sure all global network variables are reset */ @@ -601,7 +601,7 @@ ResExtractNet(startlist, goodies, cellname) 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) { @@ -640,43 +640,28 @@ ResExtractNet(startlist, goodies, cellname) /* Copy Paint */ DevTiles = NULL; - lasttile = NULL; - for (fix = startlist; fix != NULL; fix = fix->fp_next) - { - ResDevTile *newdevtiles, *tmp; #ifdef ARIEL - if ((ResOptionsFlags & ResOpt_Power) && + if ((ResOptionsFlags & ResOpt_Power) && strcmp(fix->fp_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; + 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; - /* 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. - */ - TTMaskZero(&FirstTileMask); - TTMaskSetMask(&FirstTileMask, &DBConnectTbl[fix->fp_ttype]); + /* 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. + */ + TTMaskZero(&FirstTileMask); + TTMaskSetMask(&FirstTileMask, &DBConnectTbl[fix->fp_ttype]); - newdevtiles = DBTreeCopyConnectDCS(&scx, &FirstTileMask, 0, + DevTiles = DBTreeCopyConnectDCS(&scx, &FirstTileMask, 0, ResCopyMask, &TiPlaneRect, ResUse); - for (tmp = newdevtiles; tmp && tmp->nextDev; tmp = tmp->nextDev); - if (newdevtiles) - { - if (DevTiles) - lasttile->nextDev = newdevtiles; - else - DevTiles = newdevtiles; - lasttile = tmp; - } - } - ExtResetTiles(scx.scx_use->cu_def, extUnInit); /* Find all contacts in design and note their position */ 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/ResRex.c b/resis/ResRex.c index 8b34acd4..ace19b58 100644 --- a/resis/ResRex.c +++ b/resis/ResRex.c @@ -53,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; @@ -478,9 +479,10 @@ 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 @@ -488,13 +490,13 @@ typedef enum { fp.fp_loc = rect.r_ll; fp.fp_next = NULL; if (ResExtractNet(&fp, &gparams, NULL) != 0) return; - ResPrintResistorList(stdout,ResResList); - ResPrintDeviceList(stdout,ResRDevList); + ResPrintResistorList(stdout, ResResList); + ResPrintDeviceList(stdout, ResRDevList); #ifdef LAPLACE if (ResOptionsFlags & ResOpt_DoLaplace) { TxPrintf("Laplace solved: %d matched %d\n", - LaplaceMissCount,LaplaceMatchCount); + LaplaceMissCount, LaplaceMatchCount); } #endif @@ -521,11 +523,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: @@ -548,7 +550,7 @@ typedef enum { } ResOptionsFlags |= ResOpt_Signal; #ifdef ARIEL - ResOptionsFlags &= ~ResOpt_Power; + ResOptionsFlags &= ~ResOpt_Power; #endif resisdata.tolerance = tolerance; @@ -610,8 +612,6 @@ resSubcircuitFunc(cellDef, rdata) return 0; } - - /* *------------------------------------------------------------------------- * @@ -870,7 +870,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 { @@ -879,7 +879,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; } @@ -1071,8 +1071,8 @@ ResCheckSimNodes(celldef, resisdata) fp.fp_next = NULL; if (ResExtractNet(&fp, &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 { @@ -1091,7 +1091,7 @@ ResCheckSimNodes(celldef, resisdata) } } #ifdef PARANOID - ResSanityChecks(node->name,ResResList,ResNodeList,ResDevList); + ResSanityChecks(node->name, ResResList, ResNodeList, ResDevList); #endif ResCleanUpEverything(); } @@ -1104,7 +1104,7 @@ ResCheckSimNodes(celldef, resisdata) if (ResOptionsFlags & ResOpt_DoExtFile) { - ResPrintExtDev(ResExtFile,ResRDevList); + ResPrintExtDev(ResExtFile, ResRDevList); } /* @@ -1427,9 +1427,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) @@ -1555,7 +1556,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/ResUtils.c b/resis/ResUtils.c index 1e305705..778a9b9a 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; @@ -205,7 +204,7 @@ ResAddPlumbing(tile, arg) /* find diffusion (if present) to be source contact */ /* top */ - for (tp2= RT(tile); RIGHT(tp2) > LEFT(tile); tp2 = BL(tp2)) + for (tp2 = RT(tile); RIGHT(tp2) > LEFT(tile); tp2 = BL(tp2)) { if TTMaskHasType(&(devptr->exts_deviceSDTypes[0]), TiGetBottomType(tp2)) @@ -218,9 +217,9 @@ ResAddPlumbing(tile, arg) } } - /*bottom*/ + /* bottom */ if (source == NULL) - for (tp2= LB(tile); LEFT(tp2) < RIGHT(tile); tp2 = TR(tp2)) + for (tp2 = LB(tile); LEFT(tp2) < RIGHT(tile); tp2 = TR(tp2)) { if TTMaskHasType(&(devptr->exts_deviceSDTypes[0]), TiGetTopType(tp2)) @@ -233,9 +232,9 @@ ResAddPlumbing(tile, arg) } } - /*right*/ + /* right */ if (source == NULL) - for (tp2= TR(tile); TOP(tp2) > BOTTOM(tile); tp2 = LB(tp2)) + for (tp2 = TR(tile); TOP(tp2) > BOTTOM(tile); tp2 = LB(tp2)) { if TTMaskHasType(&(devptr->exts_deviceSDTypes[0]), TiGetLeftType(tp2)) @@ -248,9 +247,9 @@ ResAddPlumbing(tile, arg) } } - /*left*/ + /* left */ if (source == NULL) - for (tp2= BL(tile); BOTTOM(tp2) < TOP(tile); tp2 = RT(tp2)) + for (tp2 = BL(tile); BOTTOM(tp2) < TOP(tile); tp2 = RT(tp2)) { if TTMaskHasType(&(devptr->exts_deviceSDTypes[0]), TiGetRightType(tp2)) @@ -273,7 +272,7 @@ ResAddPlumbing(tile, arg) if (source != (Tile *) NULL) { - STACKPUSH((ClientData) (source),resDevStack); + STACKPUSH((ClientData)source, resDevStack); } while (!StackEmpty(resDevStack)) { @@ -287,54 +286,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 +341,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,13 +358,13 @@ 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); + STACKPUSH((ClientData)tp2, resDevStack); Junk->deviceList = resDev; Junk->tj_status |= RES_TILE_DEV; @@ -378,14 +377,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 +396,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 +440,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 +457,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,17 +528,17 @@ 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); } @@ -627,7 +626,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 +665,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 +690,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); } From 1c0dbc907ad8a5d9f9c3ec16306d6b9bbb8b3c5b Mon Sep 17 00:00:00 2001 From: Tim Edwards Date: Thu, 27 May 2021 16:13:06 -0400 Subject: [PATCH 13/30] Recast all uses of resist-class and device class in routines using code from extflat from type unsigned long to type TileTypeBitMask. This increases the number of types of each to 256 and tracks the number of types, so it should be difficult to exceed this amount. --- ext2sim/ext2sim.c | 36 ++++++++++++++-------------- ext2spice/ext2hier.c | 8 +++---- ext2spice/ext2spice.c | 56 +++++++++++++++++++++---------------------- ext2spice/ext2spice.h | 26 +++++++------------- extflat/EFantenna.c | 18 +++++++------- extflat/EFbuild.c | 4 ++-- extflat/extflat.h | 3 --- resis/ResRex.c | 4 ++-- 8 files changed, 71 insertions(+), 84 deletions(-) diff --git a/ext2sim/ext2sim.c b/ext2sim/ext2sim.c index ce0ad59b..9ef866c8 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; @@ -1402,7 +1402,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 1cba8f8d..bd7aaf81 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..ea423a51 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,26 @@ 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; \ + 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 d6e3f500..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 */ @@ -232,12 +232,12 @@ runantennacheck: idx = 0; while (ExtGetDevInfo(idx++, &devname, NULL, NULL, NULL, NULL, NULL)) { - if (idx == MAXDEVTYPES) + if (idx == TT_MAXTYPES) { TxError("Error: Ran out of space for device types!\n"); break; } - efBuildAddStr(EFDevTypes, &EFDevNumTypes, MAXDEVTYPES, devname); + efBuildAddStr(EFDevTypes, &EFDevNumTypes, TT_MAXTYPES, devname); } /* Build device lookup table */ diff --git a/extflat/EFbuild.c b/extflat/EFbuild.c index 21db87ab..07d59fdd 100644 --- a/extflat/EFbuild.c +++ b/extflat/EFbuild.c @@ -49,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 */ @@ -802,7 +802,7 @@ efBuildDevice(def, class, type, r, argc, argv) nterminals = (argc - argstart) / 3; - dev_type = efBuildAddStr(EFDevTypes, &EFDevNumTypes, MAXDEVTYPES, type); + dev_type = efBuildAddStr(EFDevTypes, &EFDevNumTypes, TT_MAXTYPES, type); /* Determine if this device has been seen before */ /* NOTE: This is done by tile type, not name, because the extresist 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/resis/ResRex.c b/resis/ResRex.c index ace19b58..f2d99a51 100644 --- a/resis/ResRex.c +++ b/resis/ResRex.c @@ -109,12 +109,12 @@ ExtResisForDef(celldef, resisdata) idx = 0; while (ExtGetDevInfo(idx++, &devname, NULL, NULL, NULL, NULL, NULL)) { - if (idx == MAXDEVTYPES) + if (idx == TT_MAXTYPES) { TxError("Error: Ran out of space for device types!\n"); break; } - efBuildAddStr(EFDevTypes, &EFDevNumTypes, MAXDEVTYPES, devname); + efBuildAddStr(EFDevTypes, &EFDevNumTypes, TT_MAXTYPES, devname); } HashInit(&ResNodeTable, INITFLATSIZE, HT_STRINGKEYS); From 7d6c7f5797d452e19811c22b68a5a0843be0574e Mon Sep 17 00:00:00 2001 From: Tim Edwards Date: Thu, 27 May 2021 16:15:56 -0400 Subject: [PATCH 14/30] Updated the version number. --- VERSION | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/VERSION b/VERSION index 367f6320..cae37761 100644 --- a/VERSION +++ b/VERSION @@ -1 +1 @@ -8.3.170 +8.3.171 From a8fcca13ee2342a707f30930398ccf0539a8546a Mon Sep 17 00:00:00 2001 From: Tim Edwards Date: Tue, 1 Jun 2021 10:25:34 -0400 Subject: [PATCH 15/30] Corrected an error in the implementation of the CIF "mask-hints" operator that failed to set cifplane to curplane before drawing into it. This can cause the "mask-hints" layers to vanish, or worse, cause a segfault. --- VERSION | 2 +- cif/CIFgen.c | 3 ++- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/VERSION b/VERSION index cae37761..49b7564b 100644 --- a/VERSION +++ b/VERSION @@ -1 +1 @@ -8.3.171 +8.3.172 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++) { From 0503ce0ebf05768ef8ba91ecb662c0a0e311c240 Mon Sep 17 00:00:00 2001 From: Tim Edwards Date: Fri, 4 Jun 2021 12:26:11 -0400 Subject: [PATCH 16/30] Corrected the "surround_ok" spacing rule, which did not prevent the layers2->layers1 swapped case from being implemented; the surround_ok rule type is by definition asymmetric and the two layer sets cannot just be swapped. --- VERSION | 2 +- drc/DRCtech.c | 7 +++++-- 2 files changed, 6 insertions(+), 3 deletions(-) diff --git a/VERSION b/VERSION index 49b7564b..bd9847a9 100644 --- a/VERSION +++ b/VERSION @@ -1 +1 @@ -8.3.172 +8.3.173 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); From 78be76a65075fc338da3c22514c2f9047745935a Mon Sep 17 00:00:00 2001 From: Tim Edwards Date: Sat, 5 Jun 2021 17:02:39 -0400 Subject: [PATCH 17/30] Corrected a potential crash condition if attempting to read a GDS cell without any edit cell defined. --- VERSION | 2 +- calma/CalmaRead.c | 6 ++++++ 2 files changed, 7 insertions(+), 1 deletion(-) diff --git a/VERSION b/VERSION index bd9847a9..fd696242 100644 --- a/VERSION +++ b/VERSION @@ -1 +1 @@ -8.3.173 +8.3.174 diff --git a/calma/CalmaRead.c b/calma/CalmaRead.c index 9857f8d0..64139209 100644 --- a/calma/CalmaRead.c +++ b/calma/CalmaRead.c @@ -164,6 +164,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); From 35b60531e5dd7af758b4975918deee55bc21c628 Mon Sep 17 00:00:00 2001 From: Tim Edwards Date: Sun, 6 Jun 2021 21:44:52 -0400 Subject: [PATCH 18/30] Corrected CalmaRead to remove a syntax error that managed to end up in the last commit, unfortunately. Thanks to Matt Guthaus for alerting me to this. Also updated parts of the extresist code that remove the dependence on ResConDCS; this is a minor update and should not affect the operation of extresist. It is preparatory to doing more work to support additional device types like capacitors, bipolars, and diodes. --- VERSION | 2 +- calma/CalmaRead.c | 3 +- ext2sim/ext2sim.c | 3 - resis/Makefile | 2 +- resis/ResConDCS.c | 535 --------------------------------------------- resis/ResMain.c | 161 ++++++++++++-- resis/ResMerge.c | 1 + resis/ResReadSim.c | 36 ++- resis/ResRex.c | 14 +- resis/ResUtils.c | 9 +- resis/resis.h | 4 +- 11 files changed, 177 insertions(+), 593 deletions(-) delete mode 100644 resis/ResConDCS.c diff --git a/VERSION b/VERSION index fd696242..90d348e0 100644 --- a/VERSION +++ b/VERSION @@ -1 +1 @@ -8.3.174 +8.3.175 diff --git a/calma/CalmaRead.c b/calma/CalmaRead.c index 64139209..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 */ @@ -167,7 +168,7 @@ CalmaReadFile(file, filename) if (EditCellUse == (CellUse *)NULL) { TxError("Cannot read GDS: There is no edit cell.\n"); - return + return; } /* We will use full cell names as keys in this hash table */ diff --git a/ext2sim/ext2sim.c b/ext2sim/ext2sim.c index 9ef866c8..507dd1ea 100644 --- a/ext2sim/ext2sim.c +++ b/ext2sim/ext2sim.c @@ -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)) { 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/ResConDCS.c b/resis/ResConDCS.c deleted file mode 100644 index fb8c695f..00000000 --- a/resis/ResConDCS.c +++ /dev/null @@ -1,535 +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))); - GeoTransRect(&scx->scx_trans, &devArea, &thisDev->area); - thisDev->type = TiGetType(tp); - thisDev->nextDev = DevList; - DevList = thisDev; - ResCalcPerimOverlap(thisDev, tp); - } - } - - /* 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)) - { - 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); - - /* 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/ResMain.c b/resis/ResMain.c index 2ceaefb6..f338d7fc 100644 --- a/resis/ResMain.c +++ b/resis/ResMain.c @@ -20,6 +20,7 @@ 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" @@ -560,7 +561,103 @@ ResProcessTiles(goodies, origin) 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, @@ -574,18 +671,20 @@ ResProcessTiles(goodies, origin) */ bool -ResExtractNet(fix, goodies, cellname) - ResFixPoint *fix; +ResExtractNet(node, goodies, cellname) + ResSimNode *node; ResGlobalParams *goodies; char *cellname; { SearchContext scx; int pNum; - ResDevTile *DevTiles; TileTypeBitMask FirstTileMask; Point startpoint; static int first = 1; - ResDevTile *newdevtiles, *tmp; + ResDevTile *DevTiles, *thisDev; + ResFixPoint *fix; + devPtr *tptr; + int resMakeDevFunc(); /* Make sure all global network variables are reset */ @@ -638,29 +737,55 @@ ResExtractNet(fix, goodies, cellname) DBCellClearDef(ResUse->cu_def); - /* Copy Paint */ - DevTiles = NULL; - #ifdef ARIEL if ((ResOptionsFlags & ResOpt_Power) && - strcmp(fix->fp_name, goodies->rg_name) != 0) continue; + 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 + 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; + + /* 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[fix->fp_ttype]); + TTMaskSetMask(&FirstTileMask, &DBConnectTbl[node->type]); - DevTiles = DBTreeCopyConnectDCS(&scx, &FirstTileMask, 0, - ResCopyMask, &TiPlaneRect, ResUse); + /* DevTiles = DBTreeCopyConnectDCS(&scx, &FirstTileMask, 0, + ResCopyMask, &TiPlaneRect, ResUse); */ + 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); diff --git a/resis/ResMerge.c b/resis/ResMerge.c index 4882dbde..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]; diff --git a/resis/ResReadSim.c b/resis/ResReadSim.c index a969404d..74ccd7e3 100644 --- a/resis/ResReadSim.c +++ b/resis/ResReadSim.c @@ -207,7 +207,7 @@ ResReadSim(simfile, fetproc, capproc, resproc, attrproc, mergeproc, subproc) devptr = ExtCurStyle->exts_device[fettype]; sheetr = (float)devptr->exts_linearResist; - result = (*fetproc)(line, sheetr, fettype); + result = (*fetproc)(line, sheetr, devptr); } if (result != 0) { @@ -374,6 +374,8 @@ ResSimSubckt(line) 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; @@ -402,33 +404,29 @@ 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; /* Subcircuit types may not have a length or width value, in which */ /* case it is zero. Don't induce a divide-by-zero error. */ @@ -454,8 +452,6 @@ ResSimSubckt(line) return rvalue; } - - /* *------------------------------------------------------------------------- * @@ -469,10 +465,10 @@ ResSimSubckt(line) */ int -ResSimDevice(line, rpersquare, ttype) +ResSimDevice(line, rpersquare, devptr) char line[][MAXTOKEN]; float rpersquare; - TileType ttype; + ExtDevice *devptr; { RDev *device; @@ -511,7 +507,7 @@ ResSimDevice(line, rpersquare, ttype) device->rs_gattr=RDEV_NOATTR; device->rs_sattr=RDEV_NOATTR; device->rs_dattr=RDEV_NOATTR; - device->rs_ttype = ttype; + device->rs_devptr = devptr; device->gate = device->source = device->drain = device->subs = NULL; diff --git a/resis/ResRex.c b/resis/ResRex.c index f2d99a51..64caa1a4 100644 --- a/resis/ResRex.c +++ b/resis/ResRex.c @@ -464,7 +464,7 @@ typedef enum { CellDef *def; Rect rect; int oldoptions; - ResFixPoint fp; + ResSimNode lnode; if (ToolGetBoxWindow((Rect *) NULL, (int *) NULL) == NULL) { @@ -486,10 +486,9 @@ typedef enum { 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; + lnode.location = rect.r_ll; + lnode.type = tt; + if (ResExtractNet(&lnode, &gparams, NULL) != 0) return; ResPrintResistorList(stdout, ResResList); ResPrintDeviceList(stdout, ResRDevList); #ifdef LAPLACE @@ -1066,10 +1065,7 @@ ResCheckSimNodes(celldef, resisdata) 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) { /* On error, don't output this net, but keep going */ TxError("Error in extracting node %s\n", node->name); diff --git a/resis/ResUtils.c b/resis/ResUtils.c index 778a9b9a..31e35201 100644 --- a/resis/ResUtils.c +++ b/resis/ResUtils.c @@ -545,7 +545,7 @@ ResRemovePlumbing(tile, arg) /* *------------------------------------------------------------------------- * - * 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 @@ -603,8 +603,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, @@ -626,7 +627,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; diff --git a/resis/resis.h b/resis/resis.h index 9507df0f..1594346a 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; From 36f61ca6010cc1d46ffec07606213b990a865235 Mon Sep 17 00:00:00 2001 From: Tim Edwards Date: Mon, 7 Jun 2021 16:38:12 -0400 Subject: [PATCH 19/30] Modified the CIF/GDS array processing in CIFhier.c, finding that there were incorrect assumptions made in the code from 35 years back or so, for the case where the CIF layer halo is larger than the size/separation of the cells in the array. The new code will prevent the array routine from copying hierarchical additions to the mask layers outside of the array area. Whether or not the new code has its own faulty assumptions remains to be seen through thorough vetting. --- VERSION | 2 +- cif/CIFhier.c | 288 ++++++++++++++++++++++++++++++++++++-------------- 2 files changed, 207 insertions(+), 83 deletions(-) diff --git a/VERSION b/VERSION index 90d348e0..683e77d6 100644 --- a/VERSION +++ b/VERSION @@ -1 +1 @@ -8.3.175 +8.3.176 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; } From e9f21885b3d93ad396f534ff0c136c728b59edcc Mon Sep 17 00:00:00 2001 From: Tim Edwards Date: Fri, 11 Jun 2021 16:53:23 -0400 Subject: [PATCH 20/30] Corrected an error in initNodeClient in ext2spice that uses TTMaskSetMask() like = instead of |=, which doesn't work because the mask is uninitialized. --- ext2spice/ext2spice.h | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/ext2spice/ext2spice.h b/ext2spice/ext2spice.h index ea423a51..4a30d847 100644 --- a/ext2spice/ext2spice.h +++ b/ext2spice/ext2spice.h @@ -132,7 +132,8 @@ typedef struct { #define initNodeClient(node) \ { \ (node)->efnode_client = (ClientData) mallocMagic((unsigned) (sizeof(nodeClient))); \ - (( nodeClient *)(node)->efnode_client)->spiceNodeName = NULL; \ + (( nodeClient *)(node)->efnode_client)->spiceNodeName = NULL; \ + TTMaskZero (&((nodeClient *) (node)->efnode_client)->m_w.visitMask); \ TTMaskSetMask(&(((nodeClient *)(node)->efnode_client)->m_w.visitMask), &initMask);\ } From 75386e64678f079acf17dc5efb947366f1d06845 Mon Sep 17 00:00:00 2001 From: Tim Edwards Date: Sat, 12 Jun 2021 11:40:13 -0400 Subject: [PATCH 21/30] Corrected the GDS read routine so that the "gds noduplicates" option does not get undermined by GDS files that have cell instances appear before cell definitions. --- VERSION | 2 +- calma/CalmaRdcl.c | 14 +++++++++++++- 2 files changed, 14 insertions(+), 2 deletions(-) diff --git a/VERSION b/VERSION index 683e77d6..8700effb 100644 --- a/VERSION +++ b/VERSION @@ -1 +1 @@ -8.3.176 +8.3.177 diff --git a/calma/CalmaRdcl.c b/calma/CalmaRdcl.c index 71be0d79..04ae21df 100644 --- a/calma/CalmaRdcl.c +++ b/calma/CalmaRdcl.c @@ -1262,7 +1262,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); } From df26cf1acef50b21b3b512645ac9f1c0821ab856 Mon Sep 17 00:00:00 2001 From: Tim Edwards Date: Sat, 12 Jun 2021 20:29:09 -0400 Subject: [PATCH 22/30] This corrects the issue raised in pull request #75 that breaks the compile on clang and probably other finicky compilers (as well as just being wrong). --- extract/ExtCell.c | 2 +- utils/ihash.h | 1 + 2 files changed, 2 insertions(+), 1 deletion(-) 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/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 */ From 6e09586c5482c782250d02c8fd654067f2b3ff4c Mon Sep 17 00:00:00 2001 From: Tim Edwards Date: Sun, 13 Jun 2021 12:23:07 -0400 Subject: [PATCH 23/30] Changed the property attribute number used for cell instance names from 98 (arbitrarily selected) to 61 (apparently commonly used by other tools). This should help increase compatibility with GDS files output from other tools. --- VERSION | 2 +- calma/CalmaRdcl.c | 3 ++- calma/CalmaWrite.c | 2 +- calma/calmaInt.h | 1 + 4 files changed, 5 insertions(+), 3 deletions(-) diff --git a/VERSION b/VERSION index 8700effb..195161e2 100644 --- a/VERSION +++ b/VERSION @@ -1 +1 @@ -8.3.177 +8.3.178 diff --git a/calma/CalmaRdcl.c b/calma/CalmaRdcl.c index 04ae21df..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; diff --git a/calma/CalmaWrite.c b/calma/CalmaWrite.c index cb1857cd..de67873b 100644 --- a/calma/CalmaWrite.c +++ b/calma/CalmaWrite.c @@ -1346,7 +1346,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 */ From b335dfafff1f412c396807fd2af65046860b4a54 Mon Sep 17 00:00:00 2001 From: Tim Edwards Date: Sun, 13 Jun 2021 20:17:19 -0400 Subject: [PATCH 24/30] Modified the node merging in ExtHier.c to match the node merging optimization done in ExtFlat, which is to keep a count of the number of different node names assigned to the node so that when merging, the one with fewer nodes can be updated to match the one with more nodes. Note: This change is made on the assumption that the names for node1 and node2 are equally preferred. Supposedly the first name in the node list is canonical, so if node1 is preferred in any case, it may be necessary to move the first item of the second list to the beginning (a minor code change). --- extract/ExtHier.c | 157 ++++++++++++++++++++++++++++++++----------- extract/extractInt.h | 1 + 2 files changed, 117 insertions(+), 41 deletions(-) diff --git a/extract/ExtHier.c b/extract/ExtHier.c index 8056a8e9..a16c4702 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; + node2->node_names = 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; + node2->node_names = 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; + node2->node_names = 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; + node2->node_names = 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/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 From 37c5355b8f62147f0ef0400bd7b6a2e4028a1017 Mon Sep 17 00:00:00 2001 From: Tim Edwards Date: Sun, 13 Jun 2021 21:47:33 -0400 Subject: [PATCH 25/30] A very minor change to the code of the last commit preserves the behavior of keeping the same first record when merging two nodes. This does not seem to have any effect on extraction output. But since the order of nodes can make a difference and there is no performance impact in the code change, I will keep it as-is. --- extract/ExtHier.c | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/extract/ExtHier.c b/extract/ExtHier.c index a16c4702..83b58587 100644 --- a/extract/ExtHier.c +++ b/extract/ExtHier.c @@ -211,8 +211,8 @@ extHierSubstrate(ha, use, x, y) 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; - node2->node_names = node1->node_names; + 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); } @@ -412,8 +412,8 @@ extHierConnectFunc1(oneTile, ha) 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; - node2->node_names = node1->node_names; + 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); } @@ -516,8 +516,8 @@ extHierConnectFunc2(cum, ha) 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; - node2->node_names = node1->node_names; + 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); } @@ -618,8 +618,8 @@ extHierConnectFunc3(cum, ha) 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; - node2->node_names = node1->node_names; + 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); } From 39630ea710d85bddab8f43b94c4bd48f0256c2c9 Mon Sep 17 00:00:00 2001 From: Tim Edwards Date: Mon, 14 Jun 2021 09:45:36 -0400 Subject: [PATCH 26/30] Added missing function declaration for GeoCanonicalRect in geometry.h. --- VERSION | 2 +- utils/geometry.h | 3 ++- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/VERSION b/VERSION index 195161e2..8975ef2d 100644 --- a/VERSION +++ b/VERSION @@ -1 +1 @@ -8.3.178 +8.3.179 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 *); /* *------------------------------------------------------------------- From e55c1ecbdae1d0545a684d33a97f35ab6881f6d9 Mon Sep 17 00:00:00 2001 From: Tim Edwards Date: Thu, 17 Jun 2021 12:40:21 -0400 Subject: [PATCH 27/30] Corrected issues with GDS write that come from two features recently introduced: The use of substitutions for PDKPATH and home directory in path names for GDS files referenced in abstract views, and the "gds addendum" option. Both were interfering with magic's handling of writing GDS files from abstract layout views. --- VERSION | 2 +- calma/CalmaWrite.c | 112 ++++++++++++++++++++++++++++++++++++------ database/DBcellname.c | 5 +- 3 files changed, 100 insertions(+), 19 deletions(-) diff --git a/VERSION b/VERSION index 8975ef2d..281008b3 100644 --- a/VERSION +++ b/VERSION @@ -1 +1 @@ -8.3.179 +8.3.180 diff --git a/calma/CalmaWrite.c b/calma/CalmaWrite.c index de67873b..5e895d95 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 @@ -355,6 +360,22 @@ CalmaWrite(rootDef, f) HashFreeKill(&calmaLibHash); HashKill(&calmaPrefixHash); + + /* + * 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). + */ + HashStartSearch(&hs); + while ((he = HashNext(&calmaUndefHash, &hs)) != NULL) + { + char *refname = (char *)HashGetValue(he); + if (refname && (refname[0] == '0')) + TxError("Error: Cell %s is not defined in the output file!\n", + refname + 1); + } + + HashFreeKill(&calmaUndefHash); return (good); } @@ -409,14 +430,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 +510,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 +545,7 @@ calmaDumpStructure(def, outf, calmaDefHash, filename) HashSetValue(he, (char *)newnameptr); } } - if (dotptr) *dotptr = '.'; + if (filenamesubbed) freeMagic(filenamesubbed); } else { @@ -614,11 +672,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 +704,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 +736,6 @@ calmaFullDump(def, fi, outf, filename) */ while (TRUE) { - HashEntry *he2; - rval = random() % 26; rval = 'A' + rval; uniqlibname[0] = (char)(rval & 127); @@ -700,6 +762,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; 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); } From f001502a1868977a4d9c9fc5a27c09b2589d744c Mon Sep 17 00:00:00 2001 From: Tim Edwards Date: Thu, 17 Jun 2021 12:55:45 -0400 Subject: [PATCH 28/30] One small enhancement to the code of the previous commit: If a cell is referenced by a GDS "addendum" file but is not in either the tree of the root def or any other dumped GDS file, then check the database for those files and output them if they exist. This allows one way to get around missing cells in the GDS output if a cell from a GDS addendum is used but no cells from the library that the file is an addendum of are used. --- calma/CalmaWrite.c | 41 +++++++++++++++++++++++++---------------- 1 file changed, 25 insertions(+), 16 deletions(-) diff --git a/calma/CalmaWrite.c b/calma/CalmaWrite.c index 5e895d95..c4eb4127 100644 --- a/calma/CalmaWrite.c +++ b/calma/CalmaWrite.c @@ -342,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); @@ -360,21 +384,6 @@ CalmaWrite(rootDef, f) HashFreeKill(&calmaLibHash); HashKill(&calmaPrefixHash); - - /* - * 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). - */ - HashStartSearch(&hs); - while ((he = HashNext(&calmaUndefHash, &hs)) != NULL) - { - char *refname = (char *)HashGetValue(he); - if (refname && (refname[0] == '0')) - TxError("Error: Cell %s is not defined in the output file!\n", - refname + 1); - } - HashFreeKill(&calmaUndefHash); return (good); } From e36560fb9021f46465b7bc7f06dcdbfba57b57d8 Mon Sep 17 00:00:00 2001 From: Tim Edwards Date: Sat, 19 Jun 2021 10:30:47 -0400 Subject: [PATCH 29/30] Added a missing include of ctype.h to a source file that uses the isalnum() subroutine. Corrected an assignment in utils/tech.c which was a syntax error that passes through the compiler. --- VERSION | 2 +- resis/ResMain.c | 3 - resis/ResUtils.c | 142 ++++++++++++++++++++++++--------------------- resis/resis.h | 1 + utils/tech.c | 2 +- windows/windMain.c | 1 + 6 files changed, 81 insertions(+), 70 deletions(-) diff --git a/VERSION b/VERSION index 281008b3..86c6b851 100644 --- a/VERSION +++ b/VERSION @@ -1 +1 @@ -8.3.180 +8.3.181 diff --git a/resis/ResMain.c b/resis/ResMain.c index f338d7fc..78e32d29 100644 --- a/resis/ResMain.c +++ b/resis/ResMain.c @@ -46,7 +46,6 @@ extern ResSimNode *ResInitializeNode(); extern HashTable ResNodeTable; - /* *-------------------------------------------------------------------------- * @@ -757,8 +756,6 @@ ResExtractNet(node, goodies, cellname) TTMaskZero(&FirstTileMask); TTMaskSetMask(&FirstTileMask, &DBConnectTbl[node->type]); - /* DevTiles = DBTreeCopyConnectDCS(&scx, &FirstTileMask, 0, - ResCopyMask, &TiPlaneRect, ResUse); */ DBTreeCopyConnect(&scx, &FirstTileMask, 0, ResCopyMask, &TiPlaneRect, SEL_DO_LABELS, ResUse); diff --git a/resis/ResUtils.c b/resis/ResUtils.c index 31e35201..be22317d 100644 --- a/resis/ResUtils.c +++ b/resis/ResUtils.c @@ -200,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)) { @@ -303,7 +315,7 @@ ResAddPlumbing(tile, arg) { 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; @@ -316,7 +328,7 @@ ResAddPlumbing(tile, arg) { 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; @@ -329,7 +341,7 @@ ResAddPlumbing(tile, arg) { 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; @@ -365,7 +377,7 @@ ResAddPlumbing(tile, arg) { Junk = resAddField(tp2); STACKPUSH((ClientData)tp2, resDevStack); - Junk->deviceList = resDev; + Junk->deviceList = resDev; Junk->tj_status |= RES_TILE_DEV; } @@ -465,7 +477,7 @@ ResAddPlumbing(tile, arg) if (j2->tj_status & RES_TILE_SD) { j2->tj_status &= ~RES_TILE_SD; - STACKPUSH((ClientData)tp2 ,resDevStack); + STACKPUSH((ClientData)tp2, resDevStack); } } } diff --git a/resis/resis.h b/resis/resis.h index 1594346a..0c6d95d3 100644 --- a/resis/resis.h +++ b/resis/resis.h @@ -514,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/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" From b0ed7f09a915681caa89490adc8f3eb625bbdd9c Mon Sep 17 00:00:00 2001 From: Tim Edwards Date: Wed, 23 Jun 2021 17:41:32 -0400 Subject: [PATCH 30/30] Modified the "flatten" command so that when used with "-dobox", it is not necessary that the target cell not exist. That allows a layout to be flattened into a destination in pieces. Also found that the "flatten" command never frees memory for the CellUse it creates for the copy, so fixed that as well. --- VERSION | 2 +- commands/CmdFI.c | 13 +++++++++---- 2 files changed, 10 insertions(+), 5 deletions(-) diff --git a/VERSION b/VERSION index 86c6b851..1d110651 100644 --- a/VERSION +++ b/VERSION @@ -1 +1 @@ -8.3.181 +8.3.182 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(); }