Added an option "gds flatglob [<string>|none]" that allows flattening
of input cells on a per-cellname basis, using glob-style pattern matching. This is probably the best way to deal with 3rd-party vendor GDS with unfortunate practices like dividing devices up among cells in a hierarchy, even though it comes across as a bit of a hack solution.
This commit is contained in:
parent
47f37cc13a
commit
bcc7b3d06d
|
|
@ -291,6 +291,7 @@ calmaParseStructure(filename)
|
|||
bool was_called;
|
||||
bool was_initialized;
|
||||
bool predefined;
|
||||
bool do_flatten;
|
||||
CellDef *def;
|
||||
|
||||
/* Make sure this is a structure; if not, let the caller know we're done */
|
||||
|
|
@ -359,9 +360,6 @@ calmaParseStructure(filename)
|
|||
cifCurReadPlanes = cifSubcellPlanes;
|
||||
cifReadCellDef->cd_flags &= ~CDDEREFERENCE;
|
||||
|
||||
/* Done with strname */
|
||||
if (strname != NULL) freeMagic(strname);
|
||||
|
||||
/* For read-only cells, set flag in def */
|
||||
if (CalmaReadOnly)
|
||||
cifReadCellDef->cd_flags |= CDVENDORGDS;
|
||||
|
|
@ -410,7 +408,36 @@ calmaParseStructure(filename)
|
|||
/* cifReadCellDef->cd_flags |= CDNOEDIT; */
|
||||
}
|
||||
|
||||
/* Make sure it ends with an ENDSTR record */
|
||||
/* Check if the cell name matches the pattern list of cells to flatten */
|
||||
|
||||
do_flatten = FALSE;
|
||||
if ((CalmaFlattenUsesByName != NULL) && (!was_called) && (nsrefs == 0))
|
||||
{
|
||||
int i = 0;
|
||||
char *pattern;
|
||||
|
||||
while (TRUE)
|
||||
{
|
||||
pattern = CalmaFlattenUsesByName[i];
|
||||
if (pattern == NULL) break;
|
||||
i++;
|
||||
|
||||
/* Check pattern against strname */
|
||||
if (Match(pattern, strname))
|
||||
{
|
||||
do_flatten = TRUE;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (CalmaFlattenUses && (!was_called) && (npaths < CalmaFlattenLimit)
|
||||
&& (nsrefs == 0))
|
||||
do_flatten = TRUE;
|
||||
|
||||
/* Done with strname */
|
||||
if (strname != NULL) freeMagic(strname);
|
||||
|
||||
/* Make sure the structure ends with an ENDSTR record */
|
||||
if (!calmaSkipExact(CALMA_ENDSTR)) goto syntaxerror;
|
||||
|
||||
/*
|
||||
|
|
@ -418,8 +445,8 @@ calmaParseStructure(filename)
|
|||
* cell by painting when instanced. But---if this cell was
|
||||
* instanced before it was defined, then it can't be flattened.
|
||||
*/
|
||||
if (CalmaFlattenUses && (!was_called) && (npaths < CalmaFlattenLimit)
|
||||
&& (nsrefs == 0))
|
||||
|
||||
if (do_flatten)
|
||||
{
|
||||
/* If CDFLATGDS is already set, may need to remove */
|
||||
/* existing planes and free memory. */
|
||||
|
|
@ -617,7 +644,7 @@ calmaElementSref(filename)
|
|||
*/
|
||||
|
||||
def = calmaLookCell(sname);
|
||||
if (!def && (CalmaPostOrder || CalmaFlattenUses))
|
||||
if (!def && (CalmaPostOrder || CalmaFlattenUses || (CalmaFlattenUsesByName != NULL)))
|
||||
{
|
||||
/* Force the GDS parser to read the cell definition in
|
||||
* post-order. If cellname "sname" is not defined before
|
||||
|
|
|
|||
|
|
@ -63,6 +63,11 @@ bool CalmaFlattenUses = FALSE; /* If TRUE, small cells in the input
|
|||
* performance when handling contacts
|
||||
* saved as subcell arrays.
|
||||
*/
|
||||
char **CalmaFlattenUsesByName = NULL; /* NULL-terminated list of strings
|
||||
* to do glob-style pattern matching
|
||||
* to determine what cells to flatten
|
||||
* by cellname.
|
||||
*/
|
||||
bool CalmaReadOnly = FALSE; /* Set files to read-only and
|
||||
* retain file position information
|
||||
* so cells can be written verbatim.
|
||||
|
|
|
|||
|
|
@ -37,6 +37,7 @@ extern bool CalmaMergeTiles;
|
|||
extern bool CalmaFlattenArrays;
|
||||
extern bool CalmaNoDRCCheck;
|
||||
extern bool CalmaFlattenUses;
|
||||
extern char **CalmaFlattenUsesByName;
|
||||
extern bool CalmaReadOnly;
|
||||
extern bool CalmaContactArrays;
|
||||
extern bool CalmaPostOrder;
|
||||
|
|
|
|||
126
commands/CmdCD.c
126
commands/CmdCD.c
|
|
@ -94,20 +94,21 @@ bool cmdDumpParseArgs();
|
|||
#define CALMA_CONTACTS 3
|
||||
#define CALMA_DRCCHECK 4
|
||||
#define CALMA_FLATTEN 5
|
||||
#define CALMA_ORDERING 6
|
||||
#define CALMA_LABELS 7
|
||||
#define CALMA_LIBRARY 8
|
||||
#define CALMA_LOWER 9
|
||||
#define CALMA_MERGE 10
|
||||
#define CALMA_NO_STAMP 11
|
||||
#define CALMA_NO_DUP 12
|
||||
#define CALMA_READ 13
|
||||
#define CALMA_READONLY 14
|
||||
#define CALMA_RESCALE 15
|
||||
#define CALMA_WARNING 16
|
||||
#define CALMA_WRITE 17
|
||||
#define CALMA_POLYS 18
|
||||
#define CALMA_PATHS 19
|
||||
#define CALMA_FLATGLOB 6
|
||||
#define CALMA_ORDERING 7
|
||||
#define CALMA_LABELS 8
|
||||
#define CALMA_LIBRARY 9
|
||||
#define CALMA_LOWER 10
|
||||
#define CALMA_MERGE 11
|
||||
#define CALMA_NO_STAMP 12
|
||||
#define CALMA_NO_DUP 13
|
||||
#define CALMA_READ 14
|
||||
#define CALMA_READONLY 15
|
||||
#define CALMA_RESCALE 16
|
||||
#define CALMA_WARNING 17
|
||||
#define CALMA_WRITE 18
|
||||
#define CALMA_POLYS 19
|
||||
#define CALMA_PATHS 20
|
||||
|
||||
#define CALMA_WARN_HELP CIF_WARN_END /* undefined by CIF module */
|
||||
|
||||
|
|
@ -136,6 +137,7 @@ CmdCalma(w, cmd)
|
|||
"contacts [yes|no] optimize output by arraying contacts as subcells",
|
||||
"drccheck [yes|no] mark all cells as needing DRC checking",
|
||||
"flatten [yes|no|limit] flatten simple cells (e.g., contacts) on input",
|
||||
"flatglob [<name>|none] flatten cells by name with glob patterning",
|
||||
"ordering [on|off] cause cells to be read in post-order",
|
||||
"labels [yes|no] cause labels to be output when writing GDS-II",
|
||||
"library [yes|no] do not output the top level, only subcells",
|
||||
|
|
@ -350,6 +352,102 @@ CmdCalma(w, cmd)
|
|||
CalmaFlattenUses = (option < 4) ? FALSE : TRUE;
|
||||
return;
|
||||
|
||||
case CALMA_FLATGLOB:
|
||||
|
||||
if (cmd->tx_argc == 2)
|
||||
{
|
||||
if (CalmaFlattenUsesByName != NULL)
|
||||
{
|
||||
int i = 0;
|
||||
char *pattern;
|
||||
#ifdef MAGIC_WRAPPER
|
||||
Tcl_Obj *lobj = Tcl_NewListObj(0, NULL);
|
||||
while (TRUE)
|
||||
{
|
||||
pattern = CalmaFlattenUsesByName[i];
|
||||
if (pattern == NULL) break;
|
||||
i++;
|
||||
Tcl_ListObjAppendElement(magicinterp, lobj,
|
||||
Tcl_NewStringObj(pattern, -1));
|
||||
}
|
||||
Tcl_SetObjResult(magicinterp, lobj);
|
||||
#else
|
||||
TxPrintf("Glob patterns for cells to flatten:\n");
|
||||
while (TRUE)
|
||||
{
|
||||
pattern = CalmaFlattenUsesByName[i];
|
||||
if (pattern == NULL) break;
|
||||
i++;
|
||||
TxPrintf(" \"%s\"\n", pattern);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
return;
|
||||
}
|
||||
else if (cmd->tx_argc != 3)
|
||||
goto wrongNumArgs;
|
||||
|
||||
if (!strcasecmp(cmd->tx_argv[2], "none"))
|
||||
{
|
||||
int i = 0;
|
||||
if (CalmaFlattenUsesByName == (char **)NULL) return;
|
||||
while (TRUE)
|
||||
{
|
||||
char *pattern = CalmaFlattenUsesByName[i];
|
||||
if (pattern == NULL) break;
|
||||
freeMagic(pattern);
|
||||
i++;
|
||||
}
|
||||
freeMagic(CalmaFlattenUsesByName);
|
||||
CalmaFlattenUsesByName = (char **)NULL;
|
||||
}
|
||||
else
|
||||
{
|
||||
char **newpatterns;
|
||||
char *pattern;
|
||||
int i = 0;
|
||||
|
||||
if (CalmaFlattenUsesByName == (char **)NULL)
|
||||
i = 1;
|
||||
else
|
||||
{
|
||||
while (TRUE)
|
||||
{
|
||||
pattern = CalmaFlattenUsesByName[i++];
|
||||
if (pattern == NULL) break;
|
||||
}
|
||||
}
|
||||
newpatterns = (char **)mallocMagic((i + 1) * sizeof(char *));
|
||||
i = 0;
|
||||
if (CalmaFlattenUsesByName != (char **)NULL)
|
||||
{
|
||||
while (TRUE)
|
||||
{
|
||||
pattern = CalmaFlattenUsesByName[i];
|
||||
if (pattern == NULL) break;
|
||||
newpatterns[i] = StrDup((char **)NULL, pattern);
|
||||
i++;
|
||||
}
|
||||
}
|
||||
newpatterns[i++] = StrDup((char **)NULL, cmd->tx_argv[2]);
|
||||
newpatterns[i] = (char *)NULL;
|
||||
|
||||
i = 0;
|
||||
if (CalmaFlattenUsesByName != (char **)NULL)
|
||||
{
|
||||
while (TRUE)
|
||||
{
|
||||
pattern = CalmaFlattenUsesByName[i];
|
||||
if (pattern == NULL) break;
|
||||
freeMagic(pattern);
|
||||
i++;
|
||||
}
|
||||
freeMagic(CalmaFlattenUsesByName);
|
||||
}
|
||||
CalmaFlattenUsesByName = newpatterns;
|
||||
}
|
||||
return;
|
||||
|
||||
case CALMA_ORDERING:
|
||||
if (cmd->tx_argc == 2)
|
||||
{
|
||||
|
|
|
|||
Loading…
Reference in New Issue