Implemented glob-style matching for label selection. Introduces
an optional extra argument to the "select" command that can be used to select labels by glob-style matching; e.g., "select area labels VSS*" or "select less area labels *_1". This will help in managing labels after flattening a standard cell design; e.g., by using "select less area labels */VDD".
This commit is contained in:
parent
537b1f057d
commit
2f7813094b
|
|
@ -570,10 +570,11 @@ CmdSee(w, cmd)
|
||||||
|
|
||||||
/* ARGSUSED */
|
/* ARGSUSED */
|
||||||
void
|
void
|
||||||
cmdSelectArea(layers, less, option)
|
cmdSelectArea(layers, less, option, globmatch)
|
||||||
char *layers; /* Which layers are to be selected. */
|
char *layers; /* Which layers are to be selected. */
|
||||||
bool less;
|
bool less;
|
||||||
int option; /* Option from defined list above */
|
int option; /* Option from defined list above */
|
||||||
|
char *globmatch; /* Optional match string for labels */
|
||||||
{
|
{
|
||||||
SearchContext scx;
|
SearchContext scx;
|
||||||
TileTypeBitMask mask;
|
TileTypeBitMask mask;
|
||||||
|
|
@ -617,7 +618,7 @@ cmdSelectArea(layers, less, option)
|
||||||
|
|
||||||
if (less)
|
if (less)
|
||||||
{
|
{
|
||||||
(void) SelRemoveArea(&scx.scx_area, &mask);
|
(void) SelRemoveArea(&scx.scx_area, &mask, globmatch);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -633,7 +634,7 @@ cmdSelectArea(layers, less, option)
|
||||||
TTMaskClearType(&mask, i);
|
TTMaskClearType(&mask, i);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
SelectArea(&scx, &mask, crec->dbw_bitmask);
|
SelectArea(&scx, &mask, crec->dbw_bitmask, globmatch);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|
@ -831,7 +832,7 @@ CmdSelect(w, cmd)
|
||||||
* also used to step through multiple uses.
|
* also used to step through multiple uses.
|
||||||
*/
|
*/
|
||||||
static bool lessCycle = FALSE, lessCellCycle = FALSE;
|
static bool lessCycle = FALSE, lessCellCycle = FALSE;
|
||||||
char path[200], *printPath, **msg, **optionArgs, *feedtext, *pstr;
|
char path[200], *printPath, **msg, **optionArgs, *feedtext, *pstr, *globmatch;
|
||||||
TerminalPath tpath;
|
TerminalPath tpath;
|
||||||
CellUse *use;
|
CellUse *use;
|
||||||
CellDef *rootBoxDef;
|
CellDef *rootBoxDef;
|
||||||
|
|
@ -854,6 +855,7 @@ CmdSelect(w, cmd)
|
||||||
|
|
||||||
#define MARGIN 2
|
#define MARGIN 2
|
||||||
|
|
||||||
|
globmatch = NULL;
|
||||||
bzero(&scx, sizeof(SearchContext));
|
bzero(&scx, sizeof(SearchContext));
|
||||||
windCheckOnlyWindow(&w, DBWclientID);
|
windCheckOnlyWindow(&w, DBWclientID);
|
||||||
if ((w == (MagWindow *) NULL) || (w->w_client != DBWclientID))
|
if ((w == (MagWindow *) NULL) || (w->w_client != DBWclientID))
|
||||||
|
|
@ -977,17 +979,19 @@ CmdSelect(w, cmd)
|
||||||
*/
|
*/
|
||||||
|
|
||||||
case SEL_AREA:
|
case SEL_AREA:
|
||||||
if (cmd->tx_argc > 3)
|
if (cmd->tx_argc > 4)
|
||||||
{
|
{
|
||||||
usageError:
|
usageError:
|
||||||
TxError("Bad arguments:\n select %s\n",
|
TxError("Bad arguments:\n select %s\n",
|
||||||
cmdSelectMsg[option+1]);
|
cmdSelectMsg[option+1]);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
if (cmd->tx_argc == 4)
|
||||||
|
globmatch = optionArgs[2]; /* Label matching by glob */
|
||||||
if (!(more || less)) SelectClear();
|
if (!(more || less)) SelectClear();
|
||||||
if (cmd->tx_argc == 3)
|
if (cmd->tx_argc >= 3)
|
||||||
cmdSelectArea(optionArgs[1], less, option);
|
cmdSelectArea(optionArgs[1], less, option, globmatch);
|
||||||
else cmdSelectArea("*,label,subcell", less);
|
else cmdSelectArea("*,label,subcell", less, option, globmatch);
|
||||||
return;
|
return;
|
||||||
|
|
||||||
/*--------------------------------------------------------------------
|
/*--------------------------------------------------------------------
|
||||||
|
|
@ -1000,8 +1004,8 @@ CmdSelect(w, cmd)
|
||||||
if (cmd->tx_argc > 3) goto usageError;
|
if (cmd->tx_argc > 3) goto usageError;
|
||||||
if (!(more || less)) SelectClear();
|
if (!(more || less)) SelectClear();
|
||||||
if (cmd->tx_argc == 3)
|
if (cmd->tx_argc == 3)
|
||||||
cmdSelectArea(optionArgs[1], less, option);
|
cmdSelectArea(optionArgs[1], less, option, globmatch);
|
||||||
else cmdSelectArea("*,label,subcell", less, option);
|
else cmdSelectArea("*,label,subcell", less, option, globmatch);
|
||||||
return;
|
return;
|
||||||
|
|
||||||
/*--------------------------------------------------------------------
|
/*--------------------------------------------------------------------
|
||||||
|
|
|
||||||
|
|
@ -27,6 +27,7 @@ static char rcsid[] __attribute__ ((unused)) = "$Header: /usr/cvsroot/magic-8.0/
|
||||||
#include "utils/malloc.h"
|
#include "utils/malloc.h"
|
||||||
#include "tiles/tile.h"
|
#include "tiles/tile.h"
|
||||||
#include "utils/hash.h"
|
#include "utils/hash.h"
|
||||||
|
#include "utils/utils.h"
|
||||||
#include "database/database.h"
|
#include "database/database.h"
|
||||||
#include "database/databaseInt.h"
|
#include "database/databaseInt.h"
|
||||||
#include "textio/textio.h"
|
#include "textio/textio.h"
|
||||||
|
|
@ -83,6 +84,9 @@ struct copyLabelArg
|
||||||
* to be filled in with total area of
|
* to be filled in with total area of
|
||||||
* all labels copied.
|
* all labels copied.
|
||||||
*/
|
*/
|
||||||
|
char *cla_glob; /* If non-NULL, used for glob-style
|
||||||
|
* matching of labels during copy.
|
||||||
|
*/
|
||||||
};
|
};
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|
@ -595,6 +599,7 @@ DBCellCopyAllLabels(scx, mask, xMask, targetUse, pArea)
|
||||||
|
|
||||||
arg.cla_targetUse = targetUse;
|
arg.cla_targetUse = targetUse;
|
||||||
arg.cla_bbox = pArea;
|
arg.cla_bbox = pArea;
|
||||||
|
arg.cla_glob = NULL;
|
||||||
if (pArea != NULL)
|
if (pArea != NULL)
|
||||||
{
|
{
|
||||||
pArea->r_xbot = 0;
|
pArea->r_xbot = 0;
|
||||||
|
|
@ -619,6 +624,9 @@ dbCopyAllLabels(scx, lab, tpath, arg)
|
||||||
CellDef *def;
|
CellDef *def;
|
||||||
|
|
||||||
def = arg->cla_targetUse->cu_def;
|
def = arg->cla_targetUse->cu_def;
|
||||||
|
if (arg->cla_glob != NULL)
|
||||||
|
if (!Match(arg->cla_glob, lab->lab_text))
|
||||||
|
return 0;
|
||||||
if (!GEO_LABEL_IN_AREA(&lab->lab_rect, &(scx->scx_area))) return 0;
|
if (!GEO_LABEL_IN_AREA(&lab->lab_rect, &(scx->scx_area))) return 0;
|
||||||
GeoTransRect(&scx->scx_trans, &lab->lab_rect, &labTargetRect);
|
GeoTransRect(&scx->scx_trans, &lab->lab_rect, &labTargetRect);
|
||||||
targetPos = GeoTransPos(&scx->scx_trans, lab->lab_just);
|
targetPos = GeoTransPos(&scx->scx_trans, lab->lab_just);
|
||||||
|
|
@ -648,6 +656,66 @@ dbCopyAllLabels(scx, lab, tpath, arg)
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
*-----------------------------------------------------------------------------
|
||||||
|
*
|
||||||
|
* DBCellCopyGlobLabels --
|
||||||
|
*
|
||||||
|
* Copy labels from the tree rooted at scx->scx_use to targetUse,
|
||||||
|
* transforming according to the transform in scx. Only labels
|
||||||
|
* attached to layers of the types specified by mask and which
|
||||||
|
* match the string "globmatch" by glob-style matching are copied.
|
||||||
|
* The area to be copied is determined by GEO_LABEL_IN_AREA.
|
||||||
|
*
|
||||||
|
* Results:
|
||||||
|
* None.
|
||||||
|
*
|
||||||
|
* Side effects:
|
||||||
|
* Copies labels to targetUse, clipping against scx->scx_area.
|
||||||
|
* If pArea is given, store in it the bounding box of all the
|
||||||
|
* labels copied.
|
||||||
|
*
|
||||||
|
*-----------------------------------------------------------------------------
|
||||||
|
*/
|
||||||
|
|
||||||
|
void
|
||||||
|
DBCellCopyGlobLabels(scx, mask, xMask, targetUse, pArea, globmatch)
|
||||||
|
SearchContext *scx; /* Describes root cell to search, area to
|
||||||
|
* copy, transform from root cell to coords
|
||||||
|
* of targetUse.
|
||||||
|
*/
|
||||||
|
TileTypeBitMask *mask; /* Only labels of these types are copied */
|
||||||
|
int xMask; /* Expansion state mask to be used in search */
|
||||||
|
CellUse *targetUse; /* Cell into which labels are to be stuffed */
|
||||||
|
Rect *pArea; /* If non-NULL, points to a box that will be
|
||||||
|
* filled in with bbox (in targetUse coords)
|
||||||
|
* of all labels copied. Will be degenerate
|
||||||
|
* if nothing was copied.
|
||||||
|
*/
|
||||||
|
char *globmatch; /* If non-NULL, only labels matching this
|
||||||
|
* string by glob-style matching are copied.
|
||||||
|
*/
|
||||||
|
{
|
||||||
|
int dbCopyAllLabels();
|
||||||
|
struct copyLabelArg arg;
|
||||||
|
|
||||||
|
/* DBTeeSrLabels finds all the labels that we want plus some more.
|
||||||
|
* We'll filter out the ones that we don't need.
|
||||||
|
*/
|
||||||
|
|
||||||
|
arg.cla_targetUse = targetUse;
|
||||||
|
arg.cla_bbox = pArea;
|
||||||
|
arg.cla_glob = globmatch;
|
||||||
|
if (pArea != NULL)
|
||||||
|
{
|
||||||
|
pArea->r_xbot = 0;
|
||||||
|
pArea->r_xtop = -1;
|
||||||
|
}
|
||||||
|
(void) DBTreeSrLabels(scx, mask, xMask, (TerminalPath *) 0,
|
||||||
|
TF_LABEL_ATTACH, dbCopyAllLabels,
|
||||||
|
(ClientData) &arg);
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
*-----------------------------------------------------------------------------
|
*-----------------------------------------------------------------------------
|
||||||
*
|
*
|
||||||
|
|
|
||||||
|
|
@ -228,7 +228,7 @@ DBPutFontLabel(cellDef, rect, font, size, rot, offset, align, text, type, flags)
|
||||||
/*
|
/*
|
||||||
* ----------------------------------------------------------------------------
|
* ----------------------------------------------------------------------------
|
||||||
*
|
*
|
||||||
* DBEraseLabel --
|
* DBEraseGlobLabel --
|
||||||
*
|
*
|
||||||
* Delete labels attached to tiles of the indicated types that
|
* Delete labels attached to tiles of the indicated types that
|
||||||
* are in the given area (as determined by the macro GEO_LABEL_IN_AREA).
|
* are in the given area (as determined by the macro GEO_LABEL_IN_AREA).
|
||||||
|
|
@ -250,13 +250,13 @@ DBPutFontLabel(cellDef, rect, font, size, rot, offset, align, text, type, flags)
|
||||||
* still enough material to keep them around. The rect pointed to
|
* still enough material to keep them around. The rect pointed to
|
||||||
* by areaReturn is filled with the area affected by removing the
|
* by areaReturn is filled with the area affected by removing the
|
||||||
* label, for purposes of redrawing the necessary portions of the
|
* label, for purposes of redrawing the necessary portions of the
|
||||||
* screen.
|
* screen.
|
||||||
*
|
*
|
||||||
* ----------------------------------------------------------------------------
|
* ----------------------------------------------------------------------------
|
||||||
*/
|
*/
|
||||||
|
|
||||||
bool
|
bool
|
||||||
DBEraseLabel(cellDef, area, mask, areaReturn)
|
DBEraseGlobLabel(cellDef, area, mask, areaReturn, globmatch)
|
||||||
CellDef *cellDef; /* Cell being modified */
|
CellDef *cellDef; /* Cell being modified */
|
||||||
Rect *area; /* Area from which labels are to be erased.
|
Rect *area; /* Area from which labels are to be erased.
|
||||||
* This may be a point; any labels touching
|
* This may be a point; any labels touching
|
||||||
|
|
@ -266,6 +266,9 @@ DBEraseLabel(cellDef, area, mask, areaReturn)
|
||||||
* be erased.
|
* be erased.
|
||||||
*/
|
*/
|
||||||
Rect *areaReturn; /* Expand this with label bounding box */
|
Rect *areaReturn; /* Expand this with label bounding box */
|
||||||
|
char *globmatch; /* If non-NULL, do glob-style matching of
|
||||||
|
* any label against this string.
|
||||||
|
*/
|
||||||
{
|
{
|
||||||
Label *lab, *labPrev;
|
Label *lab, *labPrev;
|
||||||
bool erasedAny = FALSE;
|
bool erasedAny = FALSE;
|
||||||
|
|
@ -289,6 +292,10 @@ DBEraseLabel(cellDef, area, mask, areaReturn)
|
||||||
if (DBConnectsTo(newType, lab->lab_type)) goto nextLab;
|
if (DBConnectsTo(newType, lab->lab_type)) goto nextLab;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if (globmatch != NULL)
|
||||||
|
{
|
||||||
|
if (!Match(globmatch, lab->lab_text)) goto nextLab;
|
||||||
|
}
|
||||||
|
|
||||||
DBWLabelChanged(cellDef, lab, DBW_ALLWINDOWS);
|
DBWLabelChanged(cellDef, lab, DBW_ALLWINDOWS);
|
||||||
if (labPrev == NULL)
|
if (labPrev == NULL)
|
||||||
|
|
@ -319,6 +326,39 @@ DBEraseLabel(cellDef, area, mask, areaReturn)
|
||||||
&& (r1)->r_xtop == (r2)->r_xtop \
|
&& (r1)->r_xtop == (r2)->r_xtop \
|
||||||
&& (r1)->r_ytop == (r2)->r_ytop)
|
&& (r1)->r_ytop == (r2)->r_ytop)
|
||||||
|
|
||||||
|
/*
|
||||||
|
* ----------------------------------------------------------------------------
|
||||||
|
*
|
||||||
|
* DBEraseLabel ---
|
||||||
|
*
|
||||||
|
* Wrapper around DBEraseGlobLabel() with globmatch set to NULL so
|
||||||
|
* that labels are erased verbatim rather that being matched against
|
||||||
|
* a glob-style string.
|
||||||
|
*
|
||||||
|
* Results:
|
||||||
|
* Passes back the result of DBEraseGlobLabel()
|
||||||
|
*
|
||||||
|
* Side effects:
|
||||||
|
* See DBEraseGlobLabel()
|
||||||
|
*
|
||||||
|
* ----------------------------------------------------------------------------
|
||||||
|
*/
|
||||||
|
|
||||||
|
bool
|
||||||
|
DBEraseLabel(cellDef, area, mask, areaReturn)
|
||||||
|
CellDef *cellDef; /* Cell being modified */
|
||||||
|
Rect *area; /* Area from which labels are to be erased.
|
||||||
|
* This may be a point; any labels touching
|
||||||
|
* or overlapping it are erased.
|
||||||
|
*/
|
||||||
|
TileTypeBitMask *mask; /* Mask of types from which labels are to
|
||||||
|
* be erased.
|
||||||
|
*/
|
||||||
|
Rect *areaReturn; /* Expand this with label bounding box */
|
||||||
|
{
|
||||||
|
return DBEraseGlobLabel(cellDef, area, mask, areaReturn, NULL);
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* ----------------------------------------------------------------------------
|
* ----------------------------------------------------------------------------
|
||||||
*
|
*
|
||||||
|
|
|
||||||
|
|
@ -783,6 +783,7 @@ extern void DBPathSubstitute();
|
||||||
extern Label *DBPutLabel();
|
extern Label *DBPutLabel();
|
||||||
extern Label *DBPutFontLabel();
|
extern Label *DBPutFontLabel();
|
||||||
extern void DBFontLabelSetBBox();
|
extern void DBFontLabelSetBBox();
|
||||||
|
extern bool DBEraseGlobLabel();
|
||||||
extern bool DBEraseLabel();
|
extern bool DBEraseLabel();
|
||||||
extern void DBEraseLabelAll();
|
extern void DBEraseLabelAll();
|
||||||
extern void DBEraseLabelsByContent();
|
extern void DBEraseLabelsByContent();
|
||||||
|
|
@ -875,6 +876,7 @@ extern void DBCellCopyAllPaint();
|
||||||
extern void DBCellCheckCopyAllPaint();
|
extern void DBCellCheckCopyAllPaint();
|
||||||
extern void DBCellCopyLabels();
|
extern void DBCellCopyLabels();
|
||||||
extern void DBCellCopyAllLabels();
|
extern void DBCellCopyAllLabels();
|
||||||
|
extern void DBCellCopyGlobLabels();
|
||||||
extern void DBCellCopyCells();
|
extern void DBCellCopyCells();
|
||||||
extern void DBCellCopyAllCells();
|
extern void DBCellCopyAllCells();
|
||||||
extern Plane *DBCellGenerateSubstrate();
|
extern Plane *DBCellGenerateSubstrate();
|
||||||
|
|
|
||||||
|
|
@ -1432,7 +1432,7 @@ lefWriteMacro(def, f, scale, setback, pinonly, toplayer, domaster)
|
||||||
{
|
{
|
||||||
Rect psetback;
|
Rect psetback;
|
||||||
GEO_EXPAND(&boundary, -pinonly, &psetback);
|
GEO_EXPAND(&boundary, -pinonly, &psetback);
|
||||||
SelRemoveArea(&psetback, &DBAllButSpaceAndDRCBits);
|
SelRemoveArea(&psetback, &DBAllButSpaceAndDRCBits, NULL);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -1461,14 +1461,14 @@ lefWriteMacro(def, f, scale, setback, pinonly, toplayer, domaster)
|
||||||
|
|
||||||
SelectNet(&scx, lab->lab_type, 0, NULL, FALSE);
|
SelectNet(&scx, lab->lab_type, 0, NULL, FALSE);
|
||||||
GEO_EXPAND(&boundary, -setback, &carea);
|
GEO_EXPAND(&boundary, -setback, &carea);
|
||||||
SelRemoveArea(&carea, &DBAllButSpaceAndDRCBits);
|
SelRemoveArea(&carea, &DBAllButSpaceAndDRCBits, NULL);
|
||||||
|
|
||||||
/* Apply any additional setback from the "-pinonly" option */
|
/* Apply any additional setback from the "-pinonly" option */
|
||||||
if (pinonly > setback)
|
if (pinonly > setback)
|
||||||
{
|
{
|
||||||
Rect psetback;
|
Rect psetback;
|
||||||
GEO_EXPAND(&boundary, -pinonly, &psetback);
|
GEO_EXPAND(&boundary, -pinonly, &psetback);
|
||||||
SelRemoveArea(&psetback, &DBAllButSpaceAndDRCBits);
|
SelRemoveArea(&psetback, &DBAllButSpaceAndDRCBits, NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Paint over the label area so that labels do not simply */
|
/* Paint over the label area so that labels do not simply */
|
||||||
|
|
@ -1487,7 +1487,7 @@ lefWriteMacro(def, f, scale, setback, pinonly, toplayer, domaster)
|
||||||
{
|
{
|
||||||
Rect psetback;
|
Rect psetback;
|
||||||
GEO_EXPAND(&boundary, -pinonly, &psetback);
|
GEO_EXPAND(&boundary, -pinonly, &psetback);
|
||||||
SelRemoveArea(&psetback, &DBAllButSpaceAndDRCBits);
|
SelRemoveArea(&psetback, &DBAllButSpaceAndDRCBits, NULL);
|
||||||
|
|
||||||
/* Paint over the label area so that labels do not simply */
|
/* Paint over the label area so that labels do not simply */
|
||||||
/* disappear by being inside the setback area. */
|
/* disappear by being inside the setback area. */
|
||||||
|
|
|
||||||
122
resis/ResRex.c
122
resis/ResRex.c
|
|
@ -106,7 +106,7 @@ ExtResisForDef(celldef, resisdata)
|
||||||
RDev *oldRDev;
|
RDev *oldRDev;
|
||||||
HashSearch hs;
|
HashSearch hs;
|
||||||
HashEntry *entry;
|
HashEntry *entry;
|
||||||
devPtr *tptr,*oldtptr;
|
devPtr *tptr, *oldtptr;
|
||||||
ResSimNode *node;
|
ResSimNode *node;
|
||||||
int result, idx;
|
int result, idx;
|
||||||
char *devname;
|
char *devname;
|
||||||
|
|
@ -1495,18 +1495,13 @@ ResFixDevName(line, type, device, layoutnode)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#if 1
|
||||||
|
|
||||||
/*
|
/*
|
||||||
*-------------------------------------------------------------------------
|
*-------------------------------------------------------------------------
|
||||||
*
|
*
|
||||||
* ResSortByGate -- sorts device pointers whose terminal field is either
|
* Deprecated function. Horribly inefficient. See qsort() version below.
|
||||||
* drain or source by gate node number, then by drain (source) number.
|
* (Not yet implemented; still under test.)
|
||||||
* This places devices with identical connections next to one
|
|
||||||
* another.
|
|
||||||
*
|
|
||||||
* Results: none
|
|
||||||
*
|
|
||||||
* Side Effects: modifies order of devices
|
|
||||||
*
|
*
|
||||||
*-------------------------------------------------------------------------
|
*-------------------------------------------------------------------------
|
||||||
*/
|
*/
|
||||||
|
|
@ -1520,6 +1515,8 @@ ResSortByGate(DevpointerList)
|
||||||
devPtr *working, *current;
|
devPtr *working, *current;
|
||||||
devPtr *last = NULL, *gatelist = NULL;
|
devPtr *last = NULL, *gatelist = NULL;
|
||||||
|
|
||||||
|
/* Split out GATE entries into separate list (gatelist) */
|
||||||
|
|
||||||
working = *DevpointerList;
|
working = *DevpointerList;
|
||||||
while (working != NULL)
|
while (working != NULL)
|
||||||
{
|
{
|
||||||
|
|
@ -1544,6 +1541,9 @@ ResSortByGate(DevpointerList)
|
||||||
working = working->nextDev;
|
working = working->nextDev;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Sort the SOURCE and DRAIN list (DevpointerList) */
|
||||||
|
|
||||||
while (changed == TRUE)
|
while (changed == TRUE)
|
||||||
{
|
{
|
||||||
changed = localchange = FALSE;
|
changed = localchange = FALSE;
|
||||||
|
|
@ -1599,6 +1599,9 @@ ResSortByGate(DevpointerList)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Add the GATE list back to the end of Devpointerlist */
|
||||||
|
|
||||||
if (working == NULL)
|
if (working == NULL)
|
||||||
{
|
{
|
||||||
*DevpointerList = gatelist;
|
*DevpointerList = gatelist;
|
||||||
|
|
@ -1612,6 +1615,107 @@ ResSortByGate(DevpointerList)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#endif /* 1 */
|
||||||
|
|
||||||
|
#if 0
|
||||||
|
|
||||||
|
/*
|
||||||
|
*-------------------------------------------------------------------------
|
||||||
|
*
|
||||||
|
* devSortFunc ---
|
||||||
|
*
|
||||||
|
* qsort() sorting function for gates. See description in
|
||||||
|
* ResSortByGate() below.
|
||||||
|
*
|
||||||
|
* Returns:
|
||||||
|
* 1 or -1 depending on comparison result. The devices are sorted
|
||||||
|
* by gate first, then source or drain.
|
||||||
|
*
|
||||||
|
* Side effects:
|
||||||
|
* qsort() reorders the indexed list of which dev1 and dev2 are
|
||||||
|
* components.
|
||||||
|
*
|
||||||
|
*-------------------------------------------------------------------------
|
||||||
|
*/
|
||||||
|
|
||||||
|
int
|
||||||
|
devSortFunc(dev1, dev2)
|
||||||
|
devPtr *dev1, *dev2;
|
||||||
|
{
|
||||||
|
RDev *rd1 = dev1->thisDev;
|
||||||
|
RDev *rd2 = dev2->thisDev;
|
||||||
|
|
||||||
|
if (dev1->terminal == GATE)
|
||||||
|
return 1;
|
||||||
|
else if (dev2->terminal == GATE)
|
||||||
|
return -1;
|
||||||
|
else if (rd1->gate > rd2->gate)
|
||||||
|
return 1;
|
||||||
|
else if (rd1->gate == rd2->gate)
|
||||||
|
{
|
||||||
|
if ((dev1->terminal == SOURCE &&
|
||||||
|
dev2->terminal == SOURCE &&
|
||||||
|
rd1->drain > rd2->drain) ||
|
||||||
|
(dev1->terminal == SOURCE &&
|
||||||
|
dev2->terminal == DRAIN &&
|
||||||
|
rd1->drain > rd2->source) ||
|
||||||
|
(dev1->terminal == DRAIN &&
|
||||||
|
dev2->terminal == SOURCE &&
|
||||||
|
rd1->source > rd2->drain) ||
|
||||||
|
(dev1->terminal == DRAIN &&
|
||||||
|
dev2->terminal == DRAIN &&
|
||||||
|
rd1->source > rd2->source))
|
||||||
|
{
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
*-------------------------------------------------------------------------
|
||||||
|
*
|
||||||
|
* ResSortByGate -- sorts device pointers whose terminal field is either
|
||||||
|
* drain or source by gate node number, then by drain (source) number.
|
||||||
|
* This places devices with identical connections next to one
|
||||||
|
* another.
|
||||||
|
*
|
||||||
|
* Results: none
|
||||||
|
*
|
||||||
|
* Side Effects: modifies order of devices
|
||||||
|
*
|
||||||
|
*-------------------------------------------------------------------------
|
||||||
|
*/
|
||||||
|
|
||||||
|
void
|
||||||
|
ResSortByGate(DevpointerList)
|
||||||
|
devPtr **DevpointerList;
|
||||||
|
{
|
||||||
|
devPtr *working, **Devindexed;
|
||||||
|
int listlen, listidx;
|
||||||
|
|
||||||
|
/* Linked lists are very slow to sort. Create an indexed list */
|
||||||
|
/* and run qsort() to sort, then regenerate the links. */
|
||||||
|
|
||||||
|
listlen = 0;
|
||||||
|
for (working = *DevpointerList; working; working = working->nextDev) listlen++;
|
||||||
|
Devindexed = (devPtr **)mallocMagic(listlen * sizeof(devPtr *));
|
||||||
|
listidx = 0;
|
||||||
|
for (working = *DevpointerList; working; working = working->nextDev)
|
||||||
|
Devindexed[listidx++] = working;
|
||||||
|
|
||||||
|
qsort(Devindexed, (size_t)listlen, (size_t)sizeof(devPtr *), devSortFunc);
|
||||||
|
|
||||||
|
for (listidx = 0; listidx < listlen - 1; listidx++)
|
||||||
|
Devindexed[listidx]->nextDev = Devindexed[listidx + 1];
|
||||||
|
Devindexed[listidx]->nextDev = NULL;
|
||||||
|
|
||||||
|
*Devpointerlist = Devindexed[0];
|
||||||
|
freeMagic(Devindexed);
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif /* 0 */
|
||||||
|
|
||||||
/*
|
/*
|
||||||
*-------------------------------------------------------------------------
|
*-------------------------------------------------------------------------
|
||||||
*
|
*
|
||||||
|
|
|
||||||
|
|
@ -413,7 +413,7 @@ SelectIntersect(scx, type, xMask, negate)
|
||||||
*/
|
*/
|
||||||
|
|
||||||
void
|
void
|
||||||
SelectArea(scx, types, xMask)
|
SelectArea(scx, types, xMask, globmatch)
|
||||||
SearchContext *scx; /* Describes the area in which material
|
SearchContext *scx; /* Describes the area in which material
|
||||||
* is to be selected. The resulting
|
* is to be selected. The resulting
|
||||||
* coordinates should map to the coordinates
|
* coordinates should map to the coordinates
|
||||||
|
|
@ -433,6 +433,10 @@ SelectArea(scx, types, xMask)
|
||||||
* considered. 0 means treat everything as
|
* considered. 0 means treat everything as
|
||||||
* expanded.
|
* expanded.
|
||||||
*/
|
*/
|
||||||
|
char *globmatch; /* If non-NULL, and if L_LABELS is among the
|
||||||
|
* selection types, then do glob-style matching
|
||||||
|
* of any labels against this string.
|
||||||
|
*/
|
||||||
{
|
{
|
||||||
Rect labelArea, cellArea;
|
Rect labelArea, cellArea;
|
||||||
|
|
||||||
|
|
@ -457,8 +461,13 @@ SelectArea(scx, types, xMask)
|
||||||
/* Select labels. */
|
/* Select labels. */
|
||||||
|
|
||||||
if (TTMaskHasType(types, L_LABEL))
|
if (TTMaskHasType(types, L_LABEL))
|
||||||
(void) DBCellCopyAllLabels(scx, &DBAllTypeBits, xMask,
|
{
|
||||||
SelectUse, &labelArea);
|
if (globmatch != NULL)
|
||||||
|
DBCellCopyGlobLabels(scx, &DBAllTypeBits, xMask, SelectUse, &labelArea,
|
||||||
|
globmatch);
|
||||||
|
else
|
||||||
|
DBCellCopyAllLabels(scx, &DBAllTypeBits, xMask, SelectUse, &labelArea);
|
||||||
|
}
|
||||||
else (void) DBCellCopyAllLabels(scx, types, xMask, SelectUse, &labelArea);
|
else (void) DBCellCopyAllLabels(scx, types, xMask, SelectUse, &labelArea);
|
||||||
|
|
||||||
/* Select unexpanded cell uses. */
|
/* Select unexpanded cell uses. */
|
||||||
|
|
@ -803,7 +812,7 @@ chunkdone:
|
||||||
|
|
||||||
if (less)
|
if (less)
|
||||||
{
|
{
|
||||||
SelRemoveArea(&bestChunk, &typeMask);
|
SelRemoveArea(&bestChunk, &typeMask, NULL);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
|
@ -813,7 +822,7 @@ chunkdone:
|
||||||
if (DBIsContact(type))
|
if (DBIsContact(type))
|
||||||
TTMaskSetOnlyType(&typeMask, type);
|
TTMaskSetOnlyType(&typeMask, type);
|
||||||
|
|
||||||
SelectArea(&newscx, &typeMask, xMask);
|
SelectArea(&newscx, &typeMask, xMask, NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (pArea != NULL) *pArea = bestChunk;
|
if (pArea != NULL) *pArea = bestChunk;
|
||||||
|
|
|
||||||
|
|
@ -117,9 +117,10 @@ selRemoveCellFunc(scx, cdarg)
|
||||||
*/
|
*/
|
||||||
|
|
||||||
void
|
void
|
||||||
SelRemoveArea(area, mask)
|
SelRemoveArea(area, mask, globmatch)
|
||||||
Rect *area;
|
Rect *area;
|
||||||
TileTypeBitMask *mask;
|
TileTypeBitMask *mask;
|
||||||
|
char *globmatch;
|
||||||
{
|
{
|
||||||
SearchContext scx;
|
SearchContext scx;
|
||||||
Rect bbox, areaReturn;
|
Rect bbox, areaReturn;
|
||||||
|
|
@ -134,7 +135,12 @@ SelRemoveArea(area, mask)
|
||||||
|
|
||||||
areaReturn = *area;
|
areaReturn = *area;
|
||||||
if (TTMaskHasType(mask, L_LABEL))
|
if (TTMaskHasType(mask, L_LABEL))
|
||||||
DBEraseLabel(SelectDef, area, &DBAllTypeBits, &areaReturn);
|
{
|
||||||
|
if (globmatch != NULL)
|
||||||
|
DBEraseGlobLabel(SelectDef, area, &DBAllTypeBits, &areaReturn, globmatch);
|
||||||
|
else
|
||||||
|
DBEraseLabel(SelectDef, area, &DBAllTypeBits, &areaReturn);
|
||||||
|
}
|
||||||
else
|
else
|
||||||
DBEraseLabel(SelectDef, area, mask, &areaReturn);
|
DBEraseLabel(SelectDef, area, mask, &areaReturn);
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -230,7 +230,7 @@ WirePickType(type, width)
|
||||||
SelectClear();
|
SelectClear();
|
||||||
scx.scx_area = box;
|
scx.scx_area = box;
|
||||||
TTMaskSetOnlyType(&mask, WireType);
|
TTMaskSetOnlyType(&mask, WireType);
|
||||||
SelectArea(&scx, &mask, crec->dbw_bitmask);
|
SelectArea(&scx, &mask, crec->dbw_bitmask, NULL);
|
||||||
DBWSetBox(scx.scx_use->cu_def, &box);
|
DBWSetBox(scx.scx_use->cu_def, &box);
|
||||||
TxPrintf("Using %s wires %d units wide.\n",
|
TxPrintf("Using %s wires %d units wide.\n",
|
||||||
DBTypeLongName(WireType), WireWidth);
|
DBTypeLongName(WireType), WireWidth);
|
||||||
|
|
@ -989,18 +989,18 @@ WireAddContact(newType, newWidth)
|
||||||
GEO_EXPAND(&contactArea, -oldOverlap, &tmp);
|
GEO_EXPAND(&contactArea, -oldOverlap, &tmp);
|
||||||
scx.scx_area = tmp;
|
scx.scx_area = tmp;
|
||||||
TTMaskSetOnlyType(&mask, contact->con_type);
|
TTMaskSetOnlyType(&mask, contact->con_type);
|
||||||
SelectArea(&scx, &mask, 0);
|
SelectArea(&scx, &mask, 0, NULL);
|
||||||
if (conSurround1 != 0)
|
if (conSurround1 != 0)
|
||||||
{
|
{
|
||||||
GEO_EXPAND(&tmp, conSurround1, &scx.scx_area);
|
GEO_EXPAND(&tmp, conSurround1, &scx.scx_area);
|
||||||
TTMaskSetOnlyType(&mask, contact->con_layer1);
|
TTMaskSetOnlyType(&mask, contact->con_layer1);
|
||||||
SelectArea(&scx, &mask, 0);
|
SelectArea(&scx, &mask, 0, NULL);
|
||||||
}
|
}
|
||||||
if (conSurround2 != 0)
|
if (conSurround2 != 0)
|
||||||
{
|
{
|
||||||
GEO_EXPAND(&tmp, conSurround2, &scx.scx_area);
|
GEO_EXPAND(&tmp, conSurround2, &scx.scx_area);
|
||||||
TTMaskSetOnlyType(&mask, contact->con_layer2);
|
TTMaskSetOnlyType(&mask, contact->con_layer2);
|
||||||
SelectArea(&scx, &mask, 0);
|
SelectArea(&scx, &mask, 0, NULL);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue