Implemented a return value for the cell read-in checks with an option
to stop the search whenever a cell is not found. Used this to implement a new option for GDS writes, "gds undefined allow|disallow" (default "disallow") controls whether or not GDS with undefined references will be allowed to be written. Similarly affects CIF and LEF writes, extraction, and DRC (when running "drc check" from the top).
This commit is contained in:
parent
fa5a49ac3d
commit
7dfe407787
|
|
@ -53,12 +53,13 @@ static char rcsid[] __attribute__ ((unused)) ="$Header: /usr/cvsroot/magic-8.0/c
|
|||
#include "utils/stack.h"
|
||||
|
||||
/* Exports */
|
||||
bool CalmaDoLibrary = FALSE; /* If TRUE, do not output the top level */
|
||||
bool CalmaDoLabels = TRUE; /* If FALSE, don't output labels with GDS-II */
|
||||
bool CalmaDoLower = TRUE; /* If TRUE, allow lowercase labels. */
|
||||
bool CalmaFlattenArrays = FALSE; /* If TRUE, output arrays as individual uses */
|
||||
bool CalmaAddendum = FALSE; /* If TRUE, do not output readonly cell defs */
|
||||
bool CalmaNoDateStamp = FALSE; /* If TRUE, output zero for creation date stamp */
|
||||
bool CalmaDoLibrary = FALSE; /* If TRUE, do not output the top level */
|
||||
bool CalmaDoLabels = TRUE; /* If FALSE, don't output labels with GDS-II */
|
||||
bool CalmaDoLower = TRUE; /* If TRUE, allow lowercase labels. */
|
||||
bool CalmaFlattenArrays = FALSE; /* If TRUE, output arrays as individual uses */
|
||||
bool CalmaAddendum = FALSE; /* If TRUE, do not output readonly cell defs */
|
||||
bool CalmaNoDateStamp = FALSE; /* If TRUE, output zero for creation date stamp */
|
||||
bool CalmaAllowUndefined = FALSE; /* If TRUE, allow calls to undefined cells */
|
||||
|
||||
/* Experimental stuff---not thoroughly tested (as of Sept. 2007)! */
|
||||
bool CalmaContactArrays = FALSE; /* If TRUE, output contacts as subcell arrays */
|
||||
|
|
@ -305,7 +306,12 @@ CalmaWrite(rootDef, f)
|
|||
*/
|
||||
|
||||
dummy.cu_def = rootDef;
|
||||
DBCellReadArea(&dummy, &rootDef->cd_bbox);
|
||||
if (DBCellReadArea(&dummy, &rootDef->cd_bbox, !CalmaAllowUndefined))
|
||||
{
|
||||
TxError("Failure to read entire subtree of the cell.\n");
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
DBFixMismatch();
|
||||
|
||||
/*
|
||||
|
|
|
|||
|
|
@ -41,6 +41,7 @@ extern char **CalmaFlattenUsesByName;
|
|||
extern bool CalmaReadOnly;
|
||||
extern bool CalmaContactArrays;
|
||||
extern bool CalmaPostOrder;
|
||||
extern bool CalmaAllowUndefined;
|
||||
|
||||
/* Externally-visible procedures: */
|
||||
extern bool CalmaWrite();
|
||||
|
|
|
|||
|
|
@ -132,14 +132,18 @@ CIFWrite(rootDef, f)
|
|||
*/
|
||||
|
||||
dummy.cu_def = rootDef;
|
||||
DBCellReadArea(&dummy, &rootDef->cd_bbox);
|
||||
if (DBCellReadArea(&dummy, &rootDef->cd_bbox, TRUE))
|
||||
{
|
||||
TxError("Failure to read in entire subtree of the cell.\n");
|
||||
return (FALSE);
|
||||
}
|
||||
DBFixMismatch();
|
||||
|
||||
if (CIFCurStyle->cs_reducer == 0)
|
||||
{
|
||||
TxError("The current CIF output style can only be used for writing\n");
|
||||
TxError("Calma output. Try picking another output style.\n");
|
||||
return (TRUE);
|
||||
return (FALSE);
|
||||
}
|
||||
|
||||
/*
|
||||
|
|
|
|||
|
|
@ -109,6 +109,7 @@ bool cmdDumpParseArgs();
|
|||
#define CALMA_WRITE 18
|
||||
#define CALMA_POLYS 19
|
||||
#define CALMA_PATHS 20
|
||||
#define CALMA_UNDEFINED 21
|
||||
|
||||
#define CALMA_WARN_HELP CIF_WARN_END /* undefined by CIF module */
|
||||
|
||||
|
|
@ -127,6 +128,7 @@ CmdCalma(w, cmd)
|
|||
static char *gdsExts[] = {".gds", ".gds2", ".strm", "", NULL};
|
||||
static char *cmdCalmaYesNo[] = {
|
||||
"no", "false", "off", "0", "yes", "true", "on", "1", 0 };
|
||||
static char *cmdCalmaAllowDisallow[] = {"disallow", "0", "allow", "1", 0};
|
||||
static char *cmdCalmaWarnOptions[] = { "default", "none", "align",
|
||||
"limit", "redirect", "help", 0 };
|
||||
static char *cmdCalmaOption[] =
|
||||
|
|
@ -156,6 +158,8 @@ CmdCalma(w, cmd)
|
|||
" put non-Manhattan polygons into subcells",
|
||||
"path subcells [yes|no]\n"
|
||||
" put wire paths into individual subcells",
|
||||
"undefined [allow|disallow]\n"
|
||||
" [dis]allow writing of GDS with calls to undefined cells",
|
||||
NULL
|
||||
};
|
||||
|
||||
|
|
@ -279,6 +283,26 @@ CmdCalma(w, cmd)
|
|||
CalmaAddendum = (option < 4) ? FALSE : TRUE;
|
||||
return;
|
||||
|
||||
case CALMA_UNDEFINED:
|
||||
if (cmd->tx_argc == 2)
|
||||
{
|
||||
#ifdef MAGIC_WRAPPER
|
||||
Tcl_SetObjResult(magicinterp, Tcl_NewBooleanObj(CalmaAllowUndefined));
|
||||
#else
|
||||
TxPrintf("Writing of GDS file with undefined cells is %sallowed.\n",
|
||||
(CalmaAllowUndefined) ? "" : "dis");
|
||||
#endif
|
||||
return;
|
||||
}
|
||||
else if (cmd->tx_argc != 3)
|
||||
goto wrongNumArgs;
|
||||
|
||||
option = Lookup(cmd->tx_argv[2], cmdCalmaAllowDisallow);
|
||||
if (option < 0)
|
||||
goto wrongNumArgs;
|
||||
CalmaAllowUndefined = (option < 2) ? FALSE : TRUE;
|
||||
return;
|
||||
|
||||
case CALMA_CONTACTS:
|
||||
if (cmd->tx_argc == 2)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -275,7 +275,8 @@ dbUnexpandFunc(scx, arg)
|
|||
* the given rectangle.
|
||||
*
|
||||
* Results:
|
||||
* None.
|
||||
* If "halt_on_error" is TRUE, then return 1 if any subcell could not
|
||||
* be read. Otherwise, return 0.
|
||||
*
|
||||
* Side effects:
|
||||
* May make new cells known to the database. Sets the CDAVAILABLE
|
||||
|
|
@ -284,10 +285,11 @@ dbUnexpandFunc(scx, arg)
|
|||
* ----------------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
void
|
||||
DBCellReadArea(rootUse, rootRect)
|
||||
int
|
||||
DBCellReadArea(rootUse, rootRect, halt_on_error)
|
||||
CellUse *rootUse; /* Root cell use from which search begins */
|
||||
Rect *rootRect; /* Area to be read, in root coordinates */
|
||||
bool halt_on_error; /* If TRUE, failure to find a cell causes a halt */
|
||||
{
|
||||
int dbReadAreaFunc();
|
||||
SearchContext scontext;
|
||||
|
|
@ -295,30 +297,39 @@ DBCellReadArea(rootUse, rootRect)
|
|||
scontext.scx_use = rootUse;
|
||||
scontext.scx_trans = GeoIdentityTransform;
|
||||
scontext.scx_area = *rootRect;
|
||||
(void) dbReadAreaFunc(&scontext);
|
||||
if (dbReadAreaFunc(&scontext, halt_on_error) == 1)
|
||||
return 1;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int
|
||||
dbReadAreaFunc(scx)
|
||||
dbReadAreaFunc(scx, halt_on_error)
|
||||
SearchContext *scx; /* Pointer to context specifying
|
||||
* the cell use to be read in, and
|
||||
* an area to be recursively read in
|
||||
* coordinates of the cell use's def.
|
||||
*/
|
||||
bool halt_on_error; /* If TURE, failure to find a cell causes a halt */
|
||||
{
|
||||
CellDef *def = scx->scx_use->cu_def;
|
||||
|
||||
if ((def->cd_flags & CDAVAILABLE) == 0)
|
||||
{
|
||||
bool dereference = (def->cd_flags & CDDEREFERENCE) ? TRUE : FALSE;
|
||||
(void) DBCellRead(def, (char *) NULL, TRUE, dereference, NULL);
|
||||
if (DBCellRead(def, (char *)NULL, TRUE, dereference, NULL) == FALSE)
|
||||
if (halt_on_error)
|
||||
return 1;
|
||||
|
||||
/* Note: we don't have to invoke DBReComputeBbox here because
|
||||
* if the bbox changed then there was a timestamp mismatch and
|
||||
* the timestamp code will take care of the bounding box later.
|
||||
*/
|
||||
}
|
||||
|
||||
(void) DBCellSrArea(scx, dbReadAreaFunc, (ClientData) NULL);
|
||||
if (DBCellSrArea(scx, dbReadAreaFunc, (ClientData)halt_on_error))
|
||||
if (halt_on_error)
|
||||
return 1;
|
||||
|
||||
/* Be clever about handling arrays: if the search area covers this
|
||||
* whole definition, then there's no need to look at any other
|
||||
|
|
@ -328,5 +339,6 @@ dbReadAreaFunc(scx)
|
|||
|
||||
if (GEO_SURROUND(&scx->scx_area, &scx->scx_use->cu_def->cd_bbox))
|
||||
return 2;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -899,7 +899,7 @@ DBReadBackup(name)
|
|||
*
|
||||
* DBCellRead --
|
||||
*
|
||||
* This is the wrapper for DBCellReadDef. The routine has been divided into
|
||||
* This is the wrapper for dbCellReadDef. The routine has been divided into
|
||||
* parts so that a single backup file can be made and recovered, and in
|
||||
* preparation for allowing certain cell definitions to be in-lined into the
|
||||
* output file (such as polygonXXXXX cells generated by the gds read-in).
|
||||
|
|
@ -2947,7 +2947,8 @@ DBCellWrite(cellDef, fileName)
|
|||
{
|
||||
bool dereference = (cellDef->cd_flags & CDDEREFERENCE) ? TRUE : FALSE;
|
||||
/* Re-aquire the lock on the new file by opening it. */
|
||||
DBCellRead(cellDef, NULL, TRUE, dereference, NULL);
|
||||
if (DBCellRead(cellDef, NULL, TRUE, dereference, NULL) == FALSE)
|
||||
return FALSE;
|
||||
}
|
||||
#endif
|
||||
|
||||
|
|
|
|||
|
|
@ -720,7 +720,7 @@ extern bool DBCellRead();
|
|||
extern bool DBTestOpen();
|
||||
extern char *DBGetTech();
|
||||
extern bool DBCellWrite();
|
||||
extern void DBCellReadArea();
|
||||
extern int DBCellReadArea();
|
||||
extern void DBFileRecovery();
|
||||
extern bool DBWriteBackup();
|
||||
extern bool DBReadBackup();
|
||||
|
|
|
|||
|
|
@ -664,7 +664,11 @@ DRCCheck(use, area)
|
|||
SearchContext scx;
|
||||
extern int drcCheckFunc(); /* Forward reference. */
|
||||
|
||||
DBCellReadArea(use, area);
|
||||
if (DBCellReadArea(use, area, TRUE))
|
||||
{
|
||||
TxError("Failure to read in entire subtree of cell.\n");
|
||||
return;
|
||||
}
|
||||
|
||||
scx.scx_use = use;
|
||||
scx.scx_x = use->cu_xlo;
|
||||
|
|
|
|||
|
|
@ -179,7 +179,11 @@ ExtAll(rootUse)
|
|||
CellUse *rootUse;
|
||||
{
|
||||
/* Make sure the entire subtree is read in */
|
||||
DBCellReadArea(rootUse, &rootUse->cu_def->cd_bbox);
|
||||
if (DBCellReadArea(rootUse, &rootUse->cu_def->cd_bbox, TRUE))
|
||||
{
|
||||
TxError("Failure to read entire subtree of cell.\n");
|
||||
return;
|
||||
}
|
||||
|
||||
/* Fix up bounding boxes if they've changed */
|
||||
DBFixMismatch();
|
||||
|
|
@ -264,7 +268,11 @@ ExtUnique(rootUse, option)
|
|||
int nwarn;
|
||||
|
||||
/* Make sure the entire subtree is read in */
|
||||
DBCellReadArea(rootUse, &rootUse->cu_def->cd_bbox);
|
||||
if (DBCellReadArea(rootUse, &rootUse->cu_def->cd_bbox, TRUE))
|
||||
{
|
||||
TxError("Failure to read entire subtree of cell.\n");
|
||||
return;
|
||||
}
|
||||
|
||||
/* Fix up bounding boxes if they've changed */
|
||||
DBFixMismatch();
|
||||
|
|
@ -526,7 +534,11 @@ ExtIncremental(rootUse)
|
|||
CellUse *rootUse;
|
||||
{
|
||||
/* Make sure the entire subtree is read in */
|
||||
DBCellReadArea(rootUse, &rootUse->cu_def->cd_bbox);
|
||||
if (DBCellReadArea(rootUse, &rootUse->cu_def->cd_bbox, TRUE))
|
||||
{
|
||||
TxError("Failure to read entire subtree of cell.\n");
|
||||
return;
|
||||
}
|
||||
|
||||
/* Fix up bounding boxes if they've changed */
|
||||
DBFixMismatch();
|
||||
|
|
|
|||
|
|
@ -169,7 +169,11 @@ ExtTimes(rootUse, f)
|
|||
HashEntry *he;
|
||||
|
||||
/* Make sure this cell is read in */
|
||||
DBCellReadArea(rootUse, &rootUse->cu_def->cd_bbox);
|
||||
if (DBCellReadArea(rootUse, &rootUse->cu_def->cd_bbox, TRUE))
|
||||
{
|
||||
TxError("Failure to read entire subtree of cell.\n");
|
||||
return;
|
||||
}
|
||||
|
||||
/* Initialize cumulative statistics */
|
||||
extCumInit(&cumFetsPerSecPaint);
|
||||
|
|
@ -1020,7 +1024,11 @@ ExtInterCount(rootUse, halo, f)
|
|||
double inter;
|
||||
|
||||
/* Make sure this cell is read in */
|
||||
DBCellReadArea(rootUse, &rootUse->cu_def->cd_bbox);
|
||||
if (DBCellReadArea(rootUse, &rootUse->cu_def->cd_bbox, TRUE))
|
||||
{
|
||||
TxError("Failure to read entire subtree of cell.\n");
|
||||
return;
|
||||
}
|
||||
|
||||
/* Initialize cumulative statistics */
|
||||
extCumInit(&cumPercentInteraction);
|
||||
|
|
|
|||
|
|
@ -201,7 +201,7 @@ GAGenChans(chanType, area, f)
|
|||
}
|
||||
|
||||
/* Make sure everything in 'area' is read */
|
||||
(void) DBCellReadArea(EditCellUse, area);
|
||||
(void) DBCellReadArea(EditCellUse, area, FALSE);
|
||||
DBFixMismatch();
|
||||
|
||||
/* Start with a clean slate */
|
||||
|
|
|
|||
|
|
@ -1982,7 +1982,11 @@ LefWriteAll(rootUse, writeTopCell, lefTech, lefHide, lefTopLayer, lefDoMaster, r
|
|||
rootdef = rootUse->cu_def;
|
||||
|
||||
/* Make sure the entire subtree is read in */
|
||||
DBCellReadArea(rootUse, &rootdef->cd_bbox);
|
||||
if (DBCellReadArea(rootUse, &rootdef->cd_bbox, TRUE))
|
||||
{
|
||||
TxError("Could not read entire subtree of the cell.\n");
|
||||
return;
|
||||
}
|
||||
|
||||
/* Fix up bounding boxes if they've changed */
|
||||
DBFixMismatch();
|
||||
|
|
|
|||
Loading…
Reference in New Issue