From 81ecdbf209135d08d7eea31d91e6c24b9d1f09a0 Mon Sep 17 00:00:00 2001 From: Tim Edwards Date: Sat, 22 Jan 2022 13:02:47 -0500 Subject: [PATCH] Added a "lef datestamp" command option which is the equivalent of "gds datestamp" for LEF reads. When set to non-default, all cell definitions created from LEF macros will be given the specified timestamp, which allows the stamps of abstract views to match the stamps of full views, preventing issues of updated timestamps whenever a layout is switched between views. --- doc/html/lef.html | 7 +++++ lef/defRead.c | 1 + lef/lefCmd.c | 65 +++++++++++++++++++++++++++++++++++++++++++---- lef/lefRead.c | 15 ++++++++--- 4 files changed, 80 insertions(+), 8 deletions(-) diff --git a/doc/html/lef.html b/doc/html/lef.html index 2be521b4..9de27c4e 100644 --- a/doc/html/lef.html +++ b/doc/html/lef.html @@ -70,6 +70,13 @@ LEF-format input and output itself would be written to a DEF file.
Options -hide, -tech, and -toplayer are the same as for the lef write command. +
datestamp [value|default] +
Force all cell definitions generated from LEF macros to have + the datestamp (timestamp) of value. This can be used to + ensure that the timestamps of abstract views match the timestamps + of the equivalent full views, so that switching between abstract + and full views does not cause timestamp mismatch handling. The + string default cancels any fixed timestamps.
help
Print help information diff --git a/lef/defRead.c b/lef/defRead.c index e7567fde..c74949c5 100644 --- a/lef/defRead.c +++ b/lef/defRead.c @@ -1597,6 +1597,7 @@ DefReadComponents(f, rootDef, sname, oscale, total) defMacro = DBCellNewDef(token); defMacro->cd_flags &= ~CDNOTFOUND; dereference = (defMacro->cd_flags & CDDEREFERENCE) ? TRUE : FALSE; + if (!DBCellRead(defMacro, (char *)NULL, TRUE, dereference, NULL)) { LefError(DEF_ERROR, "Cell %s is not defined. Maybe you " diff --git a/lef/lefCmd.c b/lef/lefCmd.c index faa5d31e..683c3672 100644 --- a/lef/lefCmd.c +++ b/lef/lefCmd.c @@ -12,6 +12,7 @@ static char rcsid[] __attribute__ ((unused)) = "$Header: /usr/cvsroot/magic-8.0/ #include #include #include +#include #include "tcltk/tclmagic.h" #include "utils/magic.h" @@ -26,7 +27,13 @@ static char rcsid[] __attribute__ ((unused)) = "$Header: /usr/cvsroot/magic-8.0/ #include "textio/txcommands.h" #include "commands/commands.h" - +int *lefDateStamp = NULL; /* If non-NULL, defines the timestamp + * to use when creating new cell defs + * from LEF or DEF. Useful when generating + * libraries to make sure that full and + * abstract views of the same cell have + * matching timestamps. + */ /* * ---------------------------------------------------------------------------- * @@ -55,7 +62,8 @@ static char rcsid[] __attribute__ ((unused)) = "$Header: /usr/cvsroot/magic-8.0/ #define LEF_READ 0 #define LEF_WRITE 1 #define LEF_WRITEALL 2 -#define LEF_HELP 3 +#define LEF_DATESTAMP 3 +#define LEF_HELP 4 void CmdLef(w, cmd) @@ -113,7 +121,6 @@ CmdLef(w, cmd) * center of the first rectangle * found on that net. */ - static char *cmdLefOption[] = { "read [filename] read a LEF file filename[.lef]\n" @@ -127,6 +134,7 @@ CmdLef(w, cmd) " writeall -all recurse on all subcells of the top-level cell\n" " writeall -hide hide all details other than ports\n" " writeall -hide [dist] hide details in area set back distance dist", + "datestamp [value] force the timestamp of cells read from LEF", "help print this help information", NULL }; @@ -208,9 +216,9 @@ CmdLef(w, cmd) namep = cmd->tx_argv[2]; if (is_lef) - LefRead(namep, lefImport, lefAnnotate); + LefRead(namep, lefImport, lefAnnotate, lefDateStamp); else - DefRead(namep, defLabelNets); + DefRead(namep, defLabelNets, lefDateStamp); break; case LEF_WRITEALL: if (!is_lef) @@ -375,6 +383,53 @@ CmdLef(w, cmd) == EditRootDef, lefTech, lefHide, lefPinOnly, lefTopLayer, lefDoMaster); break; + case LEF_DATESTAMP: + if (!is_lef) + { + TxPrintf("The \"datestamp\" option is only for LEF reads.\n"); + break; + } + if (cmd->tx_argc == 2) + { +#ifdef MAGIC_WRAPPER + if (lefDateStamp != NULL) + Tcl_SetObjResult(magicinterp, Tcl_NewIntObj(*lefDateStamp)); + else + Tcl_SetObjResult(magicinterp, Tcl_NewStringObj("default", -1)); +#else + if (lefDateStamp != NULL) + TxPrintf("Macros will contain a header creation date " + "stamp of %d.\n", *lefDateStamp); + else + TxPrintf("Macros will contain a default header creation date " + "stamp.\n"); +#endif + return; + } + else if (cmd->tx_argc != 3) + goto wrongNumArgs; + + if (!strcmp(cmd->tx_argv[2], "default")) + { + if (lefDateStamp != NULL) + { + freeMagic((char *)lefDateStamp); + lefDateStamp = NULL; + } + } + else if (StrIsInt(cmd->tx_argv[2])) + { + if (lefDateStamp == NULL) + lefDateStamp = (int *)mallocMagic(sizeof(int)); + *lefDateStamp = atoi(cmd->tx_argv[2]); + } + else + { + TxError("Unrecognizable date stamp \"%s\".\n", cmd->tx_argv[2]); + goto wrongNumArgs; + } + + break; case LEF_HELP: wrongNumArgs: TxPrintf("The \"%s\" options are:\n", cmd->tx_argv[0]); diff --git a/lef/lefRead.c b/lef/lefRead.c index 4155e674..4d328323 100644 --- a/lef/lefRead.c +++ b/lef/lefRead.c @@ -1719,7 +1719,7 @@ enum lef_macro_keys {LEF_CLASS = 0, LEF_SIZE, LEF_ORIGIN, LEF_TIMING, LEF_FOREIGN, LEF_PROPERTY, LEF_MACRO_END}; void -LefReadMacro(f, mname, oscale, importForeign, doAnnotate) +LefReadMacro(f, mname, oscale, importForeign, doAnnotate, lefTimestamp) FILE *f; /* LEF file being read */ char *mname; /* name of the macro */ float oscale; /* scale factor um->magic units */ @@ -1729,6 +1729,9 @@ LefReadMacro(f, mname, oscale, importForeign, doAnnotate) bool doAnnotate; /* If true, ignore all macros that are * not already CellDefs. */ + int *lefTimestamp; /* If non-NULL, use the value pointed to + * as the CellDef's timestamp. + */ { CellDef *lefMacro; HashEntry *he; @@ -1802,6 +1805,11 @@ LefReadMacro(f, mname, oscale, importForeign, doAnnotate) else is_imported = TRUE; } + if (lefTimestamp != NULL) + { + lefMacro->cd_timestamp = *lefTimestamp; + lefMacro->cd_flags = CDFIXEDSTAMP; + } /* Initial values */ pinNum = 1; @@ -2523,10 +2531,11 @@ enum lef_sections {LEF_VERSION = 0, LEF_END}; void -LefRead(inName, importForeign, doAnnotate) +LefRead(inName, importForeign, doAnnotate, lefTimestamp) char *inName; bool importForeign; bool doAnnotate; + int *lefTimestamp; { FILE *f; char *filename; @@ -2751,7 +2760,7 @@ LefRead(inName, importForeign, doAnnotate) TxPrintf("LEF file: Defines new cell %s\n", token); */ sprintf(tsave, "%.127s", token); - LefReadMacro(f, tsave, oscale, importForeign, doAnnotate); + LefReadMacro(f, tsave, oscale, importForeign, doAnnotate, lefTimestamp); break; case LEF_END: if (LefParseEndStatement(f, "LIBRARY") == 0)