1 // *****************************************************************************
2 // *****************************************************************************
3 // Copyright 2012 - 2015, Cadence Design Systems
4 //
5 // This file is part of the Cadence LEF/DEF Open Source
6 // Distribution, Product Version 5.8.
7 //
8 // Licensed under the Apache License, Version 2.0 (the "License");
9 // you may not use this file except in compliance with the License.
10 // You may obtain a copy of the License at
11 //
12 // http://www.apache.org/licenses/LICENSE-2.0
13 //
14 // Unless required by applicable law or agreed to in writing, software
15 // distributed under the License is distributed on an "AS IS" BASIS,
16 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
17 // implied. See the License for the specific language governing
18 // permissions and limitations under the License.
19 //
20 // For updates, support, or to become part of the LEF/DEF Community,
21 // check www.openeda.org for details.
22 //
23 // $Author$
24 // $Revision$
25 // $Date$
26 // $State: $
27 // *****************************************************************************
28 // *****************************************************************************
29
30 // This program is the diffLef core program. It has all the callback
31 // routines and write it out to a temporary file
32
33 #include <stdio.h>
34 #include <string.h>
35 #ifndef WIN32
36 # include <unistd.h>
37 #endif /* not WIN32 */
38 #include "lefrReader.hpp"
39 #include "lefwWriter.hpp"
40 #include "lefiDebug.hpp"
41
42 char defaultName[128];
43 char defaultOut[128];
44 FILE* fout;
45 int printing = 0; // Printing the output.
46 void* userData;
47
48 // TX_DIR:TRANSLATION ON
49
dataError()50 void dataError() {
51 fprintf(fout, "ERROR: returned user data is not correct!\n");
52 }
53
54
checkType(lefrCallbackType_e c)55 void checkType(lefrCallbackType_e c) {
56 if (c >= 0 && c <= lefrLibraryEndCbkType) {
57 // OK
58 } else {
59 fprintf(fout, "ERROR: callback type is out of bounds!\n");
60 }
61 }
62
63 // 05/24/2001 - Wanda da Rosa. PCR 373170
64 // This function is added due to the rounding between machines are
65 // different. For a 5, solaries will round down while hppa will roundup.
66 // This function will make sure it round up for all the machine
chkNum(double num)67 double chkNum(double num) {
68 long tempNum;
69 if ((num > 1000004) || (num < -1000004)) {
70 tempNum = (long)num;
71 if ((tempNum%5) == 0)
72 return num + 3;
73 }
74 return num;
75 }
76
77 // Print Via
lefVia(lefiVia * via,char * inName)78 void lefVia(lefiVia* via, char* inName) {
79 int i, j;
80
81 fprintf(fout, "%s %s", inName, via->name());
82 if (via->hasDefault())
83 fprintf(fout, " DEFAULT");
84 if (via->hasGenerated())
85 fprintf(fout, " GENERATED");
86 if (via->hasTopOfStack())
87 fprintf(fout, " TOPOFSTACKONLY");
88 if (via->hasForeign()) {
89 fprintf(fout, " FOREIGN %s", via->foreign());
90 if (via->hasForeignPnt()) {
91 fprintf(fout, " ( %g %g )", chkNum(via->foreignX()),
92 chkNum(via->foreignY()));
93 if (via->hasForeignOrient())
94 fprintf(fout, " %s", lefiOrientStr(via->foreignOrient()));
95 }
96 }
97 fprintf(fout, "\n");
98 if (via->hasProperties()) {
99 for (i = 0; i < via->numProperties(); i++) {
100 fprintf(fout, "%s %s PROP", inName, via->name());
101 fprintf(fout, " %s", via->propName(i));
102 if (via->propIsNumber(i))
103 fprintf(fout, " %g", chkNum(via->propNumber(i)));
104 if (via->propIsString(i))
105 fprintf(fout, " %s", via->propValue(i));
106 fprintf(fout, "\n");
107 }
108 }
109 if (via->hasViaRule()) {
110 fprintf(fout, "%s %s %g %g %s %s %s %g %g %g %g %g %g", via->name(),
111 via->viaRuleName(), via->xCutSize(), via->yCutSize(),
112 via->botMetalLayer(), via->cutLayer(), via->topMetalLayer(),
113 via->xCutSpacing(), via->yCutSpacing(), via->xBotEnc(),
114 via->yBotEnc(), via->xTopEnc(), via->yTopEnc());
115 if (via->hasRowCol())
116 fprintf(fout, " %d %d", via->numCutRows(), via->numCutCols());
117 if (via->hasOrigin())
118 fprintf(fout, " %g %g", via->xOffset(), via->yOffset());
119 if (via->hasOffset())
120 fprintf(fout, " %g %g %g %g", via->xBotOffset(), via->yBotOffset(),
121 via->xTopOffset(), via->yTopOffset());
122 if (via->hasCutPattern())
123 fprintf(fout, " %s", via->cutPattern());
124 fprintf(fout, "\n");
125 }
126 if (via->hasResistance())
127 fprintf(fout, "%s %s RESISTANCE %g\n",inName, via->name(),
128 chkNum(via->resistance()));
129 if (via->numLayers() > 0) {
130 for (i = 0; i < via->numLayers(); i++) {
131 fprintf(fout, "%s %s LAYER %s\n", inName, via->name(),
132 via->layerName(i));
133 for (j = 0; j < via->numRects(i); j++) {
134 if (via->rectColorMask(i, j)) {
135 fprintf(fout, "%s %s RECT MASK % d ( %g %g ) ( %g %g )\n",
136 inName, via->name(), via->rectColorMask(i, j),
137 chkNum(via->xl(i, j)), chkNum(via->yl(i, j)),
138 chkNum(via->xh(i, j)), chkNum(via->yh(i, j)));
139 } else {
140 fprintf(fout, "%s %s RECT ( %g %g ) ( %g %g )\n", inName,
141 via->name(),
142 chkNum(via->xl(i, j)), chkNum(via->yl(i, j)),
143 chkNum(via->xh(i, j)), chkNum(via->yh(i, j)));
144 }
145 }
146 for (j = 0; j < via->numPolygons(i); j++) {
147 struct lefiGeomPolygon poly;
148 poly = via->getPolygon(i, j);
149 if (via->polyColorMask(i, j)) {
150 fprintf(fout, "%s %s POLYGON MASK %d", inName, via->name(),
151 via->polyColorMask(i, j));
152 } else {
153 fprintf(fout, "%s %s POLYGON", inName, via->name());
154 }
155 for (int k = 0; k < poly.numPoints; k++)
156 fprintf(fout, " %g %g", poly.x[k], poly.y[k]);
157 fprintf(fout, "\n");
158 }
159 }
160 }
161 return;
162 }
163
164 // Print Spacing
lefSpacing(lefiSpacing * spacing,char * inName)165 void lefSpacing(lefiSpacing* spacing, char *inName) {
166 fprintf(fout, "%s SAMENET %s %s %g ", inName, spacing->name1(),
167 spacing->name2(), chkNum(spacing->distance()));
168 if (spacing->hasStack())
169 fprintf(fout, " STACK");
170 fprintf(fout,"\n");
171 return;
172 }
173
174 // Print Via Rule Layer
lefViaRuleLayer(lefiViaRuleLayer * vLayer,char * viaName)175 void lefViaRuleLayer(lefiViaRuleLayer* vLayer, char* viaName) {
176 fprintf(fout, "VIARULE %s LAYER %s", viaName, vLayer->name());
177 if (vLayer->hasDirection()) {
178 if (vLayer->isHorizontal())
179 fprintf(fout, " DIRECTION HORIZONTAL");
180 if (vLayer->isVertical())
181 fprintf(fout, " DIRECTION VERTICAL");
182 }
183 if (vLayer->hasEnclosure())
184 fprintf(fout, " ENCLOSURE %g %g\n", chkNum(vLayer->enclosureOverhang1()),
185 chkNum(vLayer->enclosureOverhang2()));
186 if (vLayer->hasWidth())
187 fprintf(fout, " WIDTH %g TO %g", chkNum(vLayer->widthMin()),
188 chkNum(vLayer->widthMax()));
189 if (vLayer->hasResistance())
190 fprintf(fout, " RESISTANCE %g", chkNum(vLayer->resistance()));
191 if (vLayer->hasOverhang())
192 fprintf(fout, " OVERHANG %g", chkNum(vLayer->overhang()));
193 if (vLayer->hasMetalOverhang())
194 fprintf(fout, " METALOVERHANG %g", chkNum(vLayer->metalOverhang()));
195 if (vLayer->hasSpacing())
196 fprintf(fout, " SPACING %g BY %g", chkNum(vLayer->spacingStepX()),
197 chkNum(vLayer->spacingStepY()));
198 if (vLayer->hasRect())
199 fprintf(fout, " RECT ( %g %g ) ( %g %g )", chkNum(vLayer->xl()),
200 chkNum(vLayer->yl()), chkNum(vLayer->xh()), chkNum(vLayer->yh()));
201 fprintf(fout, "\n");
202 return;
203 }
204
205 // Print Geometry
prtGeometry(lefiGeometries * geometry,char * inName)206 void prtGeometry(lefiGeometries* geometry, char* inName) {
207 int numItems = geometry->numItems();
208 int i, j;
209 lefiGeomPath* path;
210 lefiGeomPathIter* pathIter;
211 lefiGeomRect* rect;
212 lefiGeomRectIter* rectIter;
213 lefiGeomPolygon* polygon;
214 lefiGeomPolygonIter* polygonIter;
215 lefiGeomVia* via;
216 lefiGeomViaIter* viaIter;
217
218 for (i = 0; i < numItems; i++) {
219 switch (geometry->itemType(i)) {
220 case lefiGeomClassE:
221 fprintf(fout, "%s CLASS %s\n", inName, geometry->getClass(i));
222 break;
223 case lefiGeomLayerE:
224 fprintf(fout, "%s LAYER %s\n", inName, geometry->getLayer(i));
225 break;
226 case lefiGeomLayerMinSpacingE:
227 fprintf(fout, "%s SPACING %g\n", inName,
228 chkNum(geometry->getLayerMinSpacing(i)));
229 break;
230 case lefiGeomLayerExceptPgNetE:
231 fprintf(fout, "%s EXCEPTPGNET\n", inName);
232 break;
233 case lefiGeomLayerRuleWidthE:
234 fprintf(fout, "%s DESIGNRULEWIDTH %g\n", inName,
235 chkNum(geometry->getLayerRuleWidth(i)));
236 break;
237 case lefiGeomWidthE:
238 fprintf(fout, "%s WIDTH %g\n", inName,
239 chkNum(geometry->getWidth(i)));
240 break;
241 case lefiGeomPathE:
242 path = geometry->getPath(i);
243 if (path->colorMask != 0) {
244 fprintf(fout, "%s PATH MASK %d ", inName, path->colorMask);
245 } else {
246 fprintf(fout, "%s PATH ", inName);
247 }
248
249 for (j = 0; j < path->numPoints; j++) {
250 if (j+1 == path->numPoints) // last one on the list
251 fprintf(fout, " ( %g %g )\n", chkNum(path->x[j]),
252 chkNum(path->y[j]));
253 else
254 fprintf(fout, " ( %g %g )", chkNum(path->x[j]),
255 chkNum(path->y[j]));
256 }
257 break;
258 case lefiGeomPathIterE:
259 pathIter = geometry->getPathIter(i);
260 if (pathIter->colorMask != 0) {
261 fprintf(fout, "%s PATH MASK %d ITERATED ", inName,
262 pathIter->colorMask);
263 } else {
264 fprintf(fout, "%s PATH ITERATED ", inName);
265 }
266 for (j = 0; j < pathIter->numPoints; j++)
267 fprintf(fout, " ( %g %g )", chkNum(pathIter->x[j]),
268 chkNum(pathIter->y[j]));
269 fprintf(fout, " DO %g BY %g STEP %g %g\n",
270 chkNum(pathIter->xStart), chkNum(pathIter->yStart),
271 chkNum(pathIter->xStep), chkNum(pathIter->yStep));
272 break;
273 case lefiGeomRectE:
274 rect = geometry->getRect(i);
275 if (rect->colorMask != 0) {
276 fprintf(fout, "%s RECT MASK %d ( %g %g ) ( %g %g )\n",
277 inName, rect->colorMask,
278 chkNum(rect->xl), chkNum(rect->yl),
279 chkNum(rect->xh), chkNum(rect->yh));
280 } else {
281 fprintf(fout, "%s RECT ( %g %g ) ( %g %g )\n", inName,
282 chkNum(rect->xl), chkNum(rect->yl),
283 chkNum(rect->xh), chkNum(rect->yh));
284 }
285 break;
286 case lefiGeomRectIterE:
287 rectIter = geometry->getRectIter(i);
288 if (rectIter->colorMask != 0) {
289 fprintf(fout, "%s RECT MASK %d ITERATE ( %g %g ) ( %g %g )",
290 inName, rectIter->colorMask,
291 chkNum(rectIter->xl), chkNum(rectIter->yl),
292 chkNum(rectIter->xh), chkNum(rectIter->yh));
293 } else {
294 fprintf(fout, "%s RECT ITERATE ( %g %g ) ( %g %g )", inName,
295 chkNum(rectIter->xl), chkNum(rectIter->yl),
296 chkNum(rectIter->xh), chkNum(rectIter->yh));
297 }
298 fprintf(fout, " DO %g BY %g STEP %g %g ;\n",
299 chkNum(rectIter->xStart), chkNum(rectIter->yStart),
300 chkNum(rectIter->xStep), chkNum(rectIter->yStep));
301 break;
302 case lefiGeomPolygonE:
303 polygon = geometry->getPolygon(i);
304 if (polygon->colorMask != 0) {
305 fprintf(fout, "%s POLYGON MASK %d ", inName, polygon->colorMask);
306 } else {
307 fprintf(fout, "%s POLYGON ", inName);
308 }
309 for (j = 0; j < polygon->numPoints; j++) {
310 if (j+1 == polygon->numPoints) // last one on the list
311 fprintf(fout, " ( %g %g )\n", chkNum(polygon->x[j]),
312 chkNum(polygon->y[j]));
313 else
314 fprintf(fout, " ( %g %g )", chkNum(polygon->x[j]),
315 chkNum(polygon->y[j]));
316 }
317 break;
318 case lefiGeomPolygonIterE:
319 polygonIter = geometry->getPolygonIter(i);
320 if (polygonIter->colorMask != 0) {
321 fprintf(fout, "%s POLYGON MASK %d ITERATE", inName,
322 polygonIter->colorMask);
323 } else {
324 fprintf(fout, "%s POLYGON ITERATE", inName);
325 }
326 for (j = 0; j < polygonIter->numPoints; j++)
327 fprintf(fout, " ( %g %g )", chkNum(polygonIter->x[j]),
328 chkNum(polygonIter->y[j]));
329 fprintf(fout, " DO %g BY %g STEP %g %g\n",
330 chkNum(polygonIter->xStart), chkNum(polygonIter->yStart),
331 chkNum(polygonIter->xStep), chkNum(polygonIter->yStep));
332 break;
333 case lefiGeomViaE:
334 via = geometry->getVia(i);
335 if (via->topMaskNum != 0 || via->bottomMaskNum != 0 || via->cutMaskNum !=0) {
336 fprintf(fout, "%s VIA MASK %d%d%d ( %g %g ) %s\n", inName,
337 via->topMaskNum, via->cutMaskNum, via->bottomMaskNum,
338 chkNum(via->x),
339 chkNum(via->y), via->name);
340 } else {
341 fprintf(fout, "%s VIA ( %g %g ) %s\n", inName, chkNum(via->x),
342 chkNum(via->y), via->name);
343 }
344 break;
345 case lefiGeomViaIterE:
346 viaIter = geometry->getViaIter(i);
347 if (viaIter->topMaskNum != 0 || viaIter->cutMaskNum != 0 || viaIter->bottomMaskNum != 0) {
348 fprintf(fout, "%s VIA ITERATE MASK %d%d%d ( %g %g ) %s", inName,
349 viaIter->topMaskNum, viaIter->cutMaskNum,
350 viaIter->bottomMaskNum,
351 chkNum(viaIter->x), chkNum(viaIter->y), viaIter->name);
352 } else {
353 fprintf(fout, "%s VIA ITERATE ( %g %g ) %s", inName,
354 chkNum(viaIter->x), chkNum(viaIter->y), viaIter->name);
355 }
356 fprintf(fout, " DO %g BY %g STEP %g %g\n",
357 chkNum(viaIter->xStart), chkNum(viaIter->yStart),
358 chkNum(viaIter->xStep), chkNum(viaIter->yStep));
359 break;
360 default:
361 fprintf(fout, "BOGUS geometries type.\n");
362 break;
363 }
364 }
365 }
366
367 // Antenna
antennaCB(lefrCallbackType_e c,double value,lefiUserData ud)368 int antennaCB(lefrCallbackType_e c, double value, lefiUserData ud) {
369 checkType(c);
370 if (ud != userData) dataError();
371
372 switch (c) {
373 case lefrAntennaInputCbkType:
374 fprintf(fout, "ANTINPUTGATEAREA %g\n", chkNum(value));
375 break;
376 case lefrAntennaInoutCbkType:
377 fprintf(fout, "ANTINOUTDIFFAREA %g\n", chkNum(value));
378 break;
379 case lefrAntennaOutputCbkType:
380 fprintf(fout, "ANTOUTPUTDIFFAREA %g\n", chkNum(value));
381 break;
382 case lefrInputAntennaCbkType:
383 fprintf(fout, "INPUTPINANTENNASIZE %g\n", chkNum(value));
384 break;
385 case lefrOutputAntennaCbkType:
386 fprintf(fout, "OUTPUTPINANTENNASIZE %g\n", chkNum(value));
387 break;
388 case lefrInoutAntennaCbkType:
389 fprintf(fout, "INOUTPINANTENNASIZE %g\n", chkNum(value));
390 break;
391 default:
392 break;
393 }
394 return 0;
395 }
396
397 // Array
arrayCB(lefrCallbackType_e c,lefiArray * a,lefiUserData ud)398 int arrayCB(lefrCallbackType_e c, lefiArray* a, lefiUserData ud) {
399 int i, j, defCaps;
400 lefiSitePattern* pattern;
401 lefiTrackPattern* track;
402 lefiGcellPattern* gcell;
403
404 checkType(c);
405 if (ud != userData) dataError();
406
407 if (a->numSitePattern() > 0) {
408 for (i = 0; i < a->numSitePattern(); i++) {
409 pattern = a->sitePattern(i);
410 fprintf(fout, "ARRAY %s SITE %s %g %g %s DO %g BY %g STEP %g %g\n",
411 a->name(), pattern->name(), chkNum(pattern->x()),
412 chkNum(pattern->y()), lefiOrientStr(pattern->orient()),
413 chkNum(pattern->xStart()), chkNum(pattern->yStart()),
414 chkNum(pattern->xStep()), chkNum(pattern->yStep()));
415 }
416 }
417 if (a->numCanPlace() > 0) {
418 for (i = 0; i < a->numCanPlace(); i++) {
419 pattern = a->canPlace(i);
420 fprintf(fout, "ARRAY %s CANPLACE %s %g %g %s DO %g BY %g STEP %g %g\n",
421 a->name(), pattern->name(), chkNum(pattern->x()),
422 chkNum(pattern->y()), lefiOrientStr(pattern->orient()),
423 chkNum(pattern->xStart()), chkNum(pattern->yStart()),
424 chkNum(pattern->xStep()), chkNum(pattern->yStep()));
425 }
426 }
427 if (a->numCannotOccupy() > 0) {
428 for (i = 0; i < a->numCannotOccupy(); i++) {
429 pattern = a->cannotOccupy(i);
430 fprintf(fout, "ARRAY %s CANNOTOCCUPY %s %g %g %s DO %g BY %g STEP %g %g\n",
431 a->name(), pattern->name(), chkNum(pattern->x()),
432 chkNum(pattern->y()), lefiOrientStr(pattern->orient()),
433 chkNum(pattern->xStart()), chkNum(pattern->yStart()),
434 chkNum(pattern->xStep()), chkNum(pattern->yStep()));
435 }
436 }
437
438 if (a->numTrack() > 0) {
439 for (i = 0; i < a->numTrack(); i++) {
440 track = a->track(i);
441 // 11/22/99 - Wanda da Rosa, PCR 283781. Merge the track with
442 // layer names. This way, if user split the layer into different
443 // line, the diff program won't generate extra lines.
444 if (track->numLayers() == 0) {
445 fprintf(fout, "ARRAY %s TRACKS %s, %g DO %d STEP %g\n", a->name(),
446 track->name(), chkNum(track->start()), track->numTracks(),
447 chkNum(track->space()));
448 } else {
449 fprintf(fout, "ARRAY %s TRACKS %s, %g DO %d STEP %g ", a->name(),
450 track->name(), chkNum(track->start()), track->numTracks(),
451 chkNum(track->space()));
452 for (j = 0; j < track->numLayers(); j++)
453 fprintf(fout, "%s ", track->layerName(j));
454 fprintf(fout, ";\n");
455 }
456 }
457 }
458
459 if (a->numGcell() > 0) {
460 for (i = 0; i < a->numGcell(); i++) {
461 gcell = a->gcell(i);
462 fprintf(fout, "ARRAY %s GCELLGRID %s, %g DO %d STEP %g\n", a->name(),
463 gcell->name(), chkNum(gcell->start()), gcell->numCRs(),
464 chkNum(gcell->space()));
465 }
466 }
467
468 if (a->numFloorPlans() > 0) {
469 for (i = 0; i < a->numFloorPlans(); i++) {
470 for (j = 0; j < a->numSites(i); j++) {
471 pattern = a->site(i, j);
472 fprintf(fout,
473 "ARRAY %s FLOORPLAN %s %s %s %g %g %s DO %d BY %d STEP %g %g\n",
474 a->name(), a->floorPlanName(i), a->siteType(i, j),
475 pattern->name(), chkNum(pattern->x()), chkNum(pattern->y()),
476 lefiOrientStr(pattern->orient()), pattern->xStart(),
477 pattern->yStart(), chkNum(pattern->xStep()),
478 chkNum(pattern->yStep()));
479 }
480 }
481 }
482
483 defCaps = a->numDefaultCaps();
484 if (defCaps > 0) {
485 for (i = 0; i < defCaps; i++)
486 fprintf(fout, "ARRAY %s DEFAULTCAP %d MINPINS %g WIRECAP %g\n",
487 a->name(), defCaps, chkNum(a->defaultCapMinPins(i)),
488 chkNum(a->defaultCap(i)));
489 }
490 return 0;
491 }
492
493 // Busbitchar
busBitCharsCB(lefrCallbackType_e c,const char * busBit,lefiUserData ud)494 int busBitCharsCB(lefrCallbackType_e c, const char* busBit, lefiUserData ud)
495 {
496 checkType(c);
497 if (ud != userData) dataError();
498 // use the lef writer to write out the data
499 fprintf(fout, "BUSBITCHARS %s\n", busBit);
500 return 0;
501 }
502
503 // CaseSensitive
caseSensCB(lefrCallbackType_e c,int caseSense,lefiUserData ud)504 int caseSensCB(lefrCallbackType_e c, int caseSense, lefiUserData ud) {
505 checkType(c);
506 if (ud != userData) dataError();
507
508 if (caseSense == TRUE)
509 fprintf(fout, "NAMESCASESENSITIVE ON\n");
510 else
511 fprintf(fout, "NAMESCASESENSITIVE OFF\n");
512 return 0;
513 }
514
515 // FixedMask
fixedMaskCB(lefrCallbackType_e c,int fixedMask,lefiUserData ud)516 int fixedMaskCB(lefrCallbackType_e c, int fixedMask, lefiUserData ud) {
517 checkType(c);
518 if (ud != userData) dataError();
519
520 if (fixedMask == 1)
521 fprintf(fout, "FIXEDMASK ;\n");
522 return 0;
523 }
524
525 // Crearance
clearanceCB(lefrCallbackType_e c,const char * name,lefiUserData ud)526 int clearanceCB(lefrCallbackType_e c, const char* name, lefiUserData ud) {
527 checkType(c);
528 if (ud != userData) dataError();
529
530 fprintf(fout, "CLEARANCEMEASURE %s\n", name);
531 return 0;
532 }
533
534 // Crosstalk correcttable
correctTableCB(lefrCallbackType_e c,lefiCorrectionTable * table,lefiUserData ud)535 int correctTableCB(lefrCallbackType_e c, lefiCorrectionTable* table,
536 lefiUserData ud) {
537 int i, j, k, l;
538 lefiCorrectionEdge *edge;
539 lefiCorrectionResistance *resist;
540 lefiCorrectionVictim *victim;
541
542 checkType(c);
543 if (ud != userData) dataError();
544
545 fprintf(fout, "CROSSTALK CORRECTIONTABLE %d\n", table->num());
546 for (i = 0; i < table->numEdges(); i++) {
547 edge = table->edge(i);
548 // resistances
549 if (edge->numResistances()) {
550 for (j = 0; j < edge->numResistances(); j++) {
551 resist = edge->resistance(j);
552 fprintf(fout, "CROSSTALK CORRECTIONTABLE %d RESISTANCE %g\n",
553 table->num(), chkNum(resist->num(j)));
554 // victims
555 for (k = 0; k < resist->numVictims(); k++) {
556 victim = resist->victim(k);
557 if (victim->length() > 0)
558 fprintf(fout,
559 "CROSSTALK CORRECTIONTABLE %d RESISTANCE %g VICTIMLEN %g\n",
560 table->num(), chkNum(resist->num(j)),
561 chkNum(victim->length()));
562 for (l = 0; l < victim->numCorrections(); l++)
563 fprintf(fout,
564 "CROSSTALK CORRECTIONTABLE %d RESISTANCE %g VICTIM GTH %g CORRECTIONFACTOR %g\n",
565 table->num(), chkNum(resist->num(j)),
566 chkNum(victim->length()), chkNum(victim->correction(l)));
567 }
568 }
569 }
570 }
571 return 0;
572 }
573
574 // Dielectric
dielectricCB(lefrCallbackType_e c,double dielectric,lefiUserData ud)575 int dielectricCB(lefrCallbackType_e c, double dielectric, lefiUserData ud) {
576 checkType(c);
577 if (ud != userData) dataError();
578
579 fprintf(fout, "DIELECTRIC %g\n", chkNum(dielectric));
580 return 0;
581 }
582
583 // Divider
dividerCB(lefrCallbackType_e c,const char * divideChar,lefiUserData ud)584 int dividerCB(lefrCallbackType_e c, const char* divideChar, lefiUserData ud) {
585 checkType(c);
586 if (ud != userData) dataError();
587 fprintf(fout, "DIVIDER %s\n", divideChar);
588 return 0;
589 }
590
591 // Crosstalk edgeRate
edgeRateCB(lefrCallbackType_e c,double rate,lefiUserData ud)592 int edgeRateCB(lefrCallbackType_e c, double rate, lefiUserData ud) {
593 checkType(c);
594 if (ud != userData) dataError();
595 fprintf(fout, "CROSSTALK EDGERATESCALEFACTOR %g\n", chkNum(rate));
596 return 0;
597 }
598
599 // Callback routine for edgeratethreshold1
edgeRate1CB(lefrCallbackType_e c,double rate,lefiUserData ud)600 int edgeRate1CB(lefrCallbackType_e c, double rate, lefiUserData ud) {
601 checkType(c);
602 if (ud != userData) dataError();
603 fprintf(fout, "CROSSTALK EDGERATETHRESHOLD1 %g\n", chkNum(rate));
604 return 0;
605 }
606
607 // Callback routine for edgeratethreshold2
edgeRate2CB(lefrCallbackType_e c,double rate,lefiUserData ud)608 int edgeRate2CB(lefrCallbackType_e c, double rate, lefiUserData ud) {
609 checkType(c);
610 if (ud != userData) dataError();
611 fprintf(fout, "CROSSTALK EDGERATETHRESHOLD2 %g\n", chkNum(rate));
612 return 0;
613 }
614
615 // InputAntenna
inputAntCB(lefrCallbackType_e c,double antenna,lefiUserData ud)616 int inputAntCB(lefrCallbackType_e c, double antenna, lefiUserData ud) {
617 checkType(c);
618 if (ud != userData) dataError();
619 fprintf(fout, "INPUTINANTENNASIZE %g\n", chkNum(antenna));
620 return 0;
621 }
622
623 // OutputAntenna
outputAntCB(lefrCallbackType_e c,double antenna,lefiUserData ud)624 int outputAntCB(lefrCallbackType_e c, double antenna, lefiUserData ud) {
625 checkType(c);
626 if (ud != userData) dataError();
627 fprintf(fout, "OUTPUTINANTENNASIZE %g\n", chkNum(antenna));
628 return 0;
629 }
630
631
632 // InOutAntenna
inoutAntCB(lefrCallbackType_e c,double antenna,lefiUserData ud)633 int inoutAntCB(lefrCallbackType_e c, double antenna, lefiUserData ud) {
634 checkType(c);
635 if (ud != userData) dataError();
636 fprintf(fout, "INOUTPUTINANTENNASIZE %g\n", chkNum(antenna));
637 return 0;
638 }
639
640 // Irdrop
irdropCB(lefrCallbackType_e c,lefiIRDrop * irdrop,lefiUserData ud)641 int irdropCB(lefrCallbackType_e c, lefiIRDrop* irdrop, lefiUserData ud) {
642 int i;
643 checkType(c);
644 if (ud != userData) dataError();
645 fprintf(fout, "IRDROP TABLE %s ", irdrop->name());
646 for (i = 0; i < irdrop->numValues(); i++)
647 fprintf(fout, "%g %g ", chkNum(irdrop->value1(i)),
648 chkNum(irdrop->value2(i)));
649 fprintf(fout, "\n");
650 return 0;
651 }
652
653 // Layer
layerCB(lefrCallbackType_e c,lefiLayer * layer,lefiUserData ud)654 int layerCB(lefrCallbackType_e c, lefiLayer* layer, lefiUserData ud) {
655 int i, j, k;
656 double *widths, *current;
657 lefiLayerDensity* density;
658 char pType;
659 int numPoints, propNum;
660 lefiAntennaPWL* pwl;
661 int needHeading;
662 int numMinCut, numMinenclosed;
663 lefiSpacingTable* spTable;
664 lefiInfluence* influence;
665 lefiParallel* parallel;
666 lefiTwoWidths* twoWidths;
667 lefiAntennaModel* aModel;
668 lefiOrthogonal* ortho;
669
670 checkType(c);
671 if (ud != userData) dataError();
672 if (layer->hasType())
673 fprintf(fout, "LAYER %s TYPE %s\n", layer->name(), layer->type());
674 if (layer->hasMask())
675 fprintf(fout, "LAYER %s MASK %d\n", layer->name(), layer->mask());
676 if (layer->hasPitch())
677 fprintf(fout, "LAYER %s PITCH %g\n", layer->name(), chkNum(layer->pitch()));
678 else if (layer->hasXYPitch())
679 fprintf(fout, "LAYER %s PITCH %g %g\n", layer->name(),
680 chkNum(layer->pitchX()), chkNum(layer->pitchY()));
681 if (layer->hasOffset())
682 fprintf(fout, "LAYER %s OFFSET %g\n", layer->name(),
683 chkNum(layer->offset()));
684 else if (layer->hasXYOffset())
685 fprintf(fout, "LAYER %s OFFSET %g %g\n", layer->name(),
686 chkNum(layer->offsetX()), chkNum(layer->offsetY()));
687 if (layer->hasDiagPitch())
688 fprintf(fout, "LAYER %s DIAGPITCH %g\n", layer->name(),
689 chkNum(layer->diagPitch()));
690 else if (layer->hasXYDiagPitch())
691 fprintf(fout, "LAYER %s DIAGPITCH %g %g\n", layer->name(),
692 chkNum(layer->diagPitchX()), chkNum(layer->diagPitchY()));
693 if (layer->hasDiagWidth())
694 fprintf(fout, "LAYER %s DIAGWIDTH %g\n", layer->name(),
695 chkNum(layer->diagWidth()));
696 if (layer->hasDiagSpacing())
697 fprintf(fout, "LAYER %s DIAGSPACING %g\n", layer->name(),
698 chkNum(layer->diagSpacing()));
699 if (layer->hasDiagMinEdgeLength())
700 fprintf(fout, "LAYER %s DIAGMINEDGELENGTH %g\n", layer->name(),
701 chkNum(layer->diagMinEdgeLength()));
702 if (layer->hasWidth())
703 fprintf(fout, "LAYER %s WIDTH %g\n", layer->name(),
704 chkNum(layer->width()));
705 if (layer->hasArea())
706 fprintf(fout, "LAYER %s AREA %g\n", layer->name(),
707 chkNum(layer->area()));
708 if (layer->numMinSize()) {
709 fprintf(fout, "LAYER %s MINSIZE", layer->name());
710 for (i = 0; i < layer->numMinSize(); i++)
711 fprintf(fout, " %g %g", layer->minSizeWidth(i),
712 layer->minSizeLength(i));
713 fprintf(fout, "\n");
714 }
715 if (layer->hasSlotWireWidth())
716 fprintf(fout, "LAYER %s SLOTWIREWIDTH %g\n", layer->name(),
717 chkNum(layer->slotWireWidth()));
718 if (layer->hasSlotWireLength())
719 fprintf(fout, "LAYER %s SLOTWIRELENGTH %g\n", layer->name(),
720 chkNum(layer->slotWireLength()));
721 if (layer->hasSlotWidth())
722 fprintf(fout, "LAYER %s SLOTWIDTH %g\n", layer->name(),
723 chkNum(layer->slotWidth()));
724 if (layer->hasSlotLength())
725 fprintf(fout, "LAYER %s SLOTLENGTH %g\n", layer->name(),
726 chkNum(layer->slotLength()));
727 if (layer->hasMaxAdjacentSlotSpacing())
728 fprintf(fout, "LAYER %s MAXADJACENTSLOTSPACING %g\n", layer->name(),
729 chkNum(layer->maxAdjacentSlotSpacing()));
730 if (layer->hasMaxCoaxialSlotSpacing())
731 fprintf(fout, "LAYER %s MAXCOAXIALSLOTSPACING %g\n", layer->name(),
732 chkNum(layer->maxCoaxialSlotSpacing()));
733 if (layer->hasMaxEdgeSlotSpacing())
734 fprintf(fout, "LAYER %s MAXEDGESLOTSPACING %g\n", layer->name(),
735 chkNum(layer->maxEdgeSlotSpacing()));
736 if (layer->hasArraySpacing()) {
737 fprintf(fout, "LAYER %s ARRAYSPACING", layer->name());
738 if (layer->hasLongArray())
739 fprintf(fout, " LONGARRAY");
740 if (layer->hasViaWidth())
741 fprintf(fout, " WIDTH %g", chkNum(layer->viaWidth()));
742 fprintf(fout, " CUTSPACING %g", chkNum(layer->cutSpacing()));
743 fprintf(fout, "\n");
744 for (i = 1; i < layer->numArrayCuts(); i++) {
745 fprintf(fout, "LAYER %s ARRAYCUTS %i SPACING %g\n", layer->name(),
746 layer->arrayCuts(i),
747 layer->arraySpacing(i));
748 }
749 }
750 if (layer->hasSplitWireWidth())
751 fprintf(fout, "LAYER %s SPLITWIREWIDTH %g\n", layer->name(),
752 chkNum(layer->splitWireWidth()));
753 if (layer->hasMinimumDensity())
754 fprintf(fout, "LAYER %s MINIMUMDENSITY %g\n", layer->name(),
755 chkNum(layer->minimumDensity()));
756 if (layer->hasMaximumDensity())
757 fprintf(fout, "LAYER %s MAXIMUMDENSITY %g\n", layer->name(),
758 chkNum(layer->maximumDensity()));
759 if (layer->hasDensityCheckWindow())
760 fprintf(fout, "LAYER %s DENSITYCHECKWINDOW %g %g\n", layer->name(),
761 chkNum(layer->densityCheckWindowLength()),
762 chkNum(layer->densityCheckWindowWidth()));
763 if (layer->hasDensityCheckStep())
764 fprintf(fout, "LAYER %s DENSITYCHECKSTEP %g\n", layer->name(),
765 chkNum(layer->densityCheckStep()));
766 if (layer->hasFillActiveSpacing())
767 fprintf(fout, "LAYER %s FILLACTIVESPACING %g\n", layer->name(),
768 chkNum(layer->fillActiveSpacing()));
769 numMinCut = layer->numMinimumcut(); // 5.4.1
770 if (numMinCut > 0) {
771 for (i = 0; i < numMinCut; i++) {
772 fprintf(fout, "LAYER %s MINIMUMCUT %d WIDTH %g", layer->name(),
773 layer->minimumcut(i),
774 layer->minimumcutWidth(i));
775 if (layer->hasMinimumcutWithin(i))
776 fprintf(fout, " WITHIN %g", layer->minimumcutWithin(i));
777 if (layer->hasMinimumcutConnection(i))
778 fprintf(fout, " %s", layer->minimumcutConnection(i));
779 if (layer->hasMinimumcutNumCuts(i))
780 fprintf(fout, " LENGTH %g WITHIN %g",
781 layer->minimumcutLength(i),
782 layer->minimumcutDistance(i));
783 fprintf(fout, "\n");
784 }
785 }
786 if (layer->hasMaxwidth()) // 5.4.1
787 fprintf(fout, "LAYER %s MAXWIDTH %g\n", layer->name(), layer->maxwidth());
788 if (layer->hasMinwidth()) // 5.5
789 fprintf(fout, "LAYER %s MINWIDTH %g\n", layer->name(), layer->minwidth());
790 numMinenclosed = layer->numMinenclosedarea();
791 if (numMinenclosed > 0) {
792 for (i = 0; i < numMinenclosed; i++) { // 5.5, made it multiples
793 fprintf(fout, "LAYER %s MINENCLOSEDAREA %g", layer->name(),
794 layer->minenclosedarea(i));
795 if (layer->hasMinenclosedareaWidth(i))
796 fprintf(fout, " MINENCLOSEDAREAWIDTH %g",
797 layer->minenclosedareaWidth(i));
798 fprintf(fout,"\n");
799 }
800 }
801 if (layer->hasMinstep()) { // 5.4.1 & 5.6
802 for (i = 0; i < layer->numMinstep(); i++) {
803 fprintf(fout, "LAYER %s MINSTEP %g", layer->name(),
804 layer->minstep(i));
805 if (layer->hasMinstepType(i))
806 fprintf(fout, " %s", layer->minstepType(i));
807 if (layer->hasMinstepLengthsum(i))
808 fprintf(fout, " LENGTHSUM %g", layer->minstepLengthsum(i));
809 if (layer->hasMinstepMaxedges(i))
810 fprintf(fout, " MAXEDGES %d", layer->minstepMaxedges(i));
811 fprintf(fout, "\n");
812 }
813 }
814 if (layer->hasProtrusion()) // 5.4.1
815 fprintf(fout, "LAYER %s PROTRUSIONWIDTH %g LENGTH %g WIDTH %g\n",
816 layer->name(), layer->protrusionWidth1(),
817 layer->protrusionLength(), layer->protrusionWidth2());
818 if (layer->hasSpacingNumber()) {
819 for (i = 0; i < layer->numSpacing(); i++) {
820 fprintf(fout, "LAYER %s SPACING %g", layer->name(),
821 chkNum(layer->spacing(i)));
822 if (layer->spacingName(i))
823 fprintf(fout, " LAYER %s", layer->spacingName(i));
824 if (layer->hasSpacingLayerStack(i))
825 fprintf(fout, " STACK");
826 fprintf(fout,"\n");
827 if (layer->hasSpacingAdjacent(i))
828 fprintf(fout, "LAYER %s ADJACENTCUTS %d WITHIN %g\n", layer->name(),
829 layer->spacingAdjacentCuts(i),
830 chkNum(layer->spacingAdjacentWithin(i)));
831 if (layer->hasSpacingAdjacentExcept(i))
832 fprintf(fout, "LAYER %s EXCEPTSAMEPGNET\n", layer->name());
833 if (layer->hasSpacingCenterToCenter(i))
834 fprintf(fout, "LAYER %s CENTERTOCENTER\n", layer->name());
835 if (layer->hasSpacingSamenet(i)) {
836 fprintf(fout, "LAYER %s SAMENET", layer->name());
837 if (layer->hasSpacingSamenetPGonly(i))
838 fprintf(fout, " PGONLY\n");
839 else
840 fprintf(fout, "\n");
841 }
842 if (layer->hasSpacingArea(i))
843 fprintf(fout, "LAYER %s AREA %g\n", layer->name(),
844 chkNum(layer->spacingArea(i)));
845 if (layer->hasSpacingRange(i)) {
846 fprintf(fout, "LAYER %s RANGE %g %g", layer->name(),
847 chkNum(layer->spacingRangeMin(i)),
848 chkNum(layer->spacingRangeMax(i)));
849 if (layer->hasSpacingRangeUseLengthThreshold(i))
850 fprintf(fout, "USELENGTHTHRESHOLD ");
851 else if (layer->hasSpacingRangeInfluence(i)) {
852 fprintf(fout, "INFLUENCE %g ",
853 layer->spacingRangeInfluence(i));
854 if (layer->hasSpacingRangeInfluenceRange(i))
855 fprintf(fout, "RANGE %g %g ",
856 layer->spacingRangeInfluenceMin(i),
857 layer->spacingRangeInfluenceMax(i));
858 } else if (layer->hasSpacingRangeRange(i))
859 fprintf(fout, "RANGE %g %g ",
860 layer->spacingRangeRangeMin(i),
861 layer->spacingRangeRangeMax(i));
862 fprintf(fout,"\n");
863 }
864 else if (layer->hasSpacingLengthThreshold(i)) {
865 fprintf(fout, "LAYER %s LENGTHTHRESHOLD %g\n", layer->name(),
866 chkNum(layer->spacingLengthThreshold(i)));
867 if (layer->hasSpacingLengthThresholdRange(i))
868 fprintf(fout, "RANGE %g %g",
869 layer->spacingLengthThresholdRangeMin(i),
870 layer->spacingLengthThresholdRangeMax(i));
871 fprintf(fout,"\n");
872 }
873 else if (layer->hasSpacingNotchLength(i)) {
874 fprintf(fout, "LAYER %s NOTCHLENGTH %g\n", layer->name(),
875 chkNum(layer->spacingNotchLength(i)));
876 }
877 else if (layer->hasSpacingEndOfNotchWidth(i)) {
878 fprintf(fout, "LAYER %s ENDOFNOTCHWIDTH %g NOTCHSPACING %g, NOTCHLENGTH %g\n",
879 layer->name(),
880 chkNum(layer->spacingEndOfNotchWidth(i)),
881 chkNum(layer->spacingEndOfNotchSpacing(i)),
882 chkNum(layer->spacingEndOfNotchLength(i)));
883 }
884 if (layer->hasSpacingParallelOverlap(i))
885 fprintf(fout, "LAYER %s PARALLELOVERLAP\n", layer->name());
886 if (layer->hasSpacingEndOfLine(i)) {
887 fprintf(fout, "LAYER %s ENDOFLINE %g WITHIN %g ", layer->name(),
888 chkNum(layer->spacingEolWidth(i)),
889 chkNum(layer->spacingEolWithin(i)));
890 if (layer->hasSpacingParellelEdge(i)) {
891 fprintf(fout, "PARALLELEDGE %g WITHIN %g ",
892 chkNum(layer->spacingParSpace(i)),
893 chkNum(layer->spacingParWithin(i)));
894 if (layer->hasSpacingTwoEdges(i)) {
895 fprintf(fout, "TWOEDGES ");
896 }
897 }
898 fprintf(fout,"\n");
899 }
900 }
901 }
902 if (layer->hasSpacingTableOrtho()) {
903 fprintf(fout, "LAYER %s SPACINGTABLE ORTHOGONAL\n", layer->name());
904 ortho = layer->orthogonal();
905 for (i = 0; i < ortho->numOrthogonal(); i++) {
906 fprintf(fout, "LAYER %s SPACINGTABLE ORTHOGONAL WITHIN %g SPACING %g\n",
907 layer->name(), ortho->cutWithin(i),
908 ortho->orthoSpacing(i));
909 }
910 fprintf(fout, ";\n");
911 }
912 if (layer->numEnclosure() > 0) {
913 fprintf(fout, "LAYER %s ENCLOSURE", layer->name());
914 for (i = 0; i < layer->numEnclosure(); i++) {
915 if (layer->hasEnclosureRule(i))
916 fprintf(fout, " %s", layer->enclosureRule(i));
917 fprintf(fout, " %g %g", layer->enclosureOverhang1(i),
918 layer->enclosureOverhang2(i));
919 if (layer->hasEnclosureWidth(i))
920 fprintf(fout, " WIDTH %g", layer->enclosureMinWidth(i));
921 if (layer->hasEnclosureExceptExtraCut(i))
922 fprintf(fout, " EXCEPTEXTRACUT %g",
923 layer->enclosureExceptExtraCut(i));
924 if (layer->hasEnclosureMinLength(i))
925 fprintf(fout, " LENGTH %g", layer->enclosureMinLength(i));
926 fprintf(fout, "\n");
927 }
928 }
929 if (layer->numPreferEnclosure() > 0) {
930 fprintf(fout, "LAYER %s PREFERENCLOSURE", layer->name());
931 for (i = 0; i < layer->numPreferEnclosure(); i++) {
932 if (layer->hasPreferEnclosureRule(i))
933 fprintf(fout, "%s ", layer->preferEnclosureRule(i));
934 fprintf(fout, "%g %g ", layer->preferEnclosureOverhang1(i),
935 layer->preferEnclosureOverhang2(i));
936 if (layer->hasPreferEnclosureWidth(i))
937 fprintf(fout, "WIDTH %g ",layer->preferEnclosureMinWidth(i));
938 fprintf(fout, "\n");
939 }
940 }
941 if (layer->hasResistancePerCut())
942 fprintf(fout, "LAYER %s RESISTANCE %g\n", layer->name(),
943 chkNum(layer->resistancePerCut()));
944 if (layer->hasCurrentDensityPoint())
945 fprintf(fout, "LAYER %s CURRENTDEN %g\n", layer->name(),
946 chkNum(layer->currentDensityPoint()));
947 if (layer->hasCurrentDensityArray()) {
948 layer->currentDensityArray(&numPoints, &widths, ¤t);
949 for (i = 0; i < numPoints; i++)
950 fprintf(fout, "LAYER %s CURRENTDEN ( %g %g )\n", layer->name(),
951 chkNum(widths[i]), chkNum(current[i]));
952 }
953 if (layer->hasDirection())
954 fprintf(fout, "LAYER %s DIRECTION %s\n", layer->name(),
955 layer->direction());
956 if (layer->hasResistance())
957 fprintf(fout, "LAYER %s RESISTANCE RPERSQ %g\n", layer->name(),
958 chkNum(layer->resistance()));
959 if (layer->hasCapacitance())
960 fprintf(fout, "LAYER %s CAPACITANCE CPERSQDIST %g\n", layer->name(),
961 chkNum(layer->capacitance()));
962 if (layer->hasHeight())
963 fprintf(fout, "LAYER %s HEIGHT %g\n", layer->name(), chkNum(layer->height()));
964 if (layer->hasThickness())
965 fprintf(fout, "LAYER %s THICKNESS %g\n", layer->name(),
966 chkNum(layer->thickness()));
967 if (layer->hasWireExtension())
968 fprintf(fout, "LAYER %s WIREEXTENSION %g\n", layer->name(),
969 chkNum(layer->wireExtension()));
970 if (layer->hasShrinkage())
971 fprintf(fout, "LAYER %s SHRINKAGE %g\n", layer->name(),
972 chkNum(layer->shrinkage()));
973 if (layer->hasCapMultiplier())
974 fprintf(fout, "LAYER %s CAPMULTIPLIER %g\n", layer->name(),
975 chkNum(layer->capMultiplier()));
976 if (layer->hasEdgeCap())
977 fprintf(fout, "LAYER %s EDGECAPACITANCE %g\n", layer->name(),
978 chkNum(layer->edgeCap()));
979 if (layer->hasAntennaArea())
980 fprintf(fout, "LAYER %s ANTAREAFACTOR %g\n", layer->name(),
981 chkNum(layer->antennaArea()));
982 if (layer->hasAntennaLength())
983 fprintf(fout, "LAYER %s ANTLENGTHFACTOR %g\n", layer->name(),
984 chkNum(layer->antennaLength()));
985 for (j = 0; j < layer->numAntennaModel(); j++) { // 5.5
986 aModel = layer->antennaModel(j);
987
988 if (aModel->hasAntennaAreaRatio())
989 fprintf(fout, "LAYER %s %s ANTAREARATIO %g\n", layer->name(),
990 aModel->antennaOxide(),
991 chkNum(aModel->antennaAreaRatio()));
992 if (aModel->hasAntennaDiffAreaRatio())
993 fprintf(fout, "LAYER %s %s ANTDIFFAREARATIO %g\n", layer->name(),
994 aModel->antennaOxide(),
995 chkNum(aModel->antennaDiffAreaRatio()));
996 else if (aModel->hasAntennaDiffAreaRatioPWL()) {
997 pwl = aModel->antennaDiffAreaRatioPWL();
998 fprintf(fout, "LAYER %s %s ANTDIFFAREARATIO PWL", layer->name(),
999 aModel->antennaOxide());
1000 for (i = 0; i < pwl->numPWL(); i++)
1001 fprintf(fout, " %g %g", chkNum(pwl->PWLdiffusion(i)),
1002 chkNum(pwl->PWLratio(i)));
1003 fprintf(fout, "\n");
1004 }
1005 if (aModel->hasAntennaCumAreaRatio())
1006 fprintf(fout, "LAYER %s %s ANTCUMAREARATIO %g\n", layer->name(),
1007 aModel->antennaOxide(),
1008 chkNum(aModel->antennaCumAreaRatio()));
1009 if (aModel->hasAntennaCumDiffAreaRatio())
1010 fprintf(fout, "LAYER %s %s ANTCUMDIFFAREARATIO %g\n", layer->name(),
1011 aModel->antennaOxide(),
1012 chkNum(aModel->antennaCumDiffAreaRatio()));
1013 else if (aModel->hasAntennaCumDiffAreaRatioPWL()) {
1014 pwl = aModel->antennaCumDiffAreaRatioPWL();
1015 fprintf(fout, "LAYER %s %s ANTCUMDIFFAREARATIO PWL", layer->name(),
1016 aModel->antennaOxide());
1017 for (i = 0; i < pwl->numPWL(); i++)
1018 fprintf(fout, " %g %g", chkNum(pwl->PWLdiffusion(i)),
1019 chkNum(pwl->PWLratio(i)));
1020 fprintf(fout, "\n");
1021 }
1022 if (aModel->hasAntennaAreaFactor()) {
1023 fprintf(fout, "LAYER %s %s ANTAREAFACTOR %g", layer->name(),
1024 aModel->antennaOxide(),
1025 chkNum(aModel->antennaAreaFactor()));
1026 if (aModel->hasAntennaAreaFactorDUO())
1027 fprintf(fout, " DIFFUSEONLY");
1028 fprintf(fout, "\n");
1029 }
1030 if (aModel->hasAntennaSideAreaRatio())
1031 fprintf(fout, "LAYER %s %s ANTSIDEAREARATIO %g\n", layer->name(),
1032 aModel->antennaOxide(),
1033 chkNum(aModel->antennaSideAreaRatio()));
1034 if (aModel->hasAntennaDiffSideAreaRatio())
1035 fprintf(fout, "LAYER %s %s ANTDIFFSIDEAREARATIO %g\n", layer->name(),
1036 aModel->antennaOxide(),
1037 chkNum(aModel->antennaDiffSideAreaRatio()));
1038 else if (aModel->hasAntennaDiffSideAreaRatioPWL()) {
1039 pwl = aModel->antennaDiffSideAreaRatioPWL();
1040 fprintf(fout, "LAYER %s %s ANTDIFFSIDEAREARATIO PWL", layer->name(),
1041 aModel->antennaOxide());
1042 for (i = 0; i < pwl->numPWL(); i++)
1043 fprintf(fout, " %g %g", chkNum(pwl->PWLdiffusion(i)),
1044 chkNum(pwl->PWLratio(i)));
1045 fprintf(fout, "\n");
1046 }
1047 if (aModel->hasAntennaCumSideAreaRatio())
1048 fprintf(fout, "LAYER %s %s ANTCUMSIDEAREARATIO %g\n", layer->name(),
1049 aModel->antennaOxide(),
1050 chkNum(aModel->antennaCumSideAreaRatio()));
1051 if (aModel->hasAntennaCumDiffSideAreaRatio())
1052 fprintf(fout, "LAYER %s %s ANTCUMDIFFSIDEAREARATIO %g\n", layer->name(),
1053 aModel->antennaOxide(),
1054 chkNum(aModel->antennaCumDiffSideAreaRatio()));
1055 else if (aModel->hasAntennaCumDiffSideAreaRatioPWL()) {
1056 pwl = aModel->antennaCumDiffSideAreaRatioPWL();
1057 fprintf(fout, "LAYER %s %s ANTCUMDIFFSIDEAREARATIO PWL", layer->name(),
1058 aModel->antennaOxide());
1059 for (i = 0; i < pwl->numPWL(); i++)
1060 fprintf(fout, "%g %g ", chkNum(pwl->PWLdiffusion(i)),
1061 chkNum(pwl->PWLratio(i)));
1062 fprintf(fout, "\n");
1063 }
1064 if (aModel->hasAntennaSideAreaFactor()) {
1065 fprintf(fout, " ANTSIDEAREAFACTOR %g ",
1066 chkNum(aModel->antennaSideAreaFactor()));
1067 if (aModel->hasAntennaSideAreaFactorDUO())
1068 fprintf(fout, " DIFFUSEONLY ");
1069 fprintf(fout, "\n");
1070 }
1071 }
1072
1073 if (layer->numAccurrentDensity()) {
1074 for (i = 0; i < layer->numAccurrentDensity(); i++) {
1075 density = layer->accurrent(i);
1076 fprintf(fout, "LAYER %s ACCURRENTDENSITY %s", layer->name(),
1077 density->type());
1078 needHeading = 0;
1079 if (density->hasOneEntry())
1080 fprintf(fout, " %g\n", chkNum(density->oneEntry()));
1081 else {
1082 if (density->numFrequency()) {
1083 /*
1084 if (needHeading) {
1085 fprintf(fout, "LAYER %s ACCURRENTDENSITY %s", layer->name(),
1086 density->type());
1087 }
1088 */
1089 fprintf(fout, " FREQUENCY");
1090 for (j = 0; j < density->numFrequency(); j++)
1091 fprintf(fout, " %g", chkNum(density->frequency(j)));
1092 fprintf(fout, "\n");
1093 needHeading = 1;
1094 }
1095 if (density->numWidths()) {
1096 if (needHeading) {
1097 fprintf(fout, "LAYER %s ACCURRENTDENSITY %s", layer->name(),
1098 density->type());
1099 }
1100 fprintf(fout, " WIDTH");
1101 for (j = 0; j < density->numWidths(); j++)
1102 fprintf(fout, " %g", chkNum(density->width(j)));
1103 fprintf(fout, "\n");
1104 needHeading = 1;
1105 }
1106 if (density->numTableEntries()) {
1107 if (needHeading) {
1108 fprintf(fout, "LAYER %s ACCURRENTDENSITY %s", layer->name(),
1109 density->type());
1110 k = 0;
1111 }
1112 else k = 5;
1113 fprintf(fout, " TABLEENTRIES");
1114 for (j = 0; j < density->numTableEntries(); j++) {
1115 if (k > 4) {
1116 fprintf(fout,
1117 "\nLAYER %s ACCURRENTDENSITY %s TABLEENTRIES %g",
1118 layer->name(), density->type(),
1119 chkNum(density->tableEntry(j)));
1120 k = 1;
1121 } else {
1122 fprintf(fout, " %g", chkNum(density->tableEntry(j)));
1123 k++;
1124 }
1125 }
1126 fprintf(fout, "\n");
1127 needHeading = 1;
1128 }
1129 }
1130 }
1131 }
1132 if (layer->numDccurrentDensity()) {
1133 for (i = 0; i < layer->numDccurrentDensity(); i++) {
1134 density = layer->dccurrent(i);
1135 fprintf(fout, "LAYER %s DCCURRENTDENSITY %s", layer->name(),
1136 density->type());
1137 needHeading = 0;
1138 if (density->hasOneEntry())
1139 fprintf(fout, " %g\n", chkNum(density->oneEntry()));
1140 else {
1141 if (density->numCutareas()) {
1142 /*
1143 if (needHeading) {
1144 fprintf(fout, "LAYER %s DCCURRENTDENSITY %s", layer->name(),
1145 density->type());
1146 }
1147 */
1148 fprintf(fout, " CUTAREA");
1149 for (j = 0; j < density->numCutareas(); j++)
1150 fprintf(fout, " %g", chkNum(density->cutArea(j)));
1151 fprintf(fout, "\n");
1152 needHeading = 1;
1153 }
1154 if (density->numWidths()) {
1155 if (needHeading) {
1156 fprintf(fout, "LAYER %s DCCURRENTDENSITY %s", layer->name(),
1157 density->type());
1158 }
1159 fprintf(fout, " WIDTH");
1160 for (j = 0; j < density->numWidths(); j++)
1161 fprintf(fout, " %g", chkNum(density->width(j)));
1162 fprintf(fout, "\n");
1163 needHeading = 1;
1164 }
1165 if (density->numTableEntries()) {
1166 if (needHeading) {
1167 fprintf(fout, "LAYER %s DCCURRENTDENSITY %s", layer->name(),
1168 density->type());
1169 }
1170 fprintf(fout, " TABLEENTRIES");
1171 for (j = 0; j < density->numTableEntries(); j++)
1172 fprintf(fout, " %g", chkNum(density->tableEntry(j)));
1173 fprintf(fout, "\n");
1174 needHeading = 1;
1175 }
1176 }
1177 }
1178 }
1179
1180 for (i = 0; i < layer->numSpacingTable(); i++) {
1181 spTable = layer->spacingTable(i);
1182 if (spTable->isInfluence()) {
1183 influence = spTable->influence();
1184 for (j = 0; j < influence->numInfluenceEntry(); j++) {
1185 fprintf(fout, "LAYER %s SPACINGTABLE INFLUENCE WIDTH %g WITHIN %g SPACING %g\n",
1186 layer->name(), influence->width(j), influence->distance(j),
1187 influence->spacing(j));
1188 }
1189 } else if (spTable->isParallel()) {
1190 parallel = spTable->parallel();
1191 fprintf(fout, "LAYER %s SPACINGTABLE PARALLELRUNLENGTH", layer->name());
1192 for (j = 0; j < parallel->numLength(); j++) {
1193 fprintf(fout, " %g", parallel->length(j));
1194 }
1195 fprintf(fout, "\n");
1196 for (j = 0; j < parallel->numWidth(); j++) {
1197 fprintf(fout, "LAYER %s SPACINGTABLE PARALLELRUNLENGTH WIDTH %g",
1198 layer->name(), parallel->width(j));
1199 for (k = 0; k < parallel->numLength(); k++) {
1200 fprintf(fout, " %g", parallel->widthSpacing(j, k));
1201 }
1202 }
1203 fprintf(fout, "\n");
1204 } else {
1205 twoWidths = spTable->twoWidths();
1206 for (j = 0; j < twoWidths->numWidth(); j++) {
1207 fprintf(fout, "LAYER %s TWOWIDTHS", layer->name());
1208 fprintf(fout, " WIDTH %g", twoWidths->width(j));
1209 if (twoWidths->hasWidthPRL(j))
1210 fprintf(fout, " PRL %g", twoWidths->widthPRL(j));
1211 for (k = 0; k < twoWidths->numWidthSpacing(j); k++)
1212 fprintf(fout, " %g",twoWidths->widthSpacing(j, k));
1213 fprintf(fout, "\n");
1214 }
1215 }
1216 }
1217 propNum = layer->numProps();
1218 if (propNum > 0) {
1219 for (i = 0; i < propNum; i++) {
1220 fprintf(fout, "LAYER %s PROP ", layer->name());
1221 // value can either be a string or number
1222 fprintf(fout, "%s %s ", layer->propName(i),
1223 layer->propValue(i));
1224 pType = layer->propType(i);
1225 switch (pType) {
1226 case 'R': fprintf(fout, "REAL");
1227 break;
1228 case 'I': fprintf(fout, "INTEGER");
1229 break;
1230 case 'S': fprintf(fout, "STRING");
1231 break;
1232 case 'Q': fprintf(fout, "QUOTESTRING");
1233 break;
1234 case 'N': fprintf(fout, "NUMBER");
1235 break;
1236 }
1237 fprintf(fout, "\n");
1238 }
1239 }
1240
1241 return 0;
1242 }
1243
1244 // Macro
macroCB(lefrCallbackType_e c,lefiMacro * macro,lefiUserData ud)1245 int macroCB(lefrCallbackType_e c, lefiMacro* macro, lefiUserData ud) {
1246 lefiSitePattern* pattern;
1247 int propNum, i, hasPrtSym = 0;
1248
1249 checkType(c);
1250 if (ud != userData) dataError();
1251 fprintf(fout, "MACRO %s", macro->name());
1252 if (macro->hasClass())
1253 fprintf(fout, " CLASS %s", macro->macroClass());
1254 if (macro->isFixedMask())
1255 fprintf(fout, " FIXEDMASK ");
1256 if (macro->hasEEQ())
1257 fprintf(fout, " EEQ %s", macro->EEQ());
1258 if (macro->hasLEQ())
1259 fprintf(fout, " LEQ %s", macro->LEQ());
1260 if (macro->hasSource())
1261 fprintf(fout, " SOURCE %s", macro->source());
1262 if (macro->hasXSymmetry()) {
1263 fprintf(fout, " SYMMETRY X ");
1264 hasPrtSym = 1;
1265 }
1266 if (macro->hasYSymmetry()) { // print X Y & R90 in one line
1267 if (!hasPrtSym) {
1268 fprintf(fout, " SYMMETRY Y ");
1269 hasPrtSym = 1;
1270 }
1271 else
1272 fprintf(fout, "Y ");
1273 }
1274 if (macro->has90Symmetry()) {
1275 if (!hasPrtSym) {
1276 fprintf(fout, " SYMMETRY R90 ");
1277 hasPrtSym = 1;
1278 }
1279 else
1280 fprintf(fout, "R90 ");
1281 }
1282 fprintf (fout, "\n");
1283 if (macro->hasSiteName())
1284 fprintf(fout, "MACRO %s SITE %s\n", macro->name(), macro->siteName());
1285 if (macro->hasSitePattern()) {
1286 for (i = 0; i < macro->numSitePattern(); i++ ) {
1287 pattern = macro->sitePattern(i);
1288 if (pattern->hasStepPattern())
1289 fprintf(fout, "MACRO %s SITE %s %g %g %d DO %g BY %g STEP %g %g\n",
1290 macro->name(), pattern->name(), chkNum(pattern->x()),
1291 chkNum(pattern->y()), pattern->orient(),
1292 chkNum(pattern->xStart()), chkNum(pattern->yStart()),
1293 chkNum(pattern->xStep()), chkNum(pattern->yStep()));
1294 else
1295 fprintf(fout, "MACRO %s SITE %s %g %g %d\n",
1296 macro->name(), pattern->name(), chkNum(pattern->x()),
1297 chkNum(pattern->y()), pattern->orient());
1298 }
1299 }
1300 if (macro->hasSize())
1301 fprintf(fout, "MACRO %s SIZE %g BY %g\n", macro->name(),
1302 chkNum(macro->sizeX()), chkNum(macro->sizeY()));
1303 if (macro->hasForeign()) {
1304 for (i = 0; i < macro->numForeigns(); i++) {
1305 fprintf(fout, "MACRO %s FOREIGN %s", macro->name(),
1306 macro->foreignName(i));
1307 if (macro->hasForeignPoint(i)) {
1308 fprintf(fout, " ( %g %g )", chkNum(macro->foreignX(i)),
1309 chkNum(macro->foreignY(i)));
1310 if (macro->hasForeignOrient(i))
1311 fprintf(fout, " %s", lefiOrientStr(macro->foreignOrient(i)));
1312 }
1313 fprintf(fout, "\n");
1314 }
1315 }
1316 if (macro->hasOrigin())
1317 fprintf(fout, "MACRO %s ORIGIN ( %g %g )\n", macro->name(),
1318 chkNum(macro->originX()), chkNum(macro->originY()));
1319 if (macro->hasPower())
1320 fprintf(fout, "MACRO %s POWER %g\n", macro->name(), chkNum(macro->power()));
1321 propNum = macro->numProperties();
1322 if (propNum > 0) {
1323 for (i = 0; i < propNum; i++) {
1324 fprintf(fout, "MACRO %s PROP", macro->name());
1325 // value can either be a string or number
1326 if (macro->propValue(i)) {
1327 fprintf(fout, " %s %s\n", macro->propName(i), macro->propValue(i));
1328 }
1329 else
1330 fprintf(fout, " %s %g\n", macro->propName(i),
1331 chkNum(macro->propNum(i)));
1332 }
1333 }
1334 return 0;
1335 }
1336
1337 // Manufacturinggrid
manufacturingCB(lefrCallbackType_e c,double num,lefiUserData ud)1338 int manufacturingCB(lefrCallbackType_e c, double num, lefiUserData ud) {
1339 checkType(c);
1340 if (ud != userData) dataError();
1341 fprintf(fout, "MANUFACTURINGGRID %g\n", chkNum(num));
1342 return 0;
1343 }
1344
1345 // Maxviastack
maxStackViaCB(lefrCallbackType_e c,lefiMaxStackVia * maxStack,lefiUserData ud)1346 int maxStackViaCB(lefrCallbackType_e c, lefiMaxStackVia* maxStack,
1347 lefiUserData ud) {
1348 checkType(c);
1349 if (ud != userData) dataError();
1350 fprintf(fout, "MAXVIASTACK %d", maxStack->maxStackVia());
1351 if (maxStack->hasMaxStackViaRange())
1352 fprintf(fout, " RANGE %s %s",
1353 maxStack->maxStackViaBottomLayer(),
1354 maxStack->maxStackViaTopLayer());
1355 fprintf(fout, "\n");
1356 return 0;
1357 }
1358
1359 // Minfeature
minFeatureCB(lefrCallbackType_e c,lefiMinFeature * min,lefiUserData ud)1360 int minFeatureCB(lefrCallbackType_e c, lefiMinFeature* min, lefiUserData ud) {
1361 checkType(c);
1362 if (ud != userData) dataError();
1363 fprintf(fout, "MINFEATURE %g %g\n", chkNum(min->one()), chkNum(min->two()));
1364 return 0;
1365 }
1366
1367 // Universalnoisemargin
noiseMarginCB(lefrCallbackType_e c,lefiNoiseMargin * margin,lefiUserData ud)1368 int noiseMarginCB(lefrCallbackType_e c, lefiNoiseMargin* margin,
1369 lefiUserData ud) {
1370 checkType(c);
1371 if (ud != userData) dataError();
1372 fprintf(fout, "UNIVERSALNOISEMARGIN %g %g\n", chkNum(margin->high),
1373 chkNum(margin->low));
1374 return 0;
1375 }
1376
1377 // NoiseTable
noiseTableCB(lefrCallbackType_e c,lefiNoiseTable * table,lefiUserData ud)1378 int noiseTableCB(lefrCallbackType_e c, lefiNoiseTable* table, lefiUserData ud) {
1379 int i, j, k, l;
1380 lefiNoiseEdge *edge;
1381 lefiNoiseResistance *resist;
1382 lefiNoiseVictim *victim;
1383
1384 checkType(c);
1385 if (ud != userData) dataError();
1386 fprintf(fout, "CROSSTALK NOISETABLE %d\n", table->num());
1387 if (table->numEdges() > 0) {
1388 for (i = 0; i < table->numEdges(); i++) {
1389 edge = table->edge(i);
1390 // resistances
1391 if (edge->numResistances()) {
1392 for (j = 0; j < edge->numResistances(); j++) {
1393 resist = edge->resistance(j);
1394 fprintf(fout, "NOISETABLE %d RESISTANCE %g\n",
1395 table->num(), chkNum(resist->num(j)));
1396 // victims
1397 for (k = 0; k < resist->numVictims(); k++) {
1398 victim = resist->victim(k);
1399 if (victim->length() > 0)
1400 fprintf(fout, "CROSSTALK NOISETABLE %d RESISTANCE %g VICTIMLENGTH % g\n",
1401 table->num(), chkNum(resist->num(j)),
1402 chkNum(victim->length()));
1403 for (l = 0; l < victim->numNoises(); l++)
1404 fprintf(fout, "CROSSTALK NOISETABLE %d RESISTANCE %g VICTIMLENGT %g NOISEFACTOR %g\n",
1405 table->num(), chkNum(resist->num(j)),
1406 chkNum(victim->length()), chkNum(victim->noise(l)));
1407 }
1408 }
1409 }
1410 }
1411 }
1412 return 0;
1413 }
1414
1415 // Nondefault
nonDefaultCB(lefrCallbackType_e c,lefiNonDefault * def,lefiUserData ud)1416 int nonDefaultCB(lefrCallbackType_e c, lefiNonDefault* def, lefiUserData ud) {
1417 int i;
1418 lefiVia* via;
1419 lefiSpacing* spacing;
1420 char defName[1024];
1421
1422 checkType(c);
1423 if (ud != userData) dataError();
1424 if (def->hasHardspacing())
1425 fprintf(fout, "NONDEFAULTRULE HARDSPACING\n");
1426 for (i = 0; i < def->numLayers(); i++) {
1427 fprintf(fout, "NONDEFAULTRULE %s LAYER %s", def->name(),
1428 def->layerName(i));
1429 if (def->hasLayerWidth(i))
1430 fprintf(fout, " WIDTH %g", chkNum(def->layerWidth(i)));
1431 if (def->hasLayerDiagWidth(i))
1432 fprintf(fout, " DIAGWIDTH %g", chkNum(def->layerDiagWidth(i)));
1433 if (def->hasLayerSpacing(i))
1434 fprintf(fout, " SPACING %g", chkNum(def->layerSpacing(i)));
1435 if (def->hasLayerWireExtension(i))
1436 fprintf(fout, " WIREEXTENSION %g", chkNum(def->layerWireExtension(i)));
1437 if (def->hasLayerResistance(i))
1438 fprintf(fout, " RESISTANCE RPERSQ %g", chkNum(def->layerResistance(i)));
1439 if (def->hasLayerCapacitance(i))
1440 fprintf(fout, " CAPACITANCE CPERSQDIST %g",
1441 chkNum(def->layerCapacitance(i)));
1442 if (def->hasLayerEdgeCap(i))
1443 fprintf(fout, " EDGECAPACITANCE %g", chkNum(def->layerEdgeCap(i)));
1444 fprintf(fout, "\n");
1445 }
1446
1447 sprintf(defName, "NONDEFAULTRULE %s VIA", def->name());
1448 // handle via in nondefaultrule
1449 for (i = 0; i < def->numVias(); i++) {
1450 via = def->viaRule(i);
1451 lefVia(via, defName);
1452 }
1453
1454 sprintf(defName, "NONDEFAULTRULE %s SPACING", def->name());
1455 // handle spacing in nondefaultrule
1456 for (i = 0; i < def->numSpacingRules(); i++) {
1457 spacing = def->spacingRule(i);
1458 lefSpacing(spacing, defName);
1459 }
1460
1461 if (def->numUseVia() > 0) {
1462 fprintf(fout, "NONDEFAULTRULE %s USEVIA", def->name());
1463 // handle spacing in nondefaultrule
1464 for (i = 0; i < def->numUseVia(); i++)
1465 fprintf(fout, " %s", def->viaName(i));
1466 fprintf(fout, "\n");
1467 }
1468
1469 if (def->numUseViaRule() > 0) {
1470 fprintf(fout, "NONDEFAULTRULE %s USEVIARULE", def->name());
1471 // handle spacing in nondefaultrule
1472 for (i = 0; i < def->numUseViaRule(); i++)
1473 fprintf(fout, " %s", def->viaRuleName(i));
1474 fprintf(fout, "\n");
1475 }
1476
1477 if (def->numMinCuts() > 0) {
1478 fprintf(fout, "NONDEFAULTRULE %s MINCUTS", def->name());
1479 // handle spacing in nondefaultrule
1480 for (i = 0; i < def->numMinCuts(); i++)
1481 fprintf(fout, " %s %d", def->cutLayerName(i), def->numCuts(i));
1482 fprintf(fout, "\n");
1483 }
1484
1485 return 0;
1486 }
1487
1488 // Nowireextension
noWireExtCB(lefrCallbackType_e c,const char * wireExt,lefiUserData ud)1489 int noWireExtCB(lefrCallbackType_e c, const char* wireExt, lefiUserData ud) {
1490 checkType(c);
1491 if (ud != userData) dataError();
1492 fprintf(fout, "NOWIREEXTENSION %s\n", wireExt);
1493 return 0;
1494 }
1495
1496 // Obstruction
obstructionCB(lefrCallbackType_e c,lefiObstruction * obs,lefiUserData ud)1497 int obstructionCB(lefrCallbackType_e c, lefiObstruction* obs,
1498 lefiUserData ud) {
1499 lefiGeometries* geometry;
1500
1501 checkType(c);
1502 if (ud != userData) dataError();
1503 geometry = obs->geometries();
1504 prtGeometry(geometry, (char*)"OBS");
1505 return 0;
1506 }
1507
1508 // Pin
pinCB(lefrCallbackType_e c,lefiPin * pin,lefiUserData ud)1509 int pinCB(lefrCallbackType_e c, lefiPin* pin, lefiUserData ud) {
1510 int numPorts, i, j;
1511 lefiGeometries* geometry;
1512 lefiPinAntennaModel* aModel;
1513
1514 checkType(c);
1515 if (ud != userData) dataError();
1516 if (pin->hasForeign()) {
1517 if (pin->hasForeignOrient())
1518 fprintf(fout, "PIN %s FOREIGN %s STRUCTURE %g %g %s\n", pin->name(),
1519 pin->foreignName(), chkNum(pin->foreignX()),
1520 chkNum(pin->foreignY()), lefiOrientStr(pin->foreignOrient()));
1521 else if (pin->hasForeignPoint())
1522 fprintf(fout, "PIN %s FOREIGN %s STRUCTURE %g %g", pin->name(),
1523 pin->foreignName(), chkNum(pin->foreignX()),
1524 chkNum(pin->foreignY()));
1525 else
1526 fprintf(fout, "PIN %s FOREIGN %s\n", pin->name(), pin->foreignName());
1527 }
1528 if (pin->hasLEQ())
1529 fprintf(fout, "PIN %s LEQ %s\n", pin->name(), pin->LEQ());
1530 if (pin->hasDirection())
1531 fprintf(fout, "PIN %s DIRECTION %s\n", pin->name(), pin->direction());
1532 if (pin->hasUse())
1533 fprintf(fout, "PIN %s USE %s\n", pin->name(), pin->use());
1534 if (pin->hasShape())
1535 fprintf(fout, "PIN %s SHAPE %s\n", pin->name(), pin->shape());
1536 if (pin->hasMustjoin())
1537 fprintf(fout, "PIN %s MUSTJOIN %s\n", pin->name(), pin->mustjoin());
1538 if (pin->hasOutMargin())
1539 fprintf(fout, "PIN %s OUTPUTNOISEMARGIN %g %g\n", pin->name(),
1540 chkNum(pin->outMarginHigh()), chkNum(pin->outMarginLow()));
1541 if (pin->hasOutResistance())
1542 fprintf(fout, "PIN %s OUTPUTRESISTANCE %g %g\n", pin->name(),
1543 chkNum(pin->outResistanceHigh()), chkNum(pin->outResistanceLow()));
1544 if (pin->hasInMargin())
1545 fprintf(fout, "PIN %s INPUTNOISEMARGIN %g %g\n", pin->name(),
1546 chkNum(pin->inMarginHigh()), chkNum(pin->inMarginLow()));
1547 if (pin->hasPower())
1548 fprintf(fout, "PIN %s POWER %g\n", pin->name(), chkNum(pin->power()));
1549 if (pin->hasLeakage())
1550 fprintf(fout, "PIN %s LEAKAGE %g\n", pin->name(), chkNum(pin->leakage()));
1551 if (pin->hasMaxload())
1552 fprintf(fout, "PIN %s MAXLOAD %g\n", pin->name(), chkNum(pin->maxload()));
1553 if (pin->hasCapacitance())
1554 fprintf(fout, "PIN %s CAPACITANCE %g\n", pin->name(),
1555 chkNum(pin->capacitance()));
1556 if (pin->hasResistance())
1557 fprintf(fout, "PIN %s RESISTANCE %g\n", pin->name(),
1558 chkNum(pin->resistance()));
1559 if (pin->hasPulldownres())
1560 fprintf(fout, "PIN %s PULLDOWNRES %g\n", pin->name(),
1561 chkNum(pin->pulldownres()));
1562 if (pin->hasTieoffr())
1563 fprintf(fout, "PIN %s TIEOFFR %g\n", pin->name(), chkNum(pin->tieoffr()));
1564 if (pin->hasVHI())
1565 fprintf(fout, "PIN %s VHI %g\n", pin->name(), chkNum(pin->VHI()));
1566 if (pin->hasVLO())
1567 fprintf(fout, "PIN %s VLO %g\n", pin->name(), chkNum(pin->VLO()));
1568 if (pin->hasRiseVoltage())
1569 fprintf(fout, "PIN %s RISEVOLTAGETHRESHOLD %g\n", pin->name(),
1570 chkNum(pin->riseVoltage()));
1571 if (pin->hasFallVoltage())
1572 fprintf(fout, "PIN %s FALLVOLTAGETHRESHOLD %g\n", pin->name(),
1573 chkNum(pin->fallVoltage()));
1574 if (pin->hasRiseThresh())
1575 fprintf(fout, "PIN %s RISETHRESH %g\n", pin->name(),
1576 chkNum(pin->riseThresh()));
1577 if (pin->hasFallThresh())
1578 fprintf(fout, "PIN %s FALLTHRESH %g\n", pin->name(),
1579 chkNum(pin->fallThresh()));
1580 if (pin->hasRiseSatcur())
1581 fprintf(fout, "PIN %s RISESATCUR %g\n", pin->name(),
1582 chkNum(pin->riseSatcur()));
1583 if (pin->hasFallSatcur())
1584 fprintf(fout, "PIN %s FALLSATCUR %g\n", pin->name(),
1585 chkNum(pin->fallSatcur()));
1586 if (pin->hasRiseSlewLimit())
1587 fprintf(fout, "PIN %s RISESLEWLIMIT %g\n", pin->name(),
1588 chkNum(pin->riseSlewLimit()));
1589 if (pin->hasFallSlewLimit())
1590 fprintf(fout, "PIN %s FALLSLEWLIMIT %g\n", pin->name(),
1591 chkNum(pin->fallSlewLimit()));
1592 if (pin->hasCurrentSource())
1593 fprintf(fout, "PIN %s CURRENTSOURCE %s\n", pin->name(),
1594 pin->currentSource());
1595 if (pin->hasTables())
1596 fprintf(fout, "PIN %s IV_TABLES %s %s\n", pin->name(),
1597 pin->tableHighName(), pin->tableLowName());
1598 if (pin->hasTaperRule())
1599 fprintf(fout, "PIN %s TAPERRULE %s\n", pin->name(), pin->taperRule());
1600 if (pin->hasNetExpr())
1601 fprintf(fout, "PIN %s NETEXPR %s\n",pin->name(), pin->netExpr());
1602 if (pin->hasSupplySensitivity())
1603 fprintf(fout, "PIN %s SUPPLYSENSITIVITY %s\n", pin->name(),
1604 pin->supplySensitivity());
1605 if (pin->hasGroundSensitivity())
1606 fprintf(fout, "PIN %s GROUNDSENSITIVITY %s\n", pin->name(),
1607 pin->groundSensitivity());
1608 if (pin->hasAntennaSize()) {
1609 for (i = 0; i < pin->numAntennaSize(); i++) {
1610 fprintf(fout, "PIN %s ANTSIZE %g", pin->name(),
1611 chkNum(pin->antennaSize(i)));
1612 if (pin->antennaSizeLayer(i))
1613 fprintf(fout, " LAYER %s\n", pin->antennaSizeLayer(i));
1614 else
1615 fprintf(fout, "\n");
1616 }
1617 }
1618 if (pin->hasAntennaMetalArea()) {
1619 for (i = 0; i < pin->numAntennaMetalArea(); i++) {
1620 fprintf(fout, "PIN %s ANTMETALAREA %g", pin->name(),
1621 chkNum(pin->antennaMetalArea(i)));
1622 if (pin->antennaMetalAreaLayer(i))
1623 fprintf(fout, " LAYER %s\n", pin->antennaMetalAreaLayer(i));
1624 else
1625 fprintf(fout, "\n");
1626 }
1627 }
1628 if (pin->hasAntennaMetalLength()) {
1629 for (i = 0; i < pin->numAntennaMetalLength(); i++) {
1630 fprintf(fout, "PIN %s ANTMETALLENGTH %g", pin->name(),
1631 chkNum(pin->antennaMetalLength(i)));
1632 if (pin->antennaMetalLengthLayer(i))
1633 fprintf(fout, " LAYER %s\n", pin->antennaMetalLengthLayer(i));
1634 else
1635 fprintf(fout, "\n");
1636 }
1637 }
1638 if (pin->hasAntennaPartialMetalArea()) {
1639 for (i = 0; i < pin->numAntennaPartialMetalArea(); i++) {
1640 fprintf(fout, "PIN %s ANTPARTIALMETALAREA %g", pin->name(),
1641 chkNum(pin->antennaPartialMetalArea(i)));
1642 if (pin->antennaPartialMetalAreaLayer(i))
1643 fprintf(fout, " LAYER %s",
1644 pin->antennaPartialMetalAreaLayer(i));
1645 fprintf(fout, "\n");
1646 }
1647 }
1648 if (pin->hasAntennaPartialMetalSideArea()) {
1649 for (i = 0; i < pin->numAntennaPartialMetalSideArea(); i++) {
1650 fprintf(fout, "PIN %s ANTPARTIALMETALSIDEAREA %g", pin->name(),
1651 chkNum(pin->antennaPartialMetalSideArea(i)));
1652 if (pin->antennaPartialMetalSideAreaLayer(i))
1653 fprintf(fout, " LAYER %s ",
1654 pin->antennaPartialMetalSideAreaLayer(i));
1655 fprintf(fout, "\n");
1656 }
1657 }
1658 if (pin->hasAntennaPartialCutArea()) {
1659 for (i = 0; i < pin->numAntennaPartialCutArea(); i++) {
1660 fprintf(fout, "PIN %s ANTPARTIALCUTAREA %g", pin->name(),
1661 chkNum(pin->antennaPartialCutArea(i)));
1662 if (pin->antennaPartialCutAreaLayer(i))
1663 fprintf(fout, " LAYER %s ",
1664 pin->antennaPartialCutAreaLayer(i));
1665 fprintf(fout, "\n");
1666 }
1667 }
1668 if (pin->hasAntennaDiffArea()) {
1669 for (i = 0; i < pin->numAntennaDiffArea(); i++) {
1670 fprintf(fout, "PIN %s ANTDIFFAREA %g", pin->name(),
1671 chkNum(pin->antennaDiffArea(i)));
1672 if (pin->antennaDiffAreaLayer(i))
1673 fprintf(fout, " LAYER %s ", pin->antennaDiffAreaLayer(i));
1674 fprintf(fout, "\n");
1675 }
1676 }
1677
1678 for (j = 0; j < pin->numAntennaModel(); j++) {
1679 aModel = pin->antennaModel(j);
1680
1681 if (aModel->hasAntennaGateArea()) {
1682 for (i = 0; i < aModel->numAntennaGateArea(); i++)
1683 {
1684 fprintf(fout, "PIN %s %s ANTGATEAREA %g", pin->name(),
1685 aModel->antennaOxide(),
1686 chkNum(aModel->antennaGateArea(i)));
1687 if (aModel->antennaGateAreaLayer(i))
1688 fprintf(fout, " LAYER %s ",
1689 aModel->antennaGateAreaLayer(i));
1690 fprintf(fout, "\n");
1691 }
1692 }
1693 if (aModel->hasAntennaMaxAreaCar()) {
1694 for (i = 0; i < aModel->numAntennaMaxAreaCar();
1695 i++) {
1696 fprintf(fout, "PIN %s %s ANTMAXAREACAR %g", pin->name(),
1697 aModel->antennaOxide(),
1698 chkNum(aModel->antennaMaxAreaCar(i)));
1699 if (aModel->antennaMaxAreaCarLayer(i))
1700 fprintf(fout, " LAYER %s ",
1701 aModel->antennaMaxAreaCarLayer(i));
1702 fprintf(fout, "\n");
1703 }
1704 }
1705 if (aModel->hasAntennaMaxSideAreaCar()) {
1706 for (i = 0; i < aModel->numAntennaMaxSideAreaCar();
1707 i++) {
1708 fprintf(fout, "PIN %s %s ANTMAXAREACAR %g", pin->name(),
1709 aModel->antennaOxide(),
1710 chkNum(aModel->antennaMaxSideAreaCar(i)));
1711 if (aModel->antennaMaxSideAreaCarLayer(i))
1712 fprintf(fout, " LAYER %s ",
1713 aModel->antennaMaxSideAreaCarLayer(i));
1714 fprintf(fout, "\n");
1715 }
1716 }
1717 if (aModel->hasAntennaMaxCutCar()) {
1718 for (i = 0; i < aModel->numAntennaMaxCutCar(); i++)
1719 {
1720 fprintf(fout, "PIN %s %s ANTMAXCUTCAR %g", pin->name(),
1721 aModel->antennaOxide(),
1722 chkNum(aModel->antennaMaxCutCar(i)));
1723 if (aModel->antennaMaxCutCarLayer(i))
1724 fprintf(fout, " LAYER %s ",
1725 aModel->antennaMaxCutCarLayer(i));
1726 fprintf(fout, "\n");
1727 }
1728 }
1729 }
1730
1731 if (pin->numProperties() > 0) {
1732 for (i = 0; i < pin->numProperties(); i++) {
1733 fprintf(fout, "PIN %s PROP ", pin->name());
1734 // value can either be a string or number
1735 if (pin->propValue(i)) {
1736 fprintf(fout, "%s %s\n", pin->propName(i), pin->propValue(i));
1737 }
1738 else
1739 fprintf(fout, "%s %g\n", pin->propName(i), chkNum(pin->propNum(i)));
1740 }
1741 }
1742
1743 numPorts = pin->numPorts();
1744
1745 char pinName[1024];
1746
1747 for (i = 0; i < numPorts; i++) {
1748 sprintf(pinName, "PIN %s PORT", pin->name());
1749 geometry = pin->port(i);
1750 prtGeometry(geometry, pinName);
1751 }
1752 return 0;
1753 }
1754
densityCB(lefrCallbackType_e c,lefiDensity * density,lefiUserData ud)1755 int densityCB(lefrCallbackType_e c, lefiDensity* density,
1756 lefiUserData ud) {
1757 struct lefiGeomRect rect;
1758
1759 checkType(c);
1760 if (ud != userData) dataError();
1761 for (int i = 0; i < density->numLayer(); i++) {
1762 for (int j = 0; j < density->numRects(i); j++) {
1763 rect = density->getRect(i,j);
1764 fprintf(fout, "DENSITY LAYER %s RECT %g %g %g %g %g\n",
1765 density->layerName(i), rect.xl, rect.yl, rect.xh, rect.yh,
1766 density->densityValue(i,j));
1767 }
1768 }
1769 return 0;
1770 }
1771
1772 // Property definition
propDefCB(lefrCallbackType_e c,lefiProp * prop,lefiUserData ud)1773 int propDefCB(lefrCallbackType_e c, lefiProp* prop, lefiUserData ud) {
1774 checkType(c);
1775 if (ud != userData) dataError();
1776 fprintf(fout, "PROPDEF %s %s",
1777 prop->propType(), prop->propName());
1778 if (prop->hasRange())
1779 fprintf(fout, " RANGE %g %g", chkNum(prop->left()), chkNum(prop->right()));
1780 if (prop->hasNumber())
1781 fprintf(fout, " NUMBER %g", chkNum(prop->number()));
1782 switch (prop->dataType()) {
1783 case 'I':
1784 fprintf(fout, " TYPE I");
1785 break;
1786 case 'R':
1787 fprintf(fout, " TYPE R");
1788 break;
1789 case 'S':
1790 fprintf(fout, " TYPE S");
1791 break;
1792 case 'Q':
1793 fprintf(fout, " TYPE Q");
1794 break;
1795 case 'N':
1796 fprintf(fout, " TYPE N");
1797 break;
1798 }
1799 fprintf(fout, "\n");
1800 return 0;
1801 }
1802
1803 // Site
siteCB(lefrCallbackType_e c,lefiSite * site,lefiUserData ud)1804 int siteCB(lefrCallbackType_e c, lefiSite* site, lefiUserData ud) {
1805 int hasPrtSym = 0;
1806 int i;
1807
1808 checkType(c);
1809 if (ud != userData) dataError();
1810 fprintf(fout, "SITE %s", site->name());
1811 if (site->hasClass())
1812 fprintf(fout, " CLASS %s", site->siteClass());
1813 if (site->hasXSymmetry()) {
1814 fprintf(fout, " SYMMETRY X ");
1815 hasPrtSym = 1;
1816 }
1817 if (site->hasYSymmetry()) {
1818 if (hasPrtSym)
1819 fprintf(fout, "Y ");
1820 else {
1821 fprintf(fout, " SYMMETRY Y ");
1822 hasPrtSym = 1;
1823 }
1824 }
1825 if (site->has90Symmetry()) {
1826 if (hasPrtSym)
1827 fprintf(fout, "R90 ");
1828 else {
1829 fprintf(fout, " SYMMETRY R90 ");
1830 hasPrtSym = 1;
1831 }
1832 }
1833 if (site->hasSize())
1834 fprintf(fout, " SIZE %g BY %g", chkNum(site->sizeX()),
1835 chkNum(site->sizeY()));
1836 fprintf(fout, "\n");
1837 if (site->hasRowPattern()) { // 5.6, a line for ea rowpattern for sorting
1838 for (i = 0; i < site->numSites(); i++)
1839 fprintf(fout, "SITE %s ROWPATTERN %s %s\n", site->name(),
1840 site->siteName(i), site->siteOrientStr(i));
1841 }
1842
1843 return 0;
1844 }
1845
1846 // Spacing
spacingCB(lefrCallbackType_e c,lefiSpacing * spacing,lefiUserData ud)1847 int spacingCB(lefrCallbackType_e c, lefiSpacing* spacing, lefiUserData ud) {
1848 checkType(c);
1849 if (ud != userData) dataError();
1850 lefSpacing(spacing, (char*)"SPACING");
1851 return 0;
1852 }
1853
1854 // Timing
timingCB(lefrCallbackType_e c,lefiTiming * timing,lefiUserData ud)1855 int timingCB(lefrCallbackType_e c, lefiTiming* timing, lefiUserData ud) {
1856 int i;
1857 checkType(c);
1858 if (ud != userData) dataError();
1859 for (i = 0; i < timing->numFromPins(); i++)
1860 fprintf(fout, "TIMING FROMPIN %s\n", timing->fromPin(i));
1861 for (i = 0; i < timing->numToPins(); i++)
1862 fprintf(fout, "TIMING TOPIN %s\n", timing->toPin(i));
1863 fprintf(fout, "TIMING RISE SLEW1 %g %g %g %g\n",
1864 chkNum(timing->riseSlewOne()), chkNum(timing->riseSlewTwo()),
1865 chkNum(timing->riseSlewThree()), chkNum(timing->riseSlewFour()));
1866 if (timing->hasRiseSlew2())
1867 fprintf(fout, "TIMING RISE SLEW2 %g %g %g\n",
1868 chkNum(timing->riseSlewFive()), chkNum(timing->riseSlewSix()),
1869 chkNum(timing->riseSlewSeven()));
1870 if (timing->hasFallSlew())
1871 fprintf(fout, "TIMING FALL SLEW1 %g %g %g %g\n",
1872 chkNum(timing->fallSlewOne()), chkNum(timing->fallSlewTwo()),
1873 chkNum(timing->fallSlewThree()), chkNum(timing->fallSlewFour()));
1874 if (timing->hasFallSlew2())
1875 fprintf(fout, "TIMING FALL SLEW2 %g %g %g\n",
1876 chkNum(timing->fallSlewFive()), chkNum(timing->fallSlewSix()),
1877 chkNum(timing->riseSlewSeven()));
1878 if (timing->hasRiseIntrinsic()) {
1879 fprintf(fout, "TIMING RISE INTRINSIC %g %g\n",
1880 chkNum(timing->riseIntrinsicOne()),
1881 chkNum(timing->riseIntrinsicTwo()));
1882 fprintf(fout, "TIMING RISE VARIABLE %g %g\n",
1883 chkNum(timing->riseIntrinsicThree()),
1884 chkNum(timing->riseIntrinsicFour()));
1885 }
1886 if (timing->hasFallIntrinsic()) {
1887 fprintf(fout, "TIMING FALL INTRINSIC %g %g\n",
1888 chkNum(timing->fallIntrinsicOne()),
1889 chkNum(timing->fallIntrinsicTwo()));
1890 fprintf(fout, "TIMING RISE VARIABLE %g %g\n",
1891 chkNum(timing->fallIntrinsicThree()),
1892 chkNum(timing->fallIntrinsicFour()));
1893 }
1894 if (timing->hasRiseRS())
1895 fprintf(fout, "TIMING RISERS %g %g\n",
1896 chkNum(timing->riseRSOne()), chkNum(timing->riseRSTwo()));
1897 if (timing->hasRiseCS())
1898 fprintf(fout, "TIMING RISECS %g %g\n",
1899 chkNum(timing->riseCSOne()), chkNum(timing->riseCSTwo()));
1900 if (timing->hasFallRS())
1901 fprintf(fout, "TIMING FALLRS %g %g\n",
1902 chkNum(timing->fallRSOne()), chkNum(timing->fallRSTwo()));
1903 if (timing->hasFallCS())
1904 fprintf(fout, "TIMING FALLCS %g %g\n",
1905 chkNum(timing->fallCSOne()), chkNum(timing->fallCSTwo()));
1906 if (timing->hasUnateness())
1907 fprintf(fout, "TIMING UNATENESS %s\n", timing->unateness());
1908 if (timing->hasRiseAtt1())
1909 fprintf(fout, "TIMING RISESATT1 %g %g\n", chkNum(timing->riseAtt1One()),
1910 chkNum(timing->riseAtt1Two()));
1911 if (timing->hasFallAtt1())
1912 fprintf(fout, "TIMING FALLSATT1 %g %g\n", chkNum(timing->fallAtt1One()),
1913 chkNum(timing->fallAtt1Two()));
1914 if (timing->hasRiseTo())
1915 fprintf(fout, "TIMING RISET0 %g %g\n", chkNum(timing->riseToOne()),
1916 chkNum(timing->riseToTwo()));
1917 if (timing->hasFallTo())
1918 fprintf(fout, "TIMING FALLT0 %g %g\n", chkNum(timing->fallToOne()),
1919 chkNum(timing->fallToTwo()));
1920 return 0;
1921 }
1922
1923 // Units
unitsCB(lefrCallbackType_e c,lefiUnits * unit,lefiUserData ud)1924 int unitsCB(lefrCallbackType_e c, lefiUnits* unit, lefiUserData ud) {
1925 checkType(c);
1926 if (ud != userData) dataError();
1927 if (unit->hasDatabase())
1928 fprintf(fout, "UNITS DATABASE %s %g\n", unit->databaseName(),
1929 chkNum(unit->databaseNumber()));
1930 if (unit->hasCapacitance())
1931 fprintf(fout, "UNITS CAPACITANCE PICOFARADS %g\n",
1932 chkNum(unit->capacitance()));
1933 if (unit->hasResistance())
1934 fprintf(fout, "UNITS RESISTANCE OHMS %g\n", chkNum(unit->resistance()));
1935 if (unit->hasPower())
1936 fprintf(fout, "UNITS POWER MILLIWATTS %g\n", chkNum(unit->power()));
1937 if (unit->hasCurrent())
1938 fprintf(fout, "UNITS CURRENT MILLIAMPS %g\n", chkNum(unit->current()));
1939 if (unit->hasVoltage())
1940 fprintf(fout, "UNITS VOLTAGE VOLTS %g\n", chkNum(unit->voltage()));
1941 if (unit->hasFrequency())
1942 fprintf(fout, "UNITS FREQUENCY MEGAHERTZ %g\n", chkNum(unit->frequency()));
1943 return 0;
1944 }
1945
1946 // UseMinSpacing
useMinSpacingCB(lefrCallbackType_e c,lefiUseMinSpacing * spacing,lefiUserData ud)1947 int useMinSpacingCB(lefrCallbackType_e c, lefiUseMinSpacing* spacing,
1948 lefiUserData ud) {
1949 checkType(c);
1950 if (ud != userData) dataError();
1951 fprintf(fout, "USEMINSPACING %s ", spacing->name());
1952 if (spacing->value())
1953 fprintf(fout, "USEMINSPACING ON\n");
1954 else
1955 fprintf(fout, "USEMINSPACING OFF\n");
1956 return 0;
1957 }
1958
1959 // Version
versionCB(lefrCallbackType_e c,double num,lefiUserData ud)1960 int versionCB(lefrCallbackType_e c, double num, lefiUserData ud) {
1961 checkType(c);
1962 if (ud != userData) dataError();
1963 fprintf(fout, "VERSION %g\n", num);
1964 return 0;
1965 }
1966
1967 // Via
viaCB(lefrCallbackType_e c,lefiVia * via,lefiUserData ud)1968 int viaCB(lefrCallbackType_e c, lefiVia* via, lefiUserData ud) {
1969 checkType(c);
1970 if (ud != userData) dataError();
1971 lefVia(via, (char*)"VIA");
1972 return 0;
1973 }
1974
1975 // Viarule
viaRuleCB(lefrCallbackType_e c,lefiViaRule * viaRule,lefiUserData ud)1976 int viaRuleCB(lefrCallbackType_e c, lefiViaRule* viaRule, lefiUserData ud) {
1977 int numLayers, numVias, i;
1978 lefiViaRuleLayer* vLayer;
1979
1980 checkType(c);
1981 if (ud != userData) dataError();
1982 fprintf(fout, "VIARULE %s", viaRule->name());
1983 if (viaRule->hasGenerate())
1984 fprintf(fout, " GENERATE");
1985 if (viaRule->hasDefault())
1986 fprintf(fout, " DEFAULT");
1987 fprintf(fout, "\n");
1988
1989 numLayers = viaRule->numLayers();
1990 // if numLayers == 2, it is VIARULE without GENERATE and has via name
1991 // if numLayers == 3, it is VIARULE with GENERATE, and the 3rd layer is cut
1992 for (i = 0; i < numLayers; i++) {
1993 vLayer = viaRule->layer(i);
1994 lefViaRuleLayer(vLayer, viaRule->name());
1995 }
1996
1997 if (numLayers == 2) { // should have vianames
1998 numVias = viaRule->numVias();
1999 if (numVias == 0)
2000 fprintf(fout, "Should have via names in VIARULE.\n");
2001 else {
2002 for (i = 0; i < numVias; i++)
2003 fprintf(fout, "VIARULE %s VIA %s ;\n", viaRule->name(),
2004 viaRule->viaName(i));
2005 }
2006 }
2007 if (viaRule->numProps() > 0) {
2008 for (i = 0; i < viaRule->numProps(); i++) {
2009 fprintf(fout, "VIARULE %s PROP %s ", viaRule->name(),
2010 viaRule->propName(i));
2011 if (viaRule->propValue(i))
2012 fprintf(fout, "%s ", viaRule->propValue(i));
2013 switch (viaRule->propType(i)) {
2014 case 'R': fprintf(fout, "REAL ");
2015 break;
2016 case 'I': fprintf(fout, "INTEGER ");
2017 break;
2018 case 'S': fprintf(fout, "STRING ");
2019 break;
2020 case 'Q': fprintf(fout, "QUOTESTRING ");
2021 break;
2022 case 'N': fprintf(fout, "NUMBER ");
2023 break;
2024 fprintf(fout, "\n");
2025 }
2026 }
2027 }
2028 return 0;
2029 }
2030
2031 //========
2032
diffLefReadFile(char * inFile,char * outFile)2033 int diffLefReadFile(char* inFile, char* outFile) {
2034 FILE* f;
2035 int res;
2036
2037 userData = (void*)0x01020304;
2038 lefrInit();
2039
2040 // Fix of CCR 758312
2041 lefrSetRelaxMode();
2042
2043 lefrSetAntennaInputCbk(antennaCB);
2044 lefrSetAntennaInoutCbk(antennaCB);
2045 lefrSetAntennaOutputCbk(antennaCB);
2046 lefrSetArrayCbk(arrayCB);
2047 lefrSetBusBitCharsCbk(busBitCharsCB);
2048 lefrSetCaseSensitiveCbk(caseSensCB);
2049 lefrSetFixedMaskCbk(fixedMaskCB);
2050 lefrSetClearanceMeasureCbk(clearanceCB);
2051 lefrSetCorrectionTableCbk(correctTableCB);
2052 lefrSetDensityCbk(densityCB);
2053 lefrSetDielectricCbk(dielectricCB);
2054 lefrSetDividerCharCbk(dividerCB);
2055 lefrSetEdgeRateScaleFactorCbk(edgeRateCB);
2056 lefrSetEdgeRateThreshold1Cbk(edgeRate1CB);
2057 lefrSetEdgeRateThreshold2Cbk(edgeRate2CB);
2058 lefrSetInputAntennaCbk(inputAntCB);
2059 lefrSetOutputAntennaCbk(outputAntCB);
2060 lefrSetInoutAntennaCbk(inoutAntCB);
2061 lefrSetIRDropCbk(irdropCB);
2062 lefrSetLayerCbk(layerCB);
2063 lefrSetMacroCbk(macroCB);
2064 lefrSetManufacturingCbk(manufacturingCB);
2065 lefrSetMaxStackViaCbk(maxStackViaCB);
2066 lefrSetMinFeatureCbk(minFeatureCB);
2067 lefrSetNoiseMarginCbk(noiseMarginCB);
2068 lefrSetNoiseTableCbk(noiseTableCB);
2069 lefrSetNonDefaultCbk(nonDefaultCB);
2070 lefrSetNoWireExtensionCbk(noWireExtCB);
2071 lefrSetObstructionCbk(obstructionCB);
2072 lefrSetPinCbk(pinCB);
2073 lefrSetPropCbk(propDefCB);
2074 lefrSetSiteCbk(siteCB);
2075 lefrSetSpacingCbk(spacingCB);
2076 lefrSetTimingCbk(timingCB);
2077 lefrSetUnitsCbk(unitsCB);
2078 lefrSetUseMinSpacingCbk(useMinSpacingCB);
2079 lefrSetUserData((void*)3);
2080 lefrSetVersionCbk(versionCB);
2081 lefrSetViaCbk(viaCB);
2082 lefrSetViaRuleCbk(viaRuleCB);
2083
2084 if ((f = fopen(inFile,"r")) == 0) {
2085 fprintf(stderr,"Couldn't open input file '%s'\n", inFile);
2086 return(2);
2087 }
2088
2089 if ((fout = fopen(outFile,"w")) == 0) {
2090 fprintf(stderr,"Couldn't open output file '%s'\n", outFile);
2091 fclose(f);
2092 return(2);
2093 }
2094
2095 res = lefrRead(f, inFile, userData);
2096
2097 fclose(f);
2098 fclose(fout);
2099
2100 return 0;
2101 }
2102