Skip to content

Commit

Permalink
Added a fallback method for "extresist" whenever a device terminal
Browse files Browse the repository at this point in the history
connection to a net that has been decomposed into a resistor array
cannot be found.  This indicates some fundamental error in the way
extresist works.  However, it should not be producing an invalid
and unsimulatable netlist.  Instead, it makes an arbitrary connection
from the device terminal to the resistor array and adds an entry in
the output netlist (.res.ext file).  This results in a poor
representation of the resistor network to that terminal, but an
otherwise simulatable netlist.  A warning is issued to note that an
arbitrary connection has been made.  This is most typically a
"garbage in, garbage out" situation in which insufficient information
exists in a layout to inform magic on which direction current is
traveling through a net.  However, it should be possible to rewrite
the extresist code so that magic makes somewhat informed decisions
about current paths and produces a halfway decent representation of
the actual net, instead of just giving up on the detailed extraction.
  • Loading branch information
RTimothyEdwards committed Jan 15, 2025
1 parent 4445663 commit 72368a3
Show file tree
Hide file tree
Showing 4 changed files with 59 additions and 16 deletions.
2 changes: 1 addition & 1 deletion VERSION
Original file line number Diff line number Diff line change
@@ -1 +1 @@
8.3.514
8.3.515
55 changes: 41 additions & 14 deletions resis/ResPrint.c
Original file line number Diff line number Diff line change
Expand Up @@ -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)
{
Expand All @@ -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)
Expand All @@ -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);
}
}

/*
Expand Down
17 changes: 16 additions & 1 deletion resis/ResRex.c
Original file line number Diff line number Diff line change
Expand Up @@ -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)
{
Expand All @@ -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)
Expand Down Expand Up @@ -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
{
Expand Down Expand Up @@ -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)
Expand Down Expand Up @@ -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--;
Expand Down Expand Up @@ -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)
Expand Down
1 change: 1 addition & 0 deletions resis/resis.h
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down

0 comments on commit 72368a3

Please sign in to comment.