diff --git a/lef/defRead.c b/lef/defRead.c index b0b97c2f..9ec6a150 100644 --- a/lef/defRead.c +++ b/lef/defRead.c @@ -937,6 +937,40 @@ DefReadNonDefaultRules(f, rootDef, sname, oscale, total) "the number declared (%d).\n", processed, total); } +/* + *------------------------------------------------------------ + * + * defFoundOneFunc -- + * + * Simple callback function for DefReadNets() when using + * the "def read -annoatate" option. Attempts to find + * paint in the top level in the area of a pin that is + * part of the net. + * + * Note: The routine does not search on connected tiles + * and so could miss the connecting material, although + * there are multiple fall-back chances to succeed. + * + * Returns: + * 1 to stop the search, as we just take the first tile + * found and run with it. + * + * Side effects: + * Copies a pointer to the tile found into the client + * data record. + * + *------------------------------------------------------------ + */ + +int +defFoundOneFunc(tile, tret) + Tile *tile; + Tile **tret; +{ + *tret = tile; + return 1; +} + /* *------------------------------------------------------------ * @@ -976,12 +1010,13 @@ DefReadNets(f, rootDef, sname, oscale, special, dolabels, annotate, total) int total; { char *token; - char *netname = NULL; + char *netname = NULL, *prnet; int keyword, subkey; int processed = 0; LefMapping *defLayerMap; LefRules *ruleset = NULL; HashEntry *he; + bool needanno; static char *net_keys[] = { "-", @@ -1031,6 +1066,7 @@ DefReadNets(f, rootDef, sname, oscale, special, dolabels, annotate, total) /* Get net name */ token = LefNextToken(f, TRUE); if (dolabels) netname = StrDup((char **)NULL, token); + needanno = annotate; /* Update the record of the number of nets processed */ /* and spit out a message for every 5% finished. */ @@ -1041,6 +1077,62 @@ DefReadNets(f, rootDef, sname, oscale, special, dolabels, annotate, total) /* Process all properties */ while (token && (*token != ';')) { + if (needanno) + { + char *compname, *termname; + + /* Annotation only---when back-annotating */ + /* labels into a layout, the safest place to */ + /* put labels is on a terminal position */ + + if (*token == '(') + { + token = LefNextToken(f, TRUE); + if (!strcmp(token, "PIN")) + needanno = FALSE; + else + { + Rect r; + bool isvalid; + TileType ttype; + Tile *tp; + + compname = StrDup((char **)NULL, token); + token = LefNextToken(f, TRUE); + termname = (char *)mallocMagic(strlen(compname) + + strlen(token) + 3); + sprintf(termname, "%s/%s", compname, token); + ttype = CmdFindNetProc(termname, EditCellUse, &r, + FALSE, &isvalid); + if (isvalid) + { + /* The pin was found. However, there may not be + * paint on the top level over the whole pin. + * Search the area (+1) for attached paint, then + * label inside that tile. + */ + tp = NULL; + DBSrPaintArea((Tile *)NULL, + rootDef->cd_planes[DBPlane(ttype)], + &r, &DBConnectTbl[ttype], + defFoundOneFunc, (ClientData)&tp); + + if (tp != NULL) + { + TiToRect(tp, &r); + r.r_xbot = r.r_xtop = (r.r_xbot + r.r_xtop) / 2; + r.r_ybot = r.r_ytop = (r.r_ybot + r.r_ytop) / 2; + DBPutLabel(rootDef, &r, GEO_CENTER, netname, + ttype, 0, 0); + needanno = FALSE; + } + } + freeMagic(termname); + freeMagic(compname); + } + } + } + /* All connections are ignored, and we go */ /* go directly to the first property ("+") key */ @@ -1065,8 +1157,11 @@ DefReadNets(f, rootDef, sname, oscale, special, dolabels, annotate, total) case DEF_NETPROP_FIXED: case DEF_NETPROP_COVER: case DEF_NETPROP_NOSHIELD: + prnet = NULL; + if (dolabels && (needanno || (!annotate))) + prnet = netname; token = DefAddRoutes(rootDef, f, oscale, special, - netname, ruleset, defLayerMap, annotate); + prnet, ruleset, defLayerMap, annotate); ruleset = NULL; break; @@ -1309,6 +1404,7 @@ DefReadPins(f, rootDef, sname, oscale, total) int pinDir = PORT_CLASS_DEFAULT; int pinUse = PORT_USE_DEFAULT; int pinNum = 0; + int width, height, rot, size; TileType curlayer = -1; LinkedRect *rectList = NULL, *newRect; Rect *currect, topRect; @@ -1495,9 +1591,27 @@ DefReadPins(f, rootDef, sname, oscale, total) { GeoTransRect(&t, &rectList->r_r, &topRect); DBPaint(rootDef, &topRect, rectList->r_type); - DBPutLabel(rootDef, &topRect, -1, pinname, - rectList->r_type, - pinDir | pinUse | flags, pinNum); + // DBPutLabel(rootDef, &topRect, -1, pinname, + // rectList->r_type, + // pinDir | pinUse | flags, pinNum); + width = (topRect.r_xtop - topRect.r_xbot); + height = (topRect.r_ytop - topRect.r_ybot); + rot = 0; + if (height > (width * 2)) + { + int temp = height; + height = width; + width = temp; + rot = 90; + } + size = DRCGetDefaultLayerWidth(rectList->r_type); + while ((size << 1) < height) size <<= 1; + size <<= 3; /* Fonts are in 8x units */ + DBPutFontLabel(rootDef, &topRect, + 0, size, rot, &GeoOrigin, + GEO_CENTER, pinname, + rectList->r_type, + pinDir | pinUse | flags, pinNum); freeMagic(rectList); rectList = rectList->r_next; } @@ -1524,9 +1638,27 @@ DefReadPins(f, rootDef, sname, oscale, total) { GeoTransRect(&t, &rectList->r_r, &topRect); DBPaint(rootDef, &topRect, rectList->r_type); - DBPutLabel(rootDef, &topRect, -1, pinname, - rectList->r_type, - pinDir | pinUse | flags, pinNum); + // DBPutLabel(rootDef, &topRect, -1, pinname, + // rectList->r_type, + // pinDir | pinUse | flags, pinNum); + width = (topRect.r_xtop - topRect.r_xbot); + height = (topRect.r_ytop - topRect.r_ybot); + rot = 0; + if (height > (width * 2)) + { + int temp = height; + height = width; + width = temp; + rot = 90; + } + size = DRCGetDefaultLayerWidth(rectList->r_type); + while ((size << 1) < height) size <<= 1; + size <<= 3; /* Fonts are in 8x units */ + DBPutFontLabel(rootDef, &topRect, + 0, size, rot, &GeoOrigin, + GEO_CENTER, pinname, + rectList->r_type, + pinDir | pinUse | flags, pinNum); freeMagic(rectList); rectList = rectList->r_next; } diff --git a/lef/lefRead.c b/lef/lefRead.c index 0ef420c4..ca50d783 100644 --- a/lef/lefRead.c +++ b/lef/lefRead.c @@ -1868,7 +1868,8 @@ newrule: LefError(LEF_INFO, "No layer for non-default width.\n"); else rule->width = (int)roundf(fvalue / oscale); - break; + LefEndStatement(f); + break; case LEF_NONDEFLAYER_SPACE: if (!inlayer) LefError(DEF_INFO, "SPACING specified without layer.\n"); @@ -1880,6 +1881,7 @@ newrule: LefError(LEF_INFO, "No layer for non-default spacing.\n"); else rule->spacing = (int)roundf(fvalue / oscale); + LefEndStatement(f); break; case LEF_NONDEFLAYER_DIAG: case LEF_NONDEFLAYER_EXT: @@ -1888,6 +1890,7 @@ newrule: "Layer value specified without layer.\n"); /* Absorb token and ignore */ token = LefNextToken(f, TRUE); + LefEndStatement(f); break; } diff --git a/select/selOps.c b/select/selOps.c index 824899bc..cb2034f7 100644 --- a/select/selOps.c +++ b/select/selOps.c @@ -228,6 +228,12 @@ SelectCopy(transform) { SearchContext scx; + if (EditCellUse == NULL) + { + TxError("The current cell is not editable.\n"); + return; + } + /* Copy from SelectDef to Select2Def while transforming, then * let SelectAndCopy2 do the rest of the work. Don't record * anything involving Select2Def for undo-ing. @@ -1439,6 +1445,12 @@ SelectStretch(x, y) if ((x == 0) && (y == 0)) return; + if (EditCellUse == NULL) + { + TxError("The current cell is not editable.\n"); + return; + } + /* First of all, copy from SelectDef to Select2Def, moving the * selection along the way. */ diff --git a/wiring/wireTech.c b/wiring/wireTech.c index b1555a2b..1b4b9e15 100644 --- a/wiring/wireTech.c +++ b/wiring/wireTech.c @@ -36,7 +36,7 @@ static char rcsid[] __attribute__ ((unused)) = "$Header$"; #include "utils/malloc.h" /* Linked list to store contact information collected by this module: */ -Contact *WireContacts; +Contact *WireContacts = NULL; int WireUnits; // Units per lambda for wiring sizes