blob: 1fb46187448535773fd719d9f62745e0ab6d8f48 [file] [log] [blame]
// *****************************************************************************
// *****************************************************************************
// Copyright 2014 - 2017, Cadence Design Systems
//
// This file is part of the Cadence LEF/DEF Open Source
// Distribution, Product Version 5.8.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
// implied. See the License for the specific language governing
// permissions and limitations under the License.
//
// For updates, support, or to become part of the LEF/DEF Community,
// check www.openeda.org for details.
//
// $Author$
// $Revision$
// $Date$
// $State: $
// *****************************************************************************
// *****************************************************************************
#ifdef WIN32
#pragma warning (disable : 4786)
#endif
#include <stdio.h>
#include <string.h>
#include <iostream>
#include <stdlib.h>
#ifndef WIN32
# include <unistd.h>
#else
# include <windows.h>
#endif /* not WIN32 */
#include "lefrReader.hpp"
#include "lefwWriter.hpp"
#include "lefiDebug.hpp"
#include "lefiEncryptInt.hpp"
#include "lefiUtil.hpp"
char defaultName[128];
char defaultOut[128];
FILE* fout;
int printing = 0; // Printing the output.
int parse65nm = 0;
int parseLef58Type = 0;
int isSessionles = 0;
// TX_DIR:TRANSLATION ON
void dataError() {
fprintf(fout, "ERROR: returned user data is not correct!\n");
}
void checkType(lefrCallbackType_e c) {
if (c >= 0 && c <= lefrLibraryEndCbkType) {
// OK
} else {
fprintf(fout, "ERROR: callback type is out of bounds!\n");
}
}
char* orientStr(int orient) {
switch (orient) {
case 0: return ((char*)"N");
case 1: return ((char*)"W");
case 2: return ((char*)"S");
case 3: return ((char*)"E");
case 4: return ((char*)"FN");
case 5: return ((char*)"FW");
case 6: return ((char*)"FS");
case 7: return ((char*)"FE");
};
return ((char*)"BOGUS");
}
void lefVia(lefiVia *via) {
int i, j;
lefrSetCaseSensitivity(1);
fprintf(fout, "VIA %s ", via->lefiVia::name());
if (via->lefiVia::hasDefault())
fprintf(fout, "DEFAULT");
else if (via->lefiVia::hasGenerated())
fprintf(fout, "GENERATED");
fprintf(fout, "\n");
if (via->lefiVia::hasTopOfStack())
fprintf(fout, " TOPOFSTACKONLY\n");
if (via->lefiVia::hasForeign()) {
fprintf(fout, " FOREIGN %s ", via->lefiVia::foreign());
if (via->lefiVia::hasForeignPnt()) {
fprintf(fout, "( %g %g ) ", via->lefiVia::foreignX(),
via->lefiVia::foreignY());
if (via->lefiVia::hasForeignOrient())
fprintf(fout, "%s ", orientStr(via->lefiVia::foreignOrient()));
}
fprintf(fout, ";\n");
}
if (via->lefiVia::hasProperties()) {
fprintf(fout, " PROPERTY ");
for (i = 0; i < via->lefiVia::numProperties(); i++) {
fprintf(fout, "%s ", via->lefiVia::propName(i));
if (via->lefiVia::propIsNumber(i))
fprintf(fout, "%g ", via->lefiVia::propNumber(i));
if (via->lefiVia::propIsString(i))
fprintf(fout, "%s ", via->lefiVia::propValue(i));
/*
if (i+1 == via->lefiVia::numProperties()) // end of properties
fprintf(fout, ";\n");
else // just add new line
fprintf(fout, "\n");
*/
switch (via->lefiVia::propType(i)) {
case 'R':
fprintf(fout, "REAL ");
break;
case 'I':
fprintf(fout, "INTEGER ");
break;
case 'S':
fprintf(fout, "STRING ");
break;
case 'Q':
fprintf(fout, "QUOTESTRING ");
break;
case 'N':
fprintf(fout, "NUMBER ");
break;
}
}
fprintf(fout, ";\n");
}
if (via->lefiVia::hasResistance())
fprintf(fout, " RESISTANCE %g ;\n", via->lefiVia::resistance());
if (via->lefiVia::numLayers() > 0) {
for (i = 0; i < via->lefiVia::numLayers(); i++) {
fprintf(fout, " LAYER %s\n", via->lefiVia::layerName(i));
for (j = 0; j < via->lefiVia::numRects(i); j++)
if (via->lefiVia::rectColorMask(i, j)) {
fprintf(fout, " RECT MASK %d ( %f %f ) ( %f %f ) ;\n",
via->lefiVia::rectColorMask(i, j),
via->lefiVia::xl(i, j), via->lefiVia::yl(i, j),
via->lefiVia::xh(i, j), via->lefiVia::yh(i, j));
} else {
fprintf(fout, " RECT ( %f %f ) ( %f %f ) ;\n",
via->lefiVia::xl(i, j), via->lefiVia::yl(i, j),
via->lefiVia::xh(i, j), via->lefiVia::yh(i, j));
}
for (j = 0; j < via->lefiVia::numPolygons(i); j++) {
struct lefiGeomPolygon poly;
poly = via->lefiVia::getPolygon(i, j);
if (via->lefiVia::polyColorMask(i, j)) {
fprintf(fout, " POLYGON MASK %d", via->lefiVia::polyColorMask(i, j));
} else {
fprintf(fout, " POLYGON ");
}
for (int k = 0; k < poly.numPoints; k++)
fprintf(fout, " %g %g ", poly.x[k], poly.y[k]);
fprintf(fout, ";\n");
}
}
}
if (via->lefiVia::hasViaRule()) {
fprintf(fout, " VIARULE %s ;\n", via->lefiVia::viaRuleName());
fprintf(fout, " CUTSIZE %g %g ;\n", via->lefiVia::xCutSize(),
via->lefiVia::yCutSize());
fprintf(fout, " LAYERS %s %s %s ;\n", via->lefiVia::botMetalLayer(),
via->lefiVia::cutLayer(), via->lefiVia::topMetalLayer());
fprintf(fout, " CUTSPACING %g %g ;\n", via->lefiVia::xCutSpacing(),
via->lefiVia::yCutSpacing());
fprintf(fout, " ENCLOSURE %g %g %g %g ;\n", via->lefiVia::xBotEnc(),
via->lefiVia::yBotEnc(), via->lefiVia::xTopEnc(),
via->lefiVia::yTopEnc());
if (via->lefiVia::hasRowCol())
fprintf(fout, " ROWCOL %d %d ;\n", via->lefiVia::numCutRows(),
via->lefiVia::numCutCols());
if (via->lefiVia::hasOrigin())
fprintf(fout, " ORIGIN %g %g ;\n", via->lefiVia::xOffset(),
via->lefiVia::yOffset());
if (via->lefiVia::hasOffset())
fprintf(fout, " OFFSET %g %g %g %g ;\n", via->lefiVia::xBotOffset(),
via->lefiVia::yBotOffset(), via->lefiVia::xTopOffset(),
via->lefiVia::yTopOffset());
if (via->lefiVia::hasCutPattern())
fprintf(fout, " PATTERN %s ;\n", via->lefiVia::cutPattern());
}
fprintf(fout, "END %s\n", via->lefiVia::name());
return;
}
void lefSpacing(lefiSpacing* spacing) {
fprintf(fout, " SAMENET %s %s %g ", spacing->lefiSpacing::name1(),
spacing->lefiSpacing::name2(), spacing->lefiSpacing::distance());
if (spacing->lefiSpacing::hasStack())
fprintf(fout, "STACK ");
fprintf(fout,";\n");
return;
}
void lefViaRuleLayer(lefiViaRuleLayer* vLayer) {
fprintf(fout, " LAYER %s ;\n", vLayer->lefiViaRuleLayer::name());
if (vLayer->lefiViaRuleLayer::hasDirection()) {
if (vLayer->lefiViaRuleLayer::isHorizontal())
fprintf(fout, " DIRECTION HORIZONTAL ;\n");
if (vLayer->lefiViaRuleLayer::isVertical())
fprintf(fout, " DIRECTION VERTICAL ;\n");
}
if (vLayer->lefiViaRuleLayer::hasEnclosure()) {
fprintf(fout, " ENCLOSURE %g %g ;\n",
vLayer->lefiViaRuleLayer::enclosureOverhang1(),
vLayer->lefiViaRuleLayer::enclosureOverhang2());
}
if (vLayer->lefiViaRuleLayer::hasWidth())
fprintf(fout, " WIDTH %g TO %g ;\n",
vLayer->lefiViaRuleLayer::widthMin(),
vLayer->lefiViaRuleLayer::widthMax());
if (vLayer->lefiViaRuleLayer::hasResistance())
fprintf(fout, " RESISTANCE %g ;\n",
vLayer->lefiViaRuleLayer::resistance());
if (vLayer->lefiViaRuleLayer::hasOverhang())
fprintf(fout, " OVERHANG %g ;\n",
vLayer->lefiViaRuleLayer::overhang());
if (vLayer->lefiViaRuleLayer::hasMetalOverhang())
fprintf(fout, " METALOVERHANG %g ;\n",
vLayer->lefiViaRuleLayer::metalOverhang());
if (vLayer->lefiViaRuleLayer::hasSpacing())
fprintf(fout, " SPACING %g BY %g ;\n",
vLayer->lefiViaRuleLayer::spacingStepX(),
vLayer->lefiViaRuleLayer::spacingStepY());
if (vLayer->lefiViaRuleLayer::hasRect())
fprintf(fout, " RECT ( %f %f ) ( %f %f ) ;\n",
vLayer->lefiViaRuleLayer::xl(), vLayer->lefiViaRuleLayer::yl(),
vLayer->lefiViaRuleLayer::xh(), vLayer->lefiViaRuleLayer::yh());
return;
}
void prtGeometry(lefiGeometries *geometry) {
int numItems = geometry->lefiGeometries::numItems();
int i, j;
lefiGeomPath *path;
lefiGeomPathIter *pathIter;
lefiGeomRect *rect;
lefiGeomRectIter *rectIter;
lefiGeomPolygon *polygon;
lefiGeomPolygonIter *polygonIter;
lefiGeomVia *via;
lefiGeomViaIter *viaIter;
for (i = 0; i < numItems; i++) {
switch (geometry->lefiGeometries::itemType(i)) {
case lefiGeomClassE:
fprintf(fout, "CLASS %s ",
geometry->lefiGeometries::getClass(i));
break;
case lefiGeomLayerE:
fprintf(fout, " LAYER %s ;\n",
geometry->lefiGeometries::getLayer(i));
break;
case lefiGeomLayerExceptPgNetE:
fprintf(fout, " EXCEPTPGNET ;\n");
break;
case lefiGeomLayerMinSpacingE:
fprintf(fout, " SPACING %g ;\n",
geometry->lefiGeometries::getLayerMinSpacing(i));
break;
case lefiGeomLayerRuleWidthE:
fprintf(fout, " DESIGNRULEWIDTH %g ;\n",
geometry->lefiGeometries::getLayerRuleWidth(i));
break;
case lefiGeomWidthE:
fprintf(fout, " WIDTH %g ;\n",
geometry->lefiGeometries::getWidth(i));
break;
case lefiGeomPathE:
path = geometry->lefiGeometries::getPath(i);
if (path->colorMask != 0) {
fprintf(fout, " PATH MASK %d ", path->colorMask);
} else {
fprintf(fout, " PATH ");
}
for (j = 0; j < path->numPoints; j++) {
if (j + 1 == path->numPoints) // last one on the list
fprintf(fout, " ( %g %g ) ;\n", path->x[j], path->y[j]);
else
fprintf(fout, " ( %g %g )\n", path->x[j], path->y[j]);
}
break;
case lefiGeomPathIterE:
pathIter = geometry->lefiGeometries::getPathIter(i);
if (pathIter->colorMask != 0) {
fprintf(fout, " PATH MASK %d ITERATED ", pathIter->colorMask);
} else {
fprintf(fout, " PATH ITERATED ");
}
for (j = 0; j < pathIter->numPoints; j++)
fprintf(fout, " ( %g %g )\n", pathIter->x[j],
pathIter->y[j]);
fprintf(fout, " DO %g BY %g STEP %g %g ;\n", pathIter->xStart,
pathIter->yStart, pathIter->xStep, pathIter->yStep);
break;
case lefiGeomRectE:
rect = geometry->lefiGeometries::getRect(i);
if (rect->colorMask != 0) {
fprintf(fout, " RECT MASK %d ( %f %f ) ( %f %f ) ;\n",
rect->colorMask, rect->xl,
rect->yl, rect->xh, rect->yh);
} else {
fprintf(fout, " RECT ( %f %f ) ( %f %f ) ;\n", rect->xl,
rect->yl, rect->xh, rect->yh);
}
break;
case lefiGeomRectIterE:
rectIter = geometry->lefiGeometries::getRectIter(i);
if (rectIter->colorMask != 0) {
fprintf(fout, " RECT MASK %d ITERATE ( %f %f ) ( %f %f )\n",
rectIter->colorMask,
rectIter->xl, rectIter->yl, rectIter->xh, rectIter->yh);
} else {
fprintf(fout, " RECT ITERATE ( %f %f ) ( %f %f )\n",
rectIter->xl, rectIter->yl, rectIter->xh, rectIter->yh);
}
fprintf(fout, " DO %g BY %g STEP %g %g ;\n",
rectIter->xStart, rectIter->yStart, rectIter->xStep,
rectIter->yStep);
break;
case lefiGeomPolygonE:
polygon = geometry->lefiGeometries::getPolygon(i);
if (polygon->colorMask != 0) {
fprintf(fout, " POLYGON MASK %d ", polygon->colorMask);
} else {
fprintf(fout, " POLYGON ");
}
for (j = 0; j < polygon->numPoints; j++) {
if (j + 1 == polygon->numPoints) // last one on the list
fprintf(fout, " ( %g %g ) ;\n", polygon->x[j],
polygon->y[j]);
else
fprintf(fout, " ( %g %g )\n", polygon->x[j],
polygon->y[j]);
}
break;
case lefiGeomPolygonIterE:
polygonIter = geometry->lefiGeometries::getPolygonIter(i);
if (polygonIter->colorMask != 0) {
fprintf(fout, " POLYGON MASK %d ITERATE ", polygonIter->colorMask);
} else {
fprintf(fout, " POLYGON ITERATE");
}
for (j = 0; j < polygonIter->numPoints; j++)
fprintf(fout, " ( %g %g )\n", polygonIter->x[j],
polygonIter->y[j]);
fprintf(fout, " DO %g BY %g STEP %g %g ;\n",
polygonIter->xStart, polygonIter->yStart,
polygonIter->xStep, polygonIter->yStep);
break;
case lefiGeomViaE:
via = geometry->lefiGeometries::getVia(i);
if (via->topMaskNum != 0 || via->bottomMaskNum != 0 || via->cutMaskNum !=0) {
fprintf(fout, " VIA MASK %d%d%d ( %g %g ) %s ;\n",
via->topMaskNum, via->cutMaskNum, via->bottomMaskNum,
via->x, via->y,
via->name);
} else {
fprintf(fout, " VIA ( %g %g ) %s ;\n", via->x, via->y,
via->name);
}
break;
case lefiGeomViaIterE:
viaIter = geometry->lefiGeometries::getViaIter(i);
if (viaIter->topMaskNum != 0 || viaIter->cutMaskNum != 0 || viaIter->bottomMaskNum != 0) {
fprintf(fout, " VIA ITERATE MASK %d%d%d ( %g %g ) %s\n",
viaIter->topMaskNum, viaIter->cutMaskNum, viaIter->bottomMaskNum,
viaIter->x,
viaIter->y, viaIter->name);
} else {
fprintf(fout, " VIA ITERATE ( %g %g ) %s\n", viaIter->x,
viaIter->y, viaIter->name);
}
fprintf(fout, " DO %g BY %g STEP %g %g ;\n",
viaIter->xStart, viaIter->yStart,
viaIter->xStep, viaIter->yStep);
break;
default:
fprintf(fout, "BOGUS geometries type.\n");
break;
}
}
}
int antennaCB(lefrCallbackType_e c, double value, lefiUserData) {
checkType(c);
// if ((long)ud != userData) dataError();
switch (c) {
case lefrAntennaInputCbkType:
fprintf(fout, "ANTENNAINPUTGATEAREA %g ;\n", value);
break;
case lefrAntennaInoutCbkType:
fprintf(fout, "ANTENNAINOUTDIFFAREA %g ;\n", value);
break;
case lefrAntennaOutputCbkType:
fprintf(fout, "ANTENNAOUTPUTDIFFAREA %g ;\n", value);
break;
case lefrInputAntennaCbkType:
fprintf(fout, "INPUTPINANTENNASIZE %g ;\n", value);
break;
case lefrOutputAntennaCbkType:
fprintf(fout, "OUTPUTPINANTENNASIZE %g ;\n", value);
break;
case lefrInoutAntennaCbkType:
fprintf(fout, "INOUTPINANTENNASIZE %g ;\n", value);
break;
default:
fprintf(fout, "BOGUS antenna type.\n");
break;
}
return 0;
}
int arrayBeginCB(lefrCallbackType_e c, const char* name, lefiUserData) {
int status;
checkType(c);
// if ((long)ud != userData) dataError();
// use the lef writer to write the data out
status = lefwStartArray(name);
if (status != LEFW_OK)
return status;
return 0;
}
int arrayCB(lefrCallbackType_e c, lefiArray* a, lefiUserData) {
int status, i, j, defCaps;
lefiSitePattern* pattern;
lefiTrackPattern* track;
lefiGcellPattern* gcell;
checkType(c);
// if ((long)ud != userData) dataError();
if (a->lefiArray::numSitePattern() > 0) {
for (i = 0; i < a->lefiArray::numSitePattern(); i++) {
pattern = a->lefiArray::sitePattern(i);
status = lefwArraySite(pattern->lefiSitePattern::name(),
pattern->lefiSitePattern::x(),
pattern->lefiSitePattern::y(),
pattern->lefiSitePattern::orient(),
pattern->lefiSitePattern::xStart(),
pattern->lefiSitePattern::yStart(),
pattern->lefiSitePattern::xStep(),
pattern->lefiSitePattern::yStep());
if (status != LEFW_OK)
dataError();
}
}
if (a->lefiArray::numCanPlace() > 0) {
for (i = 0; i < a->lefiArray::numCanPlace(); i++) {
pattern = a->lefiArray::canPlace(i);
status = lefwArrayCanplace(pattern->lefiSitePattern::name(),
pattern->lefiSitePattern::x(),
pattern->lefiSitePattern::y(),
pattern->lefiSitePattern::orient(),
pattern->lefiSitePattern::xStart(),
pattern->lefiSitePattern::yStart(),
pattern->lefiSitePattern::xStep(),
pattern->lefiSitePattern::yStep());
if (status != LEFW_OK)
dataError();
}
}
if (a->lefiArray::numCannotOccupy() > 0) {
for (i = 0; i < a->lefiArray::numCannotOccupy(); i++) {
pattern = a->lefiArray::cannotOccupy(i);
status = lefwArrayCannotoccupy(pattern->lefiSitePattern::name(),
pattern->lefiSitePattern::x(),
pattern->lefiSitePattern::y(),
pattern->lefiSitePattern::orient(),
pattern->lefiSitePattern::xStart(),
pattern->lefiSitePattern::yStart(),
pattern->lefiSitePattern::xStep(),
pattern->lefiSitePattern::yStep());
if (status != LEFW_OK)
dataError();
}
}
if (a->lefiArray::numTrack() > 0) {
for (i = 0; i < a->lefiArray::numTrack(); i++) {
track = a->lefiArray::track(i);
fprintf(fout, " TRACKS %s, %g DO %d STEP %g\n",
track->lefiTrackPattern::name(),
track->lefiTrackPattern::start(),
track->lefiTrackPattern::numTracks(),
track->lefiTrackPattern::space());
if (track->lefiTrackPattern::numLayers() > 0) {
fprintf(fout, " LAYER ");
for (j = 0; j < track->lefiTrackPattern::numLayers(); j++)
fprintf(fout, "%s ", track->lefiTrackPattern::layerName(j));
fprintf(fout, ";\n");
}
}
}
if (a->lefiArray::numGcell() > 0) {
for (i = 0; i < a->lefiArray::numGcell(); i++) {
gcell = a->lefiArray::gcell(i);
fprintf(fout, " GCELLGRID %s, %g DO %d STEP %g\n",
gcell->lefiGcellPattern::name(),
gcell->lefiGcellPattern::start(),
gcell->lefiGcellPattern::numCRs(),
gcell->lefiGcellPattern::space());
}
}
if (a->lefiArray::numFloorPlans() > 0) {
for (i = 0; i < a->lefiArray::numFloorPlans(); i++) {
status = lefwStartArrayFloorplan(a->lefiArray::floorPlanName(i));
if (status != LEFW_OK)
dataError();
for (j = 0; j < a->lefiArray::numSites(i); j++) {
pattern = a->lefiArray::site(i, j);
status = lefwArrayFloorplan(a->lefiArray::siteType(i, j),
pattern->lefiSitePattern::name(),
pattern->lefiSitePattern::x(),
pattern->lefiSitePattern::y(),
pattern->lefiSitePattern::orient(),
(int)pattern->lefiSitePattern::xStart(),
(int)pattern->lefiSitePattern::yStart(),
pattern->lefiSitePattern::xStep(),
pattern->lefiSitePattern::yStep());
if (status != LEFW_OK)
dataError();
}
status = lefwEndArrayFloorplan(a->lefiArray::floorPlanName(i));
if (status != LEFW_OK)
dataError();
}
}
defCaps = a->lefiArray::numDefaultCaps();
if (defCaps > 0) {
status = lefwStartArrayDefaultCap(defCaps);
if (status != LEFW_OK)
dataError();
for (i = 0; i < defCaps; i++) {
status = lefwArrayDefaultCap(a->lefiArray::defaultCapMinPins(i),
a->lefiArray::defaultCap(i));
if (status != LEFW_OK)
dataError();
}
status = lefwEndArrayDefaultCap();
if (status != LEFW_OK)
dataError();
}
return 0;
}
int arrayEndCB(lefrCallbackType_e c, const char* name, lefiUserData) {
int status;
checkType(c);
// if ((long)ud != userData) dataError();
// use the lef writer to write the data out
status = lefwEndArray(name);
if (status != LEFW_OK)
return status;
return 0;
}
int busBitCharsCB(lefrCallbackType_e c, const char* busBit, lefiUserData)
{
int status;
checkType(c);
// if ((long)ud != userData) dataError();
// use the lef writer to write out the data
status = lefwBusBitChars(busBit);
if (status != LEFW_OK)
dataError();
return 0;
}
int caseSensCB(lefrCallbackType_e c, int caseSense, lefiUserData) {
checkType(c);
// if ((long)ud != userData) dataError();
if (caseSense == TRUE)
fprintf(fout, "NAMESCASESENSITIVE ON ;\n");
else
fprintf(fout, "NAMESCASESENSITIVE OFF ;\n");
return 0;
}
int fixedMaskCB(lefrCallbackType_e c, int fixedMask, lefiUserData) {
checkType(c);
if (fixedMask == 1)
fprintf(fout, "FIXEDMASK ;\n");
return 0;
}
int clearanceCB(lefrCallbackType_e c, const char* name, lefiUserData) {
checkType(c);
// if ((long)ud != userData) dataError();
fprintf(fout, "CLEARANCEMEASURE %s ;\n", name);
return 0;
}
int dividerCB(lefrCallbackType_e c, const char* name, lefiUserData) {
checkType(c);
// if ((long)ud != userData) dataError();
fprintf(fout, "DIVIDER %s ;\n", name);
return 0;
}
int noWireExtCB(lefrCallbackType_e c, const char* name, lefiUserData) {
checkType(c);
// if ((long)ud != userData) dataError();
fprintf(fout, "NOWIREEXTENSION %s ;\n", name);
return 0;
}
int noiseMarCB(lefrCallbackType_e c, lefiNoiseMargin *, lefiUserData) {
checkType(c);
// if ((long)ud != userData) dataError();
return 0;
}
int edge1CB(lefrCallbackType_e c, double name, lefiUserData) {
checkType(c);
// if ((long)ud != userData) dataError();
fprintf(fout, "EDGERATETHRESHOLD1 %g ;\n", name);
return 0;
}
int edge2CB(lefrCallbackType_e c, double name, lefiUserData) {
checkType(c);
// if ((long)ud != userData) dataError();
fprintf(fout, "EDGERATETHRESHOLD2 %g ;\n", name);
return 0;
}
int edgeScaleCB(lefrCallbackType_e c, double name, lefiUserData) {
checkType(c);
// if ((long)ud != userData) dataError();
fprintf(fout, "EDGERATESCALEFACTORE %g ;\n", name);
return 0;
}
int noiseTableCB(lefrCallbackType_e c, lefiNoiseTable *, lefiUserData) {
checkType(c);
// if ((long)ud != userData) dataError();
return 0;
}
int correctionCB(lefrCallbackType_e c, lefiCorrectionTable *, lefiUserData) {
checkType(c);
// if ((long)ud != userData) dataError();
return 0;
}
int dielectricCB(lefrCallbackType_e c, double dielectric, lefiUserData) {
checkType(c);
// if ((long)ud != userData) dataError();
fprintf(fout, "DIELECTRIC %g ;\n", dielectric);
return 0;
}
int irdropBeginCB(lefrCallbackType_e c, void*, lefiUserData){
checkType(c);
// if ((long)ud != userData) dataError();
fprintf(fout, "IRDROP\n");
return 0;
}
int irdropCB(lefrCallbackType_e c, lefiIRDrop* irdrop, lefiUserData) {
int i;
checkType(c);
// if ((long)ud != userData) dataError();
fprintf(fout, " TABLE %s ", irdrop->lefiIRDrop::name());
for (i = 0; i < irdrop->lefiIRDrop::numValues(); i++)
fprintf(fout, "%g %g ", irdrop->lefiIRDrop::value1(i),
irdrop->lefiIRDrop::value2(i));
fprintf(fout, ";\n");
return 0;
}
int irdropEndCB(lefrCallbackType_e c, void*, lefiUserData){
checkType(c);
// if ((long)ud != userData) dataError();
fprintf(fout, "END IRDROP\n");
return 0;
}
int layerCB(lefrCallbackType_e c, lefiLayer* layer, lefiUserData) {
int i, j, k;
int numPoints, propNum;
double *widths, *current;
lefiLayerDensity* density;
lefiAntennaPWL* pwl;
lefiSpacingTable* spTable;
lefiInfluence* influence;
lefiParallel* parallel;
lefiTwoWidths* twoWidths;
char pType;
int numMinCut, numMinenclosed;
lefiAntennaModel* aModel;
lefiOrthogonal* ortho;
checkType(c);
// if ((long)ud != userData) dataError();
lefrSetCaseSensitivity(0);
// Call parse65nmRules for 5.7 syntax in 5.6
if (parse65nm)
layer->lefiLayer::parse65nmRules();
// Call parseLef58Type for 5.8 syntax in 5.7
if (parseLef58Type)
layer->lefiLayer::parseLEF58Layer();
fprintf(fout, "LAYER %s\n", layer->lefiLayer::name());
if (layer->lefiLayer::hasType())
fprintf(fout, " TYPE %s ;\n", layer->lefiLayer::type());
if (layer->lefiLayer::hasLayerType())
fprintf(fout, " LAYER TYPE %s ;\n", layer->lefiLayer::layerType());
if (layer->lefiLayer::hasMask())
fprintf(fout, " MASK %d ;\n", layer->lefiLayer::mask());
if (layer->lefiLayer::hasPitch())
fprintf(fout, " PITCH %g ;\n", layer->lefiLayer::pitch());
else if (layer->lefiLayer::hasXYPitch())
fprintf(fout, " PITCH %g %g ;\n", layer->lefiLayer::pitchX(),
layer->lefiLayer::pitchY());
if (layer->lefiLayer::hasOffset())
fprintf(fout, " OFFSET %g ;\n", layer->lefiLayer::offset());
else if (layer->lefiLayer::hasXYOffset())
fprintf(fout, " OFFSET %g %g ;\n", layer->lefiLayer::offsetX(),
layer->lefiLayer::offsetY());
if (layer->lefiLayer::hasDiagPitch())
fprintf(fout, " DIAGPITCH %g ;\n", layer->lefiLayer::diagPitch());
else if (layer->lefiLayer::hasXYDiagPitch())
fprintf(fout, " DIAGPITCH %g %g ;\n", layer->lefiLayer::diagPitchX(),
layer->lefiLayer::diagPitchY());
if (layer->lefiLayer::hasDiagWidth())
fprintf(fout, " DIAGWIDTH %g ;\n", layer->lefiLayer::diagWidth());
if (layer->lefiLayer::hasDiagSpacing())
fprintf(fout, " DIAGSPACING %g ;\n", layer->lefiLayer::diagSpacing());
if (layer->lefiLayer::hasWidth())
fprintf(fout, " WIDTH %g ;\n", layer->lefiLayer::width());
if (layer->lefiLayer::hasArea())
fprintf(fout, " AREA %g ;\n", layer->lefiLayer::area());
if (layer->lefiLayer::hasSlotWireWidth())
fprintf(fout, " SLOTWIREWIDTH %g ;\n", layer->lefiLayer::slotWireWidth());
if (layer->lefiLayer::hasSlotWireLength())
fprintf(fout, " SLOTWIRELENGTH %g ;\n",
layer->lefiLayer::slotWireLength());
if (layer->lefiLayer::hasSlotWidth())
fprintf(fout, " SLOTWIDTH %g ;\n", layer->lefiLayer::slotWidth());
if (layer->lefiLayer::hasSlotLength())
fprintf(fout, " SLOTLENGTH %g ;\n", layer->lefiLayer::slotLength());
if (layer->lefiLayer::hasMaxAdjacentSlotSpacing())
fprintf(fout, " MAXADJACENTSLOTSPACING %g ;\n",
layer->lefiLayer::maxAdjacentSlotSpacing());
if (layer->lefiLayer::hasMaxCoaxialSlotSpacing())
fprintf(fout, " MAXCOAXIALSLOTSPACING %g ;\n",
layer->lefiLayer::maxCoaxialSlotSpacing());
if (layer->lefiLayer::hasMaxEdgeSlotSpacing())
fprintf(fout, " MAXEDGESLOTSPACING %g ;\n",
layer->lefiLayer::maxEdgeSlotSpacing());
if (layer->lefiLayer::hasMaxFloatingArea()) // 5.7
fprintf(fout, " MAXFLOATINGAREA %g ;\n",
layer->lefiLayer::maxFloatingArea());
if (layer->lefiLayer::hasArraySpacing()) { // 5.7
fprintf(fout, " ARRAYSPACING ");
if (layer->lefiLayer::hasLongArray())
fprintf(fout, "LONGARRAY ");
if (layer->lefiLayer::hasViaWidth())
fprintf(fout, "WIDTH %g ", layer->lefiLayer::viaWidth());
fprintf(fout, "CUTSPACING %g", layer->lefiLayer::cutSpacing());
for (i = 0; i < layer->lefiLayer::numArrayCuts(); i++)
fprintf(fout, "\n\tARRAYCUTS %d SPACING %g",
layer->lefiLayer::arrayCuts(i),
layer->lefiLayer::arraySpacing(i));
fprintf(fout, " ;\n");
}
if (layer->lefiLayer::hasSplitWireWidth())
fprintf(fout, " SPLITWIREWIDTH %g ;\n",
layer->lefiLayer::splitWireWidth());
if (layer->lefiLayer::hasMinimumDensity())
fprintf(fout, " MINIMUMDENSITY %g ;\n",
layer->lefiLayer::minimumDensity());
if (layer->lefiLayer::hasMaximumDensity())
fprintf(fout, " MAXIMUMDENSITY %g ;\n",
layer->lefiLayer::maximumDensity());
if (layer->lefiLayer::hasDensityCheckWindow())
fprintf(fout, " DENSITYCHECKWINDOW %g %g ;\n",
layer->lefiLayer::densityCheckWindowLength(),
layer->lefiLayer::densityCheckWindowWidth());
if (layer->lefiLayer::hasDensityCheckStep())
fprintf(fout, " DENSITYCHECKSTEP %g ;\n",
layer->lefiLayer::densityCheckStep());
if (layer->lefiLayer::hasFillActiveSpacing())
fprintf(fout, " FILLACTIVESPACING %g ;\n",
layer->lefiLayer::fillActiveSpacing());
// 5.4.1
numMinCut = layer->lefiLayer::numMinimumcut();
if (numMinCut > 0) {
for (i = 0; i < numMinCut; i++) {
fprintf(fout, " MINIMUMCUT %d WIDTH %g ",
layer->lefiLayer::minimumcut(i),
layer->lefiLayer::minimumcutWidth(i));
if (layer->lefiLayer::hasMinimumcutWithin(i))
fprintf(fout, "WITHIN %g ", layer->lefiLayer::minimumcutWithin(i));
if (layer->lefiLayer::hasMinimumcutConnection(i))
fprintf(fout, "%s ", layer->lefiLayer::minimumcutConnection(i));
if (layer->lefiLayer::hasMinimumcutNumCuts(i))
fprintf(fout, "LENGTH %g WITHIN %g ",
layer->lefiLayer::minimumcutLength(i),
layer->lefiLayer::minimumcutDistance(i));
fprintf(fout, ";\n");
}
}
// 5.4.1
if (layer->lefiLayer::hasMaxwidth()) {
fprintf(fout, " MAXWIDTH %g ;\n", layer->lefiLayer::maxwidth());
}
// 5.5
if (layer->lefiLayer::hasMinwidth()) {
fprintf(fout, " MINWIDTH %g ;\n", layer->lefiLayer::minwidth());
}
// 5.5
numMinenclosed = layer->lefiLayer::numMinenclosedarea();
if (numMinenclosed > 0) {
for (i = 0; i < numMinenclosed; i++) {
fprintf(fout, " MINENCLOSEDAREA %g ",
layer->lefiLayer::minenclosedarea(i));
if (layer->lefiLayer::hasMinenclosedareaWidth(i))
fprintf(fout, "MINENCLOSEDAREAWIDTH %g ",
layer->lefiLayer::minenclosedareaWidth(i));
fprintf (fout, ";\n");
}
}
// 5.4.1 & 5.6
if (layer->lefiLayer::hasMinstep()) {
for (i = 0; i < layer->lefiLayer::numMinstep(); i++) {
fprintf(fout, " MINSTEP %g ", layer->lefiLayer::minstep(i));
if (layer->lefiLayer::hasMinstepType(i))
fprintf(fout, "%s ", layer->lefiLayer::minstepType(i));
if (layer->lefiLayer::hasMinstepLengthsum(i))
fprintf(fout, "LENGTHSUM %g ",
layer->lefiLayer::minstepLengthsum(i));
if (layer->lefiLayer::hasMinstepMaxedges(i))
fprintf(fout, "MAXEDGES %d ", layer->lefiLayer::minstepMaxedges(i));
if (layer->lefiLayer::hasMinstepMinAdjLength(i))
fprintf(fout, "MINADJLENGTH %g ", layer->lefiLayer::minstepMinAdjLength(i));
if (layer->lefiLayer::hasMinstepMinBetLength(i))
fprintf(fout, "MINBETLENGTH %g ", layer->lefiLayer::minstepMinBetLength(i));
if (layer->lefiLayer::hasMinstepXSameCorners(i))
fprintf(fout, "XSAMECORNERS");
fprintf(fout, ";\n");
}
}
// 5.4.1
if (layer->lefiLayer::hasProtrusion()) {
fprintf(fout, " PROTRUSIONWIDTH %g LENGTH %g WIDTH %g ;\n",
layer->lefiLayer::protrusionWidth1(),
layer->lefiLayer::protrusionLength(),
layer->lefiLayer::protrusionWidth2());
}
if (layer->lefiLayer::hasSpacingNumber()) {
for (i = 0; i < layer->lefiLayer::numSpacing(); i++) {
fprintf(fout, " SPACING %g ", layer->lefiLayer::spacing(i));
if (layer->lefiLayer::hasSpacingName(i))
fprintf(fout, "LAYER %s ", layer->lefiLayer::spacingName(i));
if (layer->lefiLayer::hasSpacingLayerStack(i))
fprintf(fout, "STACK "); // 5.7
if (layer->lefiLayer::hasSpacingAdjacent(i))
fprintf(fout, "ADJACENTCUTS %d WITHIN %g ",
layer->lefiLayer::spacingAdjacentCuts(i),
layer->lefiLayer::spacingAdjacentWithin(i));
if (layer->lefiLayer::hasSpacingAdjacentExcept(i)) // 5.7
fprintf(fout, "EXCEPTSAMEPGNET ");
if (layer->lefiLayer::hasSpacingCenterToCenter(i))
fprintf(fout, "CENTERTOCENTER ");
if (layer->lefiLayer::hasSpacingSamenet(i)) // 5.7
fprintf(fout, "SAMENET ");
if (layer->lefiLayer::hasSpacingSamenetPGonly(i)) // 5.7
fprintf(fout, "PGONLY ");
if (layer->lefiLayer::hasSpacingArea(i)) // 5.7
fprintf(fout, "AREA %g ", layer->lefiLayer::spacingArea(i));
if (layer->lefiLayer::hasSpacingRange(i)) {
fprintf(fout, "RANGE %g %g ", layer->lefiLayer::spacingRangeMin(i),
layer->lefiLayer::spacingRangeMax(i));
if (layer->lefiLayer::hasSpacingRangeUseLengthThreshold(i))
fprintf(fout, "USELENGTHTHRESHOLD ");
else if (layer->lefiLayer::hasSpacingRangeInfluence(i)) {
fprintf(fout, "INFLUENCE %g ",
layer->lefiLayer::spacingRangeInfluence(i));
if (layer->lefiLayer::hasSpacingRangeInfluenceRange(i))
fprintf(fout, "RANGE %g %g ",
layer->lefiLayer::spacingRangeInfluenceMin(i),
layer->lefiLayer::spacingRangeInfluenceMax(i));
} else if (layer->lefiLayer::hasSpacingRangeRange(i))
fprintf(fout, "RANGE %g %g ",
layer->lefiLayer::spacingRangeRangeMin(i),
layer->lefiLayer::spacingRangeRangeMax(i));
} else if (layer->lefiLayer::hasSpacingLengthThreshold(i)) {
fprintf(fout, "LENGTHTHRESHOLD %g ",
layer->lefiLayer::spacingLengthThreshold(i));
if (layer->lefiLayer::hasSpacingLengthThresholdRange(i))
fprintf(fout, "RANGE %g %g",
layer->lefiLayer::spacingLengthThresholdRangeMin(i),
layer->lefiLayer::spacingLengthThresholdRangeMax(i));
} else if (layer->lefiLayer::hasSpacingNotchLength(i)) {// 5.7
fprintf(fout, "NOTCHLENGTH %g",
layer->lefiLayer::spacingNotchLength(i));
} else if (layer->lefiLayer::hasSpacingEndOfNotchWidth(i)) // 5.7
fprintf(fout, "ENDOFNOTCHWIDTH %g NOTCHSPACING %g, NOTCHLENGTH %g",
layer->lefiLayer::spacingEndOfNotchWidth(i),
layer->lefiLayer::spacingEndOfNotchSpacing(i),
layer->lefiLayer::spacingEndOfNotchLength(i));
if (layer->lefiLayer::hasSpacingParallelOverlap(i)) // 5.7
fprintf(fout, "PARALLELOVERLAP ");
if (layer->lefiLayer::hasSpacingEndOfLine(i)) { // 5.7
fprintf(fout, "ENDOFLINE %g WITHIN %g ",
layer->lefiLayer::spacingEolWidth(i),
layer->lefiLayer::spacingEolWithin(i));
if (layer->lefiLayer::hasSpacingParellelEdge(i)) {
fprintf(fout, "PARALLELEDGE %g WITHIN %g ",
layer->lefiLayer::spacingParSpace(i),
layer->lefiLayer::spacingParWithin(i));
if (layer->lefiLayer::hasSpacingTwoEdges(i)) {
fprintf(fout, "TWOEDGES ");
}
}
}
fprintf(fout, ";\n");
}
}
if (layer->lefiLayer::hasSpacingTableOrtho()) { // 5.7
fprintf(fout, "SPACINGTABLE ORTHOGONAL");
ortho = layer->lefiLayer::orthogonal();
for (i = 0; i < ortho->lefiOrthogonal::numOrthogonal(); i++) {
fprintf(fout, "\n WITHIN %g SPACING %g",
ortho->lefiOrthogonal::cutWithin(i),
ortho->lefiOrthogonal::orthoSpacing(i));
}
fprintf(fout, ";\n");
}
for (i = 0; i < layer->lefiLayer::numEnclosure(); i++) {
fprintf(fout, "ENCLOSURE ");
if (layer->lefiLayer::hasEnclosureRule(i))
fprintf(fout, "%s ", layer->lefiLayer::enclosureRule(i));
fprintf(fout, "%g %g ", layer->lefiLayer::enclosureOverhang1(i),
layer->lefiLayer::enclosureOverhang2(i));
if (layer->lefiLayer::hasEnclosureWidth(i))
fprintf(fout, "WIDTH %g ", layer->lefiLayer::enclosureMinWidth(i));
if (layer->lefiLayer::hasEnclosureExceptExtraCut(i))
fprintf(fout, "EXCEPTEXTRACUT %g ",
layer->lefiLayer::enclosureExceptExtraCut(i));
if (layer->lefiLayer::hasEnclosureMinLength(i))
fprintf(fout, "LENGTH %g ", layer->lefiLayer::enclosureMinLength(i));
fprintf(fout, ";\n");
}
for (i = 0; i < layer->lefiLayer::numPreferEnclosure(); i++) {
fprintf(fout, "PREFERENCLOSURE ");
if (layer->lefiLayer::hasPreferEnclosureRule(i))
fprintf(fout, "%s ", layer->lefiLayer::preferEnclosureRule(i));
fprintf(fout, "%g %g ", layer->lefiLayer::preferEnclosureOverhang1(i),
layer->lefiLayer::preferEnclosureOverhang2(i));
if (layer->lefiLayer::hasPreferEnclosureWidth(i))
fprintf(fout, "WIDTH %g ",layer->lefiLayer::preferEnclosureMinWidth(i));
fprintf(fout, ";\n");
}
if (layer->lefiLayer::hasResistancePerCut())
fprintf(fout, " RESISTANCE %g ;\n",
layer->lefiLayer::resistancePerCut());
if (layer->lefiLayer::hasCurrentDensityPoint())
fprintf(fout, " CURRENTDEN %g ;\n",
layer->lefiLayer::currentDensityPoint());
if (layer->lefiLayer::hasCurrentDensityArray()) {
layer->lefiLayer::currentDensityArray(&numPoints, &widths, &current);
for (i = 0; i < numPoints; i++)
fprintf(fout, " CURRENTDEN ( %g %g ) ;\n", widths[i], current[i]);
}
if (layer->lefiLayer::hasDirection())
fprintf(fout, " DIRECTION %s ;\n", layer->lefiLayer::direction());
if (layer->lefiLayer::hasResistance())
fprintf(fout, " RESISTANCE RPERSQ %g ;\n",
layer->lefiLayer::resistance());
if (layer->lefiLayer::hasCapacitance())
fprintf(fout, " CAPACITANCE CPERSQDIST %g ;\n",
layer->lefiLayer::capacitance());
if (layer->lefiLayer::hasEdgeCap())
fprintf(fout, " EDGECAPACITANCE %g ;\n", layer->lefiLayer::edgeCap());
if (layer->lefiLayer::hasHeight())
fprintf(fout, " TYPE %g ;\n", layer->lefiLayer::height());
if (layer->lefiLayer::hasThickness())
fprintf(fout, " THICKNESS %g ;\n", layer->lefiLayer::thickness());
if (layer->lefiLayer::hasWireExtension())
fprintf(fout, " WIREEXTENSION %g ;\n", layer->lefiLayer::wireExtension());
if (layer->lefiLayer::hasShrinkage())
fprintf(fout, " SHRINKAGE %g ;\n", layer->lefiLayer::shrinkage());
if (layer->lefiLayer::hasCapMultiplier())
fprintf(fout, " CAPMULTIPLIER %g ;\n", layer->lefiLayer::capMultiplier());
if (layer->lefiLayer::hasAntennaArea())
fprintf(fout, " ANTENNAAREAFACTOR %g ;\n",
layer->lefiLayer::antennaArea());
if (layer->lefiLayer::hasAntennaLength())
fprintf(fout, " ANTENNALENGTHFACTOR %g ;\n",
layer->lefiLayer::antennaLength());
// 5.5 AntennaModel
for (i = 0; i < layer->lefiLayer::numAntennaModel(); i++) {
aModel = layer->lefiLayer::antennaModel(i);
fprintf(fout, " ANTENNAMODEL %s ;\n",
aModel->lefiAntennaModel::antennaOxide());
if (aModel->lefiAntennaModel::hasAntennaAreaRatio())
fprintf(fout, " ANTENNAAREARATIO %g ;\n",
aModel->lefiAntennaModel::antennaAreaRatio());
if (aModel->lefiAntennaModel::hasAntennaDiffAreaRatio())
fprintf(fout, " ANTENNADIFFAREARATIO %g ;\n",
aModel->lefiAntennaModel::antennaDiffAreaRatio());
else if (aModel->lefiAntennaModel::hasAntennaDiffAreaRatioPWL()) {
pwl = aModel->lefiAntennaModel::antennaDiffAreaRatioPWL();
fprintf(fout, " ANTENNADIFFAREARATIO PWL ( ");
for (j = 0; j < pwl->lefiAntennaPWL::numPWL(); j++)
fprintf(fout, "( %g %g ) ", pwl->lefiAntennaPWL::PWLdiffusion(j),
pwl->lefiAntennaPWL::PWLratio(j));
fprintf(fout, ") ;\n");
}
if (aModel->lefiAntennaModel::hasAntennaCumAreaRatio())
fprintf(fout, " ANTENNACUMAREARATIO %g ;\n",
aModel->lefiAntennaModel::antennaCumAreaRatio());
if (aModel->lefiAntennaModel::hasAntennaCumDiffAreaRatio())
fprintf(fout, " ANTENNACUMDIFFAREARATIO %g\n",
aModel->lefiAntennaModel::antennaCumDiffAreaRatio());
if (aModel->lefiAntennaModel::hasAntennaCumDiffAreaRatioPWL()) {
pwl = aModel->lefiAntennaModel::antennaCumDiffAreaRatioPWL();
fprintf(fout, " ANTENNACUMDIFFAREARATIO PWL ( ");
for (j = 0; j < pwl->lefiAntennaPWL::numPWL(); j++)
fprintf(fout, "( %g %g ) ", pwl->lefiAntennaPWL::PWLdiffusion(j),
pwl->lefiAntennaPWL::PWLratio(j));
fprintf(fout, ") ;\n");
}
if (aModel->lefiAntennaModel::hasAntennaAreaFactor()) {
fprintf(fout, " ANTENNAAREAFACTOR %g ",
aModel->lefiAntennaModel::antennaAreaFactor());
if (aModel->lefiAntennaModel::hasAntennaAreaFactorDUO())
fprintf(fout, " DIFFUSEONLY ");
fprintf(fout, ";\n");
}
if (aModel->lefiAntennaModel::hasAntennaSideAreaRatio())
fprintf(fout, " ANTENNASIDEAREARATIO %g ;\n",
aModel->lefiAntennaModel::antennaSideAreaRatio());
if (aModel->lefiAntennaModel::hasAntennaDiffSideAreaRatio())
fprintf(fout, " ANTENNADIFFSIDEAREARATIO %g\n",
aModel->lefiAntennaModel::antennaDiffSideAreaRatio());
else if (aModel->lefiAntennaModel::hasAntennaDiffSideAreaRatioPWL()) {
pwl = aModel->lefiAntennaModel::antennaDiffSideAreaRatioPWL();
fprintf(fout, " ANTENNADIFFSIDEAREARATIO PWL ( ");
for (j = 0; j < pwl->lefiAntennaPWL::numPWL(); j++)
fprintf(fout, "( %g %g ) ", pwl->lefiAntennaPWL::PWLdiffusion(j),
pwl->lefiAntennaPWL::PWLratio(j));
fprintf(fout, ") ;\n");
}
if (aModel->lefiAntennaModel::hasAntennaCumSideAreaRatio())
fprintf(fout, " ANTENNACUMSIDEAREARATIO %g ;\n",
aModel->lefiAntennaModel::antennaCumSideAreaRatio());
if (aModel->lefiAntennaModel::hasAntennaCumDiffSideAreaRatio())
fprintf(fout, " ANTENNACUMDIFFSIDEAREARATIO %g\n",
aModel->lefiAntennaModel::antennaCumDiffSideAreaRatio());
else if (aModel->lefiAntennaModel::hasAntennaCumDiffSideAreaRatioPWL()) {
pwl = aModel->lefiAntennaModel::antennaCumDiffSideAreaRatioPWL();
fprintf(fout, " ANTENNACUMDIFFSIDEAREARATIO PWL ( ");
for (j = 0; j < pwl->lefiAntennaPWL::numPWL(); j++)
fprintf(fout, "( %g %g ) ", pwl->lefiAntennaPWL::PWLdiffusion(j),
pwl->lefiAntennaPWL::PWLratio(j));
fprintf(fout, ") ;\n");
}
if (aModel->lefiAntennaModel::hasAntennaSideAreaFactor()) {
fprintf(fout, " ANTENNASIDEAREAFACTOR %g ",
aModel->lefiAntennaModel::antennaSideAreaFactor());
if (aModel->lefiAntennaModel::hasAntennaSideAreaFactorDUO())
fprintf(fout, " DIFFUSEONLY ");
fprintf(fout, ";\n");
}
if (aModel->lefiAntennaModel::hasAntennaCumRoutingPlusCut())
fprintf(fout, " ANTENNACUMROUTINGPLUSCUT ;\n");
if (aModel->lefiAntennaModel::hasAntennaGatePlusDiff())
fprintf(fout, " ANTENNAGATEPLUSDIFF %g ;\n",
aModel->lefiAntennaModel::antennaGatePlusDiff());
if (aModel->lefiAntennaModel::hasAntennaAreaMinusDiff())
fprintf(fout, " ANTENNAAREAMINUSDIFF %g ;\n",
aModel->lefiAntennaModel::antennaAreaMinusDiff());
if (aModel->lefiAntennaModel::hasAntennaAreaDiffReducePWL()) {
pwl = aModel->lefiAntennaModel::antennaAreaDiffReducePWL();
fprintf(fout, " ANTENNAAREADIFFREDUCEPWL ( ");
for (j = 0; j < pwl->lefiAntennaPWL::numPWL(); j++)
fprintf(fout, "( %g %g ) ", pwl->lefiAntennaPWL::PWLdiffusion(j),
pwl->lefiAntennaPWL::PWLratio(j));
fprintf(fout, ") ;\n");
}
}
if (layer->lefiLayer::numAccurrentDensity()) {
for (i = 0; i < layer->lefiLayer::numAccurrentDensity(); i++) {
density = layer->lefiLayer::accurrent(i);
fprintf(fout, " ACCURRENTDENSITY %s", density->type());
if (density->hasOneEntry())
fprintf(fout, " %g ;\n", density->oneEntry());
else {
fprintf(fout, "\n");
if (density->numFrequency()) {
fprintf(fout, " FREQUENCY");
for (j = 0; j < density->numFrequency(); j++)
fprintf(fout, " %g", density->frequency(j));
fprintf(fout, " ;\n");
}
if (density->numCutareas()) {
fprintf(fout, " CUTAREA");
for (j = 0; j < density->numCutareas(); j++)
fprintf(fout, " %g", density->cutArea(j));
fprintf(fout, " ;\n");
}
if (density->numWidths()) {
fprintf(fout, " WIDTH");
for (j = 0; j < density->numWidths(); j++)
fprintf(fout, " %g", density->width(j));
fprintf(fout, " ;\n");
}
if (density->numTableEntries()) {
k = 5;
fprintf(fout, " TABLEENTRIES");
for (j = 0; j < density->numTableEntries(); j++)
if (k > 4) {
fprintf(fout, "\n %g", density->tableEntry(j));
k = 1;
} else {
fprintf(fout, " %g", density->tableEntry(j));
k++;
}
fprintf(fout, " ;\n");
}
}
}
}
if (layer->lefiLayer::numDccurrentDensity()) {
for (i = 0; i < layer->lefiLayer::numDccurrentDensity(); i++) {
density = layer->lefiLayer::dccurrent(i);
fprintf(fout, " DCCURRENTDENSITY %s", density->type());
if (density->hasOneEntry())
fprintf(fout, " %g ;\n", density->oneEntry());
else {
fprintf(fout, "\n");
if (density->numCutareas()) {
fprintf(fout, " CUTAREA");
for (j = 0; j < density->numCutareas(); j++)
fprintf(fout, " %g", density->cutArea(j));
fprintf(fout, " ;\n");
}
if (density->numWidths()) {
fprintf(fout, " WIDTH");
for (j = 0; j < density->numWidths(); j++)
fprintf(fout, " %g", density->width(j));
fprintf(fout, " ;\n");
}
if (density->numTableEntries()) {
fprintf(fout, " TABLEENTRIES");
for (j = 0; j < density->numTableEntries(); j++)
fprintf(fout, " %g", density->tableEntry(j));
fprintf(fout, " ;\n");
}
}
}
}
for (i = 0; i < layer->lefiLayer::numSpacingTable(); i++) {
spTable = layer->lefiLayer::spacingTable(i);
fprintf(fout, " SPACINGTABLE\n");
if (spTable->lefiSpacingTable::isInfluence()) {
influence = spTable->lefiSpacingTable::influence();
fprintf(fout, " INFLUENCE");
for (j = 0; j < influence->lefiInfluence::numInfluenceEntry(); j++) {
fprintf(fout, "\n WIDTH %g WITHIN %g SPACING %g",
influence->lefiInfluence::width(j),
influence->lefiInfluence::distance(j),
influence->lefiInfluence::spacing(j));
}
fprintf(fout, " ;\n");
} else if (spTable->lefiSpacingTable::isParallel()){
parallel = spTable->lefiSpacingTable::parallel();
fprintf(fout, " PARALLELRUNLENGTH");
for (j = 0; j < parallel->lefiParallel::numLength(); j++) {
fprintf(fout, " %g", parallel->lefiParallel::length(j));
}
for (j = 0; j < parallel->lefiParallel::numWidth(); j++) {
fprintf(fout, "\n WIDTH %g",
parallel->lefiParallel::width(j));
for (k = 0; k < parallel->lefiParallel::numLength(); k++) {
fprintf(fout, " %g", parallel->lefiParallel::widthSpacing(j, k));
}
}
fprintf(fout, " ;\n");
} else { // 5.7 TWOWIDTHS
twoWidths = spTable->lefiSpacingTable::twoWidths();
fprintf(fout, " TWOWIDTHS");
for (j = 0; j < twoWidths->lefiTwoWidths::numWidth(); j++) {
fprintf(fout, "\n WIDTH %g ",
twoWidths->lefiTwoWidths::width(j));
if (twoWidths->lefiTwoWidths::hasWidthPRL(j))
fprintf(fout, "PRL %g ", twoWidths->lefiTwoWidths::widthPRL(j));
for (k = 0; k < twoWidths->lefiTwoWidths::numWidthSpacing(j); k++)
fprintf(fout, "%g ",twoWidths->lefiTwoWidths::widthSpacing(j, k));
}
fprintf(fout, " ;\n");
}
}
propNum = layer->lefiLayer::numProps();
if (propNum > 0) {
fprintf(fout, " PROPERTY ");
for (i = 0; i < propNum; i++) {
// value can either be a string or number
fprintf(fout, "%s ", layer->lefiLayer::propName(i));
if (layer->lefiLayer::propIsNumber(i))
fprintf(fout, "%g ", layer->lefiLayer::propNumber(i));
if (layer->lefiLayer::propIsString(i))
fprintf(fout, "%s ", layer->lefiLayer::propValue(i));
pType = layer->lefiLayer::propType(i);
switch (pType) {
case 'R': fprintf(fout, "REAL ");
break;
case 'I': fprintf(fout, "INTEGER ");
break;
case 'S': fprintf(fout, "STRING ");
break;
case 'Q': fprintf(fout, "QUOTESTRING ");
break;
case 'N': fprintf(fout, "NUMBER ");
break;
}
}
fprintf(fout, ";\n");
}
if (layer->lefiLayer::hasDiagMinEdgeLength())
fprintf(fout, " DIAGMINEDGELENGTH %g ;\n",
layer->lefiLayer::diagMinEdgeLength());
if (layer->lefiLayer::numMinSize()) {
fprintf(fout, " MINSIZE ");
for (i = 0; i < layer->lefiLayer::numMinSize(); i++) {
fprintf(fout, "%g %g ", layer->lefiLayer::minSizeWidth(i),
layer->lefiLayer::minSizeLength(i));
}
fprintf(fout, ";\n");
}
fprintf(fout, "END %s\n", layer->lefiLayer::name());
// Set it to case sensitive from here on
lefrSetCaseSensitivity(1);
return 0;
}
int macroBeginCB(lefrCallbackType_e c, const char* macroName, lefiUserData) {
checkType(c);
// if ((long)ud != userData) dataError();
fprintf(fout, "MACRO %s\n", macroName);
return 0;
}
int macroFixedMaskCB(lefrCallbackType_e c, int,
lefiUserData) {
checkType(c);
return 0;
}
int macroClassTypeCB(lefrCallbackType_e c, const char* macroClassType,
lefiUserData) {
checkType(c);
// if ((long)ud != userData) dataError();
fprintf(fout, "MACRO CLASS %s\n", macroClassType);
return 0;
}
int macroOriginCB(lefrCallbackType_e c, lefiNum,
lefiUserData) {
checkType(c);
// if ((long)ud != userData) dataError();
// fprintf(fout, " ORIGIN ( %g %g ) ;\n", macroNum.x, macroNum.y);
return 0;
}
int macroSizeCB(lefrCallbackType_e c, lefiNum,
lefiUserData) {
checkType(c);
// if ((long)ud != userData) dataError();
// fprintf(fout, " SIZE %g BY %g ;\n", macroNum.x, macroNum.y);
return 0;
}
int macroCB(lefrCallbackType_e c, lefiMacro* macro, lefiUserData) {
lefiSitePattern* pattern;
int propNum, i, hasPrtSym = 0;
checkType(c);
// if ((long)ud != userData) dataError();
if (macro->lefiMacro::hasClass())
fprintf(fout, " CLASS %s ;\n", macro->lefiMacro::macroClass());
if (macro->lefiMacro::isFixedMask())
fprintf(fout, " FIXEDMASK ;\n");
if (macro->lefiMacro::hasEEQ())
fprintf(fout, " EEQ %s ;\n", macro->lefiMacro::EEQ());
if (macro->lefiMacro::hasLEQ())
fprintf(fout, " LEQ %s ;\n", macro->lefiMacro::LEQ());
if (macro->lefiMacro::hasSource())
fprintf(fout, " SOURCE %s ;\n", macro->lefiMacro::source());
if (macro->lefiMacro::hasXSymmetry()) {
fprintf(fout, " SYMMETRY X ");
hasPrtSym = 1;
}
if (macro->lefiMacro::hasYSymmetry()) { // print X Y & R90 in one line
if (!hasPrtSym) {
fprintf(fout, " SYMMETRY Y ");
hasPrtSym = 1;
}
else
fprintf(fout, "Y ");
}
if (macro->lefiMacro::has90Symmetry()) {
if (!hasPrtSym) {
fprintf(fout, " SYMMETRY R90 ");
hasPrtSym = 1;
}
else
fprintf(fout, "R90 ");
}
if (hasPrtSym) {
fprintf (fout, ";\n");
hasPrtSym = 0;
}
if (macro->lefiMacro::hasSiteName())
fprintf(fout, " SITE %s ;\n", macro->lefiMacro::siteName());
if (macro->lefiMacro::hasSitePattern()) {
for (i = 0; i < macro->lefiMacro::numSitePattern(); i++ ) {
pattern = macro->lefiMacro::sitePattern(i);
if (pattern->lefiSitePattern::hasStepPattern()) {
fprintf(fout, " SITE %s %g %g %s DO %g BY %g STEP %g %g ;\n",
pattern->lefiSitePattern::name(), pattern->lefiSitePattern::x(),
pattern->lefiSitePattern::y(),
orientStr(pattern->lefiSitePattern::orient()),
pattern->lefiSitePattern::xStart(),
pattern->lefiSitePattern::yStart(),
pattern->lefiSitePattern::xStep(),
pattern->lefiSitePattern::yStep());
} else {
fprintf(fout, " SITE %s %g %g %s ;\n",
pattern->lefiSitePattern::name(), pattern->lefiSitePattern::x(),
pattern->lefiSitePattern::y(),
orientStr(pattern->lefiSitePattern::orient()));
}
}
}
if (macro->lefiMacro::hasSize())
fprintf(fout, " SIZE %g BY %g ;\n", macro->lefiMacro::sizeX(),
macro->lefiMacro::sizeY());
if (macro->lefiMacro::hasForeign()) {
for (i = 0; i < macro->lefiMacro::numForeigns(); i++) {
fprintf(fout, " FOREIGN %s ", macro->lefiMacro::foreignName(i));
if (macro->lefiMacro::hasForeignPoint(i)) {
fprintf(fout, "( %g %g ) ", macro->lefiMacro::foreignX(i),
macro->lefiMacro::foreignY(i));
if (macro->lefiMacro::hasForeignOrient(i))
fprintf(fout, "%s ", macro->lefiMacro::foreignOrientStr(i));
}
fprintf(fout, ";\n");
}
}
if (macro->lefiMacro::hasOrigin())
fprintf(fout, " ORIGIN ( %g %g ) ;\n", macro->lefiMacro::originX(),
macro->lefiMacro::originY());
if (macro->lefiMacro::hasPower())
fprintf(fout, " POWER %g ;\n", macro->lefiMacro::power());
propNum = macro->lefiMacro::numProperties();
if (propNum > 0) {
fprintf(fout, " PROPERTY ");
for (i = 0; i < propNum; i++) {
// value can either be a string or number
if (macro->lefiMacro::propValue(i)) {
fprintf(fout, "%s %s ", macro->lefiMacro::propName(i),
macro->lefiMacro::propValue(i));
}
else
fprintf(fout, "%s %g ", macro->lefiMacro::propName(i),
macro->lefiMacro::propNum(i));
switch (macro->lefiMacro::propType(i)) {
case 'R': fprintf(fout, "REAL ");
break;
case 'I': fprintf(fout, "INTEGER ");
break;
case 'S': fprintf(fout, "STRING ");
break;
case 'Q': fprintf(fout, "QUOTESTRING ");
break;
case 'N': fprintf(fout, "NUMBER ");
break;
}
}
fprintf(fout, ";\n");
}
//fprintf(fout, "END %s\n", macro->lefiMacro::name());
return 0;
}
int macroEndCB(lefrCallbackType_e c, const char* macroName, lefiUserData) {
checkType(c);
// if ((long)ud != userData) dataError();
fprintf(fout, "END %s\n", macroName);
return 0;
}
int manufacturingCB(lefrCallbackType_e c, double num, lefiUserData) {
checkType(c);
// if ((long)ud != userData) dataError();
fprintf(fout, "MANUFACTURINGGRID %g ;\n", num);
return 0;
}
int maxStackViaCB(lefrCallbackType_e c, lefiMaxStackVia* maxStack,
lefiUserData) {
checkType(c);
// if ((long)ud != userData) dataError();
fprintf(fout, "MAXVIASTACK %d ", maxStack->lefiMaxStackVia::maxStackVia());
if (maxStack->lefiMaxStackVia::hasMaxStackViaRange())
fprintf(fout, "RANGE %s %s ",
maxStack->lefiMaxStackVia::maxStackViaBottomLayer(),
maxStack->lefiMaxStackVia::maxStackViaTopLayer());
fprintf(fout, ";\n");
return 0;
}
int minFeatureCB(lefrCallbackType_e c, lefiMinFeature* min, lefiUserData) {
checkType(c);
// if ((long)ud != userData) dataError();
fprintf(fout, "MINFEATURE %g %g ;\n", min->lefiMinFeature::one(),
min->lefiMinFeature::two());
return 0;
}
int nonDefaultCB(lefrCallbackType_e c, lefiNonDefault* def, lefiUserData) {
int i;
lefiVia* via;
lefiSpacing* spacing;
checkType(c);
// if ((long)ud != userData) dataError();
fprintf(fout, "NONDEFAULTRULE %s\n", def->lefiNonDefault::name());
if (def->lefiNonDefault::hasHardspacing())
fprintf(fout, " HARDSPACING ;\n");
for (i = 0; i < def->lefiNonDefault::numLayers(); i++) {
fprintf(fout, " LAYER %s\n", def->lefiNonDefault::layerName(i));
if (def->lefiNonDefault::hasLayerWidth(i))
fprintf(fout, " WIDTH %g ;\n", def->lefiNonDefault::layerWidth(i));
if (def->lefiNonDefault::hasLayerSpacing(i))
fprintf(fout, " SPACING %g ;\n",
def->lefiNonDefault::layerSpacing(i));
if (def->lefiNonDefault::hasLayerDiagWidth(i))
fprintf(fout, " DIAGWIDTH %g ;\n",
def->lefiNonDefault::layerDiagWidth(i));
if (def->lefiNonDefault::hasLayerWireExtension(i))
fprintf(fout, " WIREEXTENSION %g ;\n",
def->lefiNonDefault::layerWireExtension(i));
if (def->lefiNonDefault::hasLayerResistance(i))
fprintf(fout, " RESISTANCE RPERSQ %g ;\n",
def->lefiNonDefault::layerResistance(i));
if (def->lefiNonDefault::hasLayerCapacitance(i))
fprintf(fout, " CAPACITANCE CPERSQDIST %g ;\n",
def->lefiNonDefault::layerCapacitance(i));
if (def->lefiNonDefault::hasLayerEdgeCap(i))
fprintf(fout, " EDGECAPACITANCE %g ;\n",
def->lefiNonDefault::layerEdgeCap(i));
fprintf(fout, " END %s\n", def->lefiNonDefault::layerName(i));
}
// handle via in nondefaultrule
for (i = 0; i < def->lefiNonDefault::numVias(); i++) {
via = def->lefiNonDefault::viaRule(i);
lefVia(via);
}
// handle spacing in nondefaultrule
for (i = 0; i < def->lefiNonDefault::numSpacingRules(); i++) {
spacing = def->lefiNonDefault::spacingRule(i);
lefSpacing(spacing);
}
// handle usevia
for (i = 0; i < def->lefiNonDefault::numUseVia(); i++)
fprintf(fout, " USEVIA %s ;\n", def->lefiNonDefault::viaName(i));
// handle useviarule
for (i = 0; i < def->lefiNonDefault::numUseViaRule(); i++)
fprintf(fout, " USEVIARULE %s ;\n",
def->lefiNonDefault::viaRuleName(i));
// handle mincuts
for (i = 0; i < def->lefiNonDefault::numMinCuts(); i++) {
fprintf(fout, " MINCUTS %s %d ;\n", def->lefiNonDefault::cutLayerName(i),
def->lefiNonDefault::numCuts(i));
}
// handle property in nondefaultrule
if (def->lefiNonDefault::numProps() > 0) {
fprintf(fout, " PROPERTY ");
for (i = 0; i < def->lefiNonDefault::numProps(); i++) {
fprintf(fout, "%s ", def->lefiNonDefault::propName(i));
if (def->lefiNonDefault::propIsNumber(i))
fprintf(fout, "%g ", def->lefiNonDefault::propNumber(i));
if (def->lefiNonDefault::propIsString(i))
fprintf(fout, "%s ", def->lefiNonDefault::propValue(i));
switch(def->lefiNonDefault::propType(i)) {
case 'R': fprintf(fout, "REAL ");
break;
case 'I': fprintf(fout, "INTEGER ");
break;
case 'S': fprintf(fout, "STRING ");
break;
case 'Q': fprintf(fout, "QUOTESTRING ");
break;
case 'N': fprintf(fout, "NUMBER ");
break;
}
}
fprintf(fout, ";\n");
}
fprintf(fout, "END %s ;\n", def->lefiNonDefault::name());
return 0;
}
int obstructionCB(lefrCallbackType_e c, lefiObstruction* obs,
lefiUserData) {
lefiGeometries* geometry;
checkType(c);
// if ((long)ud != userData) dataError();
fprintf(fout, " OBS\n");
geometry = obs->lefiObstruction::geometries();
prtGeometry(geometry);
fprintf(fout, " END\n");
return 0;
}
int pinCB(lefrCallbackType_e c, lefiPin* pin, lefiUserData) {
int numPorts, i, j;
lefiGeometries* geometry;
lefiPinAntennaModel* aModel;
checkType(c);
// if ((long)ud != userData) dataError();
fprintf(fout, " PIN %s\n", pin->lefiPin::name());
if (pin->lefiPin::hasForeign()) {
for (i = 0; i < pin->lefiPin::numForeigns(); i++) {
if (pin->lefiPin::hasForeignOrient(i))
fprintf(fout, " FOREIGN %s STRUCTURE ( %g %g ) %s ;\n",
pin->lefiPin::foreignName(i), pin->lefiPin::foreignX(i),
pin->lefiPin::foreignY(i),
pin->lefiPin::foreignOrientStr(i));
else if (pin->lefiPin::hasForeignPoint(i))
fprintf(fout, " FOREIGN %s STRUCTURE ( %g %g ) ;\n",
pin->lefiPin::foreignName(i), pin->lefiPin::foreignX(i),
pin->lefiPin::foreignY(i));
else
fprintf(fout, " FOREIGN %s ;\n", pin->lefiPin::foreignName(i));
}
}
if (pin->lefiPin::hasLEQ())
fprintf(fout, " LEQ %s ;\n", pin->lefiPin::LEQ());
if (pin->lefiPin::hasDirection())
fprintf(fout, " DIRECTION %s ;\n", pin->lefiPin::direction());
if (pin->lefiPin::hasUse())
fprintf(fout, " USE %s ;\n", pin->lefiPin::use());
if (pin->lefiPin::hasShape())
fprintf(fout, " SHAPE %s ;\n", pin->lefiPin::shape());
if (pin->lefiPin::hasMustjoin())
fprintf(fout, " MUSTJOIN %s ;\n", pin->lefiPin::mustjoin());
if (pin->lefiPin::hasOutMargin())
fprintf(fout, " OUTPUTNOISEMARGIN %g %g ;\n",
pin->lefiPin::outMarginHigh(), pin->lefiPin::outMarginLow());
if (pin->lefiPin::hasOutResistance())
fprintf(fout, " OUTPUTRESISTANCE %g %g ;\n",
pin->lefiPin::outResistanceHigh(),
pin->lefiPin::outResistanceLow());
if (pin->lefiPin::hasInMargin())
fprintf(fout, " INPUTNOISEMARGIN %g %g ;\n",
pin->lefiPin::inMarginHigh(), pin->lefiPin::inMarginLow());
if (pin->lefiPin::hasPower())
fprintf(fout, " POWER %g ;\n", pin->lefiPin::power());
if (pin->lefiPin::hasLeakage())
fprintf(fout, " LEAKAGE %g ;\n", pin->lefiPin::leakage());
if (pin->lefiPin::hasMaxload())
fprintf(fout, " MAXLOAD %g ;\n", pin->lefiPin::maxload());
if (pin->lefiPin::hasCapacitance())
fprintf(fout, " CAPACITANCE %g ;\n", pin->lefiPin::capacitance());
if (pin->lefiPin::hasResistance())
fprintf(fout, " RESISTANCE %g ;\n", pin->lefiPin::resistance());
if (pin->lefiPin::hasPulldownres())
fprintf(fout, " PULLDOWNRES %g ;\n", pin->lefiPin::pulldownres());
if (pin->lefiPin::hasTieoffr())
fprintf(fout, " TIEOFFR %g ;\n", pin->lefiPin::tieoffr());
if (pin->lefiPin::hasVHI())
fprintf(fout, " VHI %g ;\n", pin->lefiPin::VHI());
if (pin->lefiPin::hasVLO())
fprintf(fout, " VLO %g ;\n", pin->lefiPin::VLO());
if (pin->lefiPin::hasRiseVoltage())
fprintf(fout, " RISEVOLTAGETHRESHOLD %g ;\n",
pin->lefiPin::riseVoltage());
if (pin->lefiPin::hasFallVoltage())
fprintf(fout, " FALLVOLTAGETHRESHOLD %g ;\n",
pin->lefiPin::fallVoltage());
if (pin->lefiPin::hasRiseThresh())
fprintf(fout, " RISETHRESH %g ;\n", pin->lefiPin::riseThresh());
if (pin->lefiPin::hasFallThresh())
fprintf(fout, " FALLTHRESH %g ;\n", pin->lefiPin::fallThresh());
if (pin->lefiPin::hasRiseSatcur())
fprintf(fout, " RISESATCUR %g ;\n", pin->lefiPin::riseSatcur());
if (pin->lefiPin::hasFallSatcur())
fprintf(fout, " FALLSATCUR %g ;\n", pin->lefiPin::fallSatcur());
if (pin->lefiPin::hasRiseSlewLimit())
fprintf(fout, " RISESLEWLIMIT %g ;\n", pin->lefiPin::riseSlewLimit());
if (pin->lefiPin::hasFallSlewLimit())
fprintf(fout, " FALLSLEWLIMIT %g ;\n", pin->lefiPin::fallSlewLimit());
if (pin->lefiPin::hasCurrentSource())
fprintf(fout, " CURRENTSOURCE %s ;\n", pin->lefiPin::currentSource());
if (pin->lefiPin::hasTables())
fprintf(fout, " IV_TABLES %s %s ;\n", pin->lefiPin::tableHighName(),
pin->lefiPin::tableLowName());
if (pin->lefiPin::hasTaperRule())
fprintf(fout, " TAPERRULE %s ;\n", pin->lefiPin::taperRule());
if (pin->lefiPin::hasNetExpr())
fprintf(fout, " NETEXPR \"%s\" ;\n", pin->lefiPin::netExpr());
if (pin->lefiPin::hasSupplySensitivity())
fprintf(fout, " SUPPLYSENSITIVITY %s ;\n",
pin->lefiPin::supplySensitivity());
if (pin->lefiPin::hasGroundSensitivity())
fprintf(fout, " GROUNDSENSITIVITY %s ;\n",
pin->lefiPin::groundSensitivity());
if (pin->lefiPin::hasAntennaSize()) {
for (i = 0; i < pin->lefiPin::numAntennaSize(); i++) {
fprintf(fout, " ANTENNASIZE %g ", pin->lefiPin::antennaSize(i));
if (pin->lefiPin::antennaSizeLayer(i))
fprintf(fout, "LAYER %s ", pin->lefiPin::antennaSizeLayer(i));
fprintf(fout, ";\n");
}
}
if (pin->lefiPin::hasAntennaMetalArea()) {
for (i = 0; i < pin->lefiPin::numAntennaMetalArea(); i++) {
fprintf(fout, " ANTENNAMETALAREA %g ",
pin->lefiPin::antennaMetalArea(i));
if (pin->lefiPin::antennaMetalAreaLayer(i))
fprintf(fout, "LAYER %s ", pin->lefiPin::antennaMetalAreaLayer(i));
fprintf(fout, ";\n");
}
}
if (pin->lefiPin::hasAntennaMetalLength()) {
for (i = 0; i < pin->lefiPin::numAntennaMetalLength(); i++) {
fprintf(fout, " ANTENNAMETALLENGTH %g ",
pin->lefiPin::antennaMetalLength(i));
if (pin->lefiPin::antennaMetalLengthLayer(i))
fprintf(fout, "LAYER %s ", pin->lefiPin::antennaMetalLengthLayer(i));
fprintf(fout, ";\n");
}
}
if (pin->lefiPin::hasAntennaPartialMetalArea()) {
for (i = 0; i < pin->lefiPin::numAntennaPartialMetalArea(); i++) {
fprintf(fout, " ANTENNAPARTIALMETALAREA %g ",
pin->lefiPin::antennaPartialMetalArea(i));
if (pin->lefiPin::antennaPartialMetalAreaLayer(i))
fprintf(fout, "LAYER %s ",
pin->lefiPin::antennaPartialMetalAreaLayer(i));
fprintf(fout, ";\n");
}
}
if (pin->lefiPin::hasAntennaPartialMetalSideArea()) {
for (i = 0; i < pin->lefiPin::numAntennaPartialMetalSideArea(); i++) {
fprintf(fout, " ANTENNAPARTIALMETALSIDEAREA %g ",
pin->lefiPin::antennaPartialMetalSideArea(i));
if (pin->lefiPin::antennaPartialMetalSideAreaLayer(i))
fprintf(fout, "LAYER %s ",
pin->lefiPin::antennaPartialMetalSideAreaLayer(i));
fprintf(fout, ";\n");
}
}
if (pin->lefiPin::hasAntennaPartialCutArea()) {
for (i = 0; i < pin->lefiPin::numAntennaPartialCutArea(); i++) {
fprintf(fout, " ANTENNAPARTIALCUTAREA %g ",
pin->lefiPin::antennaPartialCutArea(i));
if (pin->lefiPin::antennaPartialCutAreaLayer(i))
fprintf(fout, "LAYER %s ",
pin->lefiPin::antennaPartialCutAreaLayer(i));
fprintf(fout, ";\n");
}
}
if (pin->lefiPin::hasAntennaDiffArea()) {
for (i = 0; i < pin->lefiPin::numAntennaDiffArea(); i++) {
fprintf(fout, " ANTENNADIFFAREA %g ",
pin->lefiPin::antennaDiffArea(i));
if (pin->lefiPin::antennaDiffAreaLayer(i))
fprintf(fout, "LAYER %s ", pin->lefiPin::antennaDiffAreaLayer(i));
fprintf(fout, ";\n");
}
}
for (j = 0; j < pin->lefiPin::numAntennaModel(); j++) {
aModel = pin->lefiPin::antennaModel(j);
fprintf(fout, " ANTENNAMODEL %s ;\n",
aModel->lefiPinAntennaModel::antennaOxide());
if (aModel->lefiPinAntennaModel::hasAntennaGateArea()) {
for (i = 0; i < aModel->lefiPinAntennaModel::numAntennaGateArea(); i++)
{
fprintf(fout, " ANTENNAGATEAREA %g ",
aModel->lefiPinAntennaModel::antennaGateArea(i));
if (aModel->lefiPinAntennaModel::antennaGateAreaLayer(i))
fprintf(fout, "LAYER %s ",
aModel->lefiPinAntennaModel::antennaGateAreaLayer(i));
fprintf(fout, ";\n");
}
}
if (aModel->lefiPinAntennaModel::hasAntennaMaxAreaCar()) {
for (i = 0; i < aModel->lefiPinAntennaModel::numAntennaMaxAreaCar();
i++) {
fprintf(fout, " ANTENNAMAXAREACAR %g ",
aModel->lefiPinAntennaModel::antennaMaxAreaCar(i));
if (aModel->lefiPinAntennaModel::antennaMaxAreaCarLayer(i))
fprintf(fout, "LAYER %s ",
aModel->lefiPinAntennaModel::antennaMaxAreaCarLayer(i));
fprintf(fout, ";\n");
}
}
if (aModel->lefiPinAntennaModel::hasAntennaMaxSideAreaCar()) {
for (i = 0; i < aModel->lefiPinAntennaModel::numAntennaMaxSideAreaCar();
i++) {
fprintf(fout, " ANTENNAMAXSIDEAREACAR %g ",
aModel->lefiPinAntennaModel::antennaMaxSideAreaCar(i));
if (aModel->lefiPinAntennaModel::antennaMaxSideAreaCarLayer(i))
fprintf(fout, "LAYER %s ",
aModel->lefiPinAntennaModel::antennaMaxSideAreaCarLayer(i));
fprintf(fout, ";\n");
}
}
if (aModel->lefiPinAntennaModel::hasAntennaMaxCutCar()) {
for (i = 0; i < aModel->lefiPinAntennaModel::numAntennaMaxCutCar(); i++)
{
fprintf(fout, " ANTENNAMAXCUTCAR %g ",
aModel->lefiPinAntennaModel::antennaMaxCutCar(i));
if (aModel->lefiPinAntennaModel::antennaMaxCutCarLayer(i))
fprintf(fout, "LAYER %s ",
aModel->lefiPinAntennaModel::antennaMaxCutCarLayer(i));
fprintf(fout, ";\n");
}
}
}
if (pin->lefiPin::numProperties() > 0) {
fprintf(fout, " PROPERTY ");
for (i = 0; i < pin->lefiPin::numProperties(); i++) {
// value can either be a string or number
if (pin->lefiPin::propValue(i)) {
fprintf(fout, "%s %s ", pin->lefiPin::propName(i),
pin->lefiPin::propValue(i));
}
else
fprintf(fout, "%s %g ", pin->lefiPin::propName(i),
pin->lefiPin::propNum(i));
switch (pin->lefiPin::propType(i)) {
case 'R': fprintf(fout, "REAL ");
break;
case 'I': fprintf(fout, "INTEGER ");
break;
case 'S': fprintf(fout, "STRING ");
break;
case 'Q': fprintf(fout, "QUOTESTRING ");
break;
case 'N': fprintf(fout, "NUMBER ");
break;
}
}
fprintf(fout, ";\n");
}
numPorts = pin->lefiPin::numPorts();
for (i = 0; i < numPorts; i++) {
fprintf(fout," PORT\n");
geometry = pin->lefiPin::port(i);
prtGeometry(geometry);
fprintf(fout, " END\n");
}
fprintf(fout, " END %s\n", pin->lefiPin::name());
return 0;
}
int densityCB(lefrCallbackType_e c, lefiDensity* density,
lefiUserData) {
struct lefiGeomRect rect;
checkType(c);
// if ((long)ud != userData) dataError();
fprintf(fout, " DENSITY\n");
for (int i = 0; i < density->lefiDensity::numLayer(); i++) {
fprintf(fout, " LAYER %s ;\n", density->lefiDensity::layerName(i));
for (int j = 0; j < density->lefiDensity::numRects(i); j++) {
rect = density->lefiDensity::getRect(i,j);
fprintf(fout, " RECT %g %g %g %g ", rect.xl, rect.yl, rect.xh,
rect.yh);
fprintf(fout, "%g ;\n", density->lefiDensity::densityValue(i,j));
}
}
fprintf(fout, " END\n");
return 0;
}
int propDefBeginCB(lefrCallbackType_e c, void*, lefiUserData) {
checkType(c);
// if ((long)ud != userData) dataError();
fprintf(fout, "PROPERTYDEFINITIONS\n");
return 0;
}
int propDefCB(lefrCallbackType_e c, lefiProp* prop, lefiUserData) {
checkType(c);
// if ((long)ud != userData) dataError();
fprintf(fout, " %s %s", prop->lefiProp::propType(),
prop->lefiProp::propName());
switch(prop->lefiProp::dataType()) {
case 'I':
fprintf(fout, " INTEGER");
break;
case 'R':
fprintf(fout, " REAL");
break;
case 'S':
fprintf(fout, " STRING");
break;
}
if (prop->lefiProp::hasNumber())
fprintf(fout, " %g", prop->lefiProp::number());
if (prop->lefiProp::hasRange())
fprintf(fout, " RANGE %g %g", prop->lefiProp::left(),
prop->lefiProp::right());
if (prop->lefiProp::hasString())
fprintf(fout, " %s", prop->lefiProp::string());
fprintf(fout, "\n");
return 0;
}
int propDefEndCB(lefrCallbackType_e c, void*, lefiUserData) {
checkType(c);
// if ((long)ud != userData) dataError();
fprintf(fout, "END PROPERTYDEFINITIONS\n");
return 0;
}
int siteCB(lefrCallbackType_e c, lefiSite* site, lefiUserData) {
int hasPrtSym = 0;
int i;
checkType(c);
// if ((long)ud != userData) dataError();
fprintf(fout, "SITE %s\n", site->lefiSite::name());
if (site->lefiSite::hasClass())
fprintf(fout, " CLASS %s ;\n", site->lefiSite::siteClass());
if (site->lefiSite::hasXSymmetry()) {
fprintf(fout, " SYMMETRY X ");
hasPrtSym = 1;
}
if (site->lefiSite::hasYSymmetry()) {
if (hasPrtSym)
fprintf(fout, "Y ");
else {
fprintf(fout, " SYMMETRY Y ");
hasPrtSym = 1;
}
}
if (site->lefiSite::has90Symmetry()) {
if (hasPrtSym)
fprintf(fout, "R90 ");
else {
fprintf(fout, " SYMMETRY R90 ");
hasPrtSym = 1;
}
}
if (hasPrtSym)
fprintf(fout, ";\n");
if (site->lefiSite::hasSize())
fprintf(fout, " SIZE %g BY %g ;\n", site->lefiSite::sizeX(),
site->lefiSite::sizeY());
if (site->hasRowPattern()) {
fprintf(fout, " ROWPATTERN ");
for (i = 0; i < site->lefiSite::numSites(); i++)
fprintf(fout, " %s %s ", site->lefiSite::siteName(i),
site->lefiSite::siteOrientStr(i));
fprintf(fout, ";\n");
}
fprintf(fout, "END %s\n", site->lefiSite::name());
return 0;
}
int spacingBeginCB(lefrCallbackType_e c, void*, lefiUserData){
checkType(c);
// if ((long)ud != userData) dataError();
fprintf(fout, "SPACING\n");
return 0;
}
int spacingCB(lefrCallbackType_e c, lefiSpacing* spacing, lefiUserData) {
checkType(c);
// if ((long)ud != userData) dataError();
lefSpacing(spacing);
return 0;
}
int spacingEndCB(lefrCallbackType_e c, void*, lefiUserData){
checkType(c);
// if ((long)ud != userData) dataError();
fprintf(fout, "END SPACING\n");
return 0;
}
int timingCB(lefrCallbackType_e c, lefiTiming* timing, lefiUserData) {
int i;
checkType(c);
// if ((long)ud != userData) dataError();
fprintf(fout, "TIMING\n");
for (i = 0; i < timing->numFromPins(); i++)
fprintf(fout, " FROMPIN %s ;\n", timing->fromPin(i));
for (i = 0; i < timing->numToPins(); i++)
fprintf(fout, " TOPIN %s ;\n", timing->toPin(i));
fprintf(fout, " RISE SLEW1 %g %g %g %g ;\n", timing->riseSlewOne(),
timing->riseSlewTwo(), timing->riseSlewThree(),
timing->riseSlewFour());
if (timing->hasRiseSlew2())
fprintf(fout, " RISE SLEW2 %g %g %g ;\n", timing->riseSlewFive(),
timing->riseSlewSix(), timing->riseSlewSeven());
if (timing->hasFallSlew())
fprintf(fout, " FALL SLEW1 %g %g %g %g ;\n", timing->fallSlewOne(),
timing->fallSlewTwo(), timing->fallSlewThree(),
timing->fallSlewFour());
if (timing->hasFallSlew2())
fprintf(fout, " FALL SLEW2 %g %g %g ;\n", timing->fallSlewFive(),
timing->fallSlewSix(), timing->riseSlewSeven());
if (timing->hasRiseIntrinsic()) {
fprintf(fout, "TIMING RISE INTRINSIC %g %g ;\n",
timing->riseIntrinsicOne(), timing->riseIntrinsicTwo());
fprintf(fout, "TIMING RISE VARIABLE %g %g ;\n",
timing->riseIntrinsicThree(), timing->riseIntrinsicFour());
}
if (timing->hasFallIntrinsic()) {
fprintf(fout, "TIMING FALL INTRINSIC %g %g ;\n",
timing->fallIntrinsicOne(), timing->fallIntrinsicTwo());
fprintf(fout, "TIMING RISE VARIABLE %g %g ;\n",
timing->fallIntrinsicThree(), timing->fallIntrinsicFour());
}
if (timing->hasRiseRS())
fprintf(fout, "TIMING RISERS %g %g ;\n",
timing->riseRSOne(), timing->riseRSTwo());
if (timing->hasRiseCS())
fprintf(fout, "TIMING RISECS %g %g ;\n",
timing->riseCSOne(), timing->riseCSTwo());
if (timing->hasFallRS())
fprintf(fout, "TIMING FALLRS %g %g ;\n",
timing->fallRSOne(), timing->fallRSTwo());
if (timing->hasFallCS())
fprintf(fout, "TIMING FALLCS %g %g ;\n",
timing->fallCSOne(), timing->fallCSTwo());
if (timing->hasUnateness())
fprintf(fout, "TIMING UNATENESS %s ;\n", timing->unateness());
if (timing->hasRiseAtt1())
fprintf(fout, "TIMING RISESATT1 %g %g ;\n", timing->riseAtt1One(),
timing->riseAtt1Two());
if (timing->hasFallAtt1())
fprintf(fout, "TIMING FALLSATT1 %g %g ;\n", timing->fallAtt1One(),
timing->fallAtt1Two());
if (timing->hasRiseTo())
fprintf(fout, "TIMING RISET0 %g %g ;\n", timing->riseToOne(),
timing->riseToTwo());
if (timing->hasFallTo())
fprintf(fout, "TIMING FALLT0 %g %g ;\n", timing->fallToOne(),
timing->fallToTwo());
if (timing->hasSDFonePinTrigger())
fprintf(fout, " %s TABLEDIMENSION %g %g %g ;\n",
timing->SDFonePinTriggerType(), timing->SDFtriggerOne(),
timing->SDFtriggerTwo(), timing->SDFtriggerThree());
if (timing->hasSDFtwoPinTrigger())
fprintf(fout, " %s %s %s TABLEDIMENSION %g %g %g ;\n",
timing->SDFtwoPinTriggerType(), timing->SDFfromTrigger(),
timing->SDFtoTrigger(), timing->SDFtriggerOne(),
timing->SDFtriggerTwo(), timing->SDFtriggerThree());
fprintf(fout, "END TIMING\n");
return 0;
}
int unitsCB(lefrCallbackType_e c, lefiUnits* unit, lefiUserData) {
checkType(c);
// if ((long)ud != userData) dataError();
fprintf(fout, "UNITS\n");
if (unit->lefiUnits::hasDatabase())
fprintf(fout, " DATABASE %s %g ;\n", unit->lefiUnits::databaseName(),
unit->lefiUnits::databaseNumber());
if (unit->lefiUnits::hasCapacitance())
fprintf(fout, " CAPACITANCE PICOFARADS %g ;\n",
unit->lefiUnits::capacitance());
if (unit->lefiUnits::hasResistance())
fprintf(fout, " RESISTANCE OHMS %g ;\n", unit->lefiUnits::resistance());
if (unit->lefiUnits::hasPower())
fprintf(fout, " POWER MILLIWATTS %g ;\n", unit->lefiUnits::power());
if (unit->lefiUnits::hasCurrent())
fprintf(fout, " CURRENT MILLIAMPS %g ;\n", unit->lefiUnits::current());
if (unit->lefiUnits::hasVoltage())
fprintf(fout, " VOLTAGE VOLTS %g ;\n", unit->lefiUnits::voltage());
if (unit->lefiUnits::hasFrequency())
fprintf(fout, " FREQUENCY MEGAHERTZ %g ;\n",
unit->lefiUnits::frequency());
fprintf(fout, "END UNITS\n");
return 0;
}
int useMinSpacingCB(lefrCallbackType_e c, lefiUseMinSpacing* spacing,
lefiUserData) {
checkType(c);
// if ((long)ud != userData) dataError();
fprintf(fout, "USEMINSPACING %s ", spacing->lefiUseMinSpacing::name());
if (spacing->lefiUseMinSpacing::value())
fprintf(fout, "ON ;\n");
else
fprintf(fout, "OFF ;\n");
return 0;
}
int versionCB(lefrCallbackType_e c, double num, lefiUserData) {
checkType(c);
// if ((long)ud != userData) dataError();
fprintf(fout, "VERSION %g ;\n", num);
return 0;
}
int versionStrCB(lefrCallbackType_e c, const char* versionName, lefiUserData) {
checkType(c);
// if ((long)ud != userData) dataError();
fprintf(fout, "VERSION %s ;\n", versionName);
return 0;
}
int viaCB(lefrCallbackType_e c, lefiVia* via, lefiUserData) {
checkType(c);
// if ((long)ud != userData) dataError();
lefVia(via);
return 0;
}
int viaRuleCB(lefrCallbackType_e c, lefiViaRule* viaRule, lefiUserData) {
int numLayers, numVias, i;
lefiViaRuleLayer* vLayer;
checkType(c);
// if ((long)ud != userData) dataError();
fprintf(fout, "VIARULE %s", viaRule->lefiViaRule::name());
if (viaRule->lefiViaRule::hasGenerate())
fprintf(fout, " GENERATE");
if (viaRule->lefiViaRule::hasDefault())
fprintf(fout, " DEFAULT");
fprintf(fout, "\n");
numLayers = viaRule->lefiViaRule::numLayers();
// if numLayers == 2, it is VIARULE without GENERATE and has via name
// if numLayers == 3, it is VIARULE with GENERATE, and the 3rd layer is cut
for (i = 0; i < numLayers; i++) {
vLayer = viaRule->lefiViaRule::layer(i);
lefViaRuleLayer(vLayer);
}
if (numLayers == 2 && !(viaRule->lefiViaRule::hasGenerate())) {
// should have vianames
numVias = viaRule->lefiViaRule::numVias();
if (numVias == 0)
fprintf(fout, "Should have via names in VIARULE.\n");
else {
for (i = 0; i < numVias; i++)
fprintf(fout, " VIA %s ;\n", viaRule->lefiViaRule::viaName(i));
}
}
if (viaRule->lefiViaRule::numProps() > 0) {
fprintf(fout, " PROPERTY ");
for (i = 0; i < viaRule->lefiViaRule::numProps(); i++) {
fprintf(fout, "%s ", viaRule->lefiViaRule::propName(i));
if (viaRule->lefiViaRule::propValue(i))
fprintf(fout, "%s ", viaRule->lefiViaRule::propValue(i));
switch (viaRule->lefiViaRule::propType(i)) {
case 'R': fprintf(fout, "REAL ");
break;
case 'I': fprintf(fout, "INTEGER ");
break;
case 'S': fprintf(fout, "STRING ");
break;
case 'Q': fprintf(fout, "QUOTESTRING ");
break;
case 'N': fprintf(fout, "NUMBER ");
break;
}
}
fprintf(fout, ";\n");
}
fprintf(fout, "END %s\n", viaRule->lefiViaRule::name());
return 0;
}
int extensionCB(lefrCallbackType_e c, const char* extsn, lefiUserData) {
checkType(c);
// lefrSetCaseSensitivity(0);
// if ((long)ud != userData) dataError();
fprintf(fout, "BEGINEXT %s ;\n", extsn);
// lefrSetCaseSensitivity(1);
return 0;
}
int doneCB(lefrCallbackType_e c, void*, lefiUserData) {
checkType(c);
// if ((long)ud != userData) dataError();
fprintf(fout, "END LIBRARY\n");
return 0;
}
void errorCB(const char* msg) {
printf ("%s : %s\n", lefrGetUserData(), msg);
}
void warningCB(const char* msg) {
printf ("%s : %s\n", lefrGetUserData(), msg);
}
void* mallocCB(int size) {
return malloc(size);
}
void* reallocCB(void* name, int size) {
return realloc(name, size);
}
void freeCB(void* name) {
free(name);
return;
}
void lineNumberCB(int lineNo) {
fprintf(fout, "Parsed %d number of lines!!\n", lineNo);
return;
}
void printWarning(const char *str)
{
fprintf(stderr, "%s\n", str);
}
int
main(int argc, char** argv) {
char* inFile[100];
char* outFile;
FILE* f;
int res;
int noCalls = 0;
// long start_mem;
int num;
int status;
int retStr = 0;
int numInFile = 0;
int fileCt = 0;
int relax = 0;
const char* version = "N/A";
int setVer = 0;
char* userData;
int msgCb = 0;
int test1 = 0;
int test2 = 0;
int ccr749853 = 0;
int ccr1688946 = 0;
int ccr1709089 = 0;
int verbose = 0;
// start_mem = (long)sbrk(0);
userData = strdup ("(lefrw-5100)");
strcpy(defaultName,"lef.in");
strcpy(defaultOut,"list");
inFile[0] = defaultName;
outFile = defaultOut;
fout = stdout;
// userData = 0x01020304;
#ifdef WIN32
// Enable two-digit exponent format
_set_output_format(_TWO_DIGIT_EXPONENT);
#endif
argc--;
argv++;
while (argc--) {
if (strcmp(*argv, "-d") == 0) {
argv++;
argc--;
sscanf(*argv, "%d", &num);
lefiSetDebug(num, 1);
}else if (strcmp(*argv, "-nc") == 0) {
noCalls = 1;
} else if (strcmp(*argv, "-p") == 0) {
printing = 1;
} else if (strcmp(*argv, "-m") == 0) { // use the user error/warning CB
msgCb = 1;
} else if (strcmp(*argv, "-o") == 0) {
argv++;
argc--;
outFile = *argv;
if ((fout = fopen(outFile, "w")) == 0) {
fprintf(stderr, "ERROR: could not open output file\n");
return 2;
}
} else if (strcmp(*argv, "-verStr") == 0) {
/* New to set the version callback routine to return a string */
/* instead of double. */
retStr = 1;
} else if (strcmp(*argv, "-relax") == 0) {
relax = 1;
} else if (strcmp(*argv, "-65nm") == 0) {
parse65nm = 1;
} else if (strcmp(*argv, "-lef58") == 0) {
parseLef58Type = 1;
} else if (strcmp(*argv, "-ver") == 0) {
argv++;
argc--;
setVer = 1;
version = *argv;
} else if (strcmp(*argv, "-test1") == 0) {
test1 = 1;
} else if (strcmp(*argv, "-test2") == 0) {
test2 = 1;
} else if (strcmp(*argv, "-sessionless") == 0) {
isSessionles = 1;
} else if (strcmp(*argv, "-ccr749853") == 0) {
ccr749853 = 1;
} else if (strcmp(*argv, "-ccr1688946") == 0) {
ccr1688946 = 1;
} else if (strcmp(*argv, "-ccr1709089") == 0) {
ccr1709089 = 1;
} else if (argv[0][0] != '-') {
if (numInFile >= 100) {
fprintf(stderr, "ERROR: too many input files, max = 3.\n");
return 2;
}
inFile[numInFile++] = *argv;
} else {
fprintf(stderr, "ERROR: Illegal command line option: '%s'\n", *argv);
return 2;
}
argv++;
}
// sets the parser to be case sensitive...
// default was supposed to be the case but false...
// lefrSetCaseSensitivity(true);
if (isSessionles) {
lefrSetOpenLogFileAppend();
}
lefrInitSession(isSessionles ? 0 : 1);
if (noCalls == 0) {
lefrSetWarningLogFunction(printWarning);
lefrSetAntennaInputCbk(antennaCB);
lefrSetAntennaInoutCbk(antennaCB);
lefrSetAntennaOutputCbk(antennaCB);
lefrSetArrayBeginCbk(arrayBeginCB);
lefrSetArrayCbk(arrayCB);
lefrSetArrayEndCbk(arrayEndCB);
lefrSetBusBitCharsCbk(busBitCharsCB);
lefrSetCaseSensitiveCbk(caseSensCB);
lefrSetFixedMaskCbk(fixedMaskCB);
lefrSetClearanceMeasureCbk(clearanceCB);
lefrSetDensityCbk(densityCB);
lefrSetDividerCharCbk(dividerCB);
lefrSetNoWireExtensionCbk(noWireExtCB);
lefrSetNoiseMarginCbk(noiseMarCB);
lefrSetEdgeRateThreshold1Cbk(edge1CB);
lefrSetEdgeRateThreshold2Cbk(edge2CB);
lefrSetEdgeRateScaleFactorCbk(edgeScaleCB);
lefrSetExtensionCbk(extensionCB);
lefrSetNoiseTableCbk(noiseTableCB);
lefrSetCorrectionTableCbk(correctionCB);
lefrSetDielectricCbk(dielectricCB);
lefrSetIRDropBeginCbk(irdropBeginCB);
lefrSetIRDropCbk(irdropCB);
lefrSetIRDropEndCbk(irdropEndCB);
lefrSetLayerCbk(layerCB);
lefrSetLibraryEndCbk(doneCB);
lefrSetMacroBeginCbk(macroBeginCB);
lefrSetMacroCbk(macroCB);
lefrSetMacroClassTypeCbk(macroClassTypeCB);
lefrSetMacroOriginCbk(macroOriginCB);
lefrSetMacroSizeCbk(macroSizeCB);
lefrSetMacroFixedMaskCbk(macroFixedMaskCB);
lefrSetMacroEndCbk(macroEndCB);
lefrSetManufacturingCbk(manufacturingCB);
lefrSetMaxStackViaCbk(maxStackViaCB);
lefrSetMinFeatureCbk(minFeatureCB);
lefrSetNonDefaultCbk(nonDefaultCB);
lefrSetObstructionCbk(obstructionCB);
lefrSetPinCbk(pinCB);
lefrSetPropBeginCbk(propDefBeginCB);
lefrSetPropCbk(propDefCB);
lefrSetPropEndCbk(propDefEndCB);
lefrSetSiteCbk(siteCB);
lefrSetSpacingBeginCbk(spacingBeginCB);
lefrSetSpacingCbk(spacingCB);
lefrSetSpacingEndCbk(spacingEndCB);
lefrSetTimingCbk(timingCB);
lefrSetUnitsCbk(unitsCB);
lefrSetUseMinSpacingCbk(useMinSpacingCB);
lefrSetUserData((void*)3);
if (!retStr)
lefrSetVersionCbk(versionCB);
else
lefrSetVersionStrCbk(versionStrCB);
lefrSetViaCbk(viaCB);
lefrSetViaRuleCbk(viaRuleCB);
lefrSetInputAntennaCbk(antennaCB);
lefrSetOutputAntennaCbk(antennaCB);
lefrSetInoutAntennaCbk(antennaCB);
if (msgCb) {
lefrSetLogFunction(errorCB);
lefrSetWarningLogFunction(warningCB);
}
lefrSetMallocFunction(mallocCB);
lefrSetReallocFunction(reallocCB);
lefrSetFreeFunction(freeCB);
lefrSetLineNumberFunction(lineNumberCB);
lefrSetDeltaNumberLines(50);
lefrSetRegisterUnusedCallbacks();
if (relax)
lefrSetRelaxMode();
if (setVer)
(void)lefrSetVersionValue(version);
lefrSetAntennaInoutWarnings(30);
lefrSetAntennaInputWarnings(30);
lefrSetAntennaOutputWarnings(30);
lefrSetArrayWarnings(30);
lefrSetCaseSensitiveWarnings(30);
lefrSetCorrectionTableWarnings(30);
lefrSetDielectricWarnings(30);
lefrSetEdgeRateThreshold1Warnings(30);
lefrSetEdgeRateThreshold2Warnings(30);
lefrSetEdgeRateScaleFactorWarnings(30);
lefrSetInoutAntennaWarnings(30);
lefrSetInputAntennaWarnings(30);
lefrSetIRDropWarnings(30);
lefrSetLayerWarnings(30);
lefrSetMacroWarnings(30);
lefrSetMaxStackViaWarnings(30);
lefrSetMinFeatureWarnings(30);
lefrSetNoiseMarginWarnings(30);
lefrSetNoiseTableWarnings(30);
lefrSetNonDefaultWarnings(30);
lefrSetNoWireExtensionWarnings(30);
lefrSetOutputAntennaWarnings(30);
lefrSetPinWarnings(30);
lefrSetSiteWarnings(30);
lefrSetSpacingWarnings(30);
lefrSetTimingWarnings(30);
lefrSetUnitsWarnings(30);
lefrSetUseMinSpacingWarnings(30);
lefrSetViaRuleWarnings(30);
lefrSetViaWarnings(30);
}
(void) lefrSetShiftCase(); // will shift name to uppercase if caseinsensitive
// is set to off or not set
if (!isSessionles) {
lefrSetOpenLogFileAppend();
}
if (ccr749853) {
lefrSetTotalMsgLimit (5);
lefrSetLimitPerMsg (1618, 2);
}
if (ccr1688946) {
lefrRegisterLef58Type("XYZ", "CUT");
lefrRegisterLef58Type("XYZ", "CUT");
}
if (test1) { // for special tests
for (fileCt = 0; fileCt < numInFile; fileCt++) {
lefrReset();
if ((f = fopen(inFile[fileCt],"r")) == 0) {
fprintf(stderr,"Couldn't open input file '%s'\n", inFile[fileCt]);
return(2);
}
(void)lefrEnableReadEncrypted();
status = lefwInit(fout); // initialize the lef writer,
// need to be called 1st
if (status != LEFW_OK)
return 1;
res = lefrRead(f, inFile[fileCt], (void*)userData);
if (res)
fprintf(stderr, "Reader returns bad status.\n", inFile[fileCt]);
(void)lefrPrintUnusedCallbacks(fout);
(void)lefrReleaseNResetMemory();
//(void)lefrUnsetCallbacks();
(void)lefrUnsetLayerCbk();
(void)lefrUnsetNonDefaultCbk();
(void)lefrUnsetViaCbk();
}
}
else if (test2) { // for special tests
// this test is design to test the 3 APIs, lefrDisableParserMsgs,
// lefrEnableParserMsgs & lefrEnableAllMsgs
// It uses the file ccr566209.lef. This file will parser 3 times
// 1st it will have lefrDisableParserMsgs set to both 2007 & 2008
// 2nd will enable 2007 by calling lefrEnableParserMsgs
// 3rd enable all msgs by call lefrEnableAllMsgs
int nMsgs = 3;
int dMsgs[3];
if (numInFile != 1) {
fprintf(stderr,"Test 2 mode needs only 1 file\n");
return 2;
}
for (int idx=0; idx<5; idx++) {
if (idx == 0) { // msgs 2005 & 2011
fprintf(stderr,"\nPass 0: Disabling 2007, 2008, 2009\n");
dMsgs[0] = 2007;
dMsgs[1] = 2008;
dMsgs[2] = 2009;
lefrDisableParserMsgs (3, (int*)dMsgs);
} else if (idx == 1) { // msgs 2007 & 2005, 2011 did not print because
fprintf(stderr,"\nPass 1: Enable 2007\n");
dMsgs[0] = 2007; // lefrUnsetLayerCbk() was called
lefrEnableParserMsgs (1, (int*)dMsgs);
} else if (idx == 2) { // nothing were printed
fprintf(stderr,"\nPass 2: Disable all\n");
lefrDisableAllMsgs();
} else if (idx == 3) { // nothing were printed, lefrDisableParserMsgs
fprintf(stderr,"\nPass 3: Enable All\n");
lefrEnableAllMsgs();
} else if (idx == 4) { // msgs 2005 was printed
fprintf(stderr,"\nPass 4: Set limit on 2007 up 2\n");
lefrSetLimitPerMsg (2007, 2);
}
if ((f = fopen(inFile[fileCt],"r")) == 0) {
fprintf(stderr,"Couldn't open input file '%s'\n", inFile[fileCt]);
return(2);
}
(void)lefrEnableReadEncrypted();
status = lefwInit(fout); // initialize the lef writer,
// need to be called 1st
if (status != LEFW_OK)
return 1;
res = lefrRead(f, inFile[fileCt], (void*)userData);
if (res)
fprintf(stderr, "Reader returns bad status.\n", inFile[fileCt]);
(void)lefrPrintUnusedCallbacks(fout);
(void)lefrReleaseNResetMemory();
//(void)lefrUnsetCallbacks();
(void)lefrUnsetLayerCbk();
(void)lefrUnsetNonDefaultCbk();
(void)lefrUnsetViaCbk();
}
} else {
for (fileCt = 0; fileCt < numInFile; fileCt++) {
lefrReset();
if ((f = fopen(inFile[fileCt],"r")) == 0) {
fprintf(stderr,"Couldn't open input file '%s'\n", inFile[fileCt]);
return(2);
}
(void)lefrEnableReadEncrypted();
status = lefwInit(fout); // initialize the lef writer,
// need to be called 1st
if (status != LEFW_OK)
return 1;
if (ccr1709089) {
// CCR 1709089 test.
// Non-initialized lefData case.
lefrSetLimitPerMsg(10000, 10000);
}
res = lefrRead(f, inFile[fileCt], (void*)userData);
if (ccr1709089) {
// CCR 1709089 test.
// Initialized lefData case.
lefrSetLimitPerMsg(10000, 10000);
}
if (res)
fprintf(stderr, "Reader returns bad status.\n", inFile[fileCt]);
(void)lefrPrintUnusedCallbacks(fout);
(void)lefrReleaseNResetMemory();
}
(void)lefrUnsetCallbacks();
}
// Unset all the callbacks
void lefrUnsetAntennaInputCbk();
void lefrUnsetAntennaInoutCbk();
void lefrUnsetAntennaOutputCbk();
void lefrUnsetArrayBeginCbk();
void lefrUnsetArrayCbk();
void lefrUnsetArrayEndCbk();
void lefrUnsetBusBitCharsCbk();
void lefrUnsetCaseSensitiveCbk();
void lefrUnsetFixedMaskCbk();
void lefrUnsetClearanceMeasureCbk();
void lefrUnsetCorrectionTableCbk();
void lefrUnsetDensityCbk();
void lefrUnsetDielectricCbk();
void lefrUnsetDividerCharCbk();
void lefrUnsetEdgeRateScaleFactorCbk();
void lefrUnsetEdgeRateThreshold1Cbk();
void lefrUnsetEdgeRateThreshold2Cbk();
void lefrUnsetExtensionCbk();
void lefrUnsetInoutAntennaCbk();
void lefrUnsetInputAntennaCbk();
void lefrUnsetIRDropBeginCbk();
void lefrUnsetIRDropCbk();
void lefrUnsetIRDropEndCbk();
void lefrUnsetLayerCbk();
void lefrUnsetLibraryEndCbk();
void lefrUnsetMacroBeginCbk();
void lefrUnsetMacroCbk();
void lefrUnsetMacroClassTypeCbk();
void lefrUnsetMacroEndCbk();
void lefrUnsetMacroOriginCbk();
void lefrUnsetMacroSizeCbk();
void lefrUnsetManufacturingCbk();
void lefrUnsetMaxStackViaCbk();
void lefrUnsetMinFeatureCbk();
void lefrUnsetNoiseMarginCbk();
void lefrUnsetNoiseTableCbk();
void lefrUnsetNonDefaultCbk();
void lefrUnsetNoWireExtensionCbk();
void lefrUnsetObstructionCbk();
void lefrUnsetOutputAntennaCbk();
void lefrUnsetPinCbk();
void lefrUnsetPropBeginCbk();
void lefrUnsetPropCbk();
void lefrUnsetPropEndCbk();
void lefrUnsetSiteCbk();
void lefrUnsetSpacingBeginCbk();
void lefrUnsetSpacingCbk();
void lefrUnsetSpacingEndCbk();
void lefrUnsetTimingCbk();
void lefrUnsetUseMinSpacingCbk();
void lefrUnsetUnitsCbk();
void lefrUnsetVersionCbk();
void lefrUnsetVersionStrCbk();
void lefrUnsetViaCbk();
void lefrUnsetViaRuleCbk();
fclose(fout);
// Release allocated singleton data.
lefrClear();
return 0;
}