From 770a6f4a1764866da34948d3864765cef6542b1f Mon Sep 17 00:00:00 2001 From: Tim Edwards Date: Mon, 6 May 2019 16:30:29 -0400 Subject: [PATCH] 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. --- commands/CmdCD.c | 21 +++++++++++++++- database/DBcellbox.c | 5 ---- database/DBcellsrch.c | 25 +++++++++++++++++++ database/DBio.c | 58 ++++++++++++++++--------------------------- lef/defRead.c | 20 ++++++++++++++- lef/lefRead.c | 42 +++++++++++++++++++------------ select/selDisplay.c | 27 ++++++++++++++++++-- 7 files changed, 136 insertions(+), 62 deletions(-) diff --git a/commands/CmdCD.c b/commands/CmdCD.c index 65db84f9..6cd842a0 100644 --- a/commands/CmdCD.c +++ b/commands/CmdCD.c @@ -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 diff --git a/database/DBcellbox.c b/database/DBcellbox.c index 6eb8d95d..db702aa5 100644 --- a/database/DBcellbox.c +++ b/database/DBcellbox.c @@ -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 */ diff --git a/database/DBcellsrch.c b/database/DBcellsrch.c index a8fb9edc..5590f230 100644 --- a/database/DBcellsrch.c +++ b/database/DBcellsrch.c @@ -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; } diff --git a/database/DBio.c b/database/DBio.c index 09ee7d7a..3f6aca45 100644 --- a/database/DBio.c +++ b/database/DBio.c @@ -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)) diff --git a/lef/defRead.c b/lef/defRead.c index 370e3992..0b5e3261 100644 --- a/lef/defRead.c +++ b/lef/defRead.c @@ -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; diff --git a/lef/lefRead.c b/lef/lefRead.c index d9986192..3904ade4 100644 --- a/lef/lefRead.c +++ b/lef/lefRead.c @@ -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". */ diff --git a/select/selDisplay.c b/select/selDisplay.c index 90b06233..aa84a2b1 100644 --- a/select/selDisplay.c +++ b/select/selDisplay.c @@ -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;