From f15ea2a135622ffa13f666589ae131430d4eacbd Mon Sep 17 00:00:00 2001 From: Tim Edwards Date: Thu, 19 Dec 2019 10:33:22 -0500 Subject: [PATCH 1/2] Modified "lef writeall" to only generate output for the set of subcells that are direct children of the top level cell. The "-all" option was added to enable the previous behavior, although its usefulness is doubtful. --- calma/CalmaWrite.c | 2 +- lef/lefCmd.c | 12 ++++++++++-- lef/lefWrite.c | 18 ++++++++++++------ 3 files changed, 23 insertions(+), 9 deletions(-) diff --git a/calma/CalmaWrite.c b/calma/CalmaWrite.c index 0480238f..a08899fa 100644 --- a/calma/CalmaWrite.c +++ b/calma/CalmaWrite.c @@ -1024,7 +1024,7 @@ calmaOutFunc(def, f, cliprect) ((lab->lab_flags & PORT_NUM_MASK) == i)) { calmaWriteLabelFunc(lab, type, f); - break; + /* break; */ /* Do not limit to unique labels! */ } } } diff --git a/lef/lefCmd.c b/lef/lefCmd.c index 546988db..0322467a 100644 --- a/lef/lefCmd.c +++ b/lef/lefCmd.c @@ -87,6 +87,11 @@ CmdLef(w, cmd) * the macro other than pin area * immediately surrounding labels. */ + bool recurse = FALSE; /* If TRUE, recurse on all subcells + * during "writeall". By default, + * only the immediate children of the + * top level cell are output. + */ static char *cmdLefOption[] = { @@ -95,7 +100,8 @@ CmdLef(w, cmd) "write [filename] [-tech] write LEF for current cell\n" " write [filename] -hide hide all details other than ports", "writeall write all cells including the top-level cell\n" - " writeall -notop write all subcells of the top-level cell", + " writeall -notop write all children of the top-level cell\n" + " writeall -all recurse on all subcells of the top-level cell", "help print this help information", NULL }; @@ -184,11 +190,13 @@ CmdLef(w, cmd) lefTopCell = FALSE; else if (!strncmp(cmd->tx_argv[i], "-tech", 5)) lefTech = TRUE; + else if (!strncmp(cmd->tx_argv[i], "-all", 4)) + recurse = TRUE; else goto wrongNumArgs; } else goto wrongNumArgs; } - LefWriteAll(selectedUse, lefTopCell, lefTech); + LefWriteAll(selectedUse, lefTopCell, lefTech, recurse); } break; case LEF_WRITE: diff --git a/lef/lefWrite.c b/lef/lefWrite.c index 8c3f7530..2984a2fb 100644 --- a/lef/lefWrite.c +++ b/lef/lefWrite.c @@ -1133,10 +1133,11 @@ lefWriteMacro(def, f, scale, hide) */ void -LefWriteAll(rootUse, writeTopCell, lefTech) +LefWriteAll(rootUse, writeTopCell, lefTech, recurse) CellUse *rootUse; bool writeTopCell; bool lefTech; + bool recurse; { CellDef *def, *rootdef; FILE *f; @@ -1155,8 +1156,12 @@ LefWriteAll(rootUse, writeTopCell, lefTech) (void) DBCellSrDefs(0, lefDefInitFunc, (ClientData) 0); /* Recursively visit all defs in the tree and push on stack */ + /* If "recurse" is false, then only the children of the root use */ + /* are pushed (this is the default behavior). */ lefDefStack = StackNew(100); - (void) lefDefPushFunc(rootUse); + if (writeTopCell) + lefDefPushFunc(rootUse, (bool *)NULL); + DBCellEnum(rootUse->cu_def, lefDefPushFunc, (ClientData)&recurse); /* Open the file for output */ @@ -1185,8 +1190,7 @@ LefWriteAll(rootUse, writeTopCell, lefTech) { def->cd_client = (ClientData) 0; if (!SigInterruptPending) - if ((writeTopCell == TRUE) || (def != rootdef)) - lefWriteMacro(def, f, scale); + lefWriteMacro(def, f, scale); } /* End the LEF file */ @@ -1217,8 +1221,9 @@ lefDefInitFunc(def) */ int -lefDefPushFunc(use) +lefDefPushFunc(use, recurse) CellUse *use; + bool *recurse; { CellDef *def = use->cu_def; @@ -1227,7 +1232,8 @@ lefDefPushFunc(use) def->cd_client = (ClientData) 1; StackPush((ClientData) def, lefDefStack); - (void) DBCellEnum(def, lefDefPushFunc, (ClientData) 0); + if (recurse && (*recurse)) + (void) DBCellEnum(def, lefDefPushFunc, (ClientData)recurse); return (0); } From 67866c79912d91016cf5577189851299dd73d1ad Mon Sep 17 00:00:00 2001 From: Tim Edwards Date: Thu, 19 Dec 2019 17:28:06 -0500 Subject: [PATCH 2/2] Apparently GDS format does not enforce the original string character limit of the Calma definition, and probably has not done so for ages. Nobody informed me of this. The restriction has been lifted from GDS input and output in Magic. It can be reinstated if necessary by setting a flag in the cifoutput section of the techfile, but it is likely that this will not be necessary unless there are other tools that enforce the limit and will not read a GDS file that exceeds it. --- calma/CalmaRdcl.c | 10 ++++++++-- calma/CalmaWrite.c | 22 ++++++++++++++++------ cif/CIFint.h | 1 + cif/CIFtech.c | 2 ++ 4 files changed, 27 insertions(+), 8 deletions(-) diff --git a/calma/CalmaRdcl.c b/calma/CalmaRdcl.c index e69bb386..8ddb065f 100644 --- a/calma/CalmaRdcl.c +++ b/calma/CalmaRdcl.c @@ -282,7 +282,7 @@ calmaParseStructure(filename) { static int structs[] = { CALMA_STRCLASS, CALMA_STRTYPE, -1 }; int nbytes, rtype, nsrefs, osrefs, npaths; - char *strname = NULL, newname[CALMANAMELENGTH*2]; + char *strname = NULL; HashEntry *he; int suffix; int mfactor; @@ -327,15 +327,21 @@ calmaParseStructure(filename) } else { + char *newname; + CalmaReadError("Cell \"%s\" was already defined in this file.\n", strname); + newname = (char *)mallocMagic(strlen(strname) + 20); for (suffix = 1; HashGetValue(he) != NULL; suffix++) { (void) sprintf(newname, "%s_%d", strname, suffix); he = HashFind(&calmaDefInitHash, newname); } CalmaReadError("Giving this cell a new name: %s\n", newname); - strncpy(strname, newname, CALMANAMELENGTH*2); + freeMagic(strname); + strname = mallocMagic(strlen(newname) + 1); + strcpy(strname, newname); + freeMagic(newname); } } cifReadCellDef = calmaFindCell(strname, &was_called); diff --git a/calma/CalmaWrite.c b/calma/CalmaWrite.c index a08899fa..d3320376 100644 --- a/calma/CalmaWrite.c +++ b/calma/CalmaWrite.c @@ -372,7 +372,7 @@ calmaDumpStructure(def, outf, calmaDefHash, filename) char *filename; { int nbytes, rtype; - char *strname = NULL, *newnameptr, newname[CALMANAMELENGTH*2]; + char *strname = NULL, *newnameptr; HashEntry *he, *he2; CellDef *edef; char *prefix = NULL; @@ -1316,7 +1316,7 @@ calmaOutStructName(type, def, f) CellDef *def; FILE *f; { - char defname[CALMANAMELENGTH+1]; + char *defname; unsigned char c; char *cp; int calmanum; @@ -1341,10 +1341,11 @@ calmaOutStructName(type, def, f) } /* We really should ensure that the new name is unique. . . */ } - if (cp <= def->cd_name + CALMANAMELENGTH) + if ((!(CIFCurStyle->cs_flags & CWF_STRING_LIMIT)) || + (cp <= def->cd_name + CALMANAMELENGTH)) { /* Yes, it's legal: use it */ - (void) strcpy(defname, def->cd_name); + defname = StrDup(NULL, def->cd_name); } else { @@ -1352,12 +1353,14 @@ calmaOutStructName(type, def, f) bad: calmanum = (int) def->cd_client; if (calmanum < 0) calmanum = -calmanum; + defname = (char *)mallocMagic(32); (void) sprintf(defname, "XXXXX%d", calmanum); TxError("Warning: string in output unprintable; changed to \'%s\'\n", defname); } calmaOutStringRecord(type, defname, f); + freeMagic(defname); } /* Added by NP 8/21/2004 */ @@ -2734,7 +2737,7 @@ calmaOutDate(t, f) void calmaOutStringRecord(type, str, f) int type; /* Type of this record (data type is ASCII string) */ - char *str; /* String to be output (<= CALMANAMELENGTH chars) */ + char *str; /* String to be output */ FILE *f; /* Stream file */ { int len; @@ -2759,9 +2762,16 @@ calmaOutStringRecord(type, str, f) * last CALMANAMELENGTH characters (since cell names are more * likely to be unique in the last characters than in the first * characters). + * + * NOTE: GDS format has not used CALMANAMELENGTH restrictions + * for ages. Since this is a 2-byte record, then is it not + * worth checking the 65536 - 4 character limit. The CALMANAMELENGTH + * restriction must be enabled in the cifoutput flags. */ + + if (len & 01) len++; - if (len > CALMANAMELENGTH) + if ((CIFCurStyle->cs_flags & CWF_STRING_LIMIT) && (len > CALMANAMELENGTH)) { TxError("Warning: Cellname %s truncated ", str); TxError("to %s (GDS format limit)\n", str + len - CALMANAMELENGTH); diff --git a/cif/CIFint.h b/cif/CIFint.h index 79564a34..a3a59788 100644 --- a/cif/CIFint.h +++ b/cif/CIFint.h @@ -297,6 +297,7 @@ typedef struct cifstyle #define CWF_GROW_EUCLIDEAN 0x08 #define CWF_SEE_VENDOR 0x10 /* Override vendor GDS flag in cells */ #define CWF_NO_ERRORS 0x20 /* Do not generate error msgs and fdbk */ +#define CWF_STRING_LIMIT 0x40 /* Use older Calma format character limit */ /* procedures */ diff --git a/cif/CIFtech.c b/cif/CIFtech.c index 9639ea00..9f2f457b 100644 --- a/cif/CIFtech.c +++ b/cif/CIFtech.c @@ -994,6 +994,8 @@ CIFTechLine(sectionName, argc, argv) CIFCurStyle->cs_flags |= CWF_SEE_VENDOR; else if (strcmp(argv[i], "no-errors") == 0) CIFCurStyle->cs_flags |= CWF_NO_ERRORS; + else if (strcmp(argv[i], "string-limit") == 0) + CIFCurStyle->cs_flags |= CWF_STRING_LIMIT; } return TRUE; }