diff --git a/lef/lefRead.c b/lef/lefRead.c index 3104a3ba..57408c7f 100644 --- a/lef/lefRead.c +++ b/lef/lefRead.c @@ -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; diff --git a/lef/lefWrite.c b/lef/lefWrite.c index 94c35430..e2213670 100644 --- a/lef/lefWrite.c +++ b/lef/lefWrite.c @@ -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(); diff --git a/tcltk/readspice.tcl b/tcltk/readspice.tcl index ee1fab83..a282cf39 100644 --- a/tcltk/readspice.tcl +++ b/tcltk/readspice.tcl @@ -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]