1 /* CIFtech.c -
2 *
3 * This module processes the portions of technology
4 * files pertaining to CIF, and builds the tables
5 * used by the CIF generator.
6 *
7 * *********************************************************************
8 * * Copyright (C) 1985, 1990 Regents of the University of California. *
9 * * Permission to use, copy, modify, and distribute this *
10 * * software and its documentation for any purpose and without *
11 * * fee is hereby granted, provided that the above copyright *
12 * * notice appear in all copies. The University of California *
13 * * makes no representations about the suitability of this *
14 * * software for any purpose. It is provided "as is" without *
15 * * express or implied warranty. Export of this software outside *
16 * * of the United States of America may require an export license. *
17 * *********************************************************************
18 */
19
20 #ifndef lint
21 static char rcsid[] __attribute__ ((unused)) = "$Header: /usr/cvsroot/magic-8.0/cif/CIFtech.c,v 1.7 2010/10/20 20:34:19 tim Exp $";
22 #endif /* not lint */
23
24 #include <stdio.h>
25 #include <stdlib.h> /* for atof() */
26 #include <string.h>
27 #include <ctype.h>
28 #include <math.h> /* for pow() */
29
30 #include "utils/magic.h"
31 #include "utils/geometry.h"
32 #include "tiles/tile.h"
33 #include "utils/hash.h"
34 #include "database/database.h"
35 #include "utils/tech.h"
36 #include "utils/utils.h"
37 #include "utils/styles.h"
38 #include "cif/CIFint.h"
39 #include "calma/calmaInt.h"
40 #include "textio/textio.h"
41 #include "utils/malloc.h"
42 #include "cif/cif.h"
43 #include "drc/drc.h" /* For WRL's DRC-CIF extensions */
44
45 /* The following statics are used to keep track of things between
46 * calls to CIFTechLine.
47 */
48
49 static CIFLayer *cifCurLayer; /* Current layer whose spec. is being read. */
50 static CIFOp *cifCurOp; /* Last geometric operation read in. */
51 static bool cifGotLabels; /* TRUE means some labels have been assigned
52 * to the current layer.
53 */
54
55 /* The following is a TileTypeBitMask array with only the CIF_SOLIDTYPE
56 * bit set in it.
57 */
58 TileTypeBitMask CIFSolidBits;
59
60 /* Forward Declarations */
61
62 void cifTechStyleInit();
63 bool cifCheckCalmaNum();
64
65 /*
66 * ----------------------------------------------------------------------------
67 *
68 * cifTechFreeStyle --
69 *
70 * This procedure frees memory for the current CIF style, and
71 * sets the current style to NULL.
72 *
73 * Results:
74 * None.
75 *
76 * Side effects:
77 * Memory is free'd.
78 *
79 * ----------------------------------------------------------------------------
80 */
81
82 void
cifTechFreeStyle()83 cifTechFreeStyle()
84 {
85 int i;
86 CIFOp *op;
87 CIFLayer *layer;
88
89 if (CIFCurStyle != NULL)
90 {
91 /* Destroy old style structure and free memory allocated to it */
92
93 for (i = 0; i < MAXCIFLAYERS; i++)
94 {
95 layer = CIFCurStyle->cs_layers[i];
96 if (layer != NULL)
97 {
98 for (op = layer->cl_ops; op != NULL; op = op->co_next)
99 {
100 if (op->co_client != (ClientData)NULL)
101 {
102 switch (op->co_opcode)
103 {
104 case CIFOP_OR:
105 case CIFOP_BBOX:
106 case CIFOP_MAXRECT:
107 case CIFOP_BOUNDARY:
108 /* These options use co_client to hold a single */
109 /* integer value, so it is not allocated. */
110 break;
111 default:
112 freeMagic((char *)op->co_client);
113 break;
114 }
115 }
116 freeMagic((char *)op);
117 }
118 freeMagic((char *)layer);
119 }
120 }
121 freeMagic(CIFCurStyle);
122 CIFCurStyle = NULL;
123 }
124 }
125
126 /*
127 * ----------------------------------------------------------------------------
128 *
129 * cifTechNewStyle --
130 *
131 * This procedure creates a new CIF style at the end of
132 * the list of style and initializes it to completely
133 * null.
134 *
135 * Results:
136 * None.
137 *
138 * Side effects:
139 * A new element is added to the end of CIFStyleList, and CIFCurStyle
140 * is set to point to it.
141 *
142 * ----------------------------------------------------------------------------
143 */
144
145 void
cifTechNewStyle()146 cifTechNewStyle()
147 {
148 cifTechFreeStyle();
149 cifTechStyleInit();
150 }
151
152 /*
153 * ----------------------------------------------------------------------------
154 *
155 * cifTechStyleInit --
156 *
157 * Fill in the current cif input style structure with initial values
158 *
159 * ----------------------------------------------------------------------------
160 */
161
162 void
cifTechStyleInit()163 cifTechStyleInit()
164 {
165 int i;
166
167 if (CIFCurStyle == NULL)
168 CIFCurStyle = (CIFStyle *) mallocMagic(sizeof(CIFStyle));
169
170 CIFCurStyle->cs_name = NULL;
171 CIFCurStyle->cs_status = TECH_NOT_LOADED;
172
173 CIFCurStyle->cs_nLayers = 0;
174 CIFCurStyle->cs_scaleFactor = 0;
175 CIFCurStyle->cs_stepSize = 0;
176 CIFCurStyle->cs_gridLimit = 0;
177 CIFCurStyle->cs_reducer = 0;
178 CIFCurStyle->cs_expander = 1;
179 CIFCurStyle->cs_yankLayers = DBZeroTypeBits;
180 CIFCurStyle->cs_hierLayers = DBZeroTypeBits;
181 CIFCurStyle->cs_flags = 0;
182 for (i=0; i<TT_MAXTYPES; i+=1)
183 {
184 CIFCurStyle->cs_labelLayer[i] = -1;
185 CIFCurStyle->cs_portLayer[i] = -1;
186 }
187 for (i = 0; i < MAXCIFLAYERS; i++)
188 CIFCurStyle->cs_layers[i] = NULL;
189 }
190
191
192 /*
193 * ----------------------------------------------------------------------------
194 *
195 * cifParseLayers --
196 *
197 * Takes a comma-separated list of layers and turns it into two
198 * masks, one of paint layers and one of previously-defined CIF
199 * layers.
200 *
201 * Results:
202 * None.
203 *
204 * Side effects:
205 * The masks pointed to by the paintMask and cifMask parameters
206 * are modified. If some of the layers are unknown, then an error
207 * message is printed.
208 *
209 * ----------------------------------------------------------------------------
210 */
211
212 void
cifParseLayers(string,style,paintMask,cifMask,spaceOK)213 cifParseLayers(string, style, paintMask, cifMask, spaceOK)
214 char *string; /* List of layers. */
215 CIFStyle *style; /* Gives CIF style for parsing string.*/
216 TileTypeBitMask *paintMask; /* Place to store mask of paint layers. If
217 * NULL, then only CIF layer names are
218 * considered.
219 */
220 TileTypeBitMask *cifMask; /* Place to store mask of CIF layers. If
221 * NULL, then only paint layer names are
222 * considered.
223 */
224 int spaceOK; /* are space layers permissible in this cif
225 layer?
226 */
227 {
228 TileTypeBitMask curCifMask, curPaintMask;
229 char curLayer[40], *p, *cp;
230 TileType paintType;
231 int i;
232 bool allResidues;
233
234 if (paintMask != NULL) TTMaskZero(paintMask);
235 if (cifMask != NULL) TTMaskZero(cifMask);
236
237 while (*string != 0)
238 {
239 p = curLayer;
240
241 if (*string == '*')
242 {
243 allResidues = TRUE;
244 string++;
245 }
246 else
247 allResidues = FALSE;
248
249 while ((*string != ',') && (*string != 0))
250 *p++ = *string++;
251 *p = 0;
252 while (*string == ',') string += 1;
253
254 /* See if this is a paint type. */
255
256 if (paintMask != NULL)
257 {
258 paintType = DBTechNameTypes(curLayer, &curPaintMask);
259 if (paintType >= 0) goto okpaint;
260 }
261 else paintType = -2;
262
263 okpaint:
264 /* See if this is the name of another CIF layer. Be
265 * careful not to let the current layer be used in
266 * generating itself. Exact match is requred on CIF
267 * layer names, but the same name can appear multiple
268 * times in different styles.
269 */
270
271 TTMaskZero(&curCifMask);
272 if (cifMask != NULL)
273 {
274 for (i = 0; i < style->cs_nLayers; i++)
275 {
276 if (style->cs_layers[i] == cifCurLayer) continue;
277 if (strcmp(curLayer, style->cs_layers[i]->cl_name) == 0)
278 {
279 TTMaskSetType(&curCifMask, i);
280 }
281 }
282 }
283
284 /* Make sure that there's exactly one match among cif and
285 * paint layers together.
286 */
287
288 if ((paintType == -1)
289 || ((paintType >= 0) && !TTMaskEqual(&curCifMask, &DBZeroTypeBits)))
290 {
291 TechError("Ambiguous layer (type) \"%s\".\n", curLayer);
292 continue;
293 }
294 if (paintType >= 0)
295 {
296 if (paintType == TT_SPACE && spaceOK ==0)
297 TechError("\"Space\" layer not permitted in CIF rules.\n");
298 else
299 {
300 TileType rtype;
301 TileTypeBitMask *rMask;
302
303 TTMaskSetMask(paintMask, &curPaintMask);
304
305 /* Add residues from '*' notation */
306 if (allResidues)
307 for (rtype = TT_TECHDEPBASE; rtype < DBNumUserLayers; rtype++)
308 {
309 rMask = DBResidueMask(rtype);
310 if (TTMaskHasType(rMask, paintType))
311 TTMaskSetType(paintMask, rtype);
312 }
313 }
314 }
315 else if (!TTMaskEqual(&curCifMask, &DBZeroTypeBits))
316 {
317 TTMaskSetMask(cifMask, &curCifMask);
318 }
319 else
320 {
321 HashEntry *he;
322 TileTypeBitMask *amask;
323
324 he = HashLookOnly(&DBTypeAliasTable, curLayer);
325 if (he != NULL)
326 {
327 amask = (TileTypeBitMask *)HashGetValue(he);
328 TTMaskSetMask(paintMask, amask);
329 }
330 else
331 TechError("Unrecognized layer (type) \"%s\".\n", curLayer);
332 }
333 }
334 }
335
336
337 /*
338 * ----------------------------------------------------------------------------
339 *
340 * CIFTechInit --
341 *
342 * Called before loading a new technology.
343 *
344 * Results:
345 * None.
346 *
347 * Side effects:
348 * Clears out list of styles and resets the current style.
349 *
350 * ----------------------------------------------------------------------------
351 */
352
353 void
CIFTechInit()354 CIFTechInit()
355 {
356 CIFKeep *style;
357
358 /* Cleanup any old info. */
359
360 cifTechFreeStyle();
361
362 /* forget the list of styles */
363
364 for (style = CIFStyleList; style != NULL; style = style->cs_next)
365 {
366 freeMagic(style->cs_name);
367 freeMagic(style);
368 }
369 CIFStyleList = NULL;
370 }
371
372 /*
373 * ----------------------------------------------------------------------------
374 *
375 * CIFTechStyleInit --
376 *
377 * Called once at beginning of technology file read-in to
378 * initialize data structures.
379 *
380 * Results:
381 * None.
382 *
383 * Side effects:
384 * Just clears out the layer data structures.
385 *
386 * ----------------------------------------------------------------------------
387 */
388
389 void
CIFTechStyleInit()390 CIFTechStyleInit()
391 {
392 CalmaTechInit();
393
394 /* Create the TileTypeBitMask array with only the CIF_SOLIDTYPE bit set */
395 TTMaskZero(&CIFSolidBits);
396 TTMaskSetType(&CIFSolidBits, CIF_SOLIDTYPE);
397
398 cifCurOp = NULL;
399 cifCurLayer = NULL;
400 cifGotLabels = FALSE;
401 }
402
403 /*
404 * ----------------------------------------------------------------------------
405 *
406 * CIFTechLimitScale --
407 *
408 * Determine if the scalefactor (ns / ds), applied to the current
409 * grid scaling, would result in a grid finer than the minimum
410 * resolution allowed by the process, as set by the "gridlimit"
411 * statement in the "cifoutput" section (note that the scaling
412 * depends on the output style chosen, and can be subverted by
413 * scaling while a fine-grid output style is active, then switching
414 * to a coarse-grid output style).
415 *
416 * Note that even if the scalefactor is larger than the minimum
417 * grid, it must be a MULTIPLE of the minimum grid, or else geometry
418 * can be generated off-grid.
419 *
420 * Results:
421 * TRUE if scaling by (ns / ds) would violate minimum grid resolution,
422 * FALSE if not.
423 *
424 * Side effects:
425 * None.
426 *
427 * ----------------------------------------------------------------------------
428 */
429
430 bool
CIFTechLimitScale(ns,ds)431 CIFTechLimitScale(ns, ds)
432 int ns, ds;
433 {
434 int gridup, scaledown;
435 int scale, limit, expand;
436
437 if (CIFCurStyle == NULL) return FALSE;
438
439 scale = CIFCurStyle->cs_scaleFactor;
440 limit = CIFCurStyle->cs_gridLimit;
441 expand = CIFCurStyle->cs_expander;
442
443 if (limit == 0) limit = 1;
444
445 gridup = limit * expand * ds;
446 scaledown = scale * ns * 10;
447
448 if ((scaledown / gridup) == 0) return TRUE;
449 if ((scaledown % gridup) != 0) return TRUE;
450
451 return FALSE;
452 }
453
454 /*
455 * ----------------------------------------------------------------------------
456 *
457 * CIFParseScale --
458 *
459 * Read a scale value and determine scaleFactor and expander values
460 *
461 * Results:
462 * Returns the value for cs_scaleFactor
463 *
464 * Side effects:
465 * Alters the value of expander (pointer to cs_expander)
466 *
467 * ----------------------------------------------------------------------------
468 */
469
470 int
CIFParseScale(true_scale,expander)471 CIFParseScale(true_scale, expander)
472 char *true_scale;
473 int *expander;
474 {
475 char *decimal;
476 short places;
477 int n, d;
478
479 decimal = strchr(true_scale, '.');
480
481 if (decimal == NULL) /* true_scale is integer */
482 {
483 *expander = 1;
484 return atoi(true_scale);
485 }
486 else
487 {
488 *decimal = '\0';
489 places = strlen(decimal + 1);
490 d = pow(10,places);
491 n = atoi(true_scale);
492 *decimal = '.';
493 n *= d;
494 n += atoi(decimal + 1);
495 ReduceFraction(&n, &d);
496 *expander = d;
497 return n;
498 }
499 }
500
501
502 /*
503 * ----------------------------------------------------------------------------
504 *
505 * CIFTechLine --
506 *
507 * This procedure is called once for each line in the "cif"
508 * section of the technology file.
509 *
510 * Results:
511 * TRUE if line parsed correctly; FALSE if fatal error condition
512 * encountered.
513 *
514 * Side effects:
515 * Sets up information in the tables of CIF layers, and
516 * prints error messages where there are problems.
517 *
518 * ----------------------------------------------------------------------------
519 */
520
521 bool
CIFTechLine(sectionName,argc,argv)522 CIFTechLine(sectionName, argc, argv)
523 char *sectionName; /* The name of this section. */
524 int argc; /* Number of fields on line. */
525 char *argv[]; /* Values of fields. */
526 {
527 TileTypeBitMask mask, tempMask, cifMask, bloatLayers;
528 int i, j, l, distance;
529 CIFLayer *newLayer;
530 CIFOp *newOp = NULL;
531 CIFKeep *newStyle, *p;
532 char **bloatArg;
533 BloatData *bloats;
534 BridgeData *bridge;
535 SquaresData *squares;
536 SlotsData *slots;
537
538 if (argc <= 0) return TRUE;
539 else if (argc >= 2) l = strlen(argv[1]);
540
541 /* See if we're starting a new CIF style. If not, make
542 * sure that the current (maybe default?) CIF style has
543 * a name.
544 */
545
546 if (strcmp(argv[0], "style") == 0)
547 {
548 if (argc != 2)
549 {
550 if ((argc != 4) || (strncmp(argv[2], "variant", 7)))
551 {
552 wrongNumArgs:
553 TechError("Wrong number of arguments in %s statement.\n",
554 argv[0]);
555 errorReturn:
556 if (newOp != NULL)
557 freeMagic((char *) newOp);
558 return TRUE;
559 }
560 }
561 for (newStyle = CIFStyleList; newStyle != NULL;
562 newStyle = newStyle->cs_next)
563 {
564 /* Here we're only establishing existence; */
565 /* break on the first variant found. */
566
567 if (!strncmp(newStyle->cs_name, argv[1], l))
568 break;
569 }
570 if (newStyle == NULL)
571 {
572 if (argc == 2)
573 {
574 newStyle = (CIFKeep *)mallocMagic(sizeof(CIFKeep));
575 newStyle->cs_next = NULL;
576 newStyle->cs_name = StrDup((char **) NULL, argv[1]);
577
578 /* Append to end of style list */
579 if (CIFStyleList == NULL)
580 CIFStyleList = newStyle;
581 else
582 {
583 for (p = CIFStyleList; p->cs_next; p = p->cs_next);
584 p->cs_next = newStyle;
585 }
586 }
587 else /* Handle style variants */
588 {
589 CIFKeep *saveStyle = NULL;
590 char *tptr, *cptr;
591
592 /* 4th argument is a comma-separated list of variants. */
593 /* In addition to the default name recorded above, */
594 /* record each of the variants. */
595
596 tptr = argv[3];
597 while (*tptr != '\0')
598 {
599 cptr = strchr(tptr, ',');
600 if (cptr != NULL) *cptr = '\0';
601 newStyle = (CIFKeep *)mallocMagic(sizeof(CIFKeep));
602 newStyle->cs_next = NULL;
603 newStyle->cs_name = (char *)mallocMagic(l
604 + strlen(tptr) + 1);
605 sprintf(newStyle->cs_name, "%s%s", argv[1], tptr);
606
607 /* Remember the first variant as the default */
608 if (saveStyle == NULL) saveStyle= newStyle;
609
610 /* Append to end of style list */
611 if (CIFStyleList == NULL)
612 CIFStyleList = newStyle;
613 else
614 {
615 for (p = CIFStyleList; p->cs_next; p = p->cs_next);
616 p->cs_next = newStyle;
617 }
618
619 if (cptr == NULL)
620 break;
621 else
622 tptr = cptr + 1;
623 }
624 newStyle = saveStyle;
625 }
626 }
627
628 if (CIFCurStyle == NULL)
629 {
630 cifTechNewStyle();
631 CIFCurStyle->cs_name = newStyle->cs_name;
632 CIFCurStyle->cs_status = TECH_PENDING;
633 }
634 else if ((CIFCurStyle->cs_status == TECH_PENDING) ||
635 (CIFCurStyle->cs_status == TECH_SUSPENDED))
636 CIFCurStyle->cs_status = TECH_LOADED;
637 else if (CIFCurStyle->cs_status == TECH_NOT_LOADED)
638 {
639 if (CIFCurStyle->cs_name == NULL)
640 return (FALSE);
641 else if (argc == 2)
642 {
643 if (!strcmp(argv[1], CIFCurStyle->cs_name))
644 CIFCurStyle->cs_status = TECH_PENDING;
645 }
646 else if (argc == 4)
647 {
648 /* Verify that the style matches one variant */
649
650 char *tptr, *cptr;
651
652 if (!strncmp(CIFCurStyle->cs_name, argv[1], l))
653 {
654 tptr = argv[3];
655 while (*tptr != '\0')
656 {
657 cptr = strchr(tptr, ',');
658 if (cptr != NULL) *cptr = '\0';
659 if (!strcmp(CIFCurStyle->cs_name + l, tptr))
660 {
661 CIFCurStyle->cs_status = TECH_PENDING;
662 return TRUE;
663 }
664 if (cptr == NULL)
665 return TRUE;
666 else
667 tptr = cptr + 1;
668 }
669 }
670 }
671 }
672 return (TRUE);
673 }
674
675 /* Only continue past this point if we are loading the cif output style */
676 if (CIFCurStyle == NULL) return FALSE;
677 if ((CIFCurStyle->cs_status != TECH_PENDING) &&
678 (CIFCurStyle->cs_status != TECH_SUSPENDED))
679 return TRUE;
680
681 /* Process scalefactor lines next. */
682
683 if (strcmp(argv[0], "scalefactor") == 0)
684 {
685 if ((argc < 2) || (argc > 4)) goto wrongNumArgs;
686 CIFCurStyle->cs_scaleFactor = CIFParseScale(argv[1],
687 &CIFCurStyle->cs_expander);
688
689 /*
690 * The "nanometers" keyword multiplies the expander by 10.
691 * Any reducer value and keyword "calmaonly" are now both ignored.
692 */
693
694 if (argc >= 3)
695 {
696 if (strncmp(argv[argc - 1], "nanom", 5) == 0)
697 CIFCurStyle->cs_expander *= 10;
698 else if (strncmp(argv[argc - 1], "angstr", 6) == 0)
699 CIFCurStyle->cs_expander *= 100;
700 }
701
702 CIFCurStyle->cs_reducer = 1; /* initial value only */
703
704 if (CIFCurStyle->cs_scaleFactor <= 0)
705 {
706 CIFCurStyle->cs_scaleFactor = 0;
707 TechError("Scalefactor must be a strictly positive value.\n");
708 goto errorReturn;
709 }
710 return TRUE;
711 }
712
713 /* New for magic-7.3.100---allow GDS database units to be other */
714 /* than nanometers. Really, there is only one option here, which */
715 /* is "units angstroms". This option does not affect CIF output, */
716 /* whose units are fixed at centimicrons. */
717
718 if (strcmp(argv[0], "units") == 0)
719 {
720 if (argc != 2) goto wrongNumArgs;
721 if (!strncmp(argv[1], "angstr", 6))
722 CIFCurStyle->cs_flags |= CWF_ANGSTROMS;
723 return TRUE;
724 }
725
726 if (strcmp(argv[0], "stepsize") == 0)
727 {
728 if (argc != 2) goto wrongNumArgs;
729 CIFCurStyle->cs_stepSize = atoi(argv[1]);
730 if (CIFCurStyle->cs_stepSize <= 0)
731 {
732 TechError("Step size must be positive integer.\n");
733 CIFCurStyle->cs_stepSize = 0;
734 }
735 return TRUE;
736 }
737
738 /* Process "gridlimit" line next. */
739 if (strncmp(argv[0], "grid", 4) == 0)
740 {
741 if (StrIsInt(argv[1]))
742 {
743 CIFCurStyle->cs_gridLimit = atoi(argv[1]);
744 if (CIFCurStyle->cs_gridLimit < 0)
745 {
746 TechError("Grid limit must be a positive integer.\n");
747 CIFCurStyle->cs_gridLimit = 0;
748 }
749 }
750 else
751 TechError("Unable to parse grid limit value.\n");
752
753 return TRUE;
754 }
755
756 /* Process "variant" lines next. */
757
758 if (strncmp(argv[0], "variant", 7) == 0)
759 {
760 int l;
761 char *cptr, *tptr;
762
763 /* If our style variant is not one of the ones declared */
764 /* on the line, then we ignore all input until we */
765 /* either reach the end of the style, the end of the */
766 /* section, or another "variant" line. */
767
768 if (argc != 2) goto wrongNumArgs;
769 tptr = argv[1];
770 while (*tptr != '\0')
771 {
772 cptr = strchr(tptr, ',');
773 if (cptr != NULL)
774 {
775 *cptr = '\0';
776 for (j = 1; isspace(*(cptr - j)); j++)
777 *(cptr - j) = '\0';
778 }
779
780 if (*tptr == '*')
781 {
782 CIFCurStyle->cs_status = TECH_PENDING;
783 return TRUE;
784 }
785 else
786 {
787 l = strlen(CIFCurStyle->cs_name) - strlen(tptr);
788 if (!strcmp(tptr, CIFCurStyle->cs_name + l))
789 {
790 CIFCurStyle->cs_status = TECH_PENDING;
791 return TRUE;
792 }
793 }
794
795 if (cptr == NULL)
796 break;
797 else
798 tptr = cptr + 1;
799 }
800 CIFCurStyle->cs_status = TECH_SUSPENDED;
801 }
802
803 /* Anything below this line is not parsed if we're in TECH_SUSPENDED mode */
804 if (CIFCurStyle->cs_status != TECH_PENDING) return TRUE;
805
806 newLayer = NULL;
807 if ((strcmp(argv[0], "templayer") == 0) || (strcmp(argv[0], "layer") == 0) ||
808 (strcmp(argv[0], "labellayer") == 0))
809 {
810 if (CIFCurStyle->cs_nLayers == MAXCIFLAYERS)
811 {
812 cifCurLayer = NULL;
813 TechError("Can't handle more than %d CIF layers.\n", MAXCIFLAYERS);
814 TechError("Your local Magic wizard can fix this.\n");
815 goto errorReturn;
816 }
817 if (argc != 2 && argc != 3)
818 {
819 cifCurLayer = NULL;
820 goto wrongNumArgs;
821 }
822 newLayer = CIFCurStyle->cs_layers[CIFCurStyle->cs_nLayers]
823 = (CIFLayer *) mallocMagic(sizeof(CIFLayer));
824 CIFCurStyle->cs_nLayers += 1;
825 if ((cifCurOp == NULL) && (cifCurLayer != NULL) && !cifGotLabels)
826 {
827 TechError("Layer \"%s\" contains no material.\n",
828 cifCurLayer->cl_name);
829 }
830 newLayer->cl_name = NULL;
831 (void) StrDup(&newLayer->cl_name, argv[1]);
832 newLayer->cl_ops = NULL;
833 newLayer->cl_flags = 0;
834 newLayer->cl_calmanum = newLayer->cl_calmatype = -1;
835 newLayer->min_width = 0; /* for growSlivers */
836 #ifdef THREE_D
837 newLayer->cl_height = 0.0;
838 newLayer->cl_thick = 0.0;
839 newLayer->cl_renderStyle = STYLE_PALEHIGHLIGHTS - TECHBEGINSTYLES;
840 #endif
841 if (strcmp(argv[0], "templayer") == 0)
842 newLayer->cl_flags |= CIF_TEMP;
843 else if (strcmp(argv[0], "labellayer") == 0)
844 newLayer->cl_flags |= CIF_LABEL;
845 cifCurLayer = newLayer;
846 cifCurOp = NULL;
847 cifGotLabels = FALSE;
848
849 /* Handle a special case of a list of layer names on the layer
850 * line. Turn them into an OR operation.
851 */
852
853 if (argc == 3)
854 {
855 cifCurOp = (CIFOp *) mallocMagic(sizeof(CIFOp));
856 cifCurOp->co_opcode = CIFOP_OR;
857 cifParseLayers(argv[2], CIFCurStyle, &cifCurOp->co_paintMask,
858 &cifCurOp->co_cifMask, FALSE);
859 cifCurOp->co_distance = 0;
860 cifCurOp->co_next = NULL;
861 cifCurOp->co_client = (ClientData)NULL;
862 cifCurLayer->cl_ops = cifCurOp;
863 }
864 return TRUE;
865 }
866
867 if (strcmp(argv[0], "labels") == 0)
868 {
869 bool portOnly = FALSE, noPort = FALSE;
870
871 if (cifCurLayer == NULL)
872 {
873 TechError("Must define layer before giving labels it holds.\n");
874 goto errorReturn;
875 }
876 if (cifCurLayer->cl_flags & CIF_TEMP)
877 TechError("Why are you attaching labels to a temporary layer?\n");
878 if (argc == 3)
879 {
880 if (!strncmp(argv[2], "port", 4))
881 portOnly = TRUE;
882 else if (!strncmp(argv[2], "noport", 6))
883 noPort = TRUE;
884 else
885 {
886 TechError("Unknown option %s for labels statement.\n", argv[2]);
887 goto wrongNumArgs;
888 }
889 }
890 else if (argc != 2) goto wrongNumArgs;
891 DBTechNoisyNameMask(argv[1], &mask);
892 for (i=0; i<TT_MAXTYPES; i+=1)
893 {
894 if (TTMaskHasType(&mask, i))
895 {
896 if (portOnly != TRUE)
897 CIFCurStyle->cs_labelLayer[i] = CIFCurStyle->cs_nLayers-1;
898 if (noPort != TRUE)
899 CIFCurStyle->cs_portLayer[i] = CIFCurStyle->cs_nLayers-1;
900 }
901 }
902 cifGotLabels = TRUE;
903 return TRUE;
904 }
905
906 if ((strcmp(argv[0], "calma") == 0) || (strncmp(argv[0], "gds", 3) == 0))
907 {
908 if (cifCurLayer == NULL)
909 {
910 TechError("Must define layers before giving their Calma types.\n");
911 goto errorReturn;
912 }
913 if (cifCurLayer->cl_flags & CIF_TEMP)
914 TechError("Why assign a Calma number to a temporary layer?\n");
915 if (argc != 3) goto wrongNumArgs;
916 if (!cifCheckCalmaNum(argv[1]) || !cifCheckCalmaNum(argv[2]))
917 TechError("Calma layer and type numbers must be 0 to %d.\n",
918 CALMA_LAYER_MAX);
919 cifCurLayer->cl_calmanum = atoi(argv[1]);
920 cifCurLayer->cl_calmatype = atoi(argv[2]);
921 return TRUE;
922 }
923 if (strcmp(argv[0], "min-width") == 0) /* used in growSliver */
924 {
925 if (cifCurLayer == NULL)
926 {
927 TechError("Must define layers before assigning a minimum width.\n");
928 goto errorReturn;
929 }
930 if (argc != 2) goto wrongNumArgs;
931 cifCurLayer->min_width = atoi(argv[1]);
932 CIFCurStyle->cs_flags |= CWF_GROW_SLIVERS;
933 return TRUE;
934 }
935
936 if (strcmp(argv[0], "render") == 0) /* used by specialopen wind3d client */
937 {
938 #ifdef THREE_D
939 float height, thick;
940 int i, style, lcnt;
941 CIFLayer *layer;
942
943 if (argc != 5) goto wrongNumArgs;
944
945 cifCurLayer = NULL; /* This is not in a layer definition */
946
947 style = DBWTechParseStyle(argv[2]);
948 if (style < 0)
949 {
950 TechError("Error: Bad render style for CIF layer.\n");
951 goto errorReturn;
952 }
953
954 if (!StrIsNumeric(argv[3]) || !StrIsNumeric(argv[4]))
955 {
956 TechError("Syntax: render <layer> <style> <height> <thick>\n");
957 goto errorReturn;
958 }
959 height = (float)atof(argv[3]);
960 thick = (float)atof(argv[4]);
961
962 lcnt = 0;
963 for (i = 0; i < CIFCurStyle->cs_nLayers; i++)
964 {
965 layer = CIFCurStyle->cs_layers[i];
966 if (!strcmp(argv[1], layer->cl_name))
967 {
968 layer->cl_height = height;
969 layer->cl_thick = thick;
970 layer->cl_renderStyle = style;
971 lcnt++;
972 }
973 }
974 if (lcnt == 0)
975 {
976 TechError("Unknown layer name.\n");
977 goto errorReturn;
978 }
979 #endif
980 return TRUE;
981 }
982
983 /*
984 * miscellaneous cif/calma-writing boolean options
985 */
986
987 if (strcmp(argv[0], "options") == 0)
988 {
989 int i;
990 if (argc < 2) goto wrongNumArgs;
991 for (i = 1; i < argc; i++)
992 {
993 if (strcmp(argv[i], "calma-permissive-labels") == 0)
994 CIFCurStyle->cs_flags |= CWF_PERMISSIVE_LABELS;
995 else if (strcmp(argv[i], "grow-euclidean") == 0)
996 CIFCurStyle->cs_flags |= CWF_GROW_EUCLIDEAN;
997 else if (strcmp(argv[i], "see-no-vendor") == 0)
998 CIFCurStyle->cs_flags |= CWF_SEE_NO_VENDOR;
999 else if (strcmp(argv[i], "no-errors") == 0)
1000 CIFCurStyle->cs_flags |= CWF_NO_ERRORS;
1001 else if (strcmp(argv[i], "string-limit") == 0)
1002 CIFCurStyle->cs_flags |= CWF_STRING_LIMIT;
1003 }
1004 return TRUE;
1005 }
1006
1007 /* Anything below here is a geometric operation, so we can
1008 * do some set-up that is common to all the operations.
1009 */
1010
1011 if (cifCurLayer == NULL)
1012 {
1013 TechError("Must define layer before specifying operation.\n");
1014 goto errorReturn;
1015 }
1016 newOp = (CIFOp *) mallocMagic(sizeof(CIFOp));
1017 TTMaskZero(&newOp->co_paintMask);
1018 TTMaskZero(&newOp->co_cifMask);
1019 newOp->co_opcode = 0;
1020 newOp->co_distance = 0;
1021 newOp->co_next = NULL;
1022 newOp->co_client = (ClientData)NULL;
1023
1024 if (strcmp(argv[0], "and") == 0)
1025 newOp->co_opcode = CIFOP_AND;
1026 else if (strcmp(argv[0], "and-not") == 0)
1027 newOp->co_opcode = CIFOP_ANDNOT;
1028 else if (strcmp(argv[0], "or") == 0)
1029 newOp->co_opcode = CIFOP_OR;
1030 else if (strcmp(argv[0], "grow") == 0)
1031 newOp->co_opcode = CIFOP_GROW;
1032 else if (strcmp(argv[0], "grow-min") == 0)
1033 newOp->co_opcode = CIFOP_GROWMIN;
1034 else if (strcmp(argv[0], "grow-grid") == 0)
1035 newOp->co_opcode = CIFOP_GROW_G;
1036 else if (strcmp(argv[0], "shrink") == 0)
1037 newOp->co_opcode = CIFOP_SHRINK;
1038 else if (strcmp(argv[0], "bloat-or") == 0)
1039 newOp->co_opcode = CIFOP_BLOAT;
1040 else if (strcmp(argv[0], "bloat-max") == 0)
1041 newOp->co_opcode = CIFOP_BLOATMAX;
1042 else if (strcmp(argv[0], "bloat-min") == 0)
1043 newOp->co_opcode = CIFOP_BLOATMIN;
1044 else if (strcmp(argv[0], "bloat-all") == 0)
1045 newOp->co_opcode = CIFOP_BLOATALL;
1046 else if (strcmp(argv[0], "squares") == 0)
1047 newOp->co_opcode = CIFOP_SQUARES;
1048 else if (strcmp(argv[0], "squares-grid") == 0)
1049 newOp->co_opcode = CIFOP_SQUARES_G;
1050 else if (strcmp(argv[0], "slots") == 0)
1051 newOp->co_opcode = CIFOP_SLOTS;
1052 else if (strcmp(argv[0], "bbox") == 0)
1053 newOp->co_opcode = CIFOP_BBOX;
1054 else if (strcmp(argv[0], "net") == 0)
1055 newOp->co_opcode = CIFOP_NET;
1056 else if (strcmp(argv[0], "maxrect") == 0)
1057 newOp->co_opcode = CIFOP_MAXRECT;
1058 else if (strcmp(argv[0], "boundary") == 0)
1059 newOp->co_opcode = CIFOP_BOUNDARY;
1060 else if (strcmp(argv[0], "mask-hints") == 0)
1061 newOp->co_opcode = CIFOP_MASKHINTS;
1062 else if (strcmp(argv[0], "close") == 0)
1063 newOp->co_opcode = CIFOP_CLOSE;
1064 else if (strcmp(argv[0], "bridge") == 0)
1065 newOp->co_opcode = CIFOP_BRIDGE;
1066 else if (strcmp(argv[0], "bridge-lim") == 0)
1067 newOp->co_opcode = CIFOP_BRIDGELIM;
1068 else
1069 {
1070 TechError("Unknown statement \"%s\".\n", argv[0]);
1071 goto errorReturn;
1072 }
1073
1074 switch (newOp->co_opcode)
1075 {
1076 case CIFOP_AND:
1077 case CIFOP_ANDNOT:
1078 case CIFOP_OR:
1079 if (argc != 2) goto wrongNumArgs;
1080 cifParseLayers(argv[1], CIFCurStyle, &newOp->co_paintMask,
1081 &newOp->co_cifMask,FALSE);
1082 break;
1083
1084 case CIFOP_GROW:
1085 case CIFOP_GROWMIN:
1086 case CIFOP_GROW_G:
1087 case CIFOP_SHRINK:
1088 case CIFOP_CLOSE:
1089 if (argc != 2) goto wrongNumArgs;
1090 newOp->co_distance = atoi(argv[1]);
1091 if (newOp->co_distance <= 0)
1092 {
1093 TechError("Grow/shrink distance must be greater than zero.\n");
1094 goto errorReturn;
1095 }
1096 break;
1097
1098 case CIFOP_BRIDGE:
1099 if (argc != 3) goto wrongNumArgs;
1100 newOp->co_distance = atoi(argv[1]);
1101 if (newOp->co_distance <= 0)
1102 {
1103 TechError("Bridge distance must be greater than zero.\n");
1104 goto errorReturn;
1105 }
1106 bridge = (BridgeData *)mallocMagic(sizeof(BridgeData));
1107 bridge->br_width = atoi(argv[2]);
1108 if (bridge->br_width <= 0)
1109 {
1110 TechError("Bridge width must be greater than zero.\n");
1111 freeMagic(bridge);
1112 goto errorReturn;
1113 }
1114 newOp->co_client = (ClientData)bridge;
1115 break;
1116
1117 case CIFOP_BRIDGELIM:
1118 if (argc != 4) goto wrongNumArgs;
1119 newOp->co_distance = atoi(argv[1]);
1120 if (newOp->co_distance <= 0)
1121 {
1122 TechError("Bridge distance must be greater than zero.\n");
1123 goto errorReturn;
1124 }
1125 bridge = (BridgeData *)mallocMagic(sizeof(BridgeData));
1126 bridge->br_width = atoi(argv[2]);
1127 if (bridge->br_width <= 0)
1128 {
1129 TechError("Bridge width must be greater than zero.\n");
1130 freeMagic(bridge);
1131 goto errorReturn;
1132 }
1133 cifParseLayers(argv[3], CIFCurStyle, &newOp->co_paintMask, &newOp->co_cifMask,FALSE);
1134 newOp->co_client = (ClientData)bridge;
1135 break;
1136
1137 case CIFOP_BLOATALL:
1138 if (argc != 3) goto wrongNumArgs;
1139 cifParseLayers(argv[1], CIFCurStyle, &newOp->co_paintMask,
1140 &newOp->co_cifMask, FALSE);
1141 bloats = (BloatData *)mallocMagic(sizeof(BloatData));
1142 for (i = 0; i < TT_MAXTYPES; i++)
1143 bloats->bl_distance[i] = 0;
1144 newOp->co_client = (ClientData)bloats;
1145 cifParseLayers(argv[2], CIFCurStyle, &mask, &cifMask, TRUE);
1146
1147 /* 5/25/2020: Lifting restriction that bloatLayers types */
1148 /* cannot be CIF or temp layers. However, CIF/temp layers */
1149 /* and magic database layers may not be mixed. */
1150
1151 if (!TTMaskIsZero(&mask) && !TTMaskIsZero(&cifMask))
1152 TechError("Can't mix CIF and magic layers in bloat statement.\n");
1153
1154 /* 10/15/2019: Lifting restriction that the types that */
1155 /* trigger the bloating must be in the same plane as the */
1156 /* types that are bloated into. */
1157
1158 TTMaskZero(&bloatLayers);
1159 if (!TTMaskIsZero(&mask))
1160 {
1161 TTMaskSetMask(&bloatLayers, &mask);
1162 for (i = 0; i < TT_MAXTYPES; i++)
1163 if (TTMaskHasType(&mask, i))
1164 bloats->bl_distance[i] = 1;
1165
1166 goto bloatCheck;
1167 }
1168 else
1169 {
1170 TTMaskSetMask(&bloatLayers, &cifMask);
1171 for (i = 0; i < TT_MAXTYPES; i++)
1172 if (TTMaskHasType(&cifMask, i))
1173 bloats->bl_distance[i] = 1;
1174
1175 bloats->bl_plane = -1; /* Indicates CIF types */
1176 }
1177 break;
1178
1179 case CIFOP_BLOAT:
1180 case CIFOP_BLOATMIN:
1181 case CIFOP_BLOATMAX:
1182 if (argc < 4) goto wrongNumArgs;
1183 cifParseLayers(argv[1], CIFCurStyle, &newOp->co_paintMask,
1184 (TileTypeBitMask *)NULL, FALSE);
1185 argc -= 2;
1186 bloatArg = argv + 2;
1187 bloatLayers = newOp->co_paintMask;
1188 bloats = (BloatData *)mallocMagic(sizeof(BloatData));
1189 for (i = 0; i < TT_MAXTYPES; i++)
1190 bloats->bl_distance[i] = 0;
1191 newOp->co_client = (ClientData)bloats;
1192
1193 while (argc > 0)
1194 {
1195 if (argc == 1) goto wrongNumArgs;
1196 if (strcmp(*bloatArg, "*") == 0)
1197 {
1198 mask = DBAllTypeBits;
1199 tempMask = DBZeroTypeBits;
1200 }
1201 else
1202 {
1203 cifParseLayers(*bloatArg, CIFCurStyle, &mask, &tempMask, TRUE);
1204 TTMaskSetMask(&bloatLayers, &mask);
1205 }
1206 if (!TTMaskEqual(&tempMask, &DBZeroTypeBits))
1207 TechError("Can't use templayers in bloat statement.\n");
1208
1209 distance = atoi(bloatArg[1]);
1210 if ((distance < 0) && (newOp->co_opcode == CIFOP_BLOAT))
1211 {
1212 TechError("Bloat-or distances must not be negative.\n");
1213 distance = 0;
1214 }
1215 for (i = 0; i < TT_MAXTYPES; i++)
1216 if (TTMaskHasType(&mask, i))
1217 bloats->bl_distance[i] = distance;
1218
1219 argc -= 2;
1220 bloatArg += 2;
1221 }
1222
1223 bloatCheck:
1224 /* Don't do any bloating at boundaries between tiles of the
1225 * types being bloated. Otherwise a bloat could pass right
1226 * through a skinny tile and out the other side.
1227 */
1228 for (i = 0; i < TT_MAXTYPES; i++)
1229 if (TTMaskHasType(&newOp->co_paintMask, i))
1230 bloats->bl_distance[i] = 0;
1231
1232 /* Make sure that all the layers specified in the statement
1233 * fall in a single plane.
1234 */
1235
1236 for (i = 0; i < PL_MAXTYPES; i++)
1237 {
1238 tempMask = bloatLayers;
1239 TTMaskAndMask(&tempMask, &DBPlaneTypes[i]);
1240 if (TTMaskEqual(&tempMask, &bloatLayers)) {
1241 bloats->bl_plane = i;
1242 goto bloatDone;
1243 }
1244 }
1245 TechError("Not all bloat layers fall in the same plane.\n");
1246 bloats->bl_plane = 0; /* Prevents magic from segfaulting */
1247 bloatDone: break;
1248
1249 case CIFOP_NET:
1250 if (argc != 3) goto wrongNumArgs;
1251 newOp->co_client = (ClientData)StrDup((char **)NULL, argv[1]);
1252 cifParseLayers(argv[2], CIFCurStyle, &newOp->co_paintMask,
1253 &newOp->co_cifMask, FALSE);
1254 break;
1255
1256 case CIFOP_MASKHINTS:
1257 if (argc != 2) goto wrongNumArgs;
1258 newOp->co_client = (ClientData)StrDup((char **)NULL, argv[1]);
1259 break;
1260
1261 case CIFOP_MAXRECT:
1262 if (argc == 2)
1263 {
1264 if (!strncmp(argv[1], "ext", 3))
1265 newOp->co_client = (ClientData)1;
1266 else if (strncmp(argv[1], "int", 3))
1267 TechError("Maxrect takes only one optional argument "
1268 "\"external\" or \"internal\" (default).\n");
1269 }
1270 else if (argc != 1)
1271 goto wrongNumArgs;
1272 break;
1273
1274 case CIFOP_BBOX:
1275 if (argc == 2)
1276 {
1277 if (!strcmp(argv[1], "top"))
1278 newOp->co_client = (ClientData)1;
1279 else
1280 TechError("BBox takes only one optional argument \"top\".\n");
1281 }
1282 else if (argc != 1)
1283 goto wrongNumArgs;
1284 break;
1285
1286 case CIFOP_BOUNDARY:
1287 /* CIFOP_BOUNDARY has no arguments */
1288 if (argc != 1)
1289 goto wrongNumArgs;
1290 break;
1291
1292 case CIFOP_SQUARES_G:
1293 case CIFOP_SQUARES:
1294
1295 squares = (SquaresData *)mallocMagic(sizeof(SquaresData));
1296 newOp->co_client = (ClientData)squares;
1297
1298 if (argc == 2)
1299 {
1300 i = atoi(argv[1]);
1301 squares->sq_border = atoi(argv[1]);
1302 if ((i <= 0) || (i & 1))
1303 {
1304 TechError("Squares must have positive even sizes.\n");
1305 goto errorReturn;
1306 }
1307 squares->sq_border = i/2;
1308 squares->sq_size = i;
1309 squares->sq_sep = i;
1310 squares->sq_gridx = 1; /* set default grid */
1311 squares->sq_gridy = 1; /* set default grid */
1312 }
1313 else if (argc == 4 || ((argc == 5 || argc == 6)
1314 && newOp->co_opcode==CIFOP_SQUARES_G))
1315 {
1316 squares->sq_border = atoi(argv[1]);
1317 if (squares->sq_border < 0)
1318 {
1319 TechError("Square border must not be negative.\n");
1320 goto errorReturn;
1321 }
1322 squares->sq_size = atoi(argv[2]);
1323 if (squares->sq_size <= 0)
1324 {
1325 TechError("Squares must have positive sizes.\n");
1326 goto errorReturn;
1327 }
1328 squares->sq_sep = atoi(argv[3]);
1329 if (squares->sq_sep <= 0)
1330 {
1331 TechError("Square separation must be positive.\n");
1332 goto errorReturn;
1333 }
1334 if (argc >= 5)
1335 {
1336 squares->sq_gridx = squares->sq_gridy = atoi(argv[4]);
1337 if (squares->sq_gridx <= 0)
1338 {
1339 TechError("Square grid must be strictly positive.\n");
1340 squares->sq_gridx = squares->sq_gridy = 1;
1341 goto errorReturn;
1342 }
1343 }
1344 else
1345 {
1346 squares->sq_gridx = 1; /* set default grid */
1347 squares->sq_gridy = 1; /* set default grid */
1348 }
1349 if (argc == 6)
1350 {
1351 squares->sq_gridy = atoi(argv[5]);
1352 if (squares->sq_gridy <= 0)
1353 {
1354 TechError("Square y-grid must be strictly positive.\n");
1355 squares->sq_gridy = 1;
1356 goto errorReturn;
1357 }
1358 }
1359 }
1360 else goto wrongNumArgs;
1361
1362 /* Ensure that squares are never placed at less than the */
1363 /* minimum allowed mask resolution. This may require that */
1364 /* operation "squares" be changed to "squares-grid". */
1365
1366 if (squares->sq_gridx < CIFCurStyle->cs_gridLimit)
1367 {
1368 squares->sq_gridx = CIFCurStyle->cs_gridLimit;
1369 newOp->co_opcode = CIFOP_SQUARES_G;
1370 }
1371 if (squares->sq_gridy < CIFCurStyle->cs_gridLimit)
1372 {
1373 squares->sq_gridy = CIFCurStyle->cs_gridLimit;
1374 newOp->co_opcode = CIFOP_SQUARES_G;
1375 }
1376 break;
1377
1378 case CIFOP_SLOTS:
1379
1380 slots = (SlotsData *)mallocMagic(sizeof(SlotsData));
1381 newOp->co_client = (ClientData)slots;
1382
1383 if (argc >= 4)
1384 {
1385 i = atoi(argv[1]);
1386 slots->sl_sborder = i;
1387 if (i < 0)
1388 {
1389 TechError("Slot border must be non-negative.\n");
1390 goto errorReturn;
1391 }
1392 i = atoi(argv[2]);
1393 slots->sl_ssize = i;
1394 if (i <= 0)
1395 {
1396 TechError("Slot short-side size must be strictly positive.\n");
1397 goto errorReturn;
1398 }
1399 i = atoi(argv[3]);
1400 slots->sl_ssep = i;
1401 if (i <= 0)
1402 {
1403 TechError("Slot separation must be strictly positive.\n");
1404 goto errorReturn;
1405 }
1406 /* Initialize other values, in case they are not specified */
1407 slots->sl_lborder = 0;
1408 slots->sl_lsize = 0;
1409 slots->sl_lsep = 0;
1410 slots->sl_offset = 0;
1411 slots->sl_start = 0;
1412 }
1413 if (argc >= 5)
1414 {
1415 i = atoi(argv[4]);
1416 slots->sl_lborder = i;
1417 if (i < 0)
1418 {
1419 TechError("Slot border must be non-negative.\n");
1420 goto errorReturn;
1421 }
1422 }
1423 if (argc >= 6)
1424 {
1425 i = atoi(argv[5]);
1426 slots->sl_lsize = i;
1427 if (i < 0)
1428 {
1429 TechError("Slot long-side size must be positive or zero.\n");
1430 goto errorReturn;
1431 }
1432 i = atoi(argv[6]);
1433 slots->sl_lsep = i;
1434 if (i < 0)
1435 {
1436 TechError("Slot long-side separation must be non-negative.\n");
1437 goto errorReturn;
1438 }
1439 else if (i == 0 && (slots->sl_lsize > 0))
1440 {
1441 TechError("Slot long-side separation must be strictly positive"
1442 " when long-side size is nonzero\n");
1443 goto errorReturn;
1444 }
1445 }
1446 if (argc >= 8)
1447 {
1448 i = atoi(argv[7]);
1449 slots->sl_offset = i;
1450 if (i < 0)
1451 {
1452 TechError("Slot offset must be non-negative.\n");
1453 goto errorReturn;
1454 }
1455 }
1456 if (argc == 9)
1457 {
1458 i = atoi(argv[8]);
1459 slots->sl_start = i;
1460 if (i < 0)
1461 {
1462 TechError("Slot start must be non-negative.\n");
1463 goto errorReturn;
1464 }
1465 }
1466 if ((argc < 4) || (argc == 6) || (argc > 9))
1467 goto wrongNumArgs;
1468 break;
1469 }
1470
1471 /* Link the new CIFOp into the list. */
1472
1473 if (cifCurOp == NULL)
1474 cifCurLayer->cl_ops = newOp;
1475 else
1476 cifCurOp->co_next = newOp;
1477 cifCurOp = newOp;
1478
1479 return TRUE;
1480 }
1481
1482 /*
1483 * ----------------------------------------------------------------------------
1484 *
1485 * cifCheckCalmaNum --
1486 *
1487 * This local procedure checks whether its argument is the ASCII
1488 * representation of a positive integer between 0 and CALMA_LAYER_MAX.
1489 *
1490 * Results:
1491 * TRUE if the argument string is valid as described above, FALSE if not.
1492 *
1493 * Side effects:
1494 * None.
1495 *
1496 * ----------------------------------------------------------------------------
1497 */
1498
1499 bool
cifCheckCalmaNum(str)1500 cifCheckCalmaNum(str)
1501 char *str;
1502 {
1503 int n = atoi(str);
1504
1505 if (n < 0 || n > CALMA_LAYER_MAX)
1506 return (FALSE);
1507
1508 while (*str) {
1509 char ch = *str++;
1510 if (ch < '0' || ch > '9')
1511 return (FALSE);
1512 }
1513
1514 return (TRUE);
1515 }
1516
1517 /*
1518 * ----------------------------------------------------------------------------
1519 *
1520 * cifComputeRadii --
1521 *
1522 * This local procedure computes and fills in the grow and
1523 * shrink distances for a layer. Before calling this procedure,
1524 * the distances must have been computed for all temporary
1525 * layers used by this layer.
1526 *
1527 * Results:
1528 * None.
1529 *
1530 * Side effects:
1531 * Modifies cl_growDist and cl_shrinkDist in layer.
1532 *
1533 * ----------------------------------------------------------------------------
1534 */
1535
1536 void
cifComputeRadii(layer,des)1537 cifComputeRadii(layer, des)
1538 CIFLayer *layer; /* Layer for which to compute distances. */
1539 CIFStyle *des; /* CIF style (used to find temp layer
1540 * distances.
1541 */
1542 {
1543 int i, grow, shrink, curGrow, curShrink;
1544 CIFOp *op;
1545 BloatData *bloats;
1546
1547 grow = shrink = 0;
1548
1549 for (op = layer->cl_ops; op != NULL; op = op->co_next)
1550 {
1551 /* BBOX, NET, and MASKHINTS operators should never be used */
1552 /* hierarchically so ignore any grow/shrink operators that */
1553 /* come after them. */
1554
1555 if (op->co_opcode == CIFOP_BBOX || op->co_opcode == CIFOP_NET ||
1556 op->co_opcode == CIFOP_MASKHINTS)
1557 break;
1558
1559 /* If CIF layers are used, switch to the max of current
1560 * distances and those of the layers used.
1561 */
1562
1563 if (!TTMaskEqual(&op->co_cifMask, &DBZeroTypeBits))
1564 {
1565 for (i=0; i < des->cs_nLayers; i++)
1566 {
1567 if (TTMaskHasType(&op->co_cifMask, i))
1568 {
1569 if (des->cs_layers[i]->cl_growDist > grow)
1570 grow = des->cs_layers[i]->cl_growDist;
1571 if (des->cs_layers[i]->cl_shrinkDist > shrink)
1572 shrink = des->cs_layers[i]->cl_shrinkDist;
1573 }
1574 }
1575 }
1576
1577 /* Add in grows and shrinks at this step. */
1578
1579 switch (op->co_opcode)
1580 {
1581 case CIFOP_AND:
1582 case CIFOP_ANDNOT:
1583 case CIFOP_OR:
1584 case CIFOP_MASKHINTS:
1585 break;
1586
1587 case CIFOP_GROW:
1588 case CIFOP_GROWMIN:
1589 case CIFOP_GROW_G:
1590 grow += op->co_distance;
1591 break;
1592
1593 case CIFOP_SHRINK:
1594 shrink += op->co_distance;
1595 break;
1596
1597 /* For bloats use the largest distances (negative values are
1598 * for shrinks).
1599 */
1600
1601 case CIFOP_BLOAT:
1602 curGrow = curShrink = 0;
1603 bloats = (BloatData *)op->co_client;
1604 for (i = 0; i < TT_MAXTYPES; i++)
1605 {
1606 if (bloats->bl_distance[i] > curGrow)
1607 curGrow = bloats->bl_distance[i];
1608 else if ((-bloats->bl_distance[i]) > curShrink)
1609 curShrink = -bloats->bl_distance[i];
1610 }
1611 grow += curGrow;
1612 shrink += curShrink;
1613 break;
1614
1615 case CIFOP_BRIDGE: break;
1616 case CIFOP_BRIDGELIM: break;
1617 case CIFOP_SQUARES: break;
1618 case CIFOP_SQUARES_G: break;
1619
1620 }
1621 }
1622
1623 layer->cl_growDist = grow;
1624 layer->cl_shrinkDist = shrink;
1625
1626 /* TxPrintf("Radii for %s: grow %d, shrink %d.\n", layer->cl_name,
1627 grow, shrink);
1628 */
1629 }
1630
1631 /*
1632 * ----------------------------------------------------------------------------
1633 *
1634 * cifComputeHalo --
1635 *
1636 * Compute grow and shrink distances for each layer, and remember the
1637 * largest. Convert from CIF/GDS to Magic internal dimensions.
1638 *
1639 * Results: None.
1640 * Side effects: Sets cs_radius value in the current cifoutput style.
1641 * ----------------------------------------------------------------------------
1642 */
1643
1644 void
cifComputeHalo(style)1645 cifComputeHalo(style)
1646 CIFStyle *style;
1647 {
1648 int maxGrow, maxShrink, i;
1649
1650 maxGrow = maxShrink = 0;
1651 for (i = 0; i < style->cs_nLayers; i++)
1652 {
1653 cifComputeRadii(style->cs_layers[i], style);
1654 if (style->cs_layers[i]->cl_growDist > maxGrow)
1655 maxGrow = style->cs_layers[i]->cl_growDist;
1656 if (style->cs_layers[i]->cl_shrinkDist > maxShrink)
1657 maxShrink = style->cs_layers[i]->cl_shrinkDist;
1658 }
1659 if (maxGrow > maxShrink)
1660 style->cs_radius = 2*maxGrow;
1661 else style->cs_radius = 2*maxShrink;
1662 style->cs_radius /= style->cs_scaleFactor;
1663 style->cs_radius++;
1664
1665 /* TxPrintf("Radius for %s CIF is %d.\n",
1666 * style->cs_name, style->cs_radius);
1667 */
1668 }
1669
1670
1671 /*
1672 * ----------------------------------------------------------------------------
1673 *
1674 * CIFTechFinal --
1675 *
1676 * This procedure is invoked after all the lines of a technology
1677 * file have been read. It checks to make sure that the
1678 * section ended at a consistent point, and computes the interaction
1679 * distances for hierarchical CIF processing.
1680 *
1681 * Results:
1682 * None.
1683 *
1684 * Side effects:
1685 * Error messages are output if there's incomplete stuff left.
1686 * Interaction distances get computed for each CIF style
1687 * in two steps. First, for each layer the total grow and
1688 * shrink distances are computed. These are the maximum distances
1689 * that edges may move because of grows and shrinks in creating
1690 * the layer. Second, the radius for the style is computed.
1691 * The radius is used in two ways: first to determine how far
1692 * apart two subcells may be and still interact during CIF
1693 * generation; and second, to see how much material to yank in
1694 * order to find all additional CIF resulting from interactions.
1695 * Right now, a conservative approach is used: use the greater
1696 * of twice the largest grow distance or twice the largest shrink
1697 * distance for both. Twice the grow distance must be considered
1698 * because two pieces of material may each grow towards the other
1699 * and interact in the middle. Twice the largest shrink distance
1700 * is needed because subcells considered individually may each
1701 * shrink away from a boundary where they touch; the parent must
1702 * fill in the gap. To do this, it must include 2S additional
1703 * material: S is the size of the gap that must be filled, but
1704 * its outside edge will shrink in by S, so we must start with
1705 * 2S material to have S left after the shrink. Finally, one extra
1706 * unit gets added because two pieces of material one radius apart
1707 * can interact: to find all this material we must look one unit
1708 * farther out for anything overlapping (the search routines only
1709 * look for overlapping material and ignore abutting material).
1710 *
1711 * ----------------------------------------------------------------------------
1712 */
1713
1714 void
CIFTechFinal()1715 CIFTechFinal()
1716 {
1717 CIFStyle *style = CIFCurStyle;
1718 CIFOp *op;
1719 int i, minReduce;
1720
1721 /* Allow the case where there's no CIF at all. This is indicated
1722 * by a NULL CIFCurStyle.
1723 */
1724
1725 if (!style) return;
1726
1727 if ((cifCurLayer != NULL) && (cifCurOp == NULL) && !cifGotLabels)
1728 {
1729 TechError("Layer \"%s\" contains no material.\n",
1730 cifCurLayer->cl_name);
1731 }
1732 cifCurLayer = NULL;
1733
1734 /*
1735 * If cs_expander > 1, then all CIF op values must be scaled accordingly.
1736 * This routine loops through all CIF output styles.
1737 */
1738
1739 CIFTechOutputScale(1, 1);
1740
1741 if (style->cs_scaleFactor <= 0)
1742 {
1743 TechError("No valid scale factor was given for %s CIF.\n",
1744 style->cs_name);
1745 style->cs_scaleFactor = 1;
1746 return;
1747 }
1748
1749 /*
1750 * Make sure that all contact layers include stacked contact types
1751 */
1752 for (i = 0; i < style->cs_nLayers; i++)
1753 for (op = style->cs_layers[i]->cl_ops; op != NULL; op = op->co_next)
1754 {
1755 TileType d, s;
1756 TileTypeBitMask *rMask;
1757
1758 for (d = TT_TECHDEPBASE; d < DBNumUserLayers; d++)
1759 if (TTMaskHasType(&op->co_paintMask, d) && DBIsContact(d))
1760 for (s = DBNumUserLayers; s < DBNumTypes; s++)
1761 {
1762 rMask = DBResidueMask(s);
1763 if (TTMaskHasType(rMask, d))
1764 TTMaskSetType(&op->co_paintMask, s);
1765 }
1766 }
1767
1768 /*
1769 * Find the largest reducer value which divides into all of the CIF values.
1770 */
1771
1772 minReduce = style->cs_scaleFactor;
1773 for (i = 0; i < style->cs_nLayers; i++)
1774 {
1775 for (op = style->cs_layers[i]->cl_ops; op != NULL; op = op->co_next)
1776 {
1777 int j, c, bvalue;
1778 if (op->co_distance > 0)
1779 {
1780 c = FindGCF(style->cs_scaleFactor, op->co_distance);
1781 if (c < minReduce) minReduce = c;
1782 }
1783 if (op->co_client)
1784 {
1785 BloatData *bloats;
1786 BridgeData *bridge;
1787 SquaresData *squares;
1788 SlotsData *slots;
1789 if (op->co_opcode == CIFOP_SLOTS)
1790 {
1791 slots = (SlotsData *)op->co_client;
1792
1793 for (j = 0; j < 8; j++)
1794 {
1795 switch (j) {
1796 case 0: bvalue = slots->sl_sborder; break;
1797 case 1: bvalue = slots->sl_ssize; break;
1798 case 2: bvalue = slots->sl_ssep; break;
1799 case 3: bvalue = slots->sl_lborder; break;
1800 case 4: bvalue = slots->sl_lsize; break;
1801 case 5: bvalue = slots->sl_lsep; break;
1802 case 6: bvalue = slots->sl_offset; break;
1803 case 7: bvalue = slots->sl_start; break;
1804 }
1805 if (bvalue != 0)
1806 {
1807 if ((j == 1) || (j == 2) || (j == 4) || (j == 5))
1808 {
1809 if (bvalue & 0x1)
1810 TxError("Internal error: slot size/sep %d"
1811 " cannot be halved.\n", bvalue);
1812 bvalue >>= 1;
1813 }
1814 c = FindGCF(style->cs_scaleFactor, bvalue);
1815 if (c < minReduce) minReduce = c;
1816 }
1817 }
1818 }
1819 if (op->co_opcode == CIFOP_SQUARES)
1820 {
1821 squares = (SquaresData *)op->co_client;
1822
1823 for (j = 0; j < 3; j++)
1824 {
1825 switch (j) {
1826 case 0: bvalue = squares->sq_border; break;
1827 case 1: bvalue = squares->sq_size; break;
1828 case 2: bvalue = squares->sq_sep; break;
1829 }
1830 if (bvalue != 0)
1831 {
1832 if ((j == 1) || (j == 2))
1833 {
1834 if (bvalue & 0x1)
1835 TxError("Internal error: contact size/sep %d"
1836 " cannot be halved.\n", bvalue);
1837 bvalue >>= 1;
1838 }
1839 c = FindGCF(style->cs_scaleFactor, bvalue);
1840 if (c < minReduce) minReduce = c;
1841 }
1842 }
1843 }
1844 else if (op->co_opcode == CIFOP_SQUARES_G)
1845 {
1846 squares = (SquaresData *)op->co_client;
1847 for (j = 0; j < TT_MAXTYPES; j++)
1848 {
1849 switch (j) {
1850 case 0: bvalue = squares->sq_border; break;
1851 case 1: bvalue = squares->sq_size; break;
1852 case 2: bvalue = squares->sq_sep; break;
1853 case 3: bvalue = squares->sq_gridx; break;
1854 case 4: bvalue = squares->sq_gridy; break;
1855 }
1856 if (bvalue != 0)
1857 {
1858 c = FindGCF(style->cs_scaleFactor, bvalue);
1859 if (c < minReduce) minReduce = c;
1860 }
1861 }
1862 }
1863 /* Presence of op->co_opcode in CIFOP_OR indicates a copy */
1864 /* of the SquaresData pointer from a following operator */
1865 /* CIFOP_BBOX and CIFOP_MAXRECT uses the co_client field */
1866 /* as a flag field, while CIFOP_NET and CIFOP_MASKHINTS */
1867 /* uses it for a string. */
1868 else
1869 {
1870 switch (op->co_opcode)
1871 {
1872 case CIFOP_OR:
1873 case CIFOP_BBOX:
1874 case CIFOP_MASKHINTS:
1875 case CIFOP_BOUNDARY:
1876 case CIFOP_MAXRECT:
1877 case CIFOP_NET:
1878 break;
1879 case CIFOP_BRIDGELIM:
1880 case CIFOP_BRIDGE:
1881 bridge = (BridgeData *)op->co_client;
1882 c = FindGCF(style->cs_scaleFactor,
1883 bridge->br_width);
1884 if (c < minReduce) minReduce = c;
1885 break;
1886 default:
1887 bloats = (BloatData *)op->co_client;
1888 for (j = 0; j < TT_MAXTYPES; j++)
1889 {
1890 if (bloats->bl_distance[j] != 0)
1891 {
1892 c = FindGCF(style->cs_scaleFactor,
1893 bloats->bl_distance[j]);
1894 if (c < minReduce) minReduce = c;
1895 }
1896 }
1897 }
1898 }
1899 }
1900 if (minReduce == 1) break;
1901 }
1902 }
1903 style->cs_reducer = minReduce;
1904
1905 /* Debug info --- Tim, 1/3/02 */
1906 /* TxPrintf("Output style %s: scaleFactor=%d, reducer=%d, expander=%d.\n",
1907 style->cs_name, style->cs_scaleFactor,
1908 style->cs_reducer, style->cs_expander); */
1909
1910 /* Compute grow and shrink distances for each layer,
1911 * and remember the largest.
1912 */
1913 cifComputeHalo(style);
1914
1915 /* Go through the layers to see which ones depend on which
1916 * other ones. The purpose of this is so that we don't
1917 * have to yank unnecessary layers in processing subcell
1918 * interactions. Also find out which layers involve only
1919 * a single OR operation, and remember the others specially
1920 * (they'll require fancy CIF geometry processing).
1921 */
1922
1923 for (i = style->cs_nLayers-1; i >= 0; i -= 1)
1924 {
1925 TileTypeBitMask ourDepend, ourYank;
1926 bool needThisLayer;
1927 int j;
1928
1929 ourDepend = DBZeroTypeBits;
1930 ourYank = DBZeroTypeBits;
1931
1932 /* This layer must be computed hierarchically if it is needed
1933 * by some other layer that is computed hierarchically, or if
1934 * it includes operations that require hierarchical processing.
1935 */
1936
1937 needThisLayer = TTMaskHasType(&style->cs_hierLayers, i);
1938
1939 for (op = style->cs_layers[i]->cl_ops; op != NULL;
1940 op = op->co_next)
1941 {
1942 BloatData *bloats;
1943
1944 TTMaskSetMask(&ourDepend, &op->co_cifMask);
1945 TTMaskSetMask(&ourYank, &op->co_paintMask);
1946 switch (op->co_opcode)
1947 {
1948 case CIFOP_BLOAT:
1949 case CIFOP_BLOATMAX:
1950 case CIFOP_BLOATMIN:
1951 bloats = (BloatData *)op->co_client;
1952 for (j = 0; j < TT_MAXTYPES; j++)
1953 if (bloats->bl_distance[j] != bloats->bl_distance[TT_SPACE])
1954 TTMaskSetType(&ourYank, j);
1955 needThisLayer = TRUE;
1956 break;
1957
1958 case CIFOP_BLOATALL:
1959 bloats = (BloatData *)op->co_client;
1960 for (j = 0; j < TT_MAXTYPES; j++)
1961 {
1962 if (bloats->bl_distance[j] != 0)
1963 {
1964 if (bloats->bl_plane < 0)
1965 TTMaskSetType(&ourDepend, j);
1966 else
1967 TTMaskSetType(&ourYank, j);
1968 }
1969 }
1970 needThisLayer = TRUE;
1971 break;
1972
1973 case CIFOP_AND:
1974 case CIFOP_ANDNOT:
1975 case CIFOP_SHRINK:
1976 case CIFOP_CLOSE:
1977 case CIFOP_BRIDGELIM:
1978 case CIFOP_BRIDGE:
1979 needThisLayer = TRUE;
1980 break;
1981 }
1982 }
1983
1984 if (needThisLayer)
1985 {
1986 TTMaskSetMask(&style->cs_yankLayers, &ourYank);
1987 TTMaskSetType(&style->cs_hierLayers, i);
1988 TTMaskSetMask(&style->cs_hierLayers, &ourDepend);
1989 }
1990 }
1991
1992 /* Added by Tim, 5/16/19 */
1993 /* Layers that depend on hierarchically generated layers */
1994 /* (i.e., templayers) must themselves be hierarchically */
1995 /* processed. */
1996
1997 for (i = 0; i < style->cs_nLayers; i++)
1998 {
1999 TileTypeBitMask ourDepend, mmask;
2000
2001 ourDepend = DBZeroTypeBits;
2002 for (op = style->cs_layers[i]->cl_ops; op != NULL; op = op->co_next)
2003 TTMaskSetMask(&ourDepend, &op->co_cifMask);
2004
2005 TTMaskAndMask3(&mmask, &ourDepend, &style->cs_hierLayers);
2006 if (!TTMaskIsZero(&mmask))
2007 TTMaskSetType(&style->cs_hierLayers, i);
2008 }
2009
2010 /* Added by Tim, 6/17/20: Do not set dependencies of BOUNDARY */
2011 /* or BBOX because these are unable to be represented in a */
2012 /* hierarchy without producing conflicting parent/child mask */
2013 /* geometry. Generally, BOUNDARY and BBOX operations are */
2014 /* intended to be restricted to the child cell and should not */
2015 /* interact hierarchically. Possibly it would be useful to */
2016 /* provide some method to preserve the bounding box information */
2017 /* when flattening? */
2018
2019 for (i = 0; i < style->cs_nLayers; i++)
2020 {
2021 for (op = style->cs_layers[i]->cl_ops; op != NULL; op = op->co_next)
2022 {
2023 if (op->co_opcode == CIFOP_BOUNDARY || op->co_opcode == CIFOP_BBOX)
2024 {
2025 TTMaskClearType(&style->cs_hierLayers, i);
2026 break;
2027 }
2028 }
2029 }
2030
2031 /* Added by Tim, 10/18/04 */
2032
2033 /* Go through the layer operators looking for those that */
2034 /* contain only OR operators followed by a single SQUARES */
2035 /* operator. If found, set the clientdata record of the OR */
2036 /* operator to be a copy of that for the SQUARES operator. */
2037 /* This is used by the GDS generator when the "gds contact */
2038 /* on" option is enabled (CalmaContactArrays is TRUE) to */
2039 /* translate contact areas into contact subcell arrays. */
2040
2041 for (i = 0; i < style->cs_nLayers; i++)
2042 {
2043 ClientData clientdata;
2044 for (op = style->cs_layers[i]->cl_ops; (op != NULL) &&
2045 (op->co_opcode == CIFOP_OR) &&
2046 (TTMaskIsZero(&op->co_cifMask)); op = op->co_next);
2047 if (op && (op->co_opcode == CIFOP_SQUARES) && (op->co_next == NULL))
2048 {
2049 clientdata = op->co_client;
2050 for (op = style->cs_layers[i]->cl_ops; op->co_opcode == CIFOP_OR;
2051 op = op->co_next)
2052 {
2053 /* Copy the client record from the CIFOP_SQUARES operator
2054 * into the CIFOP_OR operator.
2055 */
2056 op->co_client = clientdata;
2057 }
2058 }
2059 }
2060
2061 /* Uncomment this code to print out information about which
2062 * layers have to be processed hierarchically.
2063
2064 for (i = 0; i < DBNumUserLayers; i++)
2065 {
2066 if (TTMaskHasType(&style->cs_yankLayers, i))
2067 TxPrintf("Will have to yank %s in style %s.\n",
2068 DBTypeLongName(i), style->cs_name);
2069 }
2070 for (i = 0; i < CIFCurStyle->cs_nLayers; i++)
2071 {
2072 if (TTMaskHasType(&style->cs_hierLayers, i))
2073 TxPrintf("Layer %s must be processed hierarchically.\n",
2074 style->cs_layers[i]->cl_name);
2075 }
2076
2077 */
2078 }
2079
2080 /*
2081 * ----------------------------------------------------------------------------
2082 *
2083 * CIFLoadStyle --
2084 *
2085 * Re-read the technology file to load the specified technology cif output
2086 * style into structure CIFCurStyle. This is much more memory-efficient than
2087 * keeping a separate structure for each cif output style. It incurs a complete
2088 * reading of the tech file on startup and every time the cif output style is
2089 * changed, but we can assume that this does not happen often. The first
2090 * style in the technology file is assumed to be default, so that re-reading
2091 * the tech file is not necessary on startup unless the default cif output
2092 * style is changed by a call to "cif ostyle".
2093 *
2094 * ----------------------------------------------------------------------------
2095 */
2096
2097 void
CIFLoadStyle(stylename)2098 CIFLoadStyle(stylename)
2099 char *stylename;
2100 {
2101 SectionID invcif;
2102
2103 if (CIFCurStyle && (CIFCurStyle->cs_name == stylename)) return;
2104
2105 cifTechNewStyle();
2106 CIFCurStyle->cs_name = stylename;
2107
2108 invcif = TechSectionGetMask("cifoutput", NULL);
2109 TechLoad(NULL, invcif);
2110
2111 /* CIFTechFinal(); */ /* handled by TechLoad() */
2112 CIFTechOutputScale(DBLambda[0], DBLambda[1]);
2113
2114 /* If the DRC section makes reference to CIF layers, then */
2115 /* we need to re-read the DRC section as well. */
2116
2117 if ((DRCForceReload == TRUE) && (DRCCurStyle != NULL))
2118 DRCReloadCurStyle();
2119 }
2120
2121 /*
2122 * ----------------------------------------------------------------------------
2123 *
2124 * CIFGetContactSize --
2125 *
2126 * Return the smallest allowable contact size in lambda units corresponding
2127 * to the "squares" function operating on the indicated type. This value
2128 * is computed as the (cut size) + 2 * (cut border).
2129 *
2130 * 9/12/2013: Added "squares-grid" and "slots" to the functions understood
2131 * by the routine. "squares-grid" behaves the same as "squares". "slots"
2132 * can be used for contact cuts with differing metal overlap on different
2133 * sides. Normally this would define a square slot; this routine finds
2134 * the minimum cut size for the slot.
2135 *
2136 * Results:
2137 * Contact minimum dimension, in CIF/GDS units
2138 *
2139 * Side effects:
2140 * If any of edge, border, or spacing is non-NULL, the appropriate
2141 * cut dimension is filled in.
2142 *
2143 * ----------------------------------------------------------------------------
2144 */
2145
2146 int
CIFGetContactSize(type,edge,spacing,border)2147 CIFGetContactSize(type, edge, spacing, border)
2148 TileType type;
2149 int *edge;
2150 int *border;
2151 int *spacing;
2152 {
2153 CIFStyle *style = CIFCurStyle;
2154 CIFOp *op, *sop;
2155 int i;
2156 SquaresData *squares;
2157 SlotsData *slots;
2158
2159 if (style == NULL)
2160 {
2161 edge = spacing = border = 0;
2162 return 0;
2163 }
2164
2165 for (i = 0; i < style->cs_nLayers; i++)
2166 {
2167 for (op = style->cs_layers[i]->cl_ops; (op != NULL) &&
2168 (op->co_opcode == CIFOP_OR) &&
2169 (TTMaskIsZero(&op->co_cifMask)); op = op->co_next)
2170 if (TTMaskHasType(&op->co_paintMask, type))
2171 for (sop = op->co_next; sop != NULL; sop = sop->co_next)
2172 {
2173 if (sop->co_opcode == CIFOP_SQUARES ||
2174 sop->co_opcode == CIFOP_SQUARES_G)
2175 {
2176 squares = (SquaresData *)sop->co_client;
2177 if (edge != NULL) *edge = squares->sq_size;
2178 if (border != NULL) *border = squares->sq_border;
2179 if (spacing != NULL) *spacing = squares->sq_sep;
2180 return (squares->sq_size + (squares->sq_border << 1));
2181 }
2182 else if (sop->co_opcode == CIFOP_SLOTS)
2183 {
2184 slots = (SlotsData *)sop->co_client;
2185 if (edge != NULL) *edge = slots->sl_ssize;
2186 if (border != NULL) *border = slots->sl_sborder;
2187 if (spacing != NULL) *spacing = slots->sl_ssep;
2188 return (slots->sl_ssize + (slots->sl_sborder << 1));
2189 }
2190
2191 /* Anything other than an OR function will break */
2192 /* the relationship between magic layers and cuts. */
2193 /* NOTE: Making an exception for AND_NOT, which is */
2194 /* used to distinguish between small and large via */
2195 /* areas. */
2196 else if ((sop->co_opcode != CIFOP_OR) &&
2197 (sop->co_opcode != CIFOP_ANDNOT))
2198 break;
2199 }
2200 }
2201 return 0;
2202 }
2203
2204
2205 /*
2206 * ----------------------------------------------------------------------------
2207 *
2208 * CIFTechOutputScale(n, d) --
2209 *
2210 * Scale all CIF output scale factors to make them equivalent
2211 * to reducing the magic internal unit spacing by a factor of n/d.
2212 * It is important not to reduce the scaleFactor to zero! So, we
2213 * multiply scaleFactor by n and the expander by d, then reduce
2214 * the fraction using the FindGCF routine (utils/fraction.c).
2215 *
2216 * Because all CIF operation distances (grow, shrink, bloat, squares)
2217 * are in units of centimicrons multiplied by the expander (e.g.,
2218 * expander = 10 means units are in nanometers), we need to rescale them
2219 * by the expander. To optimize CIF output, the fraction scale/expander
2220 * is reduced to minimize expander; that is, to make the numbers in the
2221 * CIF output as small as possible while making sure all output can be
2222 * represented by integers.
2223 *
2224 * Note that because contacts may be placed at 1/2 grid spacing to
2225 * center them, the size and spacing of contacts as given in the
2226 * "squares" function must *always* be an even number. To ensure this,
2227 * we check for odd numbers in these positions. If there are any, and
2228 * "d" is also an odd number, then we multiply both "n" and "d" by 2.
2229 *
2230 * (Added 2/23/05)---The above is not sufficient! If the contact size
2231 * is an odd number, then centering may not be possible even if all
2232 * the contact parameters are even numbers. e.g., for size=22 in a 0.18
2233 * process (scalefactor=9), a 5x5 lambda contact is 45x45 centimicrons.
2234 * 45 - 22 = 23, so border is 11.5 centimicrons. Therefore, when
2235 * the scalefactor is even, the contact size must be even, but when the
2236 * scalefactor is odd, then we have to multiply both "n" and "d" by 2
2237 * regardless, since contact areas may be either odd or even (compare
2238 * the above example to one where the contact is drawn 6x6 lambda).
2239 *
2240 * ----------------------------------------------------------------------------
2241 */
2242
2243 void
CIFTechOutputScale(n,d)2244 CIFTechOutputScale(n, d)
2245 int n, d;
2246 {
2247 int i, j, lgcf, lexpand;
2248 CIFStyle *ostyle = CIFCurStyle;
2249 CIFLayer *cl;
2250 CIFOp *op;
2251 SquaresData *squares;
2252 SlotsData *slots;
2253 BloatData *bloats;
2254 BridgeData *bridge;
2255 bool has_odd_space = FALSE;
2256
2257 if (ostyle == NULL) return;
2258
2259 /* For contact half-grid centering, check for odd numbers. . . */
2260
2261 if (ostyle->cs_scaleFactor & 0x1)
2262 {
2263 n *= 2;
2264 d *= 2;
2265 has_odd_space = TRUE;
2266 }
2267 else if (d & 0x1)
2268 {
2269 has_odd_space = FALSE;
2270 for (i = 0; i < ostyle->cs_nLayers; i++)
2271 {
2272 cl = ostyle->cs_layers[i];
2273 for (op = cl->cl_ops; op != NULL; op = op->co_next)
2274 {
2275 if (op->co_opcode == CIFOP_SQUARES)
2276 {
2277 squares = (SquaresData *)op->co_client;
2278 if ((squares->sq_size & 0x01) || (squares->sq_sep & 0x01))
2279 {
2280 has_odd_space = TRUE;
2281 break;
2282 }
2283 }
2284 else if (op->co_opcode == CIFOP_SLOTS)
2285 {
2286 slots = (SlotsData *)op->co_client;
2287 if ((slots->sl_lsize & 0x01) || (slots->sl_lsep & 0x01)
2288 || (slots->sl_ssize & 0x01) || (slots->sl_ssep & 0x01))
2289 {
2290 has_odd_space = TRUE;
2291 break;
2292 }
2293 }
2294 }
2295
2296 if (has_odd_space)
2297 {
2298 n *= 2;
2299 d *= 2;
2300 has_odd_space = FALSE;
2301 break;
2302 }
2303 }
2304 }
2305
2306 /* fprintf(stderr, "CIFTechOutputScale(%d, %d)\n", n, d); */
2307
2308 ostyle->cs_scaleFactor *= n;
2309 ostyle->cs_expander *= d;
2310
2311 /* fprintf(stderr, "CIFStyle %s:\n", ostyle->cs_name); */
2312
2313 lexpand = ostyle->cs_expander;
2314 for (i = 0; i < ostyle->cs_nLayers; i++)
2315 {
2316 cl = ostyle->cs_layers[i];
2317 for (op = cl->cl_ops; op != NULL; op = op->co_next)
2318 {
2319 if (op->co_distance)
2320 {
2321 op->co_distance *= d;
2322 lgcf = FindGCF(abs(op->co_distance), ostyle->cs_expander);
2323 lexpand = FindGCF(lexpand, lgcf);
2324 }
2325 if (op->co_client)
2326 {
2327 int bvalue, *bptr;
2328 if (op->co_opcode == CIFOP_SQUARES)
2329 {
2330 squares = (SquaresData *)op->co_client;
2331 for (j = 0; j < 3; j++)
2332 {
2333 switch (j) {
2334 case 0: bptr = &squares->sq_border; break;
2335 case 1: bptr = &squares->sq_size; break;
2336 case 2: bptr = &squares->sq_sep; break;
2337 }
2338 if (*bptr != 0)
2339 {
2340 (*bptr) *= d;
2341 bvalue = abs(*bptr);
2342 if ((j == 1) || (j == 2)) bvalue >>= 1; /* half-grid */
2343 if (has_odd_space) bvalue >>= 1; /* force half-grid */
2344 lgcf = FindGCF(bvalue, ostyle->cs_expander);
2345 lexpand = FindGCF(lexpand, lgcf);
2346 }
2347 }
2348 }
2349 else if (op->co_opcode == CIFOP_SLOTS)
2350 {
2351 slots = (SlotsData *)op->co_client;
2352 for (j = 0; j < 8; j++)
2353 {
2354 switch (j) {
2355 case 0: bptr = &slots->sl_sborder; break;
2356 case 1: bptr = &slots->sl_ssize; break;
2357 case 2: bptr = &slots->sl_ssep; break;
2358 case 3: bptr = &slots->sl_lborder; break;
2359 case 4: bptr = &slots->sl_lsize; break;
2360 case 5: bptr = &slots->sl_lsep; break;
2361 case 6: bptr = &slots->sl_offset; break;
2362 case 7: bptr = &slots->sl_start; break;
2363 }
2364 if (*bptr != 0)
2365 {
2366 (*bptr) *= d;
2367 bvalue = abs(*bptr);
2368 if ((j == 1) || (j == 2) || (j == 4) || (j == 5))
2369 bvalue >>= 1; /* half-grid */
2370 if (has_odd_space) bvalue >>= 1; /* force half-grid */
2371 lgcf = FindGCF(bvalue, ostyle->cs_expander);
2372 lexpand = FindGCF(lexpand, lgcf);
2373 }
2374 }
2375 }
2376 else if (op->co_opcode == CIFOP_SQUARES_G)
2377 {
2378 squares = (SquaresData *)op->co_client;
2379 for (j = 0; j < 5; j++)
2380 {
2381 switch (j) {
2382 case 0: bptr = &squares->sq_border; break;
2383 case 1: bptr = &squares->sq_size; break;
2384 case 2: bptr = &squares->sq_sep; break;
2385 case 3: bptr = &squares->sq_gridx; break;
2386 case 4: bptr = &squares->sq_gridy; break;
2387 }
2388 if (*bptr != 0)
2389 {
2390 (*bptr) *= d;
2391 lgcf = FindGCF(abs(*bptr), ostyle->cs_expander);
2392 lexpand = FindGCF(lexpand, lgcf);
2393 }
2394 }
2395 }
2396 /* Presence of op->co_opcode in CIFOP_OR indicates a copy */
2397 /* of the SquaresData pointer from a following operator */
2398 /* CIFOP_BBOX uses the co_client field as a flag field. */
2399 else
2400 {
2401 switch (op->co_opcode)
2402 {
2403 case CIFOP_OR:
2404 case CIFOP_BBOX:
2405 case CIFOP_BOUNDARY:
2406 case CIFOP_MASKHINTS:
2407 case CIFOP_MAXRECT:
2408 case CIFOP_NET:
2409 break;
2410 case CIFOP_BRIDGELIM:
2411 case CIFOP_BRIDGE:
2412 bridge = (BridgeData *)op->co_client;
2413 bridge->br_width *= d;
2414 lgcf = FindGCF(abs(bridge->br_width),
2415 ostyle->cs_expander);
2416 lexpand = FindGCF(lexpand, lgcf);
2417 break;
2418 default:
2419 bloats = (BloatData *)op->co_client;
2420 for (j = 0; j < TT_MAXTYPES; j++)
2421 {
2422 if (bloats->bl_distance[j] != 0)
2423 {
2424 bloats->bl_distance[j] *= d;
2425 lgcf = FindGCF(abs(bloats->bl_distance[j]),
2426 ostyle->cs_expander);
2427 lexpand = FindGCF(lexpand, lgcf);
2428 }
2429 }
2430 }
2431 }
2432 }
2433 /* time-saving quick check */
2434 if ((lexpand == 1) && (d == 1)) break;
2435 }
2436 }
2437
2438 /* Recompute drc-cif rule distances */
2439 drcCifScale(d, 1);
2440
2441 /* Reduce the scale and all distances by the greatest common */
2442 /* factor of everything. */
2443
2444 /* fprintf(stderr, "All CIF units divisible by %d\n", lexpand); */
2445 /* fflush(stderr); */
2446
2447 lgcf = FindGCF(ostyle->cs_scaleFactor, ostyle->cs_expander);
2448 if (lgcf < lexpand) lexpand = lgcf;
2449 if (lexpand <= 1) return;
2450
2451 /* fprintf(stderr, "Expander goes from %d to %d\n", ostyle->cs_expander,
2452 ostyle->cs_expander / lexpand); */
2453 /* fprintf(stderr, "All CIF op distances are divided by %d\n", lexpand); */
2454 /* fflush(stderr); */
2455
2456 ostyle->cs_scaleFactor /= lexpand;
2457 ostyle->cs_expander /= lexpand;
2458
2459 for (i = 0; i < ostyle->cs_nLayers; i++)
2460 {
2461 cl = ostyle->cs_layers[i];
2462 for (op = cl->cl_ops; op != NULL; op = op->co_next)
2463 {
2464 if (op->co_distance)
2465 op->co_distance /= lexpand;
2466
2467 if (op->co_client)
2468 {
2469 int nlayers;
2470 switch (op->co_opcode)
2471 {
2472 case CIFOP_SLOTS:
2473 slots = (SlotsData *)op->co_client;
2474 if (slots->sl_sborder != 0)
2475 slots->sl_sborder /= lexpand;
2476 if (slots->sl_ssize != 0)
2477 slots->sl_ssize /= lexpand;
2478 if (slots->sl_ssep != 0)
2479 slots->sl_ssep /= lexpand;
2480 if (slots->sl_lborder != 0)
2481 slots->sl_lborder /= lexpand;
2482 if (slots->sl_lsize != 0)
2483 slots->sl_lsize /= lexpand;
2484 if (slots->sl_lsep != 0)
2485 slots->sl_lsep /= lexpand;
2486 if (slots->sl_offset != 0)
2487 slots->sl_offset /= lexpand;
2488 if (slots->sl_start != 0)
2489 slots->sl_start /= lexpand;
2490 break;
2491 case CIFOP_SQUARES_G:
2492 squares = (SquaresData *)op->co_client;
2493 if (squares->sq_gridx != 0)
2494 squares->sq_gridx /= lexpand;
2495 if (squares->sq_gridy != 0)
2496 squares->sq_gridy /= lexpand;
2497 /* (drop through) */
2498 case CIFOP_SQUARES:
2499 squares = (SquaresData *)op->co_client;
2500 if (squares->sq_border != 0)
2501 squares->sq_border /= lexpand;
2502 if (squares->sq_size != 0)
2503 squares->sq_size /= lexpand;
2504 if (squares->sq_sep != 0)
2505 squares->sq_sep /= lexpand;
2506 break;
2507 case CIFOP_BLOAT:
2508 case CIFOP_BLOATMIN:
2509 case CIFOP_BLOATMAX:
2510 bloats = (BloatData *)op->co_client;
2511 for (j = 0; j < TT_MAXTYPES; j++)
2512 if (bloats->bl_distance[j] != 0)
2513 bloats->bl_distance[j] /= lexpand;
2514 break;
2515 case CIFOP_BRIDGELIM:
2516 case CIFOP_BRIDGE:
2517 bridge = (BridgeData *)op->co_client;
2518 bridge->br_width /= lexpand;
2519 break;
2520 default:
2521 /* op->co_opcode in CIFOP_OR is a pointer copy, */
2522 /* in CIFOP_BBOX and CIFOP_MAXRECT is a flag, */
2523 /* and in CIFOP_NET and CIFOP_MASKHINTS is a */
2524 /* string. */
2525 break;
2526 }
2527 }
2528 }
2529 }
2530
2531 /* Recompute drc-cif rule distances */
2532 drcCifScale(1, lexpand);
2533
2534 /* Recompute value of cs_radius */
2535 cifComputeHalo(ostyle);
2536 }
2537