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:
parent
43e4cf9b03
commit
0efed5813e
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -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--;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
|
|
|||
Loading…
Reference in New Issue