diff --git a/VERSION b/VERSION index 8f3137d3..ad509384 100644 --- a/VERSION +++ b/VERSION @@ -1 +1 @@ -8.3.657 +8.3.658 diff --git a/database/DBlabel.c b/database/DBlabel.c index a77bdf18..f8e0f58a 100644 --- a/database/DBlabel.c +++ b/database/DBlabel.c @@ -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; + } } } diff --git a/resis/ResRex.c b/resis/ResRex.c index 6dfb2b8c..83ece7fb 100644 --- a/resis/ResRex.c +++ b/resis/ResRex.c @@ -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--; } diff --git a/resis/ResUtils.c b/resis/ResUtils.c index d0c85dea..c1c4e2a4 100644 --- a/resis/ResUtils.c +++ b/resis/ResUtils.c @@ -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; diff --git a/select/selCreate.c b/select/selCreate.c index 9bf27051..d7f40ba3 100644 --- a/select/selCreate.c +++ b/select/selCreate.c @@ -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);