Corrected an issue in which permutable FETs were being assumed when

checking device terminals in "extresist", leading to incorrect
assignments for devices with only 3 terminals, or for asymmetric
FETs.  Corrected "select area label" which had stopped working from
a handful of commits back when the "select" command was corrected for
visible/invisible labels and cells.  Corrected the "extresist mindelay"
command option parsing, which was not allowing mindelay to be set to 0.
This commit is contained in:
R. Timothy Edwards 2026-06-05 15:46:54 -04:00
parent 43e4cf9b03
commit 0efed5813e
5 changed files with 145 additions and 28 deletions

View File

@ -1 +1 @@
8.3.657
8.3.658

View File

@ -574,7 +574,8 @@ DBReOrientLabel(cellDef, area, newPos)
* dbGetLabelArea ---
*
* Callback function used by DBAdjustLabels. Find all material under a label
* that is *not* the label type, and return the
* that is *not* the label type, and return the label area adjusted to leave
* out that amount.
*
* Note: This clips in a regular order, and does not consider what is the
* largest rectangular area outside the area that has been clipped out.
@ -604,6 +605,26 @@ dbGetLabelArea(tile, dinfo, area)
return 0;
}
/*
* ----------------------------------------------------------------------------
*
* dbLabelNotEmpty ---
*
* Callback function used by DBAdjustLabels. Finds any material under a
* label that is the label type, and returns 1 to stop the search.
*
* ----------------------------------------------------------------------------
*/
int
dbLabelNotEmpty(tile, dinfo, clientData)
Tile *tile; /* Tile found. */
TileType dinfo; /* Split tile information (unused) */
ClientData clientData; /* (unused) */
{
return 1;
}
/*
* ----------------------------------------------------------------------------
*
@ -661,28 +682,37 @@ DBAdjustLabels(def, area)
TTMaskSetOnlyType(&lmask, lab->lab_type);
/* To do: Add compatible types (contact, residue) */
TTMaskCom(&lmask);
r = lab->lab_rect;
DBSrPaintArea((Tile *) NULL, def->cd_planes[DBPlane(lab->lab_type)],
&lab->lab_rect, &lmask, dbGetLabelArea, (ClientData) &r);
if (!GEO_RECTNULL(&r))
/* If there is no material left inside the label area, then
* the label gets reassigned to space.
*/
if (DBSrPaintArea((Tile *) NULL, def->cd_planes[DBPlane(lab->lab_type)],
&lab->lab_rect, &lmask, dbLabelNotEmpty, (ClientData)NULL) == 1)
{
if ((DBVerbose >= DB_VERBOSE_ALL) && ((def->cd_flags & CDINTERNAL) == 0))
{
TxPrintf("Adjusting size of label \"%s\" in cell %s.\n",
lab->lab_text, def->cd_name);
}
TTMaskCom(&lmask);
DBUndoEraseLabel(def, lab);
DBWLabelChanged(def, lab, DBW_ALLWINDOWS);
lab->lab_rect = r;
DBFontLabelSetBBox(lab);
DBUndoPutLabel(def, lab);
DBWLabelChanged(def, lab, DBW_ALLWINDOWS);
modified = TRUE;
adjusted = TRUE;
r = lab->lab_rect;
DBSrPaintArea((Tile *) NULL, def->cd_planes[DBPlane(lab->lab_type)],
&lab->lab_rect, &lmask, dbGetLabelArea, (ClientData) &r);
if (!GEO_RECTNULL(&r))
{
if ((DBVerbose >= DB_VERBOSE_ALL) &&
((def->cd_flags & CDINTERNAL) == 0))
{
TxPrintf("Adjusting size of label \"%s\" in cell %s.\n",
lab->lab_text, def->cd_name);
}
DBUndoEraseLabel(def, lab);
DBWLabelChanged(def, lab, DBW_ALLWINDOWS);
lab->lab_rect = r;
DBFontLabelSetBBox(lab);
DBUndoPutLabel(def, lab);
DBWLabelChanged(def, lab, DBW_ALLWINDOWS);
modified = TRUE;
adjusted = TRUE;
}
}
}

View File

@ -350,7 +350,7 @@ typedef enum {
if (cmd->tx_argc > 2)
{
resisdata->minres = MagAtof(cmd->tx_argv[2]);
if (resisdata->minres < 0)
if (resisdata->minres <= 0)
{
TxError("Usage: %s minres [value]\n", cmd->tx_argv[0]);
return;
@ -372,7 +372,7 @@ typedef enum {
if (cmd->tx_argc > 2)
{
resisdata->mindelay = MagAtof(cmd->tx_argv[2]) * P_TO_Z;
if (resisdata->mindelay <= 0)
if (resisdata->mindelay < 0)
{
TxError("Usage: %s mindelay [value]\n", cmd->tx_argv[0]);
return;
@ -1514,7 +1514,9 @@ ResFixUpConnections(extDev, layoutDev, extNode, nodename)
{
static char newname[MAXNAME], oldnodename[MAXNAME];
int notdecremented;
ExtDevice *devptr;
resNode *gate, *source, *drain, *subs;
bool doPermute = FALSE;
/* If we aren't doing output (i.e. this is just a statistical run) */
/* don't patch up networks. This cuts down on memory use. */
@ -1522,6 +1524,14 @@ ResFixUpConnections(extDev, layoutDev, extNode, nodename)
if ((ResOptionsFlags & ResOpt_DoExtFile) == 0)
return;
/* Check if device has symmetric source and drain, which will
* force a check for permutations of source and drain.
*/
devptr = extDev->rs_devptr;
if (devptr->exts_deviceSDCount > 1)
if (TTMaskEqual(&devptr->exts_deviceSDTypes[0], &devptr->exts_deviceSDTypes[1]))
doPermute = TRUE;
if (extDev->layout == NULL)
{
layoutDev->rd_status |= RES_DEV_SAVE;
@ -1581,7 +1591,7 @@ ResFixUpConnections(extDev, layoutDev, extNode, nodename)
}
}
if ((extDev->source == extNode) && (layoutDev->rd_nterms > 3))
if ((extDev->source == extNode) && doPermute)
{
/* Check for devices with only one terminal. If it was cast as drain, */
/* then swap it with the source so that the code below handles it */
@ -1627,7 +1637,7 @@ ResFixUpConnections(extDev, layoutDev, extNode, nodename)
extNode->status |= DONTKILL;
}
}
else if (layoutDev->rd_nterms > 3)
else
{
if ((source = layoutDev->rd_fet_source) != NULL)
{
@ -1674,7 +1684,31 @@ ResFixUpConnections(extDev, layoutDev, extNode, nodename)
}
}
}
else if ((extDev->drain == extNode) && (layoutDev->rd_nterms > 3))
else if (extDev->source == extNode)
{
/* Device only has 3 terminals, don't need to check for permutations */
if ((source = layoutDev->rd_fet_source) != NULL)
{
if (source->rn_name != NULL && notdecremented)
{
resNodeNum--;
notdecremented = FALSE;
}
ResFixDevName(newname, SOURCE, extDev, source);
source->rn_name = extDev->source->name;
sprintf(newname, "%s%s%d", nodename, ".t", resNodeNum++);
}
else
{
TxError("Missing source connection of device at (%d %d) on net %s\n",
layoutDev->rd_inside.r_xbot, layoutDev->rd_inside.r_ybot,
nodename);
extNode->status |= DONTKILL;
}
}
else if ((extDev->drain == extNode) && doPermute)
{
/* 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 */
@ -1733,6 +1767,28 @@ ResFixUpConnections(extDev, layoutDev, extNode, nodename)
extNode->status |= DONTKILL;
}
}
else if (extDev->drain == extNode)
{
if ((drain = layoutDev->rd_fet_drain) != NULL)
{
if (drain->rn_name != NULL && notdecremented)
{
resNodeNum--;
notdecremented = FALSE;
}
ResFixDevName(newname, DRAIN, extDev, drain);
drain->rn_name = extDev->drain->name;
sprintf(newname, "%s%s%d", nodename, ".t", resNodeNum++);
}
else
{
TxError("Missing drain connection of device at (%d %d) on net %s\n",
layoutDev->rd_inside.r_xbot, layoutDev->rd_inside.r_ybot,
nodename);
extNode->status |= DONTKILL;
}
}
else
resNodeNum--;
}

View File

@ -388,10 +388,10 @@ ResUnmarkTerminal(
/*
*-------------------------------------------------------------------------
*
* ResAddlumbing --
* ResAddPlumbing --
*
* Each tile has a resInfo structure associated with it to keep track of
* various things used by the extractor. ResAddDevPlumbing adds this structure
* various things used by the extractor. ResAddPlumbing adds this structure
* and sets the tile's ClientData field to point to it.
*
* Results: Always return 0 to keep the search going.
@ -571,6 +571,13 @@ ResAddDevPlumbing(
if (TTMaskHasType(&(devptr->exts_deviceSDTypes[sourceTerm]),
TiGetBottomType(tp2)))
{
/* If # terminals found > nterms then assume that they
* are connected, for example through a well or substrate.
*/
if ((TiGetClient(tp2) == CLIENTDEFAULT) &&
(sourceTerm == nterms - 3))
ResAddTerminalPlumbing(tp2, devptr, sourceTerm);
Info = resAddField(tp2);
if (Info->ri_status & RES_TILE_SD)
re0->sourceEdge |= TOPEDGE;
@ -622,6 +629,13 @@ ResAddDevPlumbing(
if (TTMaskHasType(&(devptr->exts_deviceSDTypes[sourceTerm]),
TiGetBottomType(tp2)))
{
/* If # terminals found > nterms then assume that they
* are connected, for example through a well or substrate.
*/
if ((TiGetClient(tp2) == CLIENTDEFAULT) &&
(sourceTerm == nterms - 3))
ResAddTerminalPlumbing(tp2, devptr, sourceTerm);
Info = resAddField(tp2);
if (Info->ri_status & RES_TILE_SD)
re0->sourceEdge |= BOTTOMEDGE;
@ -673,6 +687,13 @@ ResAddDevPlumbing(
if (TTMaskHasType(&(devptr->exts_deviceSDTypes[sourceTerm]),
TiGetBottomType(tp2)))
{
/* If # terminals found > nterms then assume that they
* are connected, for example through a well or substrate.
*/
if ((TiGetClient(tp2) == CLIENTDEFAULT) &&
(sourceTerm == nterms - 3))
ResAddTerminalPlumbing(tp2, devptr, sourceTerm);
Info = resAddField(tp2);
if (Info->ri_status & RES_TILE_SD)
re0->sourceEdge |= RIGHTEDGE;
@ -724,6 +745,13 @@ ResAddDevPlumbing(
if (TTMaskHasType(&(devptr->exts_deviceSDTypes[sourceTerm]),
TiGetBottomType(tp2)))
{
/* If # terminals found > nterms then assume that they
* are connected, for example through a well or substrate.
*/
if ((TiGetClient(tp2) == CLIENTDEFAULT) &&
(sourceTerm == nterms - 3))
ResAddTerminalPlumbing(tp2, devptr, sourceTerm);
Info = resAddField(tp2);
if (Info->ri_status & RES_TILE_SD)
re0->sourceEdge |= LEFTEDGE;

View File

@ -470,6 +470,9 @@ SelectArea(scx, types, xMask, globmatch)
if (TTMaskHasType(types, L_LABEL))
{
TTMaskClearType(types, L_LABEL);
if (TTMaskIsZero(types)) types = &DBAllButSpaceAndDRCBits;
if (globmatch != NULL)
DBCellCopyGlobLabels(scx, types, xMask, SelectUse, &labelArea,
globmatch);