Added a "gds unique" option that behaves like the default CIF behavior,

in which if a cell is read from GDS that has the same name as a cell
in memory, then the cell in memory is renamed to keep all cell names
unique in the database.
This commit is contained in:
Tim Edwards 2021-04-27 13:07:27 -04:00
parent 36f9bfb162
commit be19fda504
5 changed files with 88 additions and 1 deletions

View File

@ -1 +1 @@
8.3.159
8.3.160

View File

@ -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);
}
/*
* ----------------------------------------------------------------------------
*

View File

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

View File

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

View File

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