Compare commits

...

2 Commits

Author SHA1 Message Date
R. Timothy Edwards d9e6c78adb Corrected an issue that was caused by early work on extresist:
The original version of extresist only worked with 4-terminal FET
devices, and handling of devices with fewer terminals was ignored,
and never properly dealt with.  This commit fixes the issues with
devices such as diodes that have fewer terminals.
2026-05-27 10:52:44 -04:00
R. Timothy Edwards d8580be739 Corrected a problem caused by fixing the "select visible" command
with respect to visible/invisible labels and cells.  The change
inadvertently made the "select area" command option stop selecting
labels on the same type as the layers being selected.  This has
been fixed.
2026-05-26 17:01:45 -04:00
10 changed files with 64 additions and 58 deletions

View File

@ -1 +1 @@
8.3.650 8.3.652

View File

@ -647,6 +647,9 @@ cmdSelectArea(
if (!(crec->dbw_flags & DBW_SEELABELS)) TTMaskClearType(&mask, L_LABEL); if (!(crec->dbw_flags & DBW_SEELABELS)) TTMaskClearType(&mask, L_LABEL);
if (!(crec->dbw_flags & DBW_SEECELLS)) TTMaskClearType(&mask, L_CELL); if (!(crec->dbw_flags & DBW_SEECELLS)) TTMaskClearType(&mask, L_CELL);
} }
else if (option == SEL_AREA)
TTMaskSetType(&mask, L_LABEL);
SelectArea(&scx, &mask, crec->dbw_bitmask, globmatch); SelectArea(&scx, &mask, crec->dbw_bitmask, globmatch);
} }

View File

@ -48,7 +48,7 @@ ResNewSDDevice(tile, tp, xj, yj, direction, PendingList)
int xj, yj, direction; int xj, yj, direction;
resNode **PendingList; resNode **PendingList;
{ {
resNode *resptr; resNode *resptr = NULL;
resDevice *resDev; resDevice *resDev;
tElement *tcell; tElement *tcell;
int newnode; int newnode;
@ -64,7 +64,8 @@ ResNewSDDevice(tile, tp, xj, yj, direction, PendingList)
ri = (resInfo *) TiGetClientPTR(tp); ri = (resInfo *) TiGetClientPTR(tp);
resDev = ri->deviceList; resDev = ri->deviceList;
if ((ri->sourceEdge & direction) != 0) if ((((ri->sourceEdge & direction) != 0) && (resDev->rd_nterms == 4))
|| (resDev->rd_nterms > 2))
{ {
if (resDev->rd_fet_source == (resNode *) NULL) if (resDev->rd_fet_source == (resNode *) NULL)
{ {
@ -73,11 +74,9 @@ ResNewSDDevice(tile, tp, xj, yj, direction, PendingList)
resDev->rd_fet_source = resptr; resDev->rd_fet_source = resptr;
} }
else else
{
resptr = resDev->rd_fet_source; resptr = resDev->rd_fet_source;
}
} }
else else if (resDev->rd_nterms > 3)
{ {
if (resDev->rd_fet_drain == (resNode *) NULL) if (resDev->rd_fet_drain == (resNode *) NULL)
{ {
@ -86,9 +85,7 @@ ResNewSDDevice(tile, tp, xj, yj, direction, PendingList)
resDev->rd_fet_drain = resptr; resDev->rd_fet_drain = resptr;
} }
else else
{
resptr = resDev->rd_fet_drain; resptr = resDev->rd_fet_drain;
}
} }
if (newnode) if (newnode)
{ {
@ -99,7 +96,10 @@ ResNewSDDevice(tile, tp, xj, yj, direction, PendingList)
resptr->rn_te = tcell; resptr->rn_te = tcell;
ResAddToQueue(resptr, PendingList); ResAddToQueue(resptr, PendingList);
} }
NEWBREAK(resptr, tile, xj, yj, NULL); if (resptr != NULL)
{
NEWBREAK(resptr, tile, xj, yj, NULL);
}
} }
/* /*
@ -131,20 +131,14 @@ ResNewSubDevice(tile, tp, xj, yj, direction, PendingList)
ri = (resInfo *) TiGetClientPTR(tp); ri = (resInfo *) TiGetClientPTR(tp);
resDev = ri->deviceList; resDev = ri->deviceList;
/* Arrived at a device that has a terminal connected to substrate */ if (resDev->rd_fet_subs == (resNode *)NULL)
/* that is not a FET bulk terminal (e.g., varactor, diode). */
if (resDev->rd_nterms < 4) return;
if (resDev->rd_fet_subs == (resNode *) NULL)
{ {
resptr = (resNode *) mallocMagic((unsigned)(sizeof(resNode))); resptr = (resNode *) mallocMagic((unsigned)(sizeof(resNode)));
newnode = TRUE; newnode = TRUE;
resDev->rd_fet_subs = resptr; resDev->rd_fet_subs = resptr;
} }
else else
{ resptr = resDev->rd_fet_subs;
resptr = resDev->rd_fet_subs;
}
if (newnode) if (newnode)
{ {

View File

@ -76,10 +76,9 @@ ResCalcTileResistance(tile, info, pendingList, doneList)
if (x < MinX) MinX = x; if (x < MinX) MinX = x;
if (y > MaxY) MaxY = y; if (y > MaxY) MaxY = y;
if (y < MinY) MinY = y; if (y < MinY) MinY = y;
if (p1->br_this->rn_why == RES_NODE_DEVICE) if (p1->br_this->rn_why == RES_NODE_DEVICE)
{
device = TRUE; device = TRUE;
}
} }
/* Finally, produce resistors for partition. Keep track of */ /* Finally, produce resistors for partition. Keep track of */
@ -248,7 +247,7 @@ ResCalcEastWest(tile, pendingList, doneList, resList)
} }
else else
{ {
p3 = p2->br_next; p3 = p2->br_next;
while (p3 != NULL) while (p3 != NULL)
{ {
if (p3->br_this == currNode) if (p3->br_this == currNode)
@ -413,32 +412,32 @@ ResCalcNorthSouth(tile, pendingList, doneList, resList)
{ {
if (p2->br_this == p1->br_this) if (p2->br_this == p1->br_this)
{ {
currNode = NULL; currNode = NULL;
p1->br_next = p2->br_next; p1->br_next = p2->br_next;
freeMagic((char *)p2); freeMagic((char *)p2);
p2 = p1; p2 = p1;
} }
else if (p2->br_this == resCurrentNode) else if (p2->br_this == resCurrentNode)
{ {
currNode = p1->br_this; currNode = p1->br_this;
ResMergeNodes(p2->br_this, p1->br_this, pendingList, doneList); ResMergeNodes(p2->br_this, p1->br_this, pendingList, doneList);
freeMagic((char *)p1); freeMagic((char *)p1);
merged = TRUE; merged = TRUE;
} }
else if (p1->br_this == resCurrentNode) else if (p1->br_this == resCurrentNode)
{ {
currNode = p2->br_this; currNode = p2->br_this;
p1->br_next = p2->br_next; p1->br_next = p2->br_next;
ResMergeNodes(p1->br_this, p2->br_this, pendingList, doneList); ResMergeNodes(p1->br_this, p2->br_this, pendingList, doneList);
merged = TRUE; merged = TRUE;
freeMagic((char *)p2); freeMagic((char *)p2);
p2 = p1; p2 = p1;
} }
else else
{ {
currNode = p1->br_this; currNode = p1->br_this;
ResMergeNodes(p2->br_this, p1->br_this, pendingList, doneList); ResMergeNodes(p2->br_this, p1->br_this, pendingList, doneList);
freeMagic((char *)p1); freeMagic((char *)p1);
} }
/* /*
@ -559,7 +558,7 @@ ResCalcNearDevice(tile, pendingList, doneList, resList)
* breakpoint, then return. * breakpoint, then return.
*/ */
if (info->breakList->br_next == NULL) if (info->breakList->br_next == NULL)
{ {
freeMagic((char *)info->breakList); freeMagic((char *)info->breakList);
info->breakList = NULL; info->breakList = NULL;

View File

@ -839,9 +839,9 @@ ResTriangleCheck(resptr)
* *
* ResMergeNodes-- * ResMergeNodes--
* *
* results: none * Results: none
* *
* side effects: appends all the cElement, jElement, tElement and * Side Effects: appends all the cElement, jElement, tElement and
* resElement structures from node 2 onto node 1. Node 2 is * resElement structures from node 2 onto node 1. Node 2 is
* then eliminated. * then eliminated.
* *
@ -1010,7 +1010,7 @@ ResMergeNodes(node1, node2, pendingList, doneList)
* ResDeleteResPointer-- Deletes the pointer from a node to a resistor. * ResDeleteResPointer-- Deletes the pointer from a node to a resistor.
* Used when a resistor is deleted. * Used when a resistor is deleted.
* *
* Results:none * Results: none
* *
* Side Effects: Modifies a node's resistor list. * Side Effects: Modifies a node's resistor list.
* *
@ -1018,7 +1018,7 @@ ResMergeNodes(node1, node2, pendingList, doneList)
*/ */
void void
ResDeleteResPointer(node,resistor) ResDeleteResPointer(node, resistor)
resNode *node; resNode *node;
resResistor *resistor; resResistor *resistor;
@ -1059,7 +1059,7 @@ ResDeleteResPointer(node,resistor)
* *
* ResEliminateResistor-- * ResEliminateResistor--
* *
* Results:none * Results: none
* *
* Side Effects: Deletes a resistor. Does not delete pointers from nodes to * Side Effects: Deletes a resistor. Does not delete pointers from nodes to
* resistor. * resistor.
@ -1097,8 +1097,7 @@ ResEliminateResistor(resistor, homelist)
* they are no longer needed. If the 'info' option is used, * they are no longer needed. If the 'info' option is used,
* the node is eradicated. * the node is eradicated.
* *
* Results: * Results: none.
* None.
* *
* Side Effects: frees memory * Side Effects: frees memory
* *

View File

@ -1356,7 +1356,7 @@ ResFixUpConnections(extDev, layoutDev, extNode, nodename)
} }
if (extDev->subs == extNode) if (extDev->subs == extNode)
{ {
if ((layoutDev->rd_nterms >= 4) && ((subs = layoutDev->rd_fet_subs) != NULL)) if ((subs = layoutDev->rd_fet_subs) != NULL)
{ {
if (subs->rn_name != NULL && notdecremented) if (subs->rn_name != NULL && notdecremented)
{ {
@ -1422,7 +1422,7 @@ ResFixUpConnections(extDev, layoutDev, extNode, nodename)
extNode->status |= DONTKILL; extNode->status |= DONTKILL;
} }
} }
else else if (layoutDev->rd_nterms > 3)
{ {
if ((source = layoutDev->rd_fet_source) != NULL) if ((source = layoutDev->rd_fet_source) != NULL)
{ {
@ -1469,7 +1469,7 @@ ResFixUpConnections(extDev, layoutDev, extNode, nodename)
} }
} }
} }
else if (extDev->drain == extNode) else if ((extDev->drain == extNode) && (layoutDev->rd_nterms > 3))
{ {
/* Check for devices with only one terminal. If it was cast as source, */ /* Check for devices with only one terminal. If it was cast as source, */
/* then swap it with the drain so that the code below handles it */ /* then swap it with the drain so that the code below handles it */

View File

@ -387,7 +387,7 @@ ResMoveDevices(node1, node2)
devptr = devptr->te_nextt; devptr = devptr->te_nextt;
if (device->rd_fet_gate == node1) if (device->rd_fet_gate == node1)
device->rd_fet_gate = node2; device->rd_fet_gate = node2;
else if ((device->rd_nterms >= 4) && (device->rd_fet_subs == node1)) else if (device->rd_fet_subs == node1)
device->rd_fet_subs = node2; device->rd_fet_subs = node2;
else if (device->rd_fet_source == node1) else if (device->rd_fet_source == node1)
device->rd_fet_source = node2; device->rd_fet_source = node2;

View File

@ -231,7 +231,8 @@ ResAddPlumbing(tile, dinfo, arg)
resDev = (resDevice *)mallocMagic((unsigned)(sizeof(resDevice))); resDev = (resDevice *)mallocMagic((unsigned)(sizeof(resDevice)));
resDev->rd_nterms = nterms; resDev->rd_nterms = nterms;
resDev->rd_terminals = (resNode **) mallocMagic(nterms * sizeof(resNode *));
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_terminals[i] = (resNode *) NULL;

View File

@ -51,16 +51,24 @@ typedef struct resistor
#define rr_connection1 rr_node[0] #define rr_connection1 rr_node[0]
#define rr_connection2 rr_node[1] #define rr_connection2 rr_node[1]
/* Definitions for old FET-style MOSFET devices */ /* Definitions for old FET-style MOSFET devices. Actual devices may have
* any number of terminals. "GATE" is the identifying type; "SUBS" is
* the substrate/well connection (if it exists), and the other terminals
* make up the remaining entries. Memory will be allocated for the
* substrate whether or not one is defined for the device. If the device
* does not define a substrate connection, then this entry will remain
* NULL.
*/
#define RT_GATE 0 #define RT_GATE 0
#define RT_SOURCE 1 #define RT_SUBS 1
#define RT_DRAIN 2 #define RT_SOURCE 2
#define RT_SUBS 3 #define RT_DRAIN 3
#define rd_fet_gate rd_terminals[RT_GATE] #define rd_fet_gate rd_terminals[RT_GATE]
#define rd_fet_subs rd_terminals[RT_SUBS]
#define rd_fet_source rd_terminals[RT_SOURCE] #define rd_fet_source rd_terminals[RT_SOURCE]
#define rd_fet_drain rd_terminals[RT_DRAIN] #define rd_fet_drain rd_terminals[RT_DRAIN]
#define rd_fet_subs rd_terminals[RT_SUBS]
typedef struct device typedef struct device
{ {

View File

@ -834,6 +834,8 @@ chunkdone:
if (DBIsContact(type)) if (DBIsContact(type))
TTMaskSetOnlyType(&typeMask, type); TTMaskSetOnlyType(&typeMask, type);
/* Allow labels to be selected as part of the chunk */
TTMaskSetType(&typeMask, L_LABEL);
SelectArea(&newscx, &typeMask, xMask, NULL); SelectArea(&newscx, &typeMask, xMask, NULL);
} }