Modified LEF read and write to preserve macro PROPERTY lines. This

probably needs revisiting, because "lef write" and "lef writeall"
need handling to generate the PROPERTYDEFINITIONS block for the
PROPERTY entries to be correct.
This commit is contained in:
Tim Edwards 2020-05-29 14:31:48 -04:00
parent bad4842707
commit 4ad7ce3cf4
3 changed files with 82 additions and 8 deletions

View File

@ -1697,7 +1697,7 @@ LefEndStatement(f)
enum lef_macro_keys {LEF_CLASS = 0, LEF_SIZE, LEF_ORIGIN,
LEF_SYMMETRY, LEF_SOURCE, LEF_SITE, LEF_PIN, LEF_OBS,
LEF_TIMING, LEF_FOREIGN, LEF_MACRO_END};
LEF_TIMING, LEF_FOREIGN, LEF_PROPERTY, LEF_MACRO_END};
void
LefReadMacro(f, mname, oscale, importForeign)
@ -1712,9 +1712,9 @@ LefReadMacro(f, mname, oscale, importForeign)
HashEntry *he;
char *token, tsave[128], *propval;
int keyword, pinNum;
int keyword, pinNum, propsize;
float x, y;
bool has_size, is_imported = FALSE;
bool has_size, is_imported = FALSE, propfound;
Rect lefBBox;
static char *macro_keys[] = {
@ -1728,6 +1728,7 @@ LefReadMacro(f, mname, oscale, importForeign)
"OBS",
"TIMING",
"FOREIGN",
"PROPERTY",
"END",
NULL
};
@ -1856,6 +1857,31 @@ origin_error:
DBPropPut(lefMacro, "LEFsite", StrDup((char **)NULL, token));
LefEndStatement(f);
break;
case LEF_PROPERTY:
/* Append property key:value pairs to the cell property LEFproperties */
propval = (char *)DBPropGet(lefMacro, "LEFproperties", &propfound);
if (propfound)
propsize = strlen(propval);
else
propsize = 0;
token = LefNextToken(f, TRUE);
if (*token != '\n')
{
char *propext;
sprintf(tsave, "%.127s", token);
token = LefNextToken(f, TRUE);
propext = (char *)mallocMagic(propsize + strlen(tsave) +
strlen(token) + 4);
if (propsize > 0)
sprintf(propext, "%s %s %s", propval, tsave, token);
else
sprintf(propext, "%s %s", tsave, token);
DBPropPut(lefMacro, "LEFproperties", StrDup((char **)NULL, propext));
}
LefEndStatement(f);
break;
case LEF_PIN:
token = LefNextToken(f, TRUE);
/* Diagnostic */
@ -2464,7 +2490,7 @@ enum lef_sections {LEF_VERSION = 0,
LEF_PROPERTYDEFS, LEF_UNITS, LEF_SECTION_LAYER,
LEF_SECTION_VIA, LEF_SECTION_VIARULE, LEF_SECTION_NONDEFAULTRULE,
LEF_NOWIREEXTENSIONATPIN, LEF_SECTION_SPACING, LEF_SECTION_SITE,
LEF_PROPERTY, LEF_NOISETABLE, LEF_CORRECTIONTABLE, LEF_IRDROP,
LEF_NOISETABLE, LEF_CORRECTIONTABLE, LEF_IRDROP,
LEF_ARRAY, LEF_SECTION_TIMING, LEF_EXTENSION, LEF_MACRO,
LEF_END};
@ -2499,7 +2525,6 @@ LefRead(inName, importForeign)
"NOWIREEXTENSIONATPIN",
"SPACING",
"SITE",
"PROPERTY",
"NOISETABLE",
"CORRECTIONTABLE",
"IRDROP",
@ -2676,9 +2701,6 @@ LefRead(inName, importForeign)
sprintf(tsave, "%.127s", token);
LefSkipSection(f, tsave);
break;
case LEF_PROPERTY:
LefSkipSection(f, NULL);
break;
case LEF_NOISETABLE:
LefSkipSection(f, sections[LEF_NOISETABLE]);
break;

View File

@ -1432,6 +1432,49 @@ lefWriteMacro(def, f, scale, hide)
if (lc.numWrites > 0)
fprintf(f, IN0 "END\n"); /* end of obstruction geometries */
/* If there are any properties saved in LEFproperties, write them out */
propvalue = (char *)DBPropGet(def, "LEFproperties", &propfound);
if (propfound)
{
char *delim;
char *propfind = propvalue;
bool endfound = FALSE;
/* Properties are in space-separated key:value pairs. */
/* The value is in quotes and may contain spaces. */
/* One PROPERTY line is written per key:value pair. */
while (*propfind != '\0')
{
char dsave;
delim = propfind;
while (*delim != ' ' && *delim != '\0') delim++;
if (*delim == '\0') break;
while (*delim == ' ' && *delim != '\0') delim++;
if (*delim == '\0') break;
if (*delim == '\"')
{
delim++;
while (*delim != '\"' && *delim != '\0') delim++;
if (*delim == '\0') break;
delim++;
}
else
while (*delim != ' ' && *delim != '\0') delim++;
if (*delim == '\0') endfound = TRUE;
dsave = *delim;
*delim = '\0';
fprintf(f, IN0 "PROPERTY %s ;\n", propfind);
*delim = dsave;
if (endfound) break;
while (*delim == ' ' && *delim != '\0') delim++;
propfind = delim;
}
}
fprintf(f, "END %s\n", def->cd_name); /* end of macro */
SigDisableInterrupts();

View File

@ -78,6 +78,15 @@ proc readspice {netfile} {
foreach line $fdata {
set ftokens [split $line]
set keyword [string tolower [lindex $ftokens 0]]
# Handle SPECTRE model format
if {$keyword == "inline"} {
if {[string tolower [lindex $ftokens 1]] == "subckt"} {
set ftokens [lrange [split $line " \t()"] 1 end]
set keyword ".subckt"
}
}
if {$keyword == ".subckt"} {
set cell [lindex $ftokens 1]
set status [cellname list exists $cell]