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:
Tim Edwards 2019-05-06 16:30:29 -04:00
parent fc7249b04c
commit 770a6f4a17
7 changed files with 136 additions and 62 deletions

View File

@ -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

View File

@ -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
*/

View File

@ -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;
}

View File

@ -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))

View File

@ -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 = &rect;
}
}
}
else
r = &GeoNullRect;

View File

@ -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". */

View File

@ -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;