diff --git a/cif/CIFgen.c b/cif/CIFgen.c index 3ef1974c..4e268327 100644 --- a/cif/CIFgen.c +++ b/cif/CIFgen.c @@ -4148,6 +4148,7 @@ CIFGenLayer(op, area, cellDef, origDef, temps, clientdata) bbox.r_xtop *= cifScale; bbox.r_ybot *= cifScale; bbox.r_ytop *= cifScale; + cifScale = 1; DBNMPaintPlane(cifPlane, CIF_SOLIDTYPE, &bbox, CIFPaintTable, (PaintUndoInfo *)NULL); } @@ -4183,6 +4184,7 @@ CIFGenLayer(op, area, cellDef, origDef, temps, clientdata) bbox.r_xtop *= cifScale; bbox.r_ybot *= cifScale; bbox.r_ytop *= cifScale; + cifScale = 1; DBNMPaintPlane(curPlane, CIF_SOLIDTYPE, &bbox, CIFPaintTable, (PaintUndoInfo *)NULL); break; diff --git a/cif/CIFtech.c b/cif/CIFtech.c index 701dd369..8a55c73d 100644 --- a/cif/CIFtech.c +++ b/cif/CIFtech.c @@ -1902,11 +1902,18 @@ CIFTechFinal() case CIFOP_BLOAT: case CIFOP_BLOATMAX: case CIFOP_BLOATMIN: + bloats = (BloatData *)op->co_client; + for (j = 0; j < TT_MAXTYPES; j++) + if (bloats->bl_distance[j] != bloats->bl_distance[TT_SPACE]) + TTMaskSetType(&ourYank, j); + needThisLayer = TRUE; + break; + case CIFOP_BLOATALL: bloats = (BloatData *)op->co_client; for (j = 0; j < TT_MAXTYPES; j++) { - if (bloats->bl_distance[j] != bloats->bl_distance[TT_SPACE]) + if (bloats->bl_distance[j] != 0) { if (bloats->bl_plane < 0) TTMaskSetType(&ourDepend, j); diff --git a/lef/lefRead.c b/lef/lefRead.c index 625ecea7..22346bdb 100644 --- a/lef/lefRead.c +++ b/lef/lefRead.c @@ -2687,12 +2687,6 @@ LefRead(inName, importForeign) case LEF_SECTION_SPACING: LefSkipSection(f, sections[LEF_SECTION_SPACING]); break; - case LEF_SECTION_SITE: - token = LefNextToken(f, TRUE); - LefError(LEF_INFO, "Defines site %s (ignored)\n", token); - sprintf(tsave, "%.127s", token); - LefSkipSection(f, tsave); - break; case LEF_NOISETABLE: LefSkipSection(f, sections[LEF_NOISETABLE]); break; @@ -2711,6 +2705,7 @@ LefRead(inName, importForeign) case LEF_EXTENSION: LefSkipSection(f, sections[LEF_EXTENSION]); break; + case LEF_SECTION_SITE: case LEF_MACRO: token = LefNextToken(f, TRUE); /* Diagnostic */ diff --git a/lef/lefWrite.c b/lef/lefWrite.c index 3070c2a8..63124498 100644 --- a/lef/lefWrite.c +++ b/lef/lefWrite.c @@ -238,11 +238,12 @@ lefFileOpen(def, file, suffix, mode, prealfile) */ void -lefWriteHeader(def, f, lefTech, propTable) +lefWriteHeader(def, f, lefTech, propTable, siteTable) CellDef *def; /* Def for which to generate LEF output */ FILE *f; /* Output to this file */ bool lefTech; /* If TRUE, write layer information */ HashTable *propTable; /* Hash table of property definitions */ + HashTable *siteTable; /* Hash table of sites used */ { TileType type; HashSearch hs; @@ -296,7 +297,55 @@ lefWriteHeader(def, f, lefTech, propTable) /* This has not been implemented; only string types are supported */ fprintf(f, IN0 "MACRO %s STRING ;\n", (char *)he->h_key.h_name); } - if (nprops > 0) fprintf(f, "END PROPERTYDEFINITIONS\n"); + if (nprops > 0) fprintf(f, "END PROPERTYDEFINITIONS\n\n"); + + HashStartSearch(&hs); + while (he = HashNext(siteTable, &hs)) + { + /* Output the SITE as a macro */ + CellDef *siteDef; + float scale; + char leffmt[2][10]; + bool propfound; + char *propvalue; + Rect boundary; + + siteDef = DBCellLookDef((char *)he->h_key.h_name); + if (siteDef) + { + fprintf(f, "SITE %s\n", siteDef->cd_name); + + propvalue = (char *)DBPropGet(siteDef, "LEFsymmetry", &propfound); + if (propfound) + fprintf(f, IN0 "SYMMETRY %s ;\n", propvalue); + else + /* Usually core cells have symmetry Y only. */ + fprintf(f, IN0 "SYMMETRY Y ;\n"); + + propvalue = (char *)DBPropGet(siteDef, "LEFclass", &propfound); + if (propfound) + fprintf(f, IN0 "CLASS %s ;\n", propvalue); + else + /* Needs a class of some kind. Use CORE as default if not defined */ + fprintf(f, IN0 "CLASS CORE ;\n"); + + boundary = siteDef->cd_bbox; + if (siteDef->cd_flags & CDFIXEDBBOX) + { + propvalue = (char *)DBPropGet(def, "FIXED_BBOX", &propfound); + if (propfound) + sscanf(propvalue, "%d %d %d %d", &boundary.r_xbot, + &boundary.r_ybot, &boundary.r_xtop, &boundary.r_ytop); + } + + scale = CIFGetOutputScale(1000); /* conversion to microns */ + fprintf(f, IN0 "SIZE " FP " BY " FP " ;\n", + lefPrint(leffmt[0], scale * (float)(boundary.r_xtop - boundary.r_xbot)), + lefPrint(leffmt[1], scale * (float)(boundary.r_ytop - boundary.r_ybot))); + + fprintf(f, "END %s\n\n", siteDef->cd_name); + } + } if (!lefTech) return; @@ -1614,6 +1663,36 @@ lefWriteMacro(def, f, scale, hide) UndoEnable(); } +/* + *------------------------------------------------------------ + * + * lefGetSites --- + * + * Pull SITE instances from multiple cells into a list of + * unique entries to be written to the LEF header of an + * output LEF file. + * + *------------------------------------------------------------ + */ +int +lefGetSites(stackItem, i, clientData) + ClientData stackItem; + int i; + ClientData clientData; +{ + CellDef *def = (CellDef *)stackItem; + HashTable *lefSiteTbl = (HashTable *)clientData; + HashEntry *he; + bool propfound; + char *propvalue; + + propvalue = (char *)DBPropGet(def, "LEFsite", &propfound); + if (propfound) + he = HashFind(lefSiteTbl, propvalue); + + return 0; +} + /* *------------------------------------------------------------ * @@ -1705,7 +1784,7 @@ LefWriteAll(rootUse, writeTopCell, lefTech, lefHide, recurse) bool lefHide; bool recurse; { - HashTable propHashTbl; + HashTable propHashTbl, siteHashTbl; CellDef *def, *rootdef; FILE *f; char *filename; @@ -1753,11 +1832,16 @@ LefWriteAll(rootUse, writeTopCell, lefTech, lefHide, recurse) HashInit(&propHashTbl, 4, HT_STRINGKEYS); StackEnum(lefDefStack, lefGetProperties, &propHashTbl); + /* For all cells, collect any sites */ + HashInit(&siteHashTbl, 4, HT_STRINGKEYS); + StackEnum(lefDefStack, lefGetSites, &siteHashTbl); + /* Now generate LEF output for all the cells we just found */ - lefWriteHeader(rootdef, f, lefTech, &propHashTbl); + lefWriteHeader(rootdef, f, lefTech, &propHashTbl, &siteHashTbl); HashKill(&propHashTbl); + HashKill(&siteHashTbl); while (def = (CellDef *) StackPop(lefDefStack)) { @@ -1856,12 +1940,15 @@ LefWriteCell(def, outName, isRoot, lefTech, lefHide) if (isRoot) { - HashTable propHashTbl; + HashTable propHashTbl, siteHashTbl; HashInit(&propHashTbl, 4, HT_STRINGKEYS); lefGetProperties((ClientData)def, 0, (ClientData)&propHashTbl); - lefWriteHeader(def, f, lefTech, &propHashTbl); + HashInit(&siteHashTbl, 4, HT_STRINGKEYS); + lefGetSites((ClientData)def, 0, (ClientData)&siteHashTbl); + lefWriteHeader(def, f, lefTech, &propHashTbl, &siteHashTbl); HashKill(&propHashTbl); + HashKill(&siteHashTbl); } lefWriteMacro(def, f, scale, lefHide); fclose(f);