diff --git a/VERSION b/VERSION index aabce324..807a67da 100644 --- a/VERSION +++ b/VERSION @@ -1 +1 @@ -8.3.514 +8.3.515 diff --git a/resis/ResPrint.c b/resis/ResPrint.c index 50397eca..33da3857 100644 --- a/resis/ResPrint.c +++ b/resis/ResPrint.c @@ -212,39 +212,54 @@ ResPrintExtDev(outextfile, devices) */ void -ResPrintExtNode(outextfile, nodelist, nodename) +ResPrintExtNode(outextfile, nodelist, node) FILE *outextfile; resNode *nodelist; - char *nodename; + ResSimNode *node; { + char *nodename = node->name; int nodenum = 0; char newname[MAXNAME+32], tmpname[MAXNAME], *cp; HashEntry *entry; - ResSimNode *node, *ResInitializeNode(); + ResSimNode *newnode, *ResInitializeNode(); bool DoKillNode = TRUE; - resNode *snode = nodelist; + bool NeedFix = FALSE; + resNode *snode; /* If any of the subnode names match the original node name, then */ /* we don't want to rip out that node with a "killnode" statement. */ - for (; nodelist != NULL; nodelist = nodelist->rn_more) + for (snode = nodelist; snode != NULL; snode = snode->rn_more) { - if (nodelist->rn_name != NULL) - if (!strcmp(nodelist->rn_name, nodename)) + if (snode->rn_name != NULL) + if (!strcmp(snode->rn_name, nodename)) { DoKillNode = FALSE; break; } } + /* If any device terminal failed to extract for any reason, then */ + /* this node cannot be killed. If it is already marked for killing */ + /* then there are no connections from the node to any of its sub- */ + /* nodes, so create one an flag a warning. Note that this */ + /* condition indicates a fundamental underlying error in device */ + /* extraction, but this prevents magic from generating an invalid */ + /* netlist. */ + + if (node->status & DONTKILL) + if (DoKillNode == TRUE) + { + DoKillNode = FALSE; + NeedFix = TRUE; + } + if ((ResOptionsFlags & ResOpt_DoExtFile) && DoKillNode) - { - fprintf(outextfile, "killnode \"%s\"\n", nodename); - } + fprintf(outextfile, "killnode \"%s\"\n", nodename); /* Create "rnode" entries for each subnode */ - for (; snode != NULL; snode = snode->rn_more) + for (snode = nodelist; snode != NULL; snode = snode->rn_more) { if (snode->rn_name == NULL) { @@ -255,9 +270,9 @@ ResPrintExtNode(outextfile, nodelist, nodename) (void)sprintf(newname, "%s%s%d", tmpname, ".n", nodenum++); entry = HashFind(&ResNodeTable, newname); - node = ResInitializeNode(entry); - snode->rn_name = node->name; - node->oldname = nodename; + newnode = ResInitializeNode(entry); + snode->rn_name = newnode->name; + newnode->oldname = nodename; } if (ResOptionsFlags & ResOpt_DoExtFile) @@ -272,6 +287,18 @@ ResPrintExtNode(outextfile, nodelist, nodename) 0); } } + + if (NeedFix) + { + /* Patch up the output netlist for an orphaned node by + * creating a zero-valued resistance between it and the + * first subnode (arbitrary connection). Flag a warning. + */ + fprintf(outextfile, "resist \"%s\" \"%s\" 0.0\n", + node->name, nodelist->rn_name); + TxError("Warning: Orphaned node \"%s\" arbitrarily attached to \"%s\"\n", + node->name, nodelist->rn_name); + } } /* diff --git a/resis/ResRex.c b/resis/ResRex.c index a721f3b4..e49c9c42 100644 --- a/resis/ResRex.c +++ b/resis/ResRex.c @@ -1363,9 +1363,12 @@ ResFixUpConnections(simDev, layoutDev, simNode, nodename) sprintf(newname, "%s%s%d", nodename, ".t", resNodeNum++); } else + { TxError("Missing gate connection of device at (%d %d) on net %s\n", layoutDev->rd_inside.r_xbot, layoutDev->rd_inside.r_ybot, nodename); + simNode->status |= DONTKILL; + } } if (simDev->subs == simNode) { @@ -1381,9 +1384,12 @@ ResFixUpConnections(simDev, layoutDev, simNode, nodename) sprintf(newname, "%s%s%d", nodename, ".t", resNodeNum++); } else + { TxError("Missing substrate connection of device at (%d %d) on net %s\n", layoutDev->rd_inside.r_xbot, layoutDev->rd_inside.r_ybot, nodename); + simNode->status |= DONTKILL; + } } if (simDev->source == simNode) @@ -1425,9 +1431,12 @@ ResFixUpConnections(simDev, layoutDev, simNode, nodename) /* one to each */ } else + { TxError("Missing terminal connection of device at (%d %d) on net %s\n", layoutDev->rd_inside.r_xbot, layoutDev->rd_inside.r_ybot, nodename); + simNode->status |= DONTKILL; + } } else { @@ -1468,9 +1477,12 @@ ResFixUpConnections(simDev, layoutDev, simNode, nodename) } else + { TxError("Missing terminal connection of device at (%d %d) on net %s\n", layoutDev->rd_inside.r_xbot, layoutDev->rd_inside.r_ybot, nodename); + simNode->status |= DONTKILL; + } } } else if (simDev->drain == simNode) @@ -1525,9 +1537,12 @@ ResFixUpConnections(simDev, layoutDev, simNode, nodename) drain->rn_name = simDev->drain->name; } else + { TxError("Missing terminal connection of device at (%d %d) on net %s\n", layoutDev->rd_inside.r_xbot, layoutDev->rd_inside.r_ybot, nodename); + simNode->status |= DONTKILL; + } } else resNodeNum--; @@ -1845,7 +1860,7 @@ ResWriteExtFile(celldef, node, rctol, nidx, eidx) } if (ResOptionsFlags & ResOpt_DoExtFile) { - ResPrintExtNode(ResExtFile, ResNodeList, node->name); + ResPrintExtNode(ResExtFile, ResNodeList, node); ResPrintExtRes(ResExtFile, ResResList, newname); } if (ResOptionsFlags & ResOpt_FastHenry) diff --git a/resis/resis.h b/resis/resis.h index cc1a7470..bb110b39 100644 --- a/resis/resis.h +++ b/resis/resis.h @@ -494,6 +494,7 @@ typedef struct capval #define DRIVELOC 0x0000100 #define PORTNODE 0x0000200 #define REDUNDANT 0x0000400 +#define DONTKILL 0x0000800 /* Capacitance table constants */ #define RES_CAP_GND 0