Corrected an error in the GDS output hierarchical adjustments code

caused by the new bloat-all with templayers, which used the distance
record in the bloat structure differently than the other bloat
functions, and therefore was messing up the enumeration of layers
needing to be handled by the hierarchical output.  This was probably
also wrong for the existing bloat-all function, which might explain
some problems recently with the GDS output.
This commit is contained in:
Tim Edwards 2020-06-16 22:54:48 -04:00
parent 8297386a6c
commit bf4364da44
4 changed files with 104 additions and 13 deletions

View File

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

View File

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

View File

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

View File

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