diff --git a/VERSION b/VERSION index 70b3b850..7df9552c 100644 --- a/VERSION +++ b/VERSION @@ -1 +1 @@ -8.3.159 +8.3.160 diff --git a/calma/CalmaRdcl.c b/calma/CalmaRdcl.c index 9a379599..5f9dbae8 100644 --- a/calma/CalmaRdcl.c +++ b/calma/CalmaRdcl.c @@ -55,6 +55,7 @@ extern HashTable calmaDefInitHash; /* forward declarations */ int calmaElementSref(); bool calmaParseElement(); +void calmaUniqueCell(); /* Structure used when flattening the GDS hierarchy on read-in */ @@ -349,6 +350,7 @@ calmaParseStructure(filename) freeMagic(newname); } } + if (CalmaUnique) calmaUniqueCell(strname); /* Ensure uniqueness */ cifReadCellDef = calmaFindCell(strname, &was_called, &predefined); if (predefined == TRUE) @@ -1136,6 +1138,62 @@ gdsCopyPaintFunc(tile, gdsCopyRec) return 0; } +/* + * ---------------------------------------------------------------------------- + * + * calmaUniqueCell -- + * + * Attempt to find a cell in the GDS subcell name hash table. + * If one exists, rename its definition so that it will not + * be overwritten when the cell is redefined. + * + * Results: + * None. + * + * Side effects: + * None. + * + * ---------------------------------------------------------------------------- + */ + +void +calmaUniqueCell(sname) + char *sname; +{ + HashEntry *h; + CellDef *def, *testdef; + char *newname; + int snum = 0; + + h = HashLookOnly(&CifCellTable, sname); + if ((h == NULL) || HashGetValue(h) == 0) return; + + def = DBCellLookDef(sname); + if (def == (CellDef *)NULL) + return; + + /* Cell may have been called but not yet defined---this is okay. */ + else if ((def->cd_flags & CDAVAILABLE) == 0) + return; + + testdef = def; + newname = (char *)mallocMagic(10 + strlen(sname)); + + while (testdef != NULL) + { + /* Keep appending suffix indexes until we find one not used */ + sprintf(newname, "%s_%d", sname, ++snum); + testdef = DBCellLookDef(newname); + } + DBCellRenameDef(def, newname); + + h = HashFind(&CifCellTable, (char *)sname); + HashSetValue(h, 0); + + CalmaReadError("Warning: cell definition \"%s\" reused.\n", sname); + freeMagic(newname); +} + /* * ---------------------------------------------------------------------------- * diff --git a/calma/CalmaRead.c b/calma/CalmaRead.c index 7daed818..9857f8d0 100644 --- a/calma/CalmaRead.c +++ b/calma/CalmaRead.c @@ -87,6 +87,12 @@ bool CalmaNoDuplicates = FALSE; /* If TRUE, then if a cell exists in * in the GDS file, then the cell in * the GDS file is skipped. */ +bool CalmaUnique = FALSE; /* If TRUE, then if a cell exists in + * memory with the same name as a cell + * in the GDS file, then the cell in + * memory is renamed to a unique + * identifier with a _N suffix. + */ extern void calmaUnexpected(); extern int calmaWriteInitFunc(); diff --git a/calma/calma.h b/calma/calma.h index d37d50f3..de0314f1 100644 --- a/calma/calma.h +++ b/calma/calma.h @@ -33,6 +33,7 @@ extern bool CalmaDoLower; extern bool CalmaAddendum; extern bool CalmaNoDuplicates; extern bool CalmaNoDateStamp; +extern bool CalmaUnique; extern bool CalmaMergeTiles; extern bool CalmaFlattenArrays; extern bool CalmaNoDRCCheck; diff --git a/commands/CmdCD.c b/commands/CmdCD.c index f4034a54..1ba9e472 100644 --- a/commands/CmdCD.c +++ b/commands/CmdCD.c @@ -110,6 +110,7 @@ bool cmdDumpParseArgs(); #define CALMA_POLYS 19 #define CALMA_PATHS 20 #define CALMA_UNDEFINED 21 +#define CALMA_UNIQUE 22 #define CALMA_WARN_HELP CIF_WARN_END /* undefined by CIF module */ @@ -160,6 +161,7 @@ CmdCalma(w, cmd) " put wire paths into individual subcells", "undefined [allow|disallow]\n" " [dis]allow writing of GDS with calls to undefined cells", + "unique [yes|no] rename any cells with names duplicated in the GDS", NULL }; @@ -599,6 +601,26 @@ CmdCalma(w, cmd) CalmaNoDuplicates = (option < 4) ? FALSE : TRUE; return; + case CALMA_UNIQUE: + if (cmd->tx_argc == 2) + { +#ifdef MAGIC_WRAPPER + Tcl_SetObjResult(magicinterp, Tcl_NewBooleanObj(CalmaUnique)); +#else + TxPrintf("Cell defs that exist before reading GDS will be renamed.\n", + (CalmaUnique) ? "not " : ""); +#endif + return; + } + else if (cmd->tx_argc != 3) + goto wrongNumArgs; + + option = Lookup(cmd->tx_argv[2], cmdCalmaYesNo); + if (option < 0) + goto wrongNumArgs; + CalmaUnique = (option < 4) ? FALSE : TRUE; + return; + case CALMA_NO_STAMP: if (cmd->tx_argc == 2) {