1 // *****************************************************************************
2 // *****************************************************************************
3 // Copyright 2012 - 2013, 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 // *****************************************************************************
24
25 // This file contains code for implementing the lefwriter 5.3
26 // It has functions to set the user callback functions. If functions
27 // are set, the lefwriter will call the user callback functions when
28 // it comes to the section. If the section is required, but user
29 // does not set any callback functions, a warning will be printed
30 // both on stderr and on the output file if there is one.
31 // The lef writer does not provide any default callback functions for
32 // the required sections.
33 //
34 // Author: Wanda da Rosa
35 // Date: 05/06/99
36 //
37 // Revisions:
38
39 #include "lefwWriterCalls.hpp"
40 #include <stdlib.h>
41 #include <string.h>
42 #include "lefiDebug.hpp"
43
44 BEGIN_LEFDEF_PARSER_NAMESPACE
45
46 #define MAXCBS 30
47
48 #define lefwVersionCbk 0
49 #define lefwCaseSensitiveCbk 1
50 #define lefwNoWireExtensionCbk 2
51 #define lefwBusBitCharsCbk 3
52 #define lefwDividerCharCbk 4
53 #define lefwManufacturingGridCbk 5
54 #define lefwUseMinSpacingCbk 6
55 #define lefwClearanceMeasureCbk 7
56 #define lefwUnitsCbk 8
57 #define lefwAntennaInputGateAreaCbk 9
58 #define lefwAntennaInOutDiffAreaCbk 10
59 #define lefwAntennaOutputDiffAreaCbk 11
60 #define lefwPropDefCbk 12
61 #define lefwLayerCbk 13
62 #define lefwViaCbk 14
63 #define lefwViaRuleCbk 15
64 #define lefwNonDefaultCbk 16
65 #define lefwCrossTalkCbk 17
66 #define lefwNoiseTableCbk 18
67 #define lefwCorrectionTableCbk 19
68 #define lefwSpacingCbk 20
69 #define lefwMinFeatureCbk 21
70 #define lefwDielectricCbk 22
71 #define lefwIRDropCbk 23
72 #define lefwSiteCbk 24
73 #define lefwArrayCbk 25
74 #define lefwMacroCbk 26
75 #define lefwAntennaCbk 27
76 #define lefwExtCbk 28
77 #define lefwEndLibCbk 29
78
79 // NEW CALLBACK - then place it here.
80
81 int lefWRetVal;
82 extern int lefwHasInit;
83 extern int lefwHasInitCbk;
84
85 #define WRITER_CALLBACK(func, type) \
86 if (func) { \
87 if ((lefWRetVal = (*func)(type, lefwUserData)) == 0) { \
88 } else { \
89 lefiError(1, 0, "User callback routine returned bad status"); \
90 return lefWRetVal; \
91 } \
92 }
93
94 // *****************************************************************************
95 // Global variables
96 // *****************************************************************************
97
98 lefiUserData lefwUserData = 0;
99 static char *lefwFileName = 0;
100 static int lefwRegisterUnused = 0;
101
102 extern FILE *lefwFile;
103
104 // *****************************************************************************
105 // List of call back routines
106 // These are filled in by the user. See the
107 // "set" routines at the end of the file
108 // *****************************************************************************
109 // The callback routines
110 lefwVoidCbkFnType lefwCallbacksSeq[MAXCBS] = {
111 0, // lefwVersionCbk
112 0, // lefwCaseSensitiveCbk
113 0, // lefwNoWireExtensionCbk
114 0, // lefwBusBitCharsCbk
115 0, // lefwDividerCharCbk
116 0, // lefwManufacturingGridCbk
117 0, // lefwUseMinSpacingCbk
118 0, // lefwClearanceMeasureCbk
119 0, // lefwUnitsCbk
120 0, // lefwAntennaInputGateAreaCbk
121 0, // lefwAntennaInOutDiffAreaCbk
122 0, // lefwAntennaOutputDiffAreaCbk
123 0, // lefwPropDefCbk
124 0, // lefwLayerCbk
125 0, // lefwViaCbk
126 0, // lefwViaRuleCbk
127 0, // lefwNonDefaultCbk
128 0, // lefwCrossTalkCbk
129 0, // lefwNoiseTableCbk
130 0, // lefwCorrectionTableCbk
131 0, // lefwSpacingCbk
132 0, // lefwMinFeatureCbk
133 0, // lefwDielectricCbk
134 0, // lefwIRDropCbk
135 0, // lefwSiteCbk
136 0, // lefwArrayCbk
137 0, // lefwMacroCbk
138 0, // lefwAntennaCbk
139 0, // lefwExtCbk
140 0, // lefwEndLibCbk
141 // Add NEW CALLBACK here
142 };
143
144 // the optional and required callbacks
145 int lefwCallbacksReq[MAXCBS] = {
146 0, // Version
147 0, // CaseSensitive
148 0, // NoWireExtension
149 0, // BusBitChars
150 0, // Divider
151 0, // ManufacturingGrid
152 0, // UseMinSpacing
153 0, // ClearanceMeasure
154 0, // Units
155 0, // AntennaInputGateArea
156 0, // AntennaInOutDiffArea
157 0, // AntennaOutputDiffArea
158 0, // PropDefinition
159 0, // Layer
160 0, // Via
161 0, // ViaRule
162 0, // NonDefault
163 0, // CrossTalk
164 0, // NoiseTable
165 0, // CorrectionTable
166 0, // Spacing
167 0, // MinFeature
168 0, // Dielectric
169 0, // IRDrop
170 0, // Site
171 0, // Array
172 0, // Macro
173 0, // Antenna
174 0, // Extension
175 0, // End Library
176 // Add NEW CALLBACK here
177 };
178
179 // The section names
180 char lefwSectionNames[MAXCBS] [80] = {
181 "Version",
182 "CaseSensitive",
183 "NoWireExtension",
184 "BusBitChars",
185 "DividerChar",
186 "ManufacturingGrid",
187 "UseMinSpacing",
188 "ClearanceMeasure",
189 "Units",
190 "AntennaInputGateArea",
191 "AntennaInOutDiffArea",
192 "AntennaOutputDiffArea",
193 "PropertyDefinition",
194 "Layer",
195 "Via",
196 "ViaRule",
197 "NonDefault",
198 "CrossTalk",
199 "NoiseTable",
200 "CorrectionTable",
201 "Spacing",
202 "MinFeature",
203 "Dielectric",
204 "IRDrop",
205 "Site",
206 "Array",
207 "Macro",
208 "Antenna",
209 "Ext",
210 "End Library",
211 // Add NEW CALLBACK here
212 };
213
214 // the call back types from the lefwCallbackType_e
215 lefwCallbackType_e lefwCallbacksType[MAXCBS] = {
216 lefwVersionCbkType,
217 lefwCaseSensitiveCbkType,
218 lefwNoWireExtensionCbkType,
219 lefwBusBitCharsCbkType,
220 lefwDividerCharCbkType,
221 lefwManufacturingGridCbkType,
222 lefwUseMinSpacingCbkType,
223 lefwClearanceMeasureCbkType,
224 lefwUnitsCbkType,
225 lefwAntennaInputGateAreaCbkType,
226 lefwAntennaInOutDiffAreaCbkType,
227 lefwAntennaOutputDiffAreaCbkType,
228 lefwPropDefCbkType,
229 lefwLayerCbkType,
230 lefwViaCbkType,
231 lefwViaRuleCbkType,
232 lefwNonDefaultCbkType,
233 lefwCrossTalkCbkType,
234 lefwNoiseTableCbkType,
235 lefwCorrectionTableCbkType,
236 lefwSpacingCbkType,
237 lefwMinFeatureCbkType,
238 lefwDielectricCbkType,
239 lefwIRDropCbkType,
240 lefwSiteCbkType,
241 lefwArrayCbkType,
242 lefwMacroCbkType,
243 lefwAntennaCbkType,
244 lefwExtCbkType,
245 lefwEndLibCbkType,
246 // Add NEW TYPES here
247 };
248
249 // *****************************************************************************
250 // Routines for the callbacks
251 // *****************************************************************************
252 const char *
lefwFName()253 lefwFName()
254 {
255 return lefwFileName;
256 }
257
258
259 int
lefwWrite(FILE * f,const char * fName,lefiUserData uData)260 lefwWrite(FILE *f,
261 const char *fName,
262 lefiUserData uData)
263 {
264 int i;
265
266 if (lefwHasInitCbk == 0 && lefwHasInit == 0) {
267 fprintf(stderr, "ERROR (LEFWRIT-4100): lefwWrite called before lefwInitCbk\n");
268 return -1;
269 }
270
271 lefwFileName = (char*) fName;
272 lefwFile = f;
273 lefwUserData = uData;
274
275 // Loop through the list of callbacks and call the user define
276 // callback routines if any are set
277
278 for (i = 0; i < MAXCBS; i++) {
279 if (lefwCallbacksSeq[i] != 0) { // user has set a callback function
280 WRITER_CALLBACK(lefwCallbacksSeq[i], lefwCallbacksType[i]);
281 } else if (lefwCallbacksReq[i]) { // it is required but user hasn't set up
282 fprintf(f,
283 "# WARNING (LEFWRIT-4500): Callback for %s is required, but is not defined\n\n",
284 lefwSectionNames[i]);
285 fprintf(stderr,
286 "WARNING (LEFWRIT-4500): Callback for %s is required, but is not defined\n\n",
287 lefwSectionNames[i]);
288 }
289 }
290 return 0;
291 }
292
293 void
lefwSetUnusedCallbacks(lefwVoidCbkFnType func)294 lefwSetUnusedCallbacks(lefwVoidCbkFnType func)
295 {
296 // Set all of the callbacks that have not been set yet to
297 // the given function.
298 int i;
299
300 for (i = 0; i < MAXCBS; i++) {
301 if (lefwCallbacksSeq[i] == 0)
302 lefwCallbacksSeq[i] = (lefwVoidCbkFnType) func;
303 }
304 }
305
306 // These count up the number of times an unset callback is called...
307 static int lefwUnusedCount[100];
308
309 int
lefwCountFunc(lefwCallbackType_e e,lefiUserData d)310 lefwCountFunc(lefwCallbackType_e e,
311 lefiUserData d)
312 {
313 int i = (int) e;
314 if (lefiDebug(23))
315 printf("count %d 0x%p\n", (int) e, d);
316 if (i >= 0 && i < 100) {
317 lefwUnusedCount[i] += 1;
318 return 0;
319 }
320 return 1;
321 }
322
323 void
lefwSetRegisterUnusedCallbacks()324 lefwSetRegisterUnusedCallbacks()
325 {
326 int i;
327 lefwRegisterUnused = 1;
328 lefwSetUnusedCallbacks(lefwCountFunc);
329 for (i = 0; i < 100; i++)
330 lefwUnusedCount[i] = 0;
331 }
332
333 void
lefwPrintUnusedCallbacks(FILE * f)334 lefwPrintUnusedCallbacks(FILE *f)
335 {
336 int i;
337 int first = 1;
338
339 if (lefwRegisterUnused == 0) {
340 fprintf(f,
341 "ERROR (LEFWRIT-4101): lefwSetRegisterUnusedCallbacks was not called to setup this data.\n");
342 return;
343 }
344
345 for (i = 0; i < 100; i++) {
346 if (lefwUnusedCount[i]) {
347 if (first)
348 fprintf(f,
349 "INFO (LEFWRIT-4700): LEF items that were present but ignored because of no callback were set.\n");
350 first = 0;
351 switch ((lefwCallbackType_e) i) {
352 case lefwVersionCbkType:
353 fprintf(f, "Version");
354 break;
355 case lefwCaseSensitiveCbkType:
356 fprintf(f, "CaseSensitive");
357 break;
358 case lefwNoWireExtensionCbkType:
359 fprintf(f, "NoWireExtensionAtPins");
360 break;
361 case lefwBusBitCharsCbkType:
362 fprintf(f, "BusBitChars");
363 break;
364 case lefwDividerCharCbkType:
365 fprintf(f, "DividerChar");
366 break;
367 case lefwManufacturingGridCbkType:
368 fprintf(f, "ManufacturingGrid");
369 break;
370 case lefwUseMinSpacingCbkType:
371 fprintf(f, "UseMinSpacing");
372 break;
373 case lefwClearanceMeasureCbkType:
374 fprintf(f, "ClearanceMeasure");
375 break;
376 case lefwUnitsCbkType:
377 fprintf(f, "Units");
378 break;
379 case lefwAntennaInputGateAreaCbkType:
380 fprintf(f, "AntennaInputGateArea");
381 break;
382 case lefwAntennaInOutDiffAreaCbkType:
383 fprintf(f, "AntennaInOutDiffArea");
384 break;
385 case lefwAntennaOutputDiffAreaCbkType:
386 fprintf(f, "AntennaOutputDiffArea");
387 break;
388 case lefwPropDefCbkType:
389 fprintf(f, "PropertyDefintion");
390 break;
391 case lefwLayerCbkType:
392 fprintf(f, "Layer");
393 break;
394 case lefwViaCbkType:
395 fprintf(f, "Via");
396 break;
397 case lefwViaRuleCbkType:
398 fprintf(f, "ViaRule");
399 break;
400 case lefwNonDefaultCbkType:
401 fprintf(f, "NonDefault");
402 break;
403 case lefwCrossTalkCbkType:
404 fprintf(f, "CrossTalk");
405 break;
406 case lefwNoiseTableCbkType:
407 fprintf(f, "NoiseTable");
408 break;
409 case lefwCorrectionTableCbkType:
410 fprintf(f, "CorrectionTable");
411 break;
412 case lefwSpacingCbkType:
413 fprintf(f, "Spacing");
414 break;
415 case lefwMinFeatureCbkType:
416 fprintf(f, "MinFeature");
417 break;
418 case lefwDielectricCbkType:
419 fprintf(f, "Dielectric");
420 break;
421 case lefwIRDropCbkType:
422 fprintf(f, "IRDrop");
423 break;
424 case lefwSiteCbkType:
425 fprintf(f, "Site");
426 break;
427 case lefwArrayCbkType:
428 fprintf(f, "Array");
429 break;
430 case lefwMacroCbkType:
431 fprintf(f, "Macro");
432 break;
433 case lefwAntennaCbkType:
434 fprintf(f, "OutputAntenna");
435 break;
436 case lefwExtCbkType:
437 fprintf(f, "Extension");
438 break;
439 case lefwEndLibCbkType:
440 fprintf(f, "End Library");
441 break;
442 // NEW CALLBACK add the print here
443 default:
444 fprintf(f, "BOGUS ENTRY");
445 break;
446 }
447 fprintf(f, " %d\n", lefwUnusedCount[i]);
448 }
449 }
450 }
451
452 void
lefwSetUserData(lefiUserData d)453 lefwSetUserData(lefiUserData d)
454 {
455 lefwUserData = d;
456 }
457
458 lefiUserData
lefwGetUserData()459 lefwGetUserData()
460 {
461 return lefwUserData;
462 }
463
464 void
lefwSetUnitsCbk(lefwVoidCbkFnType f)465 lefwSetUnitsCbk(lefwVoidCbkFnType f)
466 {
467 lefwCallbacksSeq[lefwUnitsCbk] = f;
468 }
469
470 void
lefwSetDividerCharCbk(lefwVoidCbkFnType f)471 lefwSetDividerCharCbk(lefwVoidCbkFnType f)
472 {
473 lefwCallbacksSeq[lefwDividerCharCbk] = f;
474 }
475
476 void
lefwSetManufacturingGridCbk(lefwVoidCbkFnType f)477 lefwSetManufacturingGridCbk(lefwVoidCbkFnType f)
478 {
479 lefwCallbacksSeq[lefwManufacturingGridCbk] = f;
480 }
481
482 void
lefwSetUseMinSpacingCbk(lefwVoidCbkFnType f)483 lefwSetUseMinSpacingCbk(lefwVoidCbkFnType f)
484 {
485 lefwCallbacksSeq[lefwUseMinSpacingCbk] = f;
486 }
487
488 void
lefwSetClearanceMeasureCbk(lefwVoidCbkFnType f)489 lefwSetClearanceMeasureCbk(lefwVoidCbkFnType f)
490 {
491 lefwCallbacksSeq[lefwClearanceMeasureCbk] = f;
492 }
493
494 void
lefwSetNoWireExtensionCbk(lefwVoidCbkFnType f)495 lefwSetNoWireExtensionCbk(lefwVoidCbkFnType f)
496 {
497 lefwCallbacksSeq[lefwNoWireExtensionCbk] = f;
498 }
499
500 void
lefwSetBusBitCharsCbk(lefwVoidCbkFnType f)501 lefwSetBusBitCharsCbk(lefwVoidCbkFnType f)
502 {
503 lefwCallbacksSeq[lefwBusBitCharsCbk] = f;
504 }
505
506 void
lefwSetCaseSensitiveCbk(lefwVoidCbkFnType f)507 lefwSetCaseSensitiveCbk(lefwVoidCbkFnType f)
508 {
509 lefwCallbacksSeq[lefwCaseSensitiveCbk] = f;
510 }
511
512 void
lefwSetVersionCbk(lefwVoidCbkFnType f)513 lefwSetVersionCbk(lefwVoidCbkFnType f)
514 {
515 lefwCallbacksSeq[lefwVersionCbk] = f;
516 }
517
518 void
lefwSetLayerCbk(lefwVoidCbkFnType f)519 lefwSetLayerCbk(lefwVoidCbkFnType f)
520 {
521 lefwCallbacksSeq[lefwLayerCbk] = f;
522 }
523
524 void
lefwSetViaCbk(lefwVoidCbkFnType f)525 lefwSetViaCbk(lefwVoidCbkFnType f)
526 {
527 lefwCallbacksSeq[lefwViaCbk] = f;
528 }
529
530 void
lefwSetViaRuleCbk(lefwVoidCbkFnType f)531 lefwSetViaRuleCbk(lefwVoidCbkFnType f)
532 {
533 lefwCallbacksSeq[lefwViaRuleCbk] = f;
534 }
535
536 void
lefwSetSpacingCbk(lefwVoidCbkFnType f)537 lefwSetSpacingCbk(lefwVoidCbkFnType f)
538 {
539 lefwCallbacksSeq[lefwSpacingCbk] = f;
540 }
541
542 void
lefwSetIRDropCbk(lefwVoidCbkFnType f)543 lefwSetIRDropCbk(lefwVoidCbkFnType f)
544 {
545 lefwCallbacksSeq[lefwIRDropCbk] = f;
546 }
547
548 void
lefwSetDielectricCbk(lefwVoidCbkFnType f)549 lefwSetDielectricCbk(lefwVoidCbkFnType f)
550 {
551 lefwCallbacksSeq[lefwDielectricCbk] = f;
552 }
553
554 void
lefwSetMinFeatureCbk(lefwVoidCbkFnType f)555 lefwSetMinFeatureCbk(lefwVoidCbkFnType f)
556 {
557 lefwCallbacksSeq[lefwMinFeatureCbk] = f;
558 }
559
560 void
lefwSetNonDefaultCbk(lefwVoidCbkFnType f)561 lefwSetNonDefaultCbk(lefwVoidCbkFnType f)
562 {
563 lefwCallbacksSeq[lefwNonDefaultCbk] = f;
564 }
565
566 void
lefwSetSiteCbk(lefwVoidCbkFnType f)567 lefwSetSiteCbk(lefwVoidCbkFnType f)
568 {
569 lefwCallbacksSeq[lefwSiteCbk] = f;
570 }
571
572 void
lefwSetMacroCbk(lefwVoidCbkFnType f)573 lefwSetMacroCbk(lefwVoidCbkFnType f)
574 {
575 lefwCallbacksSeq[lefwMacroCbk] = f;
576 }
577
578 void
lefwSetArrayCbk(lefwVoidCbkFnType f)579 lefwSetArrayCbk(lefwVoidCbkFnType f)
580 {
581 lefwCallbacksSeq[lefwArrayCbk] = f;
582 }
583
584 void
lefwSetPropDefCbk(lefwVoidCbkFnType f)585 lefwSetPropDefCbk(lefwVoidCbkFnType f)
586 {
587 lefwCallbacksSeq[lefwPropDefCbk] = f;
588 }
589
590 void
lefwSetCrossTalkCbk(lefwVoidCbkFnType f)591 lefwSetCrossTalkCbk(lefwVoidCbkFnType f)
592 {
593 lefwCallbacksSeq[lefwCrossTalkCbk] = f;
594 }
595
596 void
lefwSetNoiseTableCbk(lefwVoidCbkFnType f)597 lefwSetNoiseTableCbk(lefwVoidCbkFnType f)
598 {
599 lefwCallbacksSeq[lefwNoiseTableCbk] = f;
600 }
601
602
603 void
lefwSetCorrectionTableCbk(lefwVoidCbkFnType f)604 lefwSetCorrectionTableCbk(lefwVoidCbkFnType f)
605 {
606 lefwCallbacksSeq[lefwCorrectionTableCbk] = f;
607 }
608
609
610 void
lefwSetAntennaCbk(lefwVoidCbkFnType f)611 lefwSetAntennaCbk(lefwVoidCbkFnType f)
612 {
613 lefwCallbacksSeq[lefwAntennaCbk] = f;
614 }
615
616 void
lefwSetExtCbk(lefwVoidCbkFnType f)617 lefwSetExtCbk(lefwVoidCbkFnType f)
618 {
619 lefwCallbacksSeq[lefwExtCbk] = f;
620 }
621
622 void
lefwSetEndLibCbk(lefwVoidCbkFnType f)623 lefwSetEndLibCbk(lefwVoidCbkFnType f)
624 {
625 lefwCallbacksSeq[lefwEndLibCbk] = f;
626 }
627
628 /* NEW CALLBACK - Each callback routine must have a routine that allows
629 * the user to set it. The set routines go here. */
630
631 void
lefwSetAntennaInputGateAreaCbk(lefwVoidCbkFnType f)632 lefwSetAntennaInputGateAreaCbk(lefwVoidCbkFnType f)
633 {
634 lefwCallbacksSeq[lefwAntennaInputGateAreaCbk] = f;
635 }
636
637 void
lefwSetAntennaInOutDiffAreaCbk(lefwVoidCbkFnType f)638 lefwSetAntennaInOutDiffAreaCbk(lefwVoidCbkFnType f)
639 {
640 lefwCallbacksSeq[lefwAntennaInOutDiffAreaCbk] = f;
641 }
642
643 void
lefwSetAntennaOutputDiffAreaCbk(lefwVoidCbkFnType f)644 lefwSetAntennaOutputDiffAreaCbk(lefwVoidCbkFnType f)
645 {
646 lefwCallbacksSeq[lefwAntennaOutputDiffAreaCbk] = f;
647 }
648
649 extern LEFI_LOG_FUNCTION lefwErrorLogFunction;
650
651 void
lefwSetLogFunction(LEFI_LOG_FUNCTION f)652 lefwSetLogFunction(LEFI_LOG_FUNCTION f)
653 {
654 lefwErrorLogFunction = f;
655 }
656 extern LEFI_WARNING_LOG_FUNCTION lefwWarningLogFunction;
657
658 void
lefwSetWarningLogFunction(LEFI_WARNING_LOG_FUNCTION f)659 lefwSetWarningLogFunction(LEFI_WARNING_LOG_FUNCTION f)
660 {
661 lefwWarningLogFunction = f;
662 }
663 END_LEFDEF_PARSER_NAMESPACE
664
665