Updated the handling of fixed bounding boxes for abstract views
(once corrected in an experimental branch but never merged). This avoids changing the actual bounding box of the cell to match the LEF bounding box, but defines a property instead and uses that property for certain functions such as displaying the bounding box outline or selecting the cell. This avoids certain related errors such as the failure to extract connections to areas outside of the fixed bounding box.
This commit is contained in:
parent
fc7249b04c
commit
770a6f4a17
|
|
@ -3678,7 +3678,7 @@ cmdDumpParseArgs(cmdName, w, cmd, dummy, scx)
|
|||
Point childPoint, editPoint, rootPoint;
|
||||
CellDef *def, *rootDef, *editDef;
|
||||
bool hasChild, hasRoot, hasTrans;
|
||||
Rect rootBox;
|
||||
Rect rootBox, bbox;
|
||||
Transform *tx_cell, trans_cell;
|
||||
char **av;
|
||||
char *cellnameptr, *fullpathname;
|
||||
|
|
@ -3792,6 +3792,25 @@ cmdDumpParseArgs(cmdName, w, cmd, dummy, scx)
|
|||
return FALSE;
|
||||
}
|
||||
|
||||
/*
|
||||
* Get def's bounding box. If def is an abstract view with CDFIXEDBBOX
|
||||
* set, then used the property FIXED_BBOX to set the bounding box.
|
||||
*/
|
||||
bbox = def->cd_bbox;
|
||||
if (def->cd_flags & CDFIXEDBBOX)
|
||||
{
|
||||
char *propvalue;
|
||||
bool found;
|
||||
|
||||
propvalue = DBPropGet(def, "FIXED_BBOX", &found);
|
||||
if (found)
|
||||
{
|
||||
if (sscanf(propvalue, "%d %d %d %d", &bbox.r_xbot, &bbox.r_ybot,
|
||||
&bbox.r_xtop, &bbox.r_ytop) != 4)
|
||||
bbox = def->cd_bbox;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Parse the remainder of the arguments to find out the reference
|
||||
* points in the child cell and the edit cell. Use the defaults
|
||||
|
|
|
|||
|
|
@ -616,11 +616,6 @@ dbReComputeBboxFunc(cellDef, boundProc, recurseProc)
|
|||
bool foundAny;
|
||||
int pNum;
|
||||
|
||||
/* Cells which declare their bounding box to be fixed */
|
||||
/* must return immediately. */
|
||||
|
||||
if (cellDef->cd_flags & CDFIXEDBBOX) return;
|
||||
|
||||
/*
|
||||
* Include area of subcells separately
|
||||
*/
|
||||
|
|
|
|||
|
|
@ -1810,6 +1810,31 @@ donecell:
|
|||
DBScalePoint(&cellDef->cd_extended.r_ll, scalen, scaled);
|
||||
DBScalePoint(&cellDef->cd_extended.r_ur, scalen, scaled);
|
||||
|
||||
/* If the cell is an abstract view with a fixed bounding box, then */
|
||||
/* adjust the bounding box property to match the new scale. */
|
||||
|
||||
if ((cellDef->cd_flags & CDFIXEDBBOX) != 0)
|
||||
{
|
||||
Rect r;
|
||||
bool found;
|
||||
char *propval;
|
||||
|
||||
propval = (char *)DBPropGet(cellDef, "FIXED_BBOX", &found);
|
||||
if (found)
|
||||
{
|
||||
if (sscanf(propval, "%d %d %d %d", &r.r_xbot, &r.r_ybot,
|
||||
&r.r_xtop, &r.r_ytop) == 4)
|
||||
{
|
||||
DBScalePoint(&r.r_ll, scalen, scaled);
|
||||
DBScalePoint(&r.r_ur, scalen, scaled);
|
||||
|
||||
propval = (char *)mallocMagic(40);
|
||||
sprintf(propval, "%d %d %d %d", r.r_xbot, r.r_ybot,
|
||||
r.r_xtop, r.r_ytop);
|
||||
DBPropPut(cellDef, "FIXED_BBOX", propval);
|
||||
}
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -1584,17 +1584,17 @@ dbReadProperties(cellDef, line, len, f, scalen, scaled)
|
|||
if (!strcmp(propertyname, "GDS_FILE"))
|
||||
cellDef->cd_flags |= CDVENDORGDS;
|
||||
|
||||
/* Also process FIXED_BBOX property, but do not keep */
|
||||
/* the property, as it should be regenerated on cell */
|
||||
/* output from the current scale. */
|
||||
/* Also process FIXED_BBOX property, as units must match */
|
||||
|
||||
if (!strcmp(propertyname, "FIXED_BBOX"))
|
||||
{
|
||||
Rect locbbox;
|
||||
|
||||
if (sscanf(propertyvalue, "%d %d %d %d",
|
||||
&(cellDef->cd_bbox.r_xbot),
|
||||
&(cellDef->cd_bbox.r_ybot),
|
||||
&(cellDef->cd_bbox.r_xtop),
|
||||
&(cellDef->cd_bbox.r_ytop)) != 4)
|
||||
&(locbbox.r_xbot),
|
||||
&(locbbox.r_ybot),
|
||||
&(locbbox.r_xtop),
|
||||
&(locbbox.r_ytop)) != 4)
|
||||
{
|
||||
TxError("Cannot read bounding box values in %s property",
|
||||
propertyname);
|
||||
|
|
@ -1605,20 +1605,25 @@ dbReadProperties(cellDef, line, len, f, scalen, scaled)
|
|||
{
|
||||
if (scalen > 1)
|
||||
{
|
||||
cellDef->cd_bbox.r_xbot *= scalen;
|
||||
cellDef->cd_bbox.r_ybot *= scalen;
|
||||
cellDef->cd_bbox.r_xtop *= scalen;
|
||||
cellDef->cd_bbox.r_ytop *= scalen;
|
||||
locbbox.r_xbot *= scalen;
|
||||
locbbox.r_ybot *= scalen;
|
||||
locbbox.r_xtop *= scalen;
|
||||
locbbox.r_ytop *= scalen;
|
||||
}
|
||||
if (scaled > 1)
|
||||
{
|
||||
cellDef->cd_bbox.r_xbot /= scaled;
|
||||
cellDef->cd_bbox.r_ybot /= scaled;
|
||||
cellDef->cd_bbox.r_xtop /= scaled;
|
||||
cellDef->cd_bbox.r_ytop /= scaled;
|
||||
locbbox.r_xbot /= scaled;
|
||||
locbbox.r_ybot /= scaled;
|
||||
locbbox.r_xtop /= scaled;
|
||||
locbbox.r_ytop /= scaled;
|
||||
}
|
||||
cellDef->cd_extended = cellDef->cd_bbox;
|
||||
cellDef->cd_flags |= CDFIXEDBBOX;
|
||||
storedvalue = (char *)mallocMagic(40);
|
||||
sprintf(storedvalue, "%d %d %d %d",
|
||||
locbbox.r_xbot, locbbox.r_ybot,
|
||||
locbbox.r_xtop, locbbox.r_ytop);
|
||||
(void) DBPropPut(cellDef, propertyname, storedvalue);
|
||||
|
||||
}
|
||||
}
|
||||
else
|
||||
|
|
@ -2538,27 +2543,6 @@ DBCellWriteFile(cellDef, f)
|
|||
DBPropEnum(cellDef, dbWritePropFunc, (ClientData)f);
|
||||
}
|
||||
|
||||
/* Fixed bounding box goes into a special property in output file */
|
||||
/* This is not kept internally as a property, so that it can be */
|
||||
/* read and written in the correct units without regard to internal */
|
||||
/* changes in scaling. */
|
||||
|
||||
if (cellDef->cd_flags & CDFIXEDBBOX)
|
||||
{
|
||||
// If there were no explicit properties, then we need to
|
||||
// write the header
|
||||
|
||||
if (cellDef->cd_props == (ClientData)NULL)
|
||||
FPRINTF(f, "<< properties >>\n");
|
||||
|
||||
sprintf(lstring, "string FIXED_BBOX %d %d %d %d\n",
|
||||
cellDef->cd_bbox.r_xbot / reducer,
|
||||
cellDef->cd_bbox.r_ybot / reducer,
|
||||
cellDef->cd_bbox.r_xtop / reducer,
|
||||
cellDef->cd_bbox.r_ytop / reducer);
|
||||
FPRINTF(f, lstring);
|
||||
}
|
||||
|
||||
FPRINTF(f, "<< end >>\n");
|
||||
|
||||
if (fflush(f) == EOF || ferror(f))
|
||||
|
|
|
|||
|
|
@ -577,7 +577,7 @@ DefReadLocation(use, f, oscale, tptr)
|
|||
float oscale;
|
||||
Transform *tptr;
|
||||
{
|
||||
Rect *r, tr;
|
||||
Rect *r, tr, rect;
|
||||
int keyword;
|
||||
char *token;
|
||||
float x, y;
|
||||
|
|
@ -611,7 +611,25 @@ DefReadLocation(use, f, oscale, tptr)
|
|||
/* restore the lower-left corner position. */
|
||||
|
||||
if (use)
|
||||
{
|
||||
r = &use->cu_def->cd_bbox;
|
||||
|
||||
/* Abstract views with fixed bounding boxes use the FIXED_BBOX property */
|
||||
|
||||
if (use->cu_def->cd_flags & CDFIXEDBBOX)
|
||||
{
|
||||
char *propval;
|
||||
bool found;
|
||||
|
||||
propval = DBPropGet(use->cu_def, "FIXED_BBOX", &found);
|
||||
if (found)
|
||||
{
|
||||
if (sscanf(propval, "%d %d %d %d", &rect.r_xbot, &rect.r_ybot,
|
||||
&rect.r_xtop, &rect.r_ytop) == 4)
|
||||
r = ▭
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
r = &GeoNullRect;
|
||||
|
||||
|
|
|
|||
|
|
@ -1370,7 +1370,7 @@ LefReadMacro(f, mname, oscale, importForeign)
|
|||
CellDef *lefMacro;
|
||||
HashEntry *he;
|
||||
|
||||
char *token, tsave[128];
|
||||
char *token, tsave[128], *propval;
|
||||
int keyword, pinNum;
|
||||
float x, y;
|
||||
bool has_size, is_imported = FALSE;
|
||||
|
|
@ -1558,40 +1558,50 @@ origin_error:
|
|||
}
|
||||
|
||||
/* Finish up creating the cell */
|
||||
DBReComputeBbox(lefMacro);
|
||||
|
||||
if (is_imported)
|
||||
{
|
||||
/* Redefine cell bounding box to match the LEF macro */
|
||||
/* Leave "extended" to mark the original bounding box */
|
||||
/* Define the FIXED_BBOX property to match the LEF macro */
|
||||
|
||||
if (has_size)
|
||||
{
|
||||
lefMacro->cd_bbox = lefBBox;
|
||||
lefMacro->cd_flags |= CDFIXEDBBOX;
|
||||
propval = (char *)mallocMagic(40);
|
||||
sprintf(propval, "%d %d %d %d",
|
||||
lefBBox.r_xbot, lefBBox.r_ybot,
|
||||
lefBBox.r_xtop, lefBBox.r_ytop);
|
||||
DBPropPut(lefMacro, "FIXED_BBOX", propval);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
DBAdjustLabelsNew(lefMacro, &TiPlaneRect, 1);
|
||||
|
||||
if (!has_size)
|
||||
if (has_size)
|
||||
{
|
||||
LefError(" Macro does not define size: computing from geometry\n");
|
||||
DBReComputeBbox(lefMacro);
|
||||
lefMacro->cd_flags |= CDFIXEDBBOX;
|
||||
propval = (char *)mallocMagic(40);
|
||||
sprintf(propval, "%d %d %d %d",
|
||||
lefBBox.r_xbot, lefBBox.r_ybot,
|
||||
lefBBox.r_xtop, lefBBox.r_ytop);
|
||||
DBPropPut(lefMacro, "FIXED_BBOX", propval);
|
||||
}
|
||||
else
|
||||
{
|
||||
char *propstr = (char *)mallocMagic(64);
|
||||
int reducer = DBCellFindScale(lefMacro);
|
||||
LefError(" Macro does not define size: computing from geometry\n");
|
||||
|
||||
lefMacro->cd_bbox = lefBBox;
|
||||
lefMacro->cd_extended = lefBBox;
|
||||
/* Set the placement bounding box property to the current bounding box */
|
||||
lefMacro->cd_flags |= CDFIXEDBBOX;
|
||||
propval = (char *)mallocMagic(40);
|
||||
sprintf(propval, "%d %d %d %d",
|
||||
lefMacro->cd_bbox.r_xbot,
|
||||
lefMacro->cd_bbox.r_ybot,
|
||||
lefMacro->cd_bbox.r_xtop,
|
||||
lefMacro->cd_bbox.r_ytop);
|
||||
DBPropPut(lefMacro, "FIXED_BBOX", propval);
|
||||
DRCCheckThis(lefMacro, TT_CHECKPAINT, &lefMacro->cd_bbox);
|
||||
}
|
||||
|
||||
/* Fix the bounding box and do not allow edits */
|
||||
lefMacro->cd_flags |= /* CDNOEDIT | */ CDFIXEDBBOX;
|
||||
|
||||
DRCCheckThis(lefMacro, TT_CHECKPAINT, &lefMacro->cd_bbox);
|
||||
}
|
||||
|
||||
/* Note: The value here is ignored, setting to "TRUE". */
|
||||
|
|
|
|||
|
|
@ -307,11 +307,34 @@ selRedisplayCellFunc(scx, window)
|
|||
SearchContext *scx; /* Describes cell found. */
|
||||
MagWindow *window; /* Window in which to redisplay. */
|
||||
{
|
||||
Rect tmp, screen;
|
||||
Rect tmp, screen, bbox;
|
||||
Point p;
|
||||
char idName[100];
|
||||
|
||||
GeoTransRect(&scx->scx_trans, &scx->scx_use->cu_def->cd_bbox, &tmp);
|
||||
/* Selections of cells with a fixed bounding box flag show the outline */
|
||||
/* of the fixed bounding box, not the actual bounding box. */
|
||||
|
||||
if (scx->scx_use->cu_def->cd_flags & CDFIXEDBBOX)
|
||||
{
|
||||
bool found;
|
||||
char *propval;
|
||||
|
||||
propval = (char *)DBPropGet(scx->scx_use->cu_def, "FIXED_BBOX", &found);
|
||||
if (found)
|
||||
{
|
||||
if (sscanf(propval, "%d %d %d %d", &bbox.r_xbot, &bbox.r_ybot,
|
||||
&bbox.r_xtop, &bbox.r_ytop) == 4)
|
||||
GeoTransRect(&scx->scx_trans, &bbox, &tmp);
|
||||
else
|
||||
found = FALSE;
|
||||
}
|
||||
if (!found)
|
||||
GeoTransRect(&scx->scx_trans, &scx->scx_use->cu_def->cd_bbox, &tmp);
|
||||
}
|
||||
else
|
||||
{
|
||||
GeoTransRect(&scx->scx_trans, &scx->scx_use->cu_def->cd_bbox, &tmp);
|
||||
}
|
||||
if (!DBSrPaintArea((Tile *) NULL, selRedisplayPlane, &tmp,
|
||||
&DBAllButSpaceBits, selAlways1, (ClientData) NULL))
|
||||
return 0;
|
||||
|
|
|
|||
Loading…
Reference in New Issue