Corrected an error in the LEF/DEF geometry reading, because I

discovered that not all LEF/DEF rectangle coordinates are in
canonical order.  Took the opportunity to update the LefError()
routine with an additional argument so that it can separate
errors, warnings, and informational messages, and will correctly
state whether the output is for a LEF or DEF read operation.
This commit is contained in:
Tim Edwards 2019-06-06 09:59:56 -04:00
parent 87c07451d1
commit 51b70f6577
4 changed files with 240 additions and 112 deletions

View File

@ -105,7 +105,7 @@ DefAddRoutes(rootDef, f, oscale, special, defLayerMap)
if (routeLayer < 0) if (routeLayer < 0)
{ {
LefError("Unknown layer type \"%s\" for NEW route\n", token); LefError(DEF_ERROR, "Unknown layer type \"%s\" for NEW route\n", token);
continue; continue;
} }
paintLayer = routeLayer; paintLayer = routeLayer;
@ -116,7 +116,7 @@ DefAddRoutes(rootDef, f, oscale, special, defLayerMap)
token = LefNextToken(f, TRUE); token = LefNextToken(f, TRUE);
if (sscanf(token, "%f", &w) != 1) if (sscanf(token, "%f", &w) != 1)
{ {
LefError("Bad width in special net\n"); LefError(DEF_ERROR, "Bad width in special net\n");
continue; continue;
} }
if (w != 0) if (w != 0)
@ -138,7 +138,7 @@ DefAddRoutes(rootDef, f, oscale, special, defLayerMap)
else if (valid == FALSE) else if (valid == FALSE)
{ {
LefError("Route has via name \"%s\" but no points!\n", token); LefError(DEF_ERROR, "Route has via name \"%s\" but no points!\n", token);
continue; continue;
} }
he = HashLookOnly(&LefInfo, token); he = HashLookOnly(&LefInfo, token);
@ -197,7 +197,8 @@ DefAddRoutes(rootDef, f, oscale, special, defLayerMap)
} }
else if ((paintLayer = DBTechNameType(LefLower(token))) >= 0) else if ((paintLayer = DBTechNameType(LefLower(token))) >= 0)
{ {
LefError("Error: Via \"%s\" named but undefined.\n", token); LefError(DEF_ERROR, "Error: Via \"%s\" named but undefined.\n",
token);
newRoute->r_r.r_xbot = refp.p_x - paintWidth; newRoute->r_r.r_xbot = refp.p_x - paintWidth;
newRoute->r_r.r_ybot = refp.p_y - paintWidth; newRoute->r_r.r_ybot = refp.p_y - paintWidth;
newRoute->r_r.r_xtop = refp.p_x + paintWidth; newRoute->r_r.r_xtop = refp.p_x + paintWidth;
@ -209,7 +210,7 @@ DefAddRoutes(rootDef, f, oscale, special, defLayerMap)
newRoute->r_r.r_ytop >>= 1; newRoute->r_r.r_ytop >>= 1;
} }
else else
LefError("Via name \"%s\" unknown in route.\n", token); LefError(DEF_ERROR, "Via name \"%s\" unknown in route.\n", token);
/* After the via, the new route layer becomes whatever */ /* After the via, the new route layer becomes whatever */
/* residue of the via was NOT the previous route layer. */ /* residue of the via was NOT the previous route layer. */
@ -244,7 +245,7 @@ DefAddRoutes(rootDef, f, oscale, special, defLayerMap)
} }
} }
else else
LefError("Via name \"%s\" unknown in route.\n", token); LefError(DEF_ERROR, "Via name \"%s\" unknown in route.\n", token);
} }
else else
{ {
@ -261,7 +262,7 @@ DefAddRoutes(rootDef, f, oscale, special, defLayerMap)
{ {
if (valid == FALSE) if (valid == FALSE)
{ {
LefError("No reference point for \"*\" wildcard\n"); LefError(DEF_ERROR, "No reference point for \"*\" wildcard\n");
goto endCoord; goto endCoord;
} }
} }
@ -271,7 +272,7 @@ DefAddRoutes(rootDef, f, oscale, special, defLayerMap)
} }
else else
{ {
LefError("Cannot parse X coordinate.\n"); LefError(DEF_ERROR, "Cannot parse X coordinate.\n");
goto endCoord; goto endCoord;
} }
token = LefNextToken(f, TRUE); /* read Y */ token = LefNextToken(f, TRUE); /* read Y */
@ -279,7 +280,7 @@ DefAddRoutes(rootDef, f, oscale, special, defLayerMap)
{ {
if (valid == FALSE) if (valid == FALSE)
{ {
LefError("No reference point for \"*\" wildcard\n"); LefError(DEF_ERROR, "No reference point for \"*\" wildcard\n");
freeMagic(newRoute); freeMagic(newRoute);
newRoute = NULL; newRoute = NULL;
goto endCoord; goto endCoord;
@ -291,7 +292,7 @@ DefAddRoutes(rootDef, f, oscale, special, defLayerMap)
} }
else else
{ {
LefError("Cannot parse Y coordinate.\n"); LefError(DEF_ERROR, "Cannot parse Y coordinate.\n");
goto endCoord; goto endCoord;
} }
@ -306,7 +307,7 @@ DefAddRoutes(rootDef, f, oscale, special, defLayerMap)
{ {
/* non-default route extension */ /* non-default route extension */
if (sscanf(token, "%f", &z) != 1) if (sscanf(token, "%f", &z) != 1)
LefError("Can't parse route extension value.\n"); LefError(DEF_ERROR, "Can't parse route extension value.\n");
/* all values will be divided by 2, so we need */ /* all values will be divided by 2, so we need */
/* to multiply up by 2 now. */ /* to multiply up by 2 now. */
@ -326,7 +327,7 @@ DefAddRoutes(rootDef, f, oscale, special, defLayerMap)
/* Skip over nonmanhattan segments, reset the reference */ /* Skip over nonmanhattan segments, reset the reference */
/* point, and output a warning. */ /* point, and output a warning. */
LefError("Can't deal with nonmanhattan geometry in route.\n"); LefError(DEF_ERROR, "Can't deal with nonmanhattan geometry in route.\n");
locarea.r_xbot = refp.p_x; locarea.r_xbot = refp.p_x;
locarea.r_ybot = refp.p_y; locarea.r_ybot = refp.p_y;
} }
@ -471,7 +472,7 @@ DefReadNets(f, rootDef, sname, oscale, special, total)
keyword = Lookup(token, net_keys); keyword = Lookup(token, net_keys);
if (keyword < 0) if (keyword < 0)
{ {
LefError("Unknown keyword \"%s\" in NET " LefError(DEF_INFO, "Unknown keyword \"%s\" in NET "
"definition; ignoring.\n", token); "definition; ignoring.\n", token);
LefEndStatement(f); LefEndStatement(f);
continue; continue;
@ -508,7 +509,7 @@ DefReadNets(f, rootDef, sname, oscale, special, total)
subkey = Lookup(token, net_property_keys); subkey = Lookup(token, net_property_keys);
if (subkey < 0) if (subkey < 0)
{ {
LefError("Unknown net property \"%s\" in " LefError(DEF_INFO, "Unknown net property \"%s\" in "
"NET definition; ignoring.\n", token); "NET definition; ignoring.\n", token);
continue; continue;
} }
@ -530,7 +531,7 @@ DefReadNets(f, rootDef, sname, oscale, special, total)
case DEF_NET_END: case DEF_NET_END:
if (!LefParseEndStatement(f, sname)) if (!LefParseEndStatement(f, sname))
{ {
LefError("Net END statement missing.\n"); LefError(DEF_ERROR, "Net END statement missing.\n");
keyword = -1; keyword = -1;
} }
break; break;
@ -542,7 +543,7 @@ DefReadNets(f, rootDef, sname, oscale, special, total)
TxPrintf(" Processed %d%s nets total.\n", processed, TxPrintf(" Processed %d%s nets total.\n", processed,
(special) ? " special" : ""); (special) ? " special" : "");
else else
LefError("Warning: Number of nets read (%d) does not match " LefError(DEF_WARNING, "Number of nets read (%d) does not match "
"the number declared (%d).\n", processed, total); "the number declared (%d).\n", processed, total);
freeMagic((char *)defLayerMap); freeMagic((char *)defLayerMap);
@ -600,7 +601,7 @@ DefReadLocation(use, f, oscale, tptr)
keyword = Lookup(token, orientations); keyword = Lookup(token, orientations);
if (keyword < 0) if (keyword < 0)
{ {
LefError("Unknown macro orientation \"%s\".\n", token); LefError(DEF_ERROR, "Unknown macro orientation \"%s\".\n", token);
return -1; return -1;
} }
@ -668,7 +669,7 @@ DefReadLocation(use, f, oscale, tptr)
return 0; return 0;
parse_error: parse_error:
LefError("Cannot parse location: must be ( X Y ) orient\n"); LefError(DEF_ERROR, "Cannot parse location: must be ( X Y ) orient\n");
return -1; return -1;
} }
@ -755,7 +756,7 @@ DefReadPins(f, rootDef, sname, oscale, total)
if (keyword < 0) if (keyword < 0)
{ {
LefError("Unknown keyword \"%s\" in PINS " LefError(DEF_INFO, "Unknown keyword \"%s\" in PINS "
"definition; ignoring.\n", token); "definition; ignoring.\n", token);
LefEndStatement(f); LefEndStatement(f);
continue; continue;
@ -769,7 +770,7 @@ DefReadPins(f, rootDef, sname, oscale, total)
if (pending) if (pending)
{ {
LefError("Pin specified without layer, was not placed.\n"); LefError(DEF_ERROR, "Pin specified without layer, was not placed.\n");
} }
/* Update the record of the number of pins */ /* Update the record of the number of pins */
@ -781,7 +782,7 @@ DefReadPins(f, rootDef, sname, oscale, total)
token = LefNextToken(f, TRUE); token = LefNextToken(f, TRUE);
if (sscanf(token, "%2047s", pinname) != 1) if (sscanf(token, "%2047s", pinname) != 1)
{ {
LefError("Bad pin statement: Need pin name\n"); LefError(DEF_ERROR, "Bad pin statement: Need pin name\n");
LefEndStatement(f); LefEndStatement(f);
break; break;
} }
@ -799,7 +800,7 @@ DefReadPins(f, rootDef, sname, oscale, total)
subkey = Lookup(token, pin_property_keys); subkey = Lookup(token, pin_property_keys);
if (subkey < 0) if (subkey < 0)
{ {
LefError("Unknown pin property \"%s\" in " LefError(DEF_ERROR, "Unknown pin property \"%s\" in "
"PINS definition; ignoring.\n", token); "PINS definition; ignoring.\n", token);
continue; continue;
} }
@ -814,7 +815,7 @@ DefReadPins(f, rootDef, sname, oscale, total)
token = LefNextToken(f, TRUE); token = LefNextToken(f, TRUE);
subkey = Lookup(token, pin_classes); subkey = Lookup(token, pin_classes);
if (subkey < 0) if (subkey < 0)
LefError("Unknown pin class\n"); LefError(DEF_ERROR, "Unknown pin class\n");
else else
pinDir = lef_class_to_bitmask[subkey]; pinDir = lef_class_to_bitmask[subkey];
break; break;
@ -869,7 +870,7 @@ DefReadPins(f, rootDef, sname, oscale, total)
case DEF_PINS_END: case DEF_PINS_END:
if (!LefParseEndStatement(f, sname)) if (!LefParseEndStatement(f, sname))
{ {
LefError("Pins END statement missing.\n"); LefError(DEF_ERROR, "Pins END statement missing.\n");
keyword = -1; keyword = -1;
} }
break; break;
@ -880,7 +881,7 @@ DefReadPins(f, rootDef, sname, oscale, total)
if (processed == total) if (processed == total)
TxPrintf(" Processed %d pins total.\n", processed); TxPrintf(" Processed %d pins total.\n", processed);
else else
LefError("Warning: Number of pins read (%d) does not match " LefError(DEF_WARNING, "Number of pins read (%d) does not match "
"the number declared (%d).\n", processed, total); "the number declared (%d).\n", processed, total);
} }
@ -939,7 +940,7 @@ DefReadVias(f, sname, oscale, total)
if (keyword < 0) if (keyword < 0)
{ {
LefError("Unknown keyword \"%s\" in VIAS " LefError(DEF_INFO, "Unknown keyword \"%s\" in VIAS "
"definition; ignoring.\n", token); "definition; ignoring.\n", token);
LefEndStatement(f); LefEndStatement(f);
continue; continue;
@ -957,7 +958,7 @@ DefReadVias(f, sname, oscale, total)
token = LefNextToken(f, TRUE); token = LefNextToken(f, TRUE);
if (sscanf(token, "%2047s", vianame) != 1) if (sscanf(token, "%2047s", vianame) != 1)
{ {
LefError("Bad via statement: Need via name\n"); LefError(DEF_ERROR, "Bad via statement: Need via name\n");
LefEndStatement(f); LefEndStatement(f);
break; break;
} }
@ -977,7 +978,7 @@ DefReadVias(f, sname, oscale, total)
} }
else else
{ {
LefError("Warning: Composite via \"%s\" redefined.\n", vianame); LefError(DEF_WARNING, "Composite via \"%s\" redefined.\n", vianame);
lefl = LefRedefined(lefl, vianame); lefl = LefRedefined(lefl, vianame);
} }
@ -993,7 +994,7 @@ DefReadVias(f, sname, oscale, total)
subkey = Lookup(token, via_property_keys); subkey = Lookup(token, via_property_keys);
if (subkey < 0) if (subkey < 0)
{ {
LefError("Unknown via property \"%s\" in " LefError(DEF_INFO, "Unknown via property \"%s\" in "
"VIAS definition; ignoring.\n", token); "VIAS definition; ignoring.\n", token);
continue; continue;
} }
@ -1010,7 +1011,7 @@ DefReadVias(f, sname, oscale, total)
case DEF_VIAS_END: case DEF_VIAS_END:
if (!LefParseEndStatement(f, sname)) if (!LefParseEndStatement(f, sname))
{ {
LefError("Vias END statement missing.\n"); LefError(DEF_ERROR, "Vias END statement missing.\n");
keyword = -1; keyword = -1;
} }
break; break;
@ -1021,7 +1022,7 @@ DefReadVias(f, sname, oscale, total)
if (processed == total) if (processed == total)
TxPrintf(" Processed %d vias total.\n", processed); TxPrintf(" Processed %d vias total.\n", processed);
else else
LefError("Warning: Number of vias read (%d) does not match " LefError(DEF_WARNING, "Number of vias read (%d) does not match "
"the number declared (%d).\n", processed, total); "the number declared (%d).\n", processed, total);
} }
@ -1093,7 +1094,7 @@ DefReadComponents(f, rootDef, sname, oscale, total)
if (keyword < 0) if (keyword < 0)
{ {
LefError("Unknown keyword \"%s\" in COMPONENT " LefError(DEF_INFO, "Unknown keyword \"%s\" in COMPONENT "
"definition; ignoring.\n", token); "definition; ignoring.\n", token);
LefEndStatement(f); LefEndStatement(f);
continue; continue;
@ -1111,7 +1112,8 @@ DefReadComponents(f, rootDef, sname, oscale, total)
token = LefNextToken(f, TRUE); token = LefNextToken(f, TRUE);
if (sscanf(token, "%511s", usename) != 1) if (sscanf(token, "%511s", usename) != 1)
{ {
LefError("Bad component statement: Need use and macro names\n"); LefError(DEF_ERROR, "Bad component statement: Need "
"use and macro names\n");
LefEndStatement(f); LefEndStatement(f);
break; break;
} }
@ -1129,8 +1131,8 @@ DefReadComponents(f, rootDef, sname, oscale, total)
defMacro->cd_flags &= ~CDNOTFOUND; defMacro->cd_flags &= ~CDNOTFOUND;
if (!DBCellRead(defMacro, (char *)NULL, TRUE, NULL)) if (!DBCellRead(defMacro, (char *)NULL, TRUE, NULL))
{ {
LefError("Cell %s is not defined. Maybe you have not " LefError(DEF_ERROR, "Cell %s is not defined. Maybe you "
"read the corresponding LEF file?\n", "have not read the corresponding LEF file?\n",
token); token);
LefEndStatement(f); LefEndStatement(f);
DBCellDeleteDef(defMacro); DBCellDeleteDef(defMacro);
@ -1163,7 +1165,7 @@ DefReadComponents(f, rootDef, sname, oscale, total)
subkey = Lookup(token, property_keys); subkey = Lookup(token, property_keys);
if (subkey < 0) if (subkey < 0)
{ {
LefError("Unknown component property \"%s\" in " LefError(DEF_INFO, "Unknown component property \"%s\" in "
"COMPONENT definition; ignoring.\n", token); "COMPONENT definition; ignoring.\n", token);
continue; continue;
} }
@ -1198,7 +1200,7 @@ DefReadComponents(f, rootDef, sname, oscale, total)
case DEF_COMP_END: case DEF_COMP_END:
if (!LefParseEndStatement(f, sname)) if (!LefParseEndStatement(f, sname))
{ {
LefError("Component END statement missing.\n"); LefError(DEF_ERROR, "Component END statement missing.\n");
keyword = -1; keyword = -1;
} }
@ -1216,7 +1218,7 @@ DefReadComponents(f, rootDef, sname, oscale, total)
if (processed == total) if (processed == total)
TxPrintf(" Processed %d subcell instances total.\n", processed); TxPrintf(" Processed %d subcell instances total.\n", processed);
else else
LefError("Warning: Number of subcells read (%d) does not match " LefError(DEF_WARNING, "Number of subcells read (%d) does not match "
"the number declared (%d).\n", processed, total); "the number declared (%d).\n", processed, total);
} }
@ -1330,7 +1332,7 @@ DefRead(inName)
keyword = Lookup(token, sections); keyword = Lookup(token, sections);
if (keyword < 0) if (keyword < 0)
{ {
LefError("Unknown keyword \"%s\" in DEF file; ignoring.\n", token); LefError(DEF_INFO, "Unknown keyword \"%s\" in DEF file; ignoring.\n", token);
LefEndStatement(f); LefEndStatement(f);
continue; continue;
} }
@ -1346,7 +1348,7 @@ DefRead(inName)
token = LefNextToken(f, TRUE); token = LefNextToken(f, TRUE);
if (strcmp(token, DBTechName)) if (strcmp(token, DBTechName))
{ {
LefError("Warning: DEF technology name \"%s\" does not" LefError(DEF_WARNING, "DEF technology name \"%s\" does not"
" match current magic technology name \"%s\"\n", " match current magic technology name \"%s\"\n",
token, DBTechName); token, DBTechName);
} }
@ -1366,8 +1368,8 @@ DefRead(inName)
token = LefNextToken(f, TRUE); token = LefNextToken(f, TRUE);
if (sscanf(token, "%d", &dscale) != 1) if (sscanf(token, "%d", &dscale) != 1)
{ {
LefError("Invalid syntax for UNITS statement.\n"); LefError(DEF_ERROR, "Invalid syntax for UNITS statement.\n");
LefError("Assuming default value of 100\n"); LefError(DEF_INFO, "Assuming default value of 100\n");
dscale = 100; dscale = 100;
} }
/* We don't care if the scale is 100, 200, 1000, or 2000. */ /* We don't care if the scale is 100, 200, 1000, or 2000. */
@ -1453,7 +1455,7 @@ DefRead(inName)
case DEF_END: case DEF_END:
if (!LefParseEndStatement(token, "DESIGN")) if (!LefParseEndStatement(token, "DESIGN"))
{ {
LefError("END statement out of context.\n"); LefError(DEF_ERROR, "END statement out of context.\n");
keyword = -1; keyword = -1;
} }
break; break;
@ -1461,7 +1463,7 @@ DefRead(inName)
if (keyword == DEF_END) break; if (keyword == DEF_END) break;
} }
TxPrintf("DEF read: Processed %d lines.\n", lefCurrentLine); TxPrintf("DEF read: Processed %d lines.\n", lefCurrentLine);
LefError(NULL); /* print statement of errors, if any, and reset */ LefError(DEF_SUMMARY, NULL); /* print statement of errors, if any, and reset */
/* Cleanup */ /* Cleanup */

View File

@ -131,7 +131,18 @@ TileType LefReadLayer();
LefMapping *defMakeInverseLayerMap(); LefMapping *defMakeInverseLayerMap();
void LefError(char *, ...); /* Variable argument procedure requires */ void LefError(int, char *, ...); /* Variable argument procedure requires */
/* parameter list. */ /* parameter list. */
/* Definitions for type passed to LefError() */
#define LEF_ERROR 0
#define LEF_WARNING 1
#define LEF_INFO 2
#define LEF_SUMMARY 3
#define DEF_ERROR 4
#define DEF_WARNING 5
#define DEF_INFO 6
#define DEF_SUMMARY 7
#endif /* _LEFINT_H */ #endif /* _LEFINT_H */

View File

@ -279,11 +279,15 @@ LefNextToken(f, ignore_eol)
/* /*
*------------------------------------------------------------ *------------------------------------------------------------
* *
* LefError -- * LefDefError --
* *
* Print an error message (via TxError) giving the line * Print an error message (via TxError) giving the line
* number of the input file on which the error occurred. * number of the input file on which the error occurred.
* *
* "type" is one of the following (see lef.h):
* LEF_ERROR, LEF_WARNING, LEF_INFO,
* DEF_ERROR, DEF_WARNING, DEF_INFO
*
* Results: * Results:
* None. * None.
* *
@ -294,34 +298,126 @@ LefNextToken(f, ignore_eol)
*/ */
void void
LefError(char *fmt, ...) LefError(int type, char *fmt, ...)
{ {
static int errors = 0; static int errors = 0, warnings = 0, messages = 0;
va_list args; va_list args;
if (fmt == NULL) /* Special case: report any errors and reset */ char *lefdeftypes[] = {"LEF", "DEF", "techfile lef section"};
int mode, level;
char *lefdeftype;
switch (type) {
case LEF_INFO:
mode = 0;
level = 0;
break;
case LEF_WARNING:
mode = 0;
level = 1;
break;
case LEF_ERROR:
mode = 0;
level = 2;
break;
case LEF_SUMMARY:
mode = 0;
level = -1;
break;
case DEF_INFO:
mode = 1;
level = 0;
break;
case DEF_WARNING:
mode = 1;
level = 1;
break;
case DEF_ERROR:
mode = 1;
level = 2;
break;
case DEF_SUMMARY:
mode = 1;
level = -1;
break;
}
lefdeftype = lefdeftypes[mode];
if ((fmt == NULL) || (level == -1))
{ {
/* Special case: report any errors and reset */
if (errors) if (errors)
{ TxPrintf("%s Read: encountered %d error%s total.\n",
TxPrintf("LEF Read: encountered %d error%s total.\n", errors, lefdeftype, errors, (errors == 1) ? "" : "s");
(errors == 1) ? "" : "s");
errors = 0; if (warnings)
} TxPrintf("%s Read: encountered %d warning%s total.\n",
lefdeftype, warnings, (warnings == 1) ? "" : "s");
errors = 0;
warnings = 0;
messages = 0;
return; return;
} }
if (errors < LEF_MAX_ERRORS) switch (level) {
{
TxError("LEF Read, Line %d: ", lefCurrentLine);
va_start(args, fmt);
Vfprintf(stderr, fmt, args);
va_end(args);
TxFlushErr();
}
else if (errors == LEF_MAX_ERRORS)
TxError("LEF Read: Further errors will not be reported.\n");
errors++; case 2:
if (errors < LEF_MAX_ERRORS)
{
if (lefCurrentLine >= 0)
TxError("%s read, Line %d (Error): ", lefdeftype, lefCurrentLine);
else
TxError("%s read (Error): ", lefdeftype);
va_start(args, fmt);
Vfprintf(stderr, fmt, args);
va_end(args);
TxFlushErr();
}
else if (errors == LEF_MAX_ERRORS)
TxError("%s Read: Further errors will not be reported.\n",
lefdeftype);
errors++;
break;
case 1:
if (warnings < LEF_MAX_ERRORS)
{
if (lefCurrentLine >= 0)
TxError("%s read, Line %d (Warning): ", lefdeftype, lefCurrentLine);
else
TxError("%s read (Warning): ", lefdeftype);
va_start(args, fmt);
Vfprintf(stderr, fmt, args);
va_end(args);
TxFlushErr();
}
else if (warnings == LEF_MAX_ERRORS)
TxError("%s read: Further warnings will not be reported.\n",
lefdeftype);
warnings++;
break;
case 0:
if (messages < LEF_MAX_ERRORS)
{
if (lefCurrentLine >= 0)
TxPrintf("%s read, Line %d (Message): ", lefdeftype, lefCurrentLine);
else
TxPrintf("%s read (Message): ", lefdeftype);
va_start(args, fmt);
Vfprintf(stdout, fmt, args);
va_end(args);
TxFlushOut();
}
else if (messages == LEF_MAX_ERRORS)
TxPrintf("%s read: Further messages will not be reported.\n",
lefdeftype);
messages++;
break;
}
} }
/* /*
@ -368,7 +464,7 @@ LefParseEndStatement(f, match)
token = LefNextToken(f, (match == NULL) ? FALSE : TRUE); token = LefNextToken(f, (match == NULL) ? FALSE : TRUE);
if (token == NULL) if (token == NULL)
{ {
LefError("Bad file read while looking for END statement\n"); LefError(LEF_ERROR, "Bad file read while looking for END statement\n");
return 0; return 0;
} }
@ -407,7 +503,7 @@ LefParseEndStatement(f, match)
* None. * None.
* *
* Side Effects: * Side Effects:
* Reads input from the specified file. Prints an * reads input from the specified file. Prints an
* error message if the expected END record cannot * error message if the expected END record cannot
* be found. * be found.
* *
@ -445,7 +541,7 @@ LefSkipSection(f, section)
} }
} }
LefError("Section %s has no END record!\n", section); LefError(LEF_ERROR, "Section %s has no END record!\n", section);
return; return;
} }
@ -623,7 +719,7 @@ LefReadLayers(f, obstruct, lreturn, rreturn)
token = LefNextToken(f, TRUE); token = LefNextToken(f, TRUE);
if (*token == ';') if (*token == ';')
{ {
LefError("Bad Layer statement\n"); LefError(LEF_ERROR, "Bad Layer statement\n");
return -1; return -1;
} }
else else
@ -670,8 +766,8 @@ LefReadLayers(f, obstruct, lreturn, rreturn)
} }
if ((curlayer < 0) && ((!lefl) || (lefl->lefClass != CLASS_IGNORE))) if ((curlayer < 0) && ((!lefl) || (lefl->lefClass != CLASS_IGNORE)))
{ {
LefError("Don't know how to parse layer \"%s\"\n", token); LefError(LEF_ERROR, "Don't know how to parse layer \"%s\"\n", token);
LefError("Try adding this name to the LEF techfile section\n"); LefError(LEF_ERROR, "Try adding this name to the LEF techfile section\n");
} }
} }
return curlayer; return curlayer;
@ -736,6 +832,7 @@ LefReadRect(f, curlayer, oscale)
char *token; char *token;
float llx, lly, urx, ury; float llx, lly, urx, ury;
static Rect paintrect; static Rect paintrect;
Rect lefrect;
bool needMatch = FALSE; bool needMatch = FALSE;
token = LefNextToken(f, TRUE); token = LefNextToken(f, TRUE);
@ -768,16 +865,23 @@ LefReadRect(f, curlayer, oscale)
if (*token != ')') goto parse_error; if (*token != ')') goto parse_error;
} }
if (curlayer < 0) if (curlayer < 0)
LefError("No layer defined for RECT.\n"); {
LefError(LEF_ERROR, "No layer defined for RECT.\n");
paintrect.r_xbot = paintrect.r_ybot = 0;
paintrect.r_xtop = paintrect.r_ytop = 0;
}
else else
{ {
/* Scale coordinates (microns to magic internal units) */ /* Scale coordinates (microns to magic internal units) */
/* Need to scale grid if necessary! */ /* Need to scale grid if necessary! */
paintrect.r_xbot = (int)roundf(llx / oscale); lefrect.r_xbot = (int)roundf(llx / oscale);
paintrect.r_ybot = (int)roundf(lly / oscale); lefrect.r_ybot = (int)roundf(lly / oscale);
paintrect.r_xtop = (int)roundf(urx / oscale); lefrect.r_xtop = (int)roundf(urx / oscale);
paintrect.r_ytop = (int)roundf(ury / oscale); lefrect.r_ytop = (int)roundf(ury / oscale);
/* Insist on non-inverted rectangles */
GeoCanonicalRect(&lefrect, &paintrect);
/* Diagnostic */ /* Diagnostic */
/* /*
@ -791,7 +895,7 @@ LefReadRect(f, curlayer, oscale)
return (&paintrect); return (&paintrect);
parse_error: parse_error:
LefError("Bad port geometry: RECT requires 4 values.\n"); LefError(LEF_ERROR, "Bad port geometry: RECT requires 4 values.\n");
return (Rect *)NULL; return (Rect *)NULL;
} }
@ -836,7 +940,7 @@ LefReadPolygon(f, curlayer, oscale, ppoints)
if (token == NULL || *token == ';') break; if (token == NULL || *token == ';') break;
if (sscanf(token, "%f", &px) != 1) if (sscanf(token, "%f", &px) != 1)
{ {
LefError("Bad X value in polygon.\n"); LefError(LEF_ERROR, "Bad X value in polygon.\n");
LefEndStatement(f); LefEndStatement(f);
break; break;
} }
@ -844,12 +948,12 @@ LefReadPolygon(f, curlayer, oscale, ppoints)
token = LefNextToken(f, TRUE); token = LefNextToken(f, TRUE);
if (token == NULL || *token == ';') if (token == NULL || *token == ';')
{ {
LefError("Missing Y value in polygon point!\n"); LefError(LEF_ERROR, "Missing Y value in polygon point!\n");
break; break;
} }
if (sscanf(token, "%f", &py) != 1) if (sscanf(token, "%f", &py) != 1)
{ {
LefError("Bad Y value in polygon.\n"); LefError(LEF_ERROR, "Bad Y value in polygon.\n");
LefEndStatement(f); LefEndStatement(f);
break; break;
} }
@ -987,7 +1091,8 @@ LefReadGeometry(lefMacro, f, oscale, do_list)
keyword = Lookup(token, geometry_keys); keyword = Lookup(token, geometry_keys);
if (keyword < 0) if (keyword < 0)
{ {
LefError("Unknown keyword \"%s\" in LEF file; ignoring.\n", token); LefError(LEF_INFO, "Unknown keyword \"%s\" in LEF file; ignoring.\n",
token);
LefEndStatement(f); LefEndStatement(f);
continue; continue;
} }
@ -1082,7 +1187,8 @@ LefReadGeometry(lefMacro, f, oscale, do_list)
case LEF_GEOMETRY_END: case LEF_GEOMETRY_END:
if (LefParseEndStatement(f, NULL) == 0) if (LefParseEndStatement(f, NULL) == 0)
{ {
LefError("Geometry (PORT or OBS) END statement missing.\n"); LefError(LEF_ERROR, "Geometry (PORT or OBS) END "
"statement missing.\n");
keyword = -1; keyword = -1;
} }
break; break;
@ -1133,12 +1239,12 @@ LefReadPort(lefMacro, f, pinName, pinNum, pinDir, pinUse, oscale)
/* Set this label to be a port */ /* Set this label to be a port */
if (lefMacro->cd_labels == NULL) if (lefMacro->cd_labels == NULL)
LefError("Internal error: No labels in cell!\n"); LefError(LEF_ERROR, "Internal error: No labels in cell!\n");
else else
{ {
newlab = lefMacro->cd_lastLabel; newlab = lefMacro->cd_lastLabel;
if (strcmp(newlab->lab_text, pinName)) if (strcmp(newlab->lab_text, pinName))
LefError("Internal error: Can't find the label!\n"); LefError(LEF_ERROR, "Internal error: Can't find the label!\n");
else /* Make this a port */ else /* Make this a port */
newlab->lab_flags = pinNum | pinUse | pinDir | PORT_DIR_MASK; newlab->lab_flags = pinNum | pinUse | pinDir | PORT_DIR_MASK;
} }
@ -1248,7 +1354,8 @@ LefReadPin(lefMacro, f, pinname, pinNum, oscale, is_imported)
keyword = Lookup(token, pin_keys); keyword = Lookup(token, pin_keys);
if (keyword < 0) if (keyword < 0)
{ {
LefError("Unknown keyword \"%s\" in LEF file; ignoring.\n", token); LefError(LEF_INFO, "Unknown keyword \"%s\" in LEF file; ignoring.\n",
token);
LefEndStatement(f); LefEndStatement(f);
continue; continue;
} }
@ -1258,7 +1365,7 @@ LefReadPin(lefMacro, f, pinname, pinNum, oscale, is_imported)
token = LefNextToken(f, TRUE); token = LefNextToken(f, TRUE);
subkey = Lookup(token, pin_classes); subkey = Lookup(token, pin_classes);
if (subkey < 0) if (subkey < 0)
LefError("Improper DIRECTION statement\n"); LefError(LEF_ERROR, "Improper DIRECTION statement\n");
else else
pinDir = lef_class_to_bitmask[subkey]; pinDir = lef_class_to_bitmask[subkey];
LefEndStatement(f); LefEndStatement(f);
@ -1267,7 +1374,7 @@ LefReadPin(lefMacro, f, pinname, pinNum, oscale, is_imported)
token = LefNextToken(f, TRUE); token = LefNextToken(f, TRUE);
subkey = Lookup(token, pin_uses); subkey = Lookup(token, pin_uses);
if (subkey < 0) if (subkey < 0)
LefError("Improper USE statement\n"); LefError(LEF_ERROR, "Improper USE statement\n");
else else
pinUse = lef_use_to_bitmask[subkey]; pinUse = lef_use_to_bitmask[subkey];
LefEndStatement(f); LefEndStatement(f);
@ -1310,7 +1417,7 @@ LefReadPin(lefMacro, f, pinname, pinNum, oscale, is_imported)
case LEF_PIN_END: case LEF_PIN_END:
if (LefParseEndStatement(f, pinname) == 0) if (LefParseEndStatement(f, pinname) == 0)
{ {
LefError("Pin END statement missing.\n"); LefError(LEF_ERROR, "Pin END statement missing.\n");
keyword = -1; keyword = -1;
} }
break; break;
@ -1404,7 +1511,7 @@ LefReadMacro(f, mname, oscale, importForeign)
sprintf(newname, "%250s_%d", mname, suffix); sprintf(newname, "%250s_%d", mname, suffix);
he = HashFind(&lefDefInitHash, newname); he = HashFind(&lefDefInitHash, newname);
} }
LefError("Cell \"%s\" was already defined in this file. " LefError(LEF_WARNING, "Cell \"%s\" was already defined in this file. "
"Renaming this cell \"%s\"\n", mname, newname); "Renaming this cell \"%s\"\n", mname, newname);
lefMacro = DBCellLookDef(newname); lefMacro = DBCellLookDef(newname);
if (lefMacro == NULL) if (lefMacro == NULL)
@ -1444,7 +1551,8 @@ LefReadMacro(f, mname, oscale, importForeign)
keyword = Lookup(token, macro_keys); keyword = Lookup(token, macro_keys);
if (keyword < 0) if (keyword < 0)
{ {
LefError("Unknown keyword \"%s\" in LEF file; ignoring.\n", token); LefError(LEF_INFO, "Unknown keyword \"%s\" in LEF file; ignoring.\n",
token);
LefEndStatement(f); LefEndStatement(f);
continue; continue;
} }
@ -1470,7 +1578,7 @@ LefReadMacro(f, mname, oscale, importForeign)
LefEndStatement(f); LefEndStatement(f);
break; break;
size_error: size_error:
LefError("Bad macro SIZE; requires values X BY Y.\n"); LefError(LEF_ERROR, "Bad macro SIZE; requires values X BY Y.\n");
LefEndStatement(f); LefEndStatement(f);
break; break;
case LEF_ORIGIN: case LEF_ORIGIN:
@ -1489,7 +1597,7 @@ size_error:
LefEndStatement(f); LefEndStatement(f);
break; break;
origin_error: origin_error:
LefError("Bad macro ORIGIN; requires 2 values.\n"); LefError(LEF_ERROR, "Bad macro ORIGIN; requires 2 values.\n");
LefEndStatement(f); LefEndStatement(f);
break; break;
case LEF_SYMMETRY: case LEF_SYMMETRY:
@ -1549,7 +1657,7 @@ origin_error:
case LEF_MACRO_END: case LEF_MACRO_END:
if (LefParseEndStatement(f, mname) == 0) if (LefParseEndStatement(f, mname) == 0)
{ {
LefError("Macro END statement missing.\n"); LefError(LEF_ERROR, "Macro END statement missing.\n");
keyword = -1; keyword = -1;
} }
break; break;
@ -1589,7 +1697,8 @@ origin_error:
} }
else else
{ {
LefError(" Macro does not define size: computing from geometry\n"); LefError(LEF_WARNING, " Macro does not define size: "
"computing from geometry\n");
/* Set the placement bounding box property to the current bounding box */ /* Set the placement bounding box property to the current bounding box */
lefMacro->cd_flags |= CDFIXEDBBOX; lefMacro->cd_flags |= CDFIXEDBBOX;
@ -1718,12 +1827,12 @@ LefAddViaGeometry(f, lefl, curlayer, oscale)
if ((currect->r_xtop - currect->r_xbot != edgeSize) || if ((currect->r_xtop - currect->r_xbot != edgeSize) ||
(currect->r_ytop - currect->r_ybot != edgeSize)) (currect->r_ytop - currect->r_ybot != edgeSize))
{ {
LefError("Warning: Cut size for magic type \"%s\" (%d x %d) does " LefError(LEF_WARNING, "Cut size for magic type \"%s\" (%d x %d) does "
"not match LEF/DEF\n", "not match LEF/DEF\n",
DBTypeLongNameTbl[lefl->type], DBTypeLongNameTbl[lefl->type],
edgeSize, edgeSize); edgeSize, edgeSize);
LefError(" via cut size (%d x %d). Magic layer cut size will " LefError(LEF_WARNING, "Via cut size (%d x %d). Magic layer "
"be used!\n", "cut size will be used!\n",
currect->r_xtop - currect->r_xbot, currect->r_xtop - currect->r_xbot,
currect->r_ytop - currect->r_ybot); currect->r_ytop - currect->r_ybot);
} }
@ -1865,7 +1974,8 @@ LefReadLayerSection(f, lname, mode, lefl)
keyword = Lookup(token, layer_keys); keyword = Lookup(token, layer_keys);
if (keyword < 0) if (keyword < 0)
{ {
LefError("Unknown keyword \"%s\" in LEF file; ignoring.\n", token); LefError(LEF_INFO, "Unknown keyword \"%s\" in LEF file; ignoring.\n",
token);
LefEndStatement(f); LefEndStatement(f);
continue; continue;
} }
@ -1877,7 +1987,7 @@ LefReadLayerSection(f, lname, mode, lefl)
{ {
typekey = Lookup(token, layer_type_keys); typekey = Lookup(token, layer_type_keys);
if (typekey < 0) if (typekey < 0)
LefError("Unknown layer type \"%s\" in LEF file; " LefError(LEF_WARNING, "Unknown layer type \"%s\" in LEF file; "
"ignoring.\n", token); "ignoring.\n", token);
} }
if (lefl->lefClass != typekey) if (lefl->lefClass != typekey)
@ -1886,7 +1996,8 @@ LefReadLayerSection(f, lname, mode, lefl)
/* and so having a different TYPE is an error. */ /* and so having a different TYPE is an error. */
/* Otherwise just ignore the type. */ /* Otherwise just ignore the type. */
if (typekey == CLASS_ROUTE || typekey == CLASS_VIA) if (typekey == CLASS_ROUTE || typekey == CLASS_VIA)
LefError("Attempt to reclassify layer %s from %s to %s\n", LefError(LEF_ERROR, "Attempt to reclassify layer %s "
"from %s to %s\n",
lname, layer_type_keys[lefl->lefClass], lname, layer_type_keys[lefl->lefClass],
layer_type_keys[typekey]); layer_type_keys[typekey]);
} }
@ -1990,7 +2101,7 @@ LefReadLayerSection(f, lname, mode, lefl)
case LEF_LAYER_END: case LEF_LAYER_END:
if (LefParseEndStatement(f, lname) == 0) if (LefParseEndStatement(f, lname) == 0)
{ {
LefError("Layer END statement missing.\n"); LefError(LEF_ERROR, "Layer END statement missing.\n");
keyword = -1; keyword = -1;
} }
break; break;
@ -2096,13 +2207,15 @@ LefRead(inName, importForeign)
HashInit(&LefCellTable, 32, HT_STRINGKEYS); HashInit(&LefCellTable, 32, HT_STRINGKEYS);
HashInit(&lefDefInitHash, 32, HT_STRINGKEYS); HashInit(&lefDefInitHash, 32, HT_STRINGKEYS);
oscale = CIFGetOutputScale(1000); oscale = CIFGetOutputScale(1000);
lefCurrentLine = 0;
while ((token = LefNextToken(f, TRUE)) != NULL) while ((token = LefNextToken(f, TRUE)) != NULL)
{ {
keyword = Lookup(token, sections); keyword = Lookup(token, sections);
if (keyword < 0) if (keyword < 0)
{ {
LefError("Unknown keyword \"%s\" in LEF file; ignoring.\n", token); LefError(LEF_INFO, "Unknown keyword \"%s\" in LEF file; ignoring.\n",
token);
LefEndStatement(f); LefEndStatement(f);
continue; continue;
} }
@ -2154,7 +2267,7 @@ LefRead(inName, importForeign)
LefSkipSection(f, tsave); LefSkipSection(f, tsave);
else else
{ {
LefError("Warning: Cut type \"%s\" redefined.\n", token); LefError(LEF_WARNING, "Cut type \"%s\" redefined.\n", token);
lefl = LefRedefined(lefl, token); lefl = LefRedefined(lefl, token);
LefReadLayerSection(f, tsave, keyword, lefl); LefReadLayerSection(f, tsave, keyword, lefl);
} }
@ -2178,7 +2291,7 @@ LefRead(inName, importForeign)
} }
else if (DBIsContact(mtype) && (keyword == LEF_SECTION_LAYER)) else if (DBIsContact(mtype) && (keyword == LEF_SECTION_LAYER))
{ {
LefError("Layer %s maps to a magic contact layer; " LefError(LEF_ERROR, "Layer %s maps to a magic contact layer; "
"must be defined in lef section of techfile\n", "must be defined in lef section of techfile\n",
token); token);
LefSkipSection(f, tsave); LefSkipSection(f, tsave);
@ -2186,7 +2299,7 @@ LefRead(inName, importForeign)
} }
else if (!DBIsContact(mtype) && (keyword != LEF_SECTION_LAYER)) else if (!DBIsContact(mtype) && (keyword != LEF_SECTION_LAYER))
{ {
LefError("Via %s maps to a non-contact magic layer; " LefError(LEF_ERROR, "Via %s maps to a non-contact magic layer; "
"must be defined in lef section of techfile\n", "must be defined in lef section of techfile\n",
token); token);
LefSkipSection(f, tsave); LefSkipSection(f, tsave);
@ -2209,7 +2322,8 @@ LefRead(inName, importForeign)
lefl = (lefLayer *)HashGetValue(he); lefl = (lefLayer *)HashGetValue(he);
if (lefl && lefl->type < 0) if (lefl && lefl->type < 0)
{ {
LefError("Layer %s is only defined for obstructions!\n", token); LefError(LEF_ERROR, "Layer %s is only defined for "
"obstructions!\n", token);
LefSkipSection(f, tsave); LefSkipSection(f, tsave);
break; break;
} }
@ -2265,7 +2379,7 @@ LefRead(inName, importForeign)
case LEF_END: case LEF_END:
if (LefParseEndStatement(f, "LIBRARY") == 0) if (LefParseEndStatement(f, "LIBRARY") == 0)
{ {
LefError("END statement out of context.\n"); LefError(LEF_ERROR, "END statement out of context.\n");
keyword = -1; keyword = -1;
} }
break; break;
@ -2273,7 +2387,7 @@ LefRead(inName, importForeign)
if (keyword == LEF_END) break; if (keyword == LEF_END) break;
} }
TxPrintf("LEF read: Processed %d lines.\n", lefCurrentLine); TxPrintf("LEF read: Processed %d lines.\n", lefCurrentLine);
LefError(NULL); /* print statement of errors, if any */ LefError(LEF_SUMMARY, NULL); /* print statement of errors, if any */
/* Cleanup */ /* Cleanup */
HashKill(&LefCellTable); HashKill(&LefCellTable);

View File

@ -115,6 +115,7 @@ LefTechInit()
HashKill(&LefInfo); HashKill(&LefInfo);
} }
HashInit(&LefInfo, 32, HT_STRINGKEYS); HashInit(&LefInfo, 32, HT_STRINGKEYS);
lefCurrentLine = -1;
} }
/* /*
@ -252,17 +253,17 @@ LefTechLine(sectionName, argc, argv)
if (i == 0) if (i == 0)
{ {
LefError("Bad magic layer type \"%s\" in LEF layer definition.\n", argv[1]); TechError("Bad magic layer type \"%s\" in LEF layer definition.\n", argv[1]);
return TRUE; return TRUE;
} }
else if ((i == 2) && (option != LEFTECH_OBS)) else if ((i == 2) && (option != LEFTECH_OBS))
{ {
LefError("Can only define multiple types for via obstruction layers.\n"); TechError("Can only define multiple types for via obstruction layers.\n");
return TRUE; return TRUE;
} }
else if (i > 2) else if (i > 2)
{ {
LefError("Too many types in LEF layer definition.\n"); TechError("Too many types in LEF layer definition.\n");
return TRUE; return TRUE;
} }