1 /*
2  * ExtTech.c --
3  *
4  * Circuit extraction.
5  * Code to read and process the sections of a technology file
6  * that are specific to circuit extraction.
7  *
8  *     *********************************************************************
9  *     * Copyright (C) 1985, 1990 Regents of the University of California. *
10  *     * Permission to use, copy, modify, and distribute this              *
11  *     * software and its documentation for any purpose and without        *
12  *     * fee is hereby granted, provided that the above copyright          *
13  *     * notice appear in all copies.  The University of California        *
14  *     * makes no representations about the suitability of this            *
15  *     * software for any purpose.  It is provided "as is" without         *
16  *     * express or implied warranty.  Export of this software outside     *
17  *     * of the United States of America may require an export license.    *
18  *     *********************************************************************
19  */
20 
21 #ifndef lint
22 static char sccsid[] = "@(#)ExtTech.c	4.8 MAGIC (Berkeley) 10/26/85";
23 #endif  /* not lint */
24 
25 #include <stdio.h>
26 #include <stdlib.h>		/* for strtod() */
27 #include <string.h>
28 #include <math.h>
29 #include <ctype.h>		/* for isspace() */
30 
31 #include "tcltk/tclmagic.h"
32 #include "utils/magic.h"
33 #include "utils/utils.h"
34 #include "utils/geometry.h"
35 #include "tiles/tile.h"
36 #include "utils/hash.h"
37 #include "database/database.h"
38 #include "database/databaseInt.h"
39 #include "utils/malloc.h"
40 #include "textio/textio.h"
41 #include "utils/tech.h"
42 #include "debug/debug.h"
43 #include "extract/extract.h"
44 #include "extract/extractInt.h"
45 #include "cif/CIFint.h"
46 #include "cif/cif.h"
47 
48 /* Whether we are converting units from microns to lambda */
49 bool doConvert;
50 
51 /* Current extraction style */
52 ExtStyle *ExtCurStyle = NULL;
53 
54 /* List of all styles */
55 ExtKeep *ExtAllStyles = NULL;
56 
57 /* Forward declarations */
58 void extTechFinalStyle();
59 void ExtLoadStyle();
60 void ExtTechScale(int, int);
61 
62 /*
63  * Table used for parsing the extract section of a .tech file
64  * Each line in the extract section is of a type determined by
65  * its first keyword.  There is one entry in the following table
66  * for each such keyword.
67  */
68 
69 typedef enum
70 {
71     AREAC, CONTACT, CSCALE,
72     DEFAULTAREACAP, DEFAULTOVERLAP, DEFAULTPERIMETER, DEFAULTSIDEOVERLAP,
73     DEFAULTSIDEWALL,
74     DEVICE, FET, FETRESIST, HEIGHT, ANTENNA, MODEL, TIEDOWN, LAMBDA, OVERC,
75     PERIMC, PLANEORDER, NOPLANEORDER, RESIST, RSCALE, SIDEHALO, SIDEOVERLAP,
76     SIDEWALL, STEP, STYLE, SUBSTRATE, UNITS, VARIANT
77 } Key;
78 
79 typedef struct
80 {
81     char	*k_name;
82     int		 k_key;
83     int		 k_minargs;
84     int		 k_maxargs;
85     char	*k_usage;
86 } keydesc;
87 
88 static keydesc keyTable[] = {
89     "areacap",		AREAC,		3,	3,
90 "types capacitance",
91 
92     "contact",		CONTACT,	3,	6,
93 "type resistance",
94 
95     "cscale",		CSCALE,		2,	2,
96 "capacitance-scalefactor",
97 
98     "defaultareacap",	DEFAULTAREACAP,	4,	6,
99 "types plane capacitance",
100 
101     "defaultoverlap",	DEFAULTOVERLAP,	6,	6,
102 "types plane otertypes otherplane capacitance",
103 
104     "defaultperimeter",	DEFAULTPERIMETER, 4,	6,
105 "types plane capacitance",
106 
107     "defaultsideoverlap", DEFAULTSIDEOVERLAP, 6, 6,
108 "types plane othertypes otherplane capacitance",
109 
110     "defaultsidewall",	DEFAULTSIDEWALL, 4,	4,
111 "types plane capacitance",
112 
113     "device",		DEVICE,		4,	10,
114 "device dev-type types options...",
115 
116     "fet",		FET,		8,	9,
117 "types terminal-types min-#-terminals name [subs-types] subs-node gscap gate-chan-cap",
118 
119     "fetresist",	FETRESIST,	4,	4,
120 "type region ohms-per-square",
121 
122     "height",		HEIGHT,		4,	4,
123 "type height-above-subtrate thickness",
124 
125     "antenna",		ANTENNA,	4,	6,
126 "type [calc-type] [antenna-ratio-proportional] antenna-ratio-const",
127 
128     "model",		MODEL,		2,	3,
129 "partial-cumulative [area-sidewall]",
130 
131     "tiedown",		TIEDOWN,	2,	2,
132 "types",
133 
134     "lambda",		LAMBDA,		2,	2,
135 "units-per-lambda",
136 
137     "overlap",		OVERC,		4,	5,
138 "toptypes bottomtypes capacitance [shieldtypes]",
139 
140     "perimc",		PERIMC,		4,	4,
141 "intypes outtypes capacitance",
142 
143     "planeorder",	PLANEORDER,	3,	3,
144 "plane index",
145     "noplaneordering",	NOPLANEORDER,	1,	1,
146 "(no arguments needed)",
147 
148     "resist",		RESIST,		3,	4,
149 "types resistance",
150 
151     "rscale",		RSCALE,		2,	2,
152 "resistance-scalefactor",
153 
154     "sidehalo",		SIDEHALO,	2,	2,
155 "halo",
156 
157     "sideoverlap",	SIDEOVERLAP,	5,	6,
158 "intypes outtypes ovtypes capacitance [shieldtypes]",
159 
160     "sidewall",		SIDEWALL,	6,	6,
161 "intypes outtypes neartypes fartypes capacitance",
162 
163     "step",		STEP,		2,	2,
164 "size",
165 
166     "style",		STYLE,		2,	4,
167 "stylename",
168 
169     "substrate",	SUBSTRATE,	3,	5,
170 "types plane [subs-node]",
171 
172     "units",		UNITS,		2,	2,
173 "lambda|microns",
174 
175     "variants",		VARIANT,	2,	2,
176 "style,...",
177 
178     0
179 };
180 
181 
182 /*
183  * Table used for parsing the "device" keyword types
184  *
185  * (Note: "10" for max types in subcircuit is arbitrary---the parser
186  * ignores max types for DEV_SUBCKT and DEV_MSUBCKT).
187  */
188 
189 /* types are enumerated in extract.h */
190 
191 static keydesc devTable[] = {
192     "mosfet",		DEV_MOSFET,		5,	10,
193 "name gate-types src-types [drn-types] sub-types|None sub-node [gscap gccap]",
194 
195     "bjt",		DEV_BJT,		5,	5,
196 "name base-types emitter-types collector-types",
197 
198     "capacitor",	DEV_CAP,		4,	8,
199 "name top-types bottom-types [sub-types|None sub-node] [[perimcap] areacap]",
200 
201     "capreverse",	DEV_CAPREV,		4,	8,
202 "name bottom-types top-types [sub-types|None sub-node] [[perimcap] areacap]",
203 
204     "resistor",		DEV_RES,		4,	6,
205 "name|None res-types terminal-types [sub-types|None sub-node]",
206 
207     "diode",		DEV_DIODE,		4,	6,
208 "name pos-types neg-types [sub-types|None sub-node]",
209 
210     "pdiode",		DEV_PDIODE,		4,	6,
211 "name pos-types neg-types [sub-types|None sub-node]",
212 
213     "ndiode",		DEV_NDIODE,		4,	6,
214 "name neg-types pos-types [sub-types|None sub-node]",
215 
216     "subcircuit",	DEV_SUBCKT,		3,	11,
217 "name dev-types [N] [term1-types ... termN-types [sub-types|None sub-node]] [options]",
218 
219     "rsubcircuit",	DEV_RSUBCKT,		4,	7,
220 "name dev-types terminal-types [sub-types|None sub-node] [options]",
221 
222     "msubcircuit",	DEV_MSUBCKT,		3,	11,
223 "name dev-types [N] [term1-types ... termN-types [sub-types|None sub-node]] [options]",
224 
225     "csubcircuit",	DEV_CSUBCKT,		4,	7,
226 "name dev-types terminal-types [sub-types|None sub-node] [options]",
227 
228     0
229 };
230 
231 #ifdef MAGIC_WRAPPER
232 
233 /*
234  * ----------------------------------------------------------------------------
235  *
236  * ExtCompareStyle --
237  *
238  *	This routine is designed to work with embedded exttosim and
239  *	exttospice.  It determines whether the current extract style
240  *	matches the string (picked up from the .ext file).  If so, it
241  *	returns TRUE.  If not, it checks whether the style exists in
242  *	the list of known files for this technology.  If so, it loads
243  *	the correct style and returns TRUE.  If not, it returns FALSE.
244  *
245  * ----------------------------------------------------------------------------
246  */
247 
248 bool
ExtCompareStyle(stylename)249 ExtCompareStyle(stylename)
250     char *stylename;
251 {
252     ExtKeep *style;
253 
254     if (!strcmp(stylename, ExtCurStyle->exts_name))
255 	return TRUE;
256     else
257     {
258 	for (style = ExtAllStyles; style != NULL; style = style->exts_next)
259 	{
260 	    if (!strcmp(stylename, style->exts_name))
261 	    {
262 		ExtLoadStyle(stylename);
263 		return TRUE;
264 	    }
265 	}
266     }
267     return FALSE;
268 }
269 
270 /*
271  * ----------------------------------------------------------------------------
272  *
273  * ExtGetDevInfo --
274  *
275  *	This routine is designed to work with the embedded exttosim and
276  *	exttospice commands under the Tcl-based magic, such that all
277  *	device information needed by these commands can be picked up
278  *	from the current extraction style (as it should!).  This
279  *	really should be set up when the extract file is read, which is
280  *	why the routine is here, although this is not a very efficient
281  *	way to do it (but it needs to be this way to keep backward
282  *	compatibility with the non-Tcl, standalone programs ext2sim and
283  *	ext2spice).
284  *
285  *	Note that finding the device by index ("idx") is horribly
286  *	inefficient, but keeps the netlist generator separated from
287  *	the extractor.  Some of this code is seriously schizophrenic,
288  *	and should not be investigated too closely.
289  *
290  * Results:
291  *	Return FALSE if no device corresponds to index "idx".  TRUE
292  *	otherwise.
293  *
294  * Side Effects:
295  *	Fills values in the argument list.
296  *
297  * Notes:
298  *	The original sd_rclassptr has been expanded to s_rclassptr and
299  *	d_rclassptr to capture asymmetric devices, bipolars, etc.  Note
300  *	that this is not a general-purpose method extending beyond two
301  *	(non-gate) terminals, and should be updated.
302  *
303  * ----------------------------------------------------------------------------
304  */
305 
306 bool
ExtGetDevInfo(idx,devnameptr,devtypeptr,s_rclassptr,d_rclassptr,sub_rclassptr,subnameptr)307 ExtGetDevInfo(idx, devnameptr, devtypeptr, s_rclassptr, d_rclassptr,
308 		sub_rclassptr, subnameptr)
309     int idx;
310     char **devnameptr;	    /* Name of extracted device model */
311     TileType *devtypeptr;   /* Magic tile type of device */
312     short *s_rclassptr;	    /* Source (1st terminal) type only */
313     short *d_rclassptr;	    /* Drain (2nd terminal) type only */
314     short *sub_rclassptr;
315     char **subnameptr;
316 {
317     TileType t;
318     TileTypeBitMask *rmask, *tmask;
319     int n, i = 0, j;
320     bool repeat, found;
321     ExtDevice *devptr;
322     char *locdname;
323     char **uniquenamelist = (char **)mallocMagic(DBNumTypes * sizeof(char *));
324 
325     found = FALSE;
326     for (t = TT_TECHDEPBASE; t < DBNumTypes; t++)
327     {
328 	for (devptr = ExtCurStyle->exts_device[t]; devptr; devptr = devptr->exts_next)
329 	{
330 	    locdname = devptr->exts_deviceName;
331 	    if (locdname != NULL)
332 	    {
333 		repeat = FALSE;
334 		for (j = 0; j < i; j++)
335 		    if (!strcmp(uniquenamelist[j], locdname))
336 		    {
337 			repeat = TRUE;
338 			break;
339 		    }
340 		if (repeat == FALSE)
341 		{
342 		    if (i == idx)
343 		    {
344 			found = TRUE;
345 			break;
346 		    }
347 		    uniquenamelist[i] = locdname;
348 		    i++;
349 		}
350 	    }
351 	}
352 	if (found == TRUE) break;
353     }
354     if (t == DBNumTypes)
355     {
356 	freeMagic(uniquenamelist);
357 	return FALSE;
358     }
359     if (devptr == NULL)
360     {
361 	freeMagic(uniquenamelist);
362 	return FALSE;
363     }
364 
365     if (devnameptr) *devnameptr = locdname;
366     if (subnameptr) *subnameptr = devptr->exts_deviceSubstrateName;
367     if (devtypeptr) *devtypeptr = t;
368 
369     tmask = &devptr->exts_deviceSDTypes[0];
370     if (s_rclassptr)
371     {
372         *s_rclassptr = (short)(-1);	/* NO_RESCLASS */
373 
374 	for (n = 0; n < ExtCurStyle->exts_numResistClasses; n++)
375 	{
376 	    rmask = &ExtCurStyle->exts_typesByResistClass[n];
377 	    if (TTMaskIntersect(rmask, tmask))
378 	    {
379 		*s_rclassptr = (short)n;
380 		break;
381 	    }
382 	}
383     }
384 
385     if (d_rclassptr)
386     {
387 	tmask = &devptr->exts_deviceSDTypes[1];
388 	if (TTMaskIsZero(tmask))
389 	{
390 	    /* Set source and drain resistance classes to be the same */
391 	    *d_rclassptr = (short)n;
392 	}
393 	else
394 	{
395 	    *d_rclassptr = (short)(-1);	/* NO_RESCLASS */
396 
397 	    for (n = 0; n < ExtCurStyle->exts_numResistClasses; n++)
398 	    {
399 		rmask = &ExtCurStyle->exts_typesByResistClass[n];
400 		if (TTMaskIntersect(rmask, tmask))
401 		{
402 		    *d_rclassptr = (short)n;
403 		    break;
404 		}
405 	    }
406 	}
407     }
408 
409     if (sub_rclassptr)
410     {
411 	tmask = &devptr->exts_deviceSubstrateTypes;
412 	*sub_rclassptr = (short)(-1);	/* NO_RESCLASS */
413 
414 	for (n = 0; n < ExtCurStyle->exts_numResistClasses; n++)
415 	{
416 	    rmask = &ExtCurStyle->exts_typesByResistClass[n];
417 	    if (TTMaskIntersect(rmask, tmask))
418 	    {
419 		*sub_rclassptr = (short)(n);
420 		break;
421 	    }
422 	}
423     }
424 
425     freeMagic(uniquenamelist);
426     return TRUE;
427 }
428 
429 #endif /* MAGIC_WRAPPER */
430 
431 /*
432  * ----------------------------------------------------------------------------
433  *
434  * extGetDevType --
435  *
436  *	Given an extraction model device name (devname), return the associated
437  *	magic tiletype for the device.
438  *
439  * Results:
440  *	Tile type that represents the device "devname" in the magic database.
441  *
442  * Notes:
443  *	It is possible for the extract section to define multiple tile types
444  *	that produce the same extracted device name, so the returned TileType
445  *	is not guaranteed to be unique to the device name.
446  *
447  * ----------------------------------------------------------------------------
448  */
449 
450 TileType
extGetDevType(devname)451 extGetDevType(devname)
452     char *devname;
453 {
454     TileType t;
455     ExtDevice *devptr;
456 
457     for (t = TT_TECHDEPBASE; t < DBNumTypes; t++)
458 	for (devptr = ExtCurStyle->exts_device[t]; devptr; devptr = devptr->exts_next)
459 	    if (!strcmp(devptr->exts_deviceName, devname))
460 		return t;
461 
462     return -1;
463 }
464 
465 /*
466  * ----------------------------------------------------------------------------
467  *
468  * ExtGetGateTypesMask --
469  *
470  *	Put a mask of FET gate types in the mask pointer argument.
471  *	Return 0 on success, 1 on failure (no extraction style set)
472  *
473  * ----------------------------------------------------------------------------
474  */
475 
476 int
ExtGetGateTypesMask(mask)477 ExtGetGateTypesMask(mask)
478     TileTypeBitMask *mask;
479 {
480     TileType ttype;
481 
482     if (ExtCurStyle == NULL) return 1;
483 
484     TTMaskZero(mask);
485     for (ttype = TT_TECHDEPBASE; ttype < DBNumTypes; ttype++)
486     {
487         if (TTMaskHasType(&ExtCurStyle->exts_deviceMask, ttype))
488         {
489             ExtDevice *devptr = ExtCurStyle->exts_device[ttype];
490 
491             for (; devptr; devptr = devptr->exts_next)
492                 if ((devptr->exts_deviceClass == DEV_MOSFET) ||
493                         (devptr->exts_deviceClass == DEV_FET) ||
494                         (devptr->exts_deviceClass == DEV_ASYMMETRIC) ||
495                         (devptr->exts_deviceClass == DEV_MSUBCKT))
496                     TTMaskSetType(mask, ttype);
497         }
498     }
499     return 0;
500 }
501 
502 /*
503  * ----------------------------------------------------------------------------
504  *
505  * ExtGetDiffTypesMask --
506  *
507  *	Put a mask of diffusion types in the mask pointer argument.
508  *	Return 0 on success, 1 on failure (no extraction style set)
509  *
510  * ----------------------------------------------------------------------------
511  */
512 
513 int
ExtGetDiffTypesMask(mask)514 ExtGetDiffTypesMask(mask)
515     TileTypeBitMask *mask;
516 {
517     TileType ttype;
518 
519     if (ExtCurStyle == NULL) return 1;
520 
521     TTMaskZero(mask);
522     TTMaskSetMask(mask, &ExtCurStyle->exts_antennaTieTypes);
523 
524     return 0;
525 }
526 
527 #ifdef THREE_D
528 /*
529  * ----------------------------------------------------------------------------
530  *
531  * ExtGetZAxis --
532  *
533  *	Get the height and thickness parameters for a layer (used by the
534  *	graphics module which does not have access to internal variables
535  *	in the extract section).
536  *
537  * Results:
538  *	None
539  *
540  * Side Effects:
541  *	Fills values "height" and "thick" in argument list.
542  *
543  * ----------------------------------------------------------------------------
544  */
545 
546 void
ExtGetZAxis(tile,height,thick)547 ExtGetZAxis(tile, height, thick)
548     Tile *tile;
549     float *height, *thick;
550 {
551     TileType ttype;
552 
553     if (ExtCurStyle == NULL) return;
554 
555     ttype = TiGetLeftType(tile);        /* Ignore non-Manhattan for now */
556 
557     /* Note that w_scale is multiplied by SUBPIXEL to get fixed-point accuracy. */
558     /* However, we downshift by only 9 (divide by 512) so that heights are      */
559     /* exaggerated in the layout by a factor of 8 (height exaggeration is       */
560     /* standard practice for VLSI cross-sections).                              */
561 
562     *height = ExtCurStyle->exts_height[ttype];
563     *thick = ExtCurStyle->exts_thick[ttype];
564 }
565 #endif  /* THREE_D */
566 
567 
568 /*
569  * ----------------------------------------------------------------------------
570  *
571  * ExtPrintStyle --
572  *
573  *	Print the available and/or current extraction styles.
574  *
575  * Results:
576  *	None.
577  *
578  * Side effects:
579  *	Output.
580  *
581  * ----------------------------------------------------------------------------
582  */
583 
584 void
ExtPrintStyle(dolist,doforall,docurrent)585 ExtPrintStyle(dolist, doforall, docurrent)
586     bool dolist;
587     bool doforall;
588     bool docurrent;
589 {
590     ExtKeep *style;
591 
592     if (docurrent)
593     {
594 	if (ExtCurStyle == NULL)
595 	    TxError("Error: No style is set\n");
596 	else
597 	{
598 	    if (!dolist) TxPrintf("The current style is \"");
599 #ifdef MAGIC_WRAPPER
600 	    if (dolist)
601 		Tcl_SetResult(magicinterp, ExtCurStyle->exts_name, NULL);
602 	    else
603 #endif
604 	    TxPrintf("%s", ExtCurStyle->exts_name);
605 	    if (!dolist) TxPrintf("\".\n");
606 	}
607     }
608 
609     if (doforall)
610     {
611 	if (!dolist) TxPrintf("The extraction styles are: ");
612 
613 	for (style = ExtAllStyles; style; style = style->exts_next)
614 	{
615 	    if (dolist)
616 	    {
617 #ifdef MAGIC_WRAPPER
618 		Tcl_AppendElement(magicinterp, style->exts_name);
619 #else
620 		if (style != ExtAllStyles) TxPrintf(" ");
621 		TxPrintf("%s", style->exts_name);
622 #endif
623 	    }
624 	    else
625 	    {
626 		if (style != ExtAllStyles) TxPrintf(", ");
627 		TxPrintf("%s", style->exts_name);
628 	    }
629 	}
630 	if (!dolist) TxPrintf(".\n");
631     }
632 }
633 
634 /*
635  * ----------------------------------------------------------------------------
636  *
637  * ExtSetStyle --
638  *
639  * Set the current extraction style to 'name', or print
640  * the available and current styles if 'name' is NULL.
641  *
642  * Results:
643  *	None.
644  *
645  * Side effects:
646  *	Just told you.
647  *
648  * ----------------------------------------------------------------------------
649  */
650 
651 void
ExtSetStyle(name)652 ExtSetStyle(name)
653     char *name;
654 {
655     ExtKeep *style, *match;
656     int length;
657 
658     if (name == NULL) return;
659 
660     match = NULL;
661     length = strlen(name);
662     for (style = ExtAllStyles; style; style = style->exts_next)
663     {
664 	if (strncmp(name, style->exts_name, length) == 0)
665 	{
666 	    if (match != NULL)
667 	    {
668 		TxError("Extraction style \"%s\" is ambiguous.\n", name);
669 		ExtPrintStyle(FALSE, TRUE, TRUE);
670 		return;
671 	    }
672 	    match = style;
673 	}
674     }
675 
676     if (match != NULL)
677     {
678 	ExtLoadStyle(match->exts_name);
679 	TxPrintf("Extraction style is now \"%s\"\n", name);
680 	return;
681     }
682 
683     TxError("\"%s\" is not one of the extraction styles Magic knows.\n", name);
684     ExtPrintStyle(FALSE, TRUE, TRUE);
685 }
686 
687 /*
688  * ----------------------------------------------------------------------------
689  *
690  * extTechStyleAlloc --
691  *
692  * Allocate memory for a new extract style structure.
693  *
694  * ----------------------------------------------------------------------------
695  */
696 
697 ExtStyle *
extTechStyleAlloc()698 extTechStyleAlloc()
699 {
700     ExtStyle *style;
701     TileType r;
702 
703     style = (ExtStyle *) mallocMagic(sizeof (ExtStyle));
704     return style;
705 }
706 
707 
708 /*
709  * ----------------------------------------------------------------------------
710  *
711  * extTechStyleInit --
712  *
713  * Fill in the extract style structure with initial values.
714  *
715  * ----------------------------------------------------------------------------
716  */
717 
718 void
extTechStyleInit(style)719 extTechStyleInit(style)
720     ExtStyle *style;
721 {
722     TileType r, s;
723 
724     style->exts_name = NULL;
725     style->exts_status = TECH_NOT_LOADED;
726 
727     style->exts_sidePlanes = style->exts_overlapPlanes = 0;
728     TTMaskZero(&style->exts_deviceMask);
729     style->exts_activeTypes = DBAllButSpaceAndDRCBits;
730 
731     for (r = 0; r < NP; r++)
732     {
733 	TTMaskZero(&style->exts_sideTypes[r]);
734 	TTMaskZero(&style->exts_overlapTypes[r]);
735 	style->exts_planeOrder[r] = -1;
736     }
737 
738     for (r = 0; r < NT; r++)
739     {
740 	TTMaskZero(&style->exts_nodeConn[r]);
741 	TTMaskZero(&style->exts_resistConn[r]);
742 	TTMaskZero(&style->exts_deviceConn[r]);
743 	style->exts_allConn[r] = DBAllTypeBits;
744 
745 	style->exts_sheetResist[r] = 0;
746 	style->exts_cornerChop[r] = 1.0;
747 	style->exts_viaResist[r] = 0;
748 	style->exts_height[r] = 0.0;
749 	style->exts_thick[r] = 0.0;
750 	style->exts_areaCap[r] = (CapValue) 0;
751 	style->exts_overlapOtherPlanes[r] = 0;
752 	TTMaskZero(&style->exts_overlapOtherTypes[r]);
753 	TTMaskZero(&style->exts_sideEdges[r]);
754 	for (s = 0; s < NT; s++)
755 	{
756 	    TTMaskZero(&style->exts_sideCoupleOtherEdges[r][s]);
757 	    TTMaskZero(&style->exts_sideOverlapOtherTypes[r][s]);
758 	    style->exts_sideOverlapOtherPlanes[r][s] = 0;
759 	    style->exts_sideCoupleCap[r][s] = (EdgeCap *) NULL;
760 	    style->exts_sideOverlapCap[r][s] = (EdgeCap *) NULL;
761 	    style->exts_perimCap[r][s] = (CapValue) 0;
762 	    style->exts_overlapCap[r][s] = (CapValue) 0;
763 
764 	    TTMaskZero(&style->exts_overlapShieldTypes[r][s]);
765 	    style->exts_overlapShieldPlanes[r][s] = 0;
766 	    style->exts_sideOverlapShieldPlanes[r][s] = 0;
767 	}
768 
769 	TTMaskZero(&style->exts_perimCapMask[r]);
770 #ifdef ARIEL
771 	TTMaskZero(&style->exts_subsTransistorTypes[r]);
772 #endif
773 	if (style->exts_device[r] != NULL)
774 	{
775 	    ExtDevice *devptr;
776 	    for (devptr = style->exts_device[r]; devptr; devptr = devptr->exts_next)
777 	    {
778 
779 		if (devptr->exts_deviceSDTypes != NULL)
780 		    freeMagic(devptr->exts_deviceSDTypes);
781 		if (devptr->exts_deviceSubstrateName != (char *) NULL)
782 		    freeMagic(devptr->exts_deviceSubstrateName);
783 		if (devptr->exts_deviceName != (char *) NULL)
784 		    freeMagic(devptr->exts_deviceName);
785 		while (devptr->exts_deviceParams != (ParamList *) NULL)
786 		{
787 		    /* Parameter lists are shared.  Only free the last one! */
788 
789 		    if (devptr->exts_deviceParams->pl_count > 1)
790 		    {
791 			devptr->exts_deviceParams->pl_count--;
792 			devptr->exts_deviceParams = (ParamList *)NULL;
793 		    }
794 		    else
795 		    {
796 			freeMagic(devptr->exts_deviceParams->pl_name);
797 			freeMagic(devptr->exts_deviceParams);
798 			devptr->exts_deviceParams = devptr->exts_deviceParams->pl_next;
799 		    }
800 		}
801 		if (devptr->exts_deviceResist.ht_table != (HashEntry **) NULL)
802 		    HashKill(&devptr->exts_deviceResist);
803 
804 		freeMagic(devptr);
805 	    }
806 	    style->exts_device[r] = (ExtDevice *)NULL;
807 	}
808     }
809 
810     style->exts_sideCoupleHalo = 0;
811     style->exts_stepSize = 100;
812     style->exts_unitsPerLambda = 100.0;
813     style->exts_resistScale = 1000;
814     style->exts_capScale = 1000;
815     style->exts_numResistClasses = 0;
816 
817     style->exts_planeOrderStatus = needPlaneOrder ;
818     TTMaskZero(&style->exts_antennaTieTypes);
819 
820     for (r = 0; r < DBNumTypes; r++)
821     {
822 	style->exts_antennaRatio[r].areaType = (char)0;
823 	style->exts_antennaRatio[r].ratioGate = 0.0;
824 	style->exts_antennaRatio[r].ratioDiffA = 0.0;
825 	style->exts_antennaRatio[r].ratioDiffB = 0.0;
826 	style->exts_resistByResistClass[r] = 0;
827 	TTMaskZero(&style->exts_typesByResistClass[r]);
828 	style->exts_typesResistChanged[r] = DBAllButSpaceAndDRCBits;
829 	TTMaskSetType(&style->exts_typesResistChanged[r], TT_SPACE);
830 	style->exts_typeToResistClass[r] = -1;
831 
832     }
833     doConvert = FALSE;
834 
835     // The exts_globSubstratePlane setting of -1 will be used to set a
836     // backwards-compatibility mode matching previous behavior with
837     // respect to the substrate when there is no "substrate" line in
838     // the techfile.
839 
840     style->exts_globSubstratePlane = -1;
841     TTMaskZero(&style->exts_globSubstrateTypes);
842     TTMaskZero(&style->exts_globSubstrateShieldTypes);
843     style->exts_globSubstrateName = (char *)NULL;
844 }
845 
846 
847 /*
848  * ----------------------------------------------------------------------------
849  *
850  * extTechStyleNew --
851  *
852  * Allocate a new style with zeroed technology variables.
853  *
854  * Results:
855  *	Allocates a new ExtStyle, initializes it, and returns it.
856  *
857  * Side effects:
858  *	See above.
859  *
860  * ----------------------------------------------------------------------------
861  */
862 
863 ExtStyle *
extTechStyleNew()864 extTechStyleNew()
865 {
866     ExtStyle *style;
867     TileType r;
868 
869     style = extTechStyleAlloc();
870 
871     /* This entry in ExtStyle is allocated and must be initialized */
872     for (r = 0; r < NT; r++)
873 	style->exts_device[r] = NULL;
874 
875     extTechStyleInit(style);
876     return style;
877 }
878 
879 /*
880  * ----------------------------------------------------------------------------
881  *
882  * aToCap --
883  *
884  *    Utility procedure for reading capacitance values.
885  *
886  * Returns:
887  *    A value of type CapValue.
888  *
889  * Side effects:
890  *    none.
891  * ----------------------------------------------------------------------------
892  */
893 
894 CapValue
aToCap(str)895 aToCap(str)
896     char *str;
897 {
898     CapValue capVal;
899     if (sscanf(str, "%lf", &capVal) != 1) {
900 	capVal = (CapValue) 0;
901 	TechError("Capacitance value %s must be a number\n", str);
902     }
903     return capVal;
904 }
905 
906 /*
907  * ----------------------------------------------------------------------------
908  *
909  * ExtLoadStyle --
910  *
911  * Re-read the technology file to load the specified technology extraction
912  * style into structure ExtCurStyle.  This is much more memory-efficient than
913  * keeping a separate (and huge!) ExtStyle structure for each extraction style.
914  * It incurs a complete reading of the tech file on startup and every time the
915  * extraction style is changed, but we can assume that this does not happen
916  * often.  The first style in the technology file is assumed to be default, so
917  * that re-reading the tech file is not necessary on startup unless the default
918  * extraction style is changed by a call to "extract style".
919  *
920  * ----------------------------------------------------------------------------
921  */
922 void
ExtLoadStyle(stylename)923 ExtLoadStyle(stylename)
924    char *stylename;
925 {
926     SectionID invext;
927 
928     extTechStyleInit(ExtCurStyle);	/* Reinitialize and mark as not	*/
929     ExtCurStyle->exts_name = stylename; /* loaded.			*/
930 
931     /* Invalidate the extract section, and reload it. 			*/
932     /* The second parameter to TechSectionGetMask is NULL because	*/
933     /* no other tech client sections depend on the extract section.	*/
934 
935     invext = TechSectionGetMask("extract", NULL);
936 
937     /* If microns are used as units, then the TechLoad needs to convert	*/
938     /* units based on *unscaled* dimensions.  Since it gets the scale	*/
939     /* factor from CIFGetOutputScale(), the CIF units need to be	*/
940     /* unscaled.  This is cumbersome but ensures that the right units	*/
941     /* are obtained.							*/
942     CIFTechOutputScale(DBLambda[1], DBLambda[0]);
943 
944     TechLoad(NULL, invext);
945 
946     /* Put the CIF output scale units back to what they were */
947     CIFTechOutputScale(DBLambda[0], DBLambda[1]);
948 
949     /* extTechFinalStyle(ExtCurStyle); */  /* Taken care of by TechLoad() */
950     ExtTechScale(DBLambda[0], DBLambda[1]);
951 }
952 
953 /*
954  * ----------------------------------------------------------------------------
955  *
956  * ExtTechInit --
957  *
958  *	Ensure that all memory allocated to the extract database has
959  *	been freed up.  Called before loading a new technology.
960  *
961  * ----------------------------------------------------------------------------
962  */
963 void
ExtTechInit()964 ExtTechInit()
965 {
966     ExtKeep *style;
967     int r;
968 
969     /* Delete everything in ExtCurStyle */
970 
971     if (ExtCurStyle != NULL)
972     {
973 	extTechStyleInit(ExtCurStyle);
974 	ExtCurStyle = NULL;
975     }
976 
977     /* Forget all the extract style names */
978 
979     for (style = ExtAllStyles; style != NULL; style = style->exts_next)
980     {
981 	freeMagic(style->exts_name);
982 	freeMagic(style);
983     }
984     ExtAllStyles = NULL;
985 }
986 
987 /*
988  * ----------------------------------------------------------------------------
989  *
990  * ExtTechSimpleAreaCap --
991  *
992  *	Parse the techfile line for the "defaultareacap" keyword.
993  *	This is equivalent to the "areacap" line but also applies
994  *	to "overlap" of types on the second plane (if specified) and
995  *	all planes below it, with appropriate intervening types.
996  *
997  * Usage:
998  *	defaultareacap types plane [[subtypes] subplane] value
999  *
1000  *	where "types" are the types for which to compute area cap,
1001  *	"plane" is the plane of "types", "subplane" is a plane
1002  *	containing wells or any types that have the same coupling
1003  *	as the substrate.  If absent, it is assumed that nothing
1004  *	shields "types" from the subtrate.  Additional optional
1005  *	"subtypes" is a list of types in "subplane" that shield.
1006  *	If absent, then all types in "subplane" are shields to the
1007  *	substrate.  "value" is the area capacitance in aF/um^2.
1008  *
1009  * Results:
1010  *	None.
1011  *
1012  * Side Effects:
1013  *	Adds information into the ExtCurStyle records.
1014  *
1015  * ----------------------------------------------------------------------------
1016  */
1017 
1018 void
ExtTechSimpleAreaCap(argc,argv)1019 ExtTechSimpleAreaCap(argc, argv)
1020     int  argc;
1021     char *argv[];
1022 {
1023     TileType s, t;
1024     TileTypeBitMask types, subtypes, shields;
1025     CapValue capVal;
1026     int plane1, plane2, plane3, pnum1, pnum2, pnum3;
1027     PlaneMask pshield;
1028 
1029     if (ExtCurStyle->exts_planeOrderStatus != seenPlaneOrder)
1030     {
1031 	TechError("Cannot parse area cap line without plane ordering!\n");
1032 	return;
1033     }
1034 
1035     DBTechNoisyNameMask(argv[1], &types);
1036     plane1 = DBTechNoisyNamePlane(argv[2]);
1037     TTMaskAndMask(&types, &DBPlaneTypes[plane1]);
1038 
1039     capVal = aToCap(argv[argc - 1]);
1040 
1041     if (argc == 4)
1042 	plane2 = -1;
1043     else
1044 	plane2 = DBTechNoisyNamePlane(argv[argc - 2]);
1045 
1046     if (argc > 5)
1047 	DBTechNoisyNameMask(argv[argc - 3], &subtypes);
1048     else
1049 	subtypes = DBAllButSpaceAndDRCBits;
1050 
1051     /* Part 1: Area cap */
1052     for (t = TT_TECHDEPBASE; t < DBNumTypes; t++)
1053 	if (TTMaskHasType(&types, t))
1054 	    ExtCurStyle->exts_areaCap[t] = capVal;
1055 
1056     if (plane2 == -1) return;		/* No "virtual" overlaps */
1057     else if (plane1 == plane2) return;  /* shouldn't happen */
1058 
1059     pnum1 = ExtCurStyle->exts_planeOrder[plane1];
1060     pnum2 = ExtCurStyle->exts_planeOrder[plane2];
1061 
1062     /* Part 2: Overlap cap on types equivalent to substrate */
1063     /* Find all types in or below plane2 (i.e., ~(space)/plane2)	   */
1064     /* Shield types are everything in the planes between plane1 and plane2 */
1065 
1066     TTMaskZero(&shields);
1067 
1068     pshield = 0;
1069     for (plane3 = PL_TECHDEPBASE; plane3 < DBNumPlanes; plane3++)
1070     {
1071 	pnum3 = ExtCurStyle->exts_planeOrder[plane3];
1072 	if (pnum3 > pnum2 && pnum3 < pnum1)
1073 	{
1074 	    TTMaskSetMask(&shields, &DBPlaneTypes[plane3]);
1075 	    pshield |= PlaneNumToMaskBit(plane3);
1076 	}
1077 	else if (pnum3 <= pnum2)
1078 	{
1079 	    TTMaskAndMask(&subtypes, &DBPlaneTypes[plane3]);
1080 	    TTMaskClearType(&subtypes, TT_SPACE);
1081 	}
1082 	TTMaskClearType(&shields, TT_SPACE);
1083     }
1084 
1085     /* Now record all of the overlap capacitances */
1086 
1087     for (s = TT_TECHDEPBASE; s < DBNumTypes; s++)
1088     {
1089 	if (TTMaskHasType(&types, s))
1090 	{
1091 	    /* Contact overlap caps are determined from residues */
1092     	    if (DBIsContact(s)) continue;
1093 
1094 	    for (t = TT_TECHDEPBASE; t < DBNumTypes; t++)
1095 	    {
1096 		if (!TTMaskHasType(&subtypes, t)) continue;
1097 
1098 		if (s == t) continue;	/* shouldn't happen */
1099 		if (ExtCurStyle->exts_overlapCap[s][t] > (CapValue) 0)
1100 		    continue;	/* redundant overlap */
1101 
1102 		ExtCurStyle->exts_overlapCap[s][t] = capVal;
1103 		ExtCurStyle->exts_overlapPlanes |= PlaneNumToMaskBit(plane1);
1104 		ExtCurStyle->exts_overlapOtherPlanes[s] |= PlaneNumToMaskBit(plane2);
1105 		TTMaskSetType(&ExtCurStyle->exts_overlapTypes[plane1], s);
1106 		TTMaskSetType(&ExtCurStyle->exts_overlapOtherTypes[s], t);
1107 
1108 		ExtCurStyle->exts_overlapShieldPlanes[s][t] = pshield;
1109 		ExtCurStyle->exts_overlapShieldTypes[s][t] = shields;
1110 	    }
1111 	}
1112     }
1113 }
1114 
1115 /*
1116  * ----------------------------------------------------------------------------
1117  *
1118  * ExtTechSimplePerimCap --
1119  *
1120  *	Parse the techfile line for the "defaultperimeter" keyword.
1121  *	This comprises both the "perimc" statement and the "sideoverlap"
1122  *	statement for overlaps to types that are effectively substrate
1123  *	(e.g., well, implant, marker layers, etc.)
1124  *
1125  * Usage:
1126  *	defaultperimeter types plane [[subtypes] subplane] value
1127  *
1128  *	where "types" are the types for which to compute fringing cap,
1129  *	"plane" is the plane of the types, "subplane" is an optional
1130  *	plane that shields "types" from substrate, and "value" is the
1131  *	fringing cap in aF/micron.  If "subplane" is omitted, then
1132  *	nothing shields "types" from the substrate.  Optional "subtypes"
1133  *	lists the types in "subplane" that shield.  Otherwise, it is
1134  *	assumed that all types in "subplane" shield "types" from the
1135  *	substrate.
1136  *
1137  * Results:
1138  *	None.
1139  *
1140  * Side Effects:
1141  *	Adds information into the ExtCurStyle records.
1142  *
1143  * ----------------------------------------------------------------------------
1144  */
1145 
1146 void
ExtTechSimplePerimCap(argc,argv)1147 ExtTechSimplePerimCap(argc, argv)
1148     int  argc;
1149     char *argv[];
1150 {
1151     TileType r, s, t;
1152     TileTypeBitMask types, nottypes, subtypes, shields;
1153     CapValue capVal;
1154     int plane1, plane2, plane3, pnum1, pnum2, pnum3;
1155     PlaneMask pshield;
1156     EdgeCap *cnew;
1157 
1158     if (ExtCurStyle->exts_planeOrderStatus != seenPlaneOrder)
1159     {
1160 	TechError("Cannot parse area cap line without plane ordering!\n");
1161 	return;
1162     }
1163 
1164     DBTechNoisyNameMask(argv[1], &types);
1165     // TTMaskCom2(&nottypes, &types);
1166     // For general use, only consider space and space-like types.
1167     // For device fringing fields, like poly to diffusion on a FET,
1168     // use perimc commands to augment the defaults.
1169     TTMaskZero(&nottypes);
1170     TTMaskSetType(&nottypes, TT_SPACE);
1171     plane1 = DBTechNoisyNamePlane(argv[2]);
1172     TTMaskAndMask(&types, &DBPlaneTypes[plane1]);
1173     TTMaskAndMask(&nottypes, &DBPlaneTypes[plane1]);
1174 
1175     capVal = aToCap(argv[argc - 1]);
1176 
1177     if (argc >= 4)
1178 	plane2 = DBTechNoisyNamePlane(argv[argc - 2]);
1179     else
1180 	plane2 = -1;
1181 
1182     if (argc > 5)
1183 	DBTechNoisyNameMask(argv[argc - 3], &subtypes);
1184     else
1185 	subtypes = DBAllButSpaceAndDRCBits;
1186 
1187     /* Part 1: Perimeter cap */
1188 
1189     for (s = TT_TECHDEPBASE; s < DBNumTypes; s++)
1190 	for (t = 0; t < DBNumTypes; t++)
1191 	    if (TTMaskHasType(&types, s) && TTMaskHasType(&nottypes, t))
1192 	    {
1193 		ExtCurStyle->exts_perimCap[s][t] = capVal;
1194 		TTMaskSetType(&ExtCurStyle->exts_perimCapMask[s], t);
1195 	    }
1196 
1197     if (plane2 == -1) return;		/* No "virtual" overlaps */
1198     else if (plane1 == plane2) return;  /* shouldn't happen */
1199 
1200     pnum1 = ExtCurStyle->exts_planeOrder[plane1];
1201     pnum2 = ExtCurStyle->exts_planeOrder[plane2];
1202 
1203     /* Part 2: Sidewall overlap cap on types equivalent to substrate	   */
1204     /* Find all types in or below plane2 (i.e., ~(space)/plane2)	   */
1205     /* Shield types are everything in the planes between plane1 and plane2 */
1206 
1207     TTMaskZero(&shields);
1208 
1209     pshield = 0;
1210     for (plane3 = PL_TECHDEPBASE; plane3 < DBNumPlanes; plane3++)
1211     {
1212 	pnum3 = ExtCurStyle->exts_planeOrder[plane3];
1213 	if (pnum3 > pnum2 && pnum3 < pnum1)
1214 	{
1215 	    TTMaskSetMask(&shields, &DBPlaneTypes[plane3]);
1216 	    pshield |= PlaneNumToMaskBit(plane3);
1217 	}
1218 	else if (pnum3 <= pnum2)
1219 	{
1220 	    TTMaskAndMask(&subtypes, &DBPlaneTypes[plane3]);
1221 	}
1222     }
1223     TTMaskClearType(&shields, TT_SPACE);
1224     TTMaskClearType(&subtypes, TT_SPACE);
1225 
1226     /* Record all of the sideoverlap capacitances */
1227 
1228     for (s = TT_TECHDEPBASE; s < DBNumTypes; s++)
1229     {
1230 	/* Side overlap computed from residues */
1231     	if (DBIsContact(s)) continue;
1232 
1233 	if (TTMaskHasType(&types, s))	// Corrected, 2/21/2017
1234 	{
1235 	    ExtCurStyle->exts_sidePlanes |= PlaneNumToMaskBit(plane1);
1236 	    TTMaskSetType(&ExtCurStyle->exts_sideTypes[plane1], s);
1237 	    TTMaskSetMask(&ExtCurStyle->exts_sideEdges[s], &nottypes);
1238 	    for (t = 0; t < DBNumTypes; t++)
1239 	    {
1240 		if (!TTMaskHasType(&nottypes, t)) continue;
1241   		if (DBIsContact(t)) continue;
1242 
1243 		TTMaskSetMask(&ExtCurStyle->exts_sideOverlapOtherTypes[s][t], &subtypes);
1244 		ExtCurStyle->exts_sideOverlapOtherPlanes[s][t] |=
1245 				PlaneNumToMaskBit(plane2);
1246 		cnew = (EdgeCap *) mallocMagic((unsigned) (sizeof (EdgeCap)));
1247 		cnew->ec_cap = capVal;
1248 		cnew->ec_far = shields;		/* Types that shield */
1249 		cnew->ec_near = subtypes;	/* Types we create cap with */
1250 		cnew->ec_pmask = PlaneNumToMaskBit(plane2);
1251 		cnew->ec_next = ExtCurStyle->exts_sideOverlapCap[s][t];
1252 		ExtCurStyle->exts_sideOverlapCap[s][t] = cnew;
1253 
1254 		for (r = TT_TECHDEPBASE; r < DBNumTypes; r++)
1255 		    if (TTMaskHasType(&subtypes, r))
1256 			ExtCurStyle->exts_sideOverlapShieldPlanes[s][r] |= pshield;
1257 	    }
1258 	}
1259 
1260 	/* Reverse case (swap "types" and "subtypes") */
1261 
1262 	if (TTMaskHasType(&subtypes, s))
1263 	{
1264 	    ExtCurStyle->exts_sidePlanes |= PlaneNumToMaskBit(plane2);
1265 	    TTMaskSetType(&ExtCurStyle->exts_sideTypes[plane2], s);
1266 	    for (t = TT_TECHDEPBASE; t < DBNumTypes; t++)
1267 	    {
1268   		if (DBIsContact(t)) continue;
1269 
1270 		TTMaskSetMask(&ExtCurStyle->exts_sideOverlapOtherTypes[s][t], &types);
1271 		ExtCurStyle->exts_sideOverlapOtherPlanes[s][t] |=
1272 				PlaneNumToMaskBit(plane1);
1273 		cnew = (EdgeCap *) mallocMagic((unsigned) (sizeof (EdgeCap)));
1274 		cnew->ec_cap = capVal;
1275 		cnew->ec_far = shields;		/* Types that shield */
1276 		cnew->ec_near = types;		/* Types we create cap with */
1277 		cnew->ec_pmask = PlaneNumToMaskBit(plane1);
1278 		cnew->ec_next = ExtCurStyle->exts_sideOverlapCap[s][t];
1279 		ExtCurStyle->exts_sideOverlapCap[s][t] = cnew;
1280 
1281 		for (r = TT_TECHDEPBASE; r < DBNumTypes; r++)
1282 		    if (TTMaskHasType(&types, r))
1283 			ExtCurStyle->exts_sideOverlapShieldPlanes[s][r] |= pshield;
1284 	    }
1285 	}
1286     }
1287 }
1288 
1289 /*
1290  * ----------------------------------------------------------------------------
1291  *
1292  * ExtTechSimpleSidewallCap --
1293  *
1294  *	Parse the techfile line for the "defaultsidewall" keyword.
1295  *
1296  * Results:
1297  *	None.
1298  *
1299  * Side Effects:
1300  *	Adds information into the ExtCurStyle records.
1301  *
1302  * ----------------------------------------------------------------------------
1303  */
1304 
1305 void
ExtTechSimpleSidewallCap(argv)1306 ExtTechSimpleSidewallCap(argv)
1307     char *argv[];
1308 {
1309     /* Like ExtTechLine, but with near = types2 and far = types1 */
1310 
1311     TileType s, t;
1312     TileTypeBitMask types1, types2;
1313     CapValue capVal;
1314     EdgeCap *cnew;
1315     int plane;
1316 
1317     DBTechNoisyNameMask(argv[1], &types1);
1318     plane = DBTechNoisyNamePlane(argv[2]);
1319     capVal = aToCap(argv[3]);
1320 
1321     // Like perimeter cap, treat only space and space-like types
1322     // TTMaskCom2(&types2, &types1);
1323     TTMaskZero(&types2);
1324     TTMaskSetType(&types2, TT_SPACE);
1325 
1326     TTMaskAndMask(&types1, &DBPlaneTypes[plane]);
1327     TTMaskAndMask(&types2, &DBPlaneTypes[plane]);
1328 
1329     if (TTMaskHasType(&types1, TT_SPACE))
1330 	TechError("Can't have space on inside of edge [ignored]\n");
1331 
1332     for (s = TT_TECHDEPBASE; s < DBNumTypes; s++)
1333     {
1334 	if (TTMaskHasType(&types1, s))
1335 	{
1336 	    ExtCurStyle->exts_sidePlanes |= PlaneNumToMaskBit(DBPlane(s));
1337 	    TTMaskSetType(&ExtCurStyle->exts_sideTypes[DBPlane(s)], s);
1338 	    TTMaskSetMask(&ExtCurStyle->exts_sideEdges[s], &types2);
1339 	    for (t = 0; t < DBNumTypes; t++)
1340 	    {
1341 		if (!TTMaskHasType(&types2, t))
1342 		    continue;
1343 		TTMaskSetMask(&ExtCurStyle->exts_sideCoupleOtherEdges[s][t], &types1);
1344 		cnew = (EdgeCap *) mallocMagic((unsigned) (sizeof (EdgeCap)));
1345 		cnew->ec_cap = capVal;
1346 		cnew->ec_near = types2;
1347 		cnew->ec_far = types1;
1348 		cnew->ec_next = ExtCurStyle->exts_sideCoupleCap[s][t];
1349 		cnew->ec_pmask = 0;
1350 		ExtCurStyle->exts_sideCoupleCap[s][t] = cnew;
1351 	    }
1352 	}
1353     }
1354 }
1355 
1356 /*
1357  * ----------------------------------------------------------------------------
1358  *
1359  * ExtTechSimpleOverlapCap --
1360  *
1361  *	Parse the techfile line for the "defaultoverlap" keyword.
1362  *	This is the same as the "overlap" statement excet that shield
1363  *	types are determined automatically from the planeorder.
1364  *
1365  * Results:
1366  *	None.
1367  *
1368  * Side Effects:
1369  *	Adds information into the ExtCurStyle records.
1370  *
1371  * ----------------------------------------------------------------------------
1372  */
1373 
1374 void
ExtTechSimpleOverlapCap(argv)1375 ExtTechSimpleOverlapCap(argv)
1376     char *argv[];
1377 {
1378     TileType s, t;
1379     TileTypeBitMask types1, types2, shields;
1380     CapValue capVal;
1381     int plane1, plane2, plane3, pnum1, pnum2, pnum3;
1382     PlaneMask pshield;
1383 
1384     if (ExtCurStyle->exts_planeOrderStatus != seenPlaneOrder)
1385     {
1386 	TechError("Cannot parse area cap line without plane ordering!\n");
1387 	return;
1388     }
1389 
1390     DBTechNoisyNameMask(argv[1], &types1);
1391     plane1 = DBTechNoisyNamePlane(argv[2]);
1392     TTMaskAndMask(&types1, &DBPlaneTypes[plane1]);
1393 
1394     DBTechNoisyNameMask(argv[3], &types2);
1395     plane2 = DBTechNoisyNamePlane(argv[4]);
1396     TTMaskAndMask(&types2, &DBPlaneTypes[plane2]);
1397 
1398     capVal = aToCap(argv[5]);
1399 
1400     pnum1 = ExtCurStyle->exts_planeOrder[plane1];
1401     pnum2 = ExtCurStyle->exts_planeOrder[plane2];
1402 
1403     /* Find all types in or below plane2 (i.e., ~(space)/plane2)	   */
1404     /* Shield types are everything in the planes between plane1 and plane2 */
1405 
1406     TTMaskZero(&shields);
1407 
1408     pshield = 0;
1409     for (plane3 = PL_TECHDEPBASE; plane3 < DBNumPlanes; plane3++)
1410     {
1411 	pnum3 = ExtCurStyle->exts_planeOrder[plane3];
1412 	if (pnum3 > pnum2 && pnum3 < pnum1)
1413 	{
1414 	    TTMaskSetMask(&shields, &DBPlaneTypes[plane3]);
1415 	    pshield |= PlaneNumToMaskBit(plane3);
1416 	}
1417     }
1418     TTMaskClearType(&shields, TT_SPACE);
1419 
1420     /* Now record all of the overlap capacitances */
1421 
1422     for (s = TT_TECHDEPBASE; s < DBNumTypes; s++)
1423     {
1424 	if (TTMaskHasType(&types1, s))
1425 	{
1426 	    /* Contact overlap caps are determined from residues */
1427   	    if (DBIsContact(s)) continue;
1428 
1429 	    for (t = TT_TECHDEPBASE; t < DBNumTypes; t++)
1430 	    {
1431 		if (!TTMaskHasType(&types2, t)) continue;
1432   		if (DBIsContact(t)) continue;
1433 
1434 		if (s == t) continue;	/* shouldn't happen */
1435 		if (plane1 == plane2) continue;  /* shouldn't happen */
1436 		if (ExtCurStyle->exts_overlapCap[s][t] > (CapValue) 0)
1437 		    continue;	/* redundant overlap */
1438 
1439 		ExtCurStyle->exts_overlapCap[s][t] = capVal;
1440 		ExtCurStyle->exts_overlapPlanes |= PlaneNumToMaskBit(plane1);
1441 		ExtCurStyle->exts_overlapOtherPlanes[s] |= PlaneNumToMaskBit(plane2);
1442 		TTMaskSetType(&ExtCurStyle->exts_overlapTypes[plane1], s);
1443 		TTMaskSetType(&ExtCurStyle->exts_overlapOtherTypes[s], t);
1444 
1445 		ExtCurStyle->exts_overlapShieldPlanes[s][t] = pshield;
1446 		ExtCurStyle->exts_overlapShieldTypes[s][t] = shields;
1447 	    }
1448 	}
1449     }
1450 }
1451 
1452 /*
1453  * ----------------------------------------------------------------------------
1454  *
1455  * ExtTechSimpleSideOverlapCap --
1456  *
1457  *	Parse the techfile line for the "defaultsideoverlap" keyword.
1458  *
1459  * Results:
1460  *	None.
1461  *
1462  * Side Effects:
1463  *	Adds information into the ExtCurStyle records.
1464  *
1465  * ----------------------------------------------------------------------------
1466  */
1467 
1468 void
ExtTechSimpleSideOverlapCap(argv)1469 ExtTechSimpleSideOverlapCap(argv)
1470     char *argv[];
1471 {
1472     TileType r, s, t;
1473     TileTypeBitMask types, nottypes, ov, notov, shields;
1474     CapValue capVal;
1475     int plane1, plane2, plane3, pnum1, pnum2, pnum3;
1476     PlaneMask pshield;
1477     EdgeCap *cnew;
1478     bool forward;
1479 
1480     if (ExtCurStyle->exts_planeOrderStatus != seenPlaneOrder)
1481     {
1482 	TechError("Cannot parse area cap line without plane ordering!\n");
1483 	return;
1484     }
1485 
1486     DBTechNoisyNameMask(argv[1], &types);
1487     plane1 = DBTechNoisyNamePlane(argv[2]);
1488 
1489     // TTMaskCom2(&nottypes, &types);
1490     TTMaskZero(&nottypes);
1491     TTMaskSetType(&nottypes, TT_SPACE);
1492 
1493     TTMaskAndMask(&types,    &DBPlaneTypes[plane1]);
1494     TTMaskAndMask(&nottypes, &DBPlaneTypes[plane1]);
1495 
1496     DBTechNoisyNameMask(argv[3], &ov);
1497     plane2 = DBTechNoisyNamePlane(argv[4]);
1498 
1499     // TTMaskCom2(&notov, &ov);
1500     TTMaskZero(&notov);
1501     TTMaskSetType(&notov, TT_SPACE);
1502 
1503     TTMaskAndMask(&ov,    &DBPlaneTypes[plane2]);
1504     TTMaskAndMask(&notov, &DBPlaneTypes[plane2]);
1505 
1506     capVal = aToCap(argv[5]);
1507 
1508     pnum1 = ExtCurStyle->exts_planeOrder[plane1];
1509     pnum2 = ExtCurStyle->exts_planeOrder[plane2];
1510 
1511     if (pnum1 == pnum2)
1512     {
1513 	TechError("Cannot have fringing capacitance between "
1514 		"types on the same plane\n");
1515 	return;
1516     }
1517 
1518     /* Fringing cap works both directions.  Consider the case plane1 <	*/
1519     /* plane2 as the "forward" case, and plane1 > plane2 as the		*/
1520     /* "reverse" case.							*/
1521 
1522     forward = (plane1 < plane2) ? TRUE : FALSE;
1523 
1524     /* Find all types in or below plane2 (i.e., ~(space)/plane2)	   */
1525     /* Shield planes are the ones between plane1 and plane2 */
1526 
1527     TTMaskZero(&shields);
1528     pshield = 0;
1529     for (plane3 = PL_TECHDEPBASE; plane3 < DBNumPlanes; plane3++)
1530     {
1531 	pnum3 = ExtCurStyle->exts_planeOrder[plane3];
1532 	if ((forward == TRUE) && (pnum3 > pnum2 && pnum3 < pnum1))
1533 	{
1534 	    TTMaskSetMask(&shields, &DBPlaneTypes[plane3]);
1535 	    pshield |= PlaneNumToMaskBit(plane3);
1536 	}
1537 	else if ((forward == FALSE) && (pnum3 < pnum2 && pnum3 > pnum1))
1538 	{
1539 	    TTMaskSetMask(&shields, &DBPlaneTypes[plane3]);
1540 	    pshield |= PlaneNumToMaskBit(plane3);
1541 	}
1542     }
1543     TTMaskClearType(&shields, TT_SPACE);
1544 
1545     /* Now record all of the sideoverlap capacitances */
1546 
1547     if (TTMaskHasType(&types, TT_SPACE) || TTMaskHasType(&ov, TT_SPACE))
1548     {
1549 	TechError("Overlap types can't contain space [ignored]\n");
1550 	return;
1551     }
1552 
1553     /* Record all of the sideoverlap capacitances */
1554 
1555     for (s = TT_TECHDEPBASE; s < DBNumTypes; s++)
1556     {
1557 	/* Side overlap computed from residues */
1558   	if (DBIsContact(s)) continue;
1559 
1560 	if (TTMaskHasType(&types, s))
1561 	{
1562 	    ExtCurStyle->exts_sidePlanes |= PlaneNumToMaskBit(plane1);
1563 	    TTMaskSetType(&ExtCurStyle->exts_sideTypes[plane1], s);
1564 	    TTMaskSetMask(&ExtCurStyle->exts_sideEdges[s], &nottypes);
1565 	    for (t = TT_SPACE; t < DBNumTypes; t++)
1566 	    {
1567 		if (!TTMaskHasType(&nottypes, t)) continue;
1568 		if (DBIsContact(t)) continue;
1569 
1570 		TTMaskSetMask(&ExtCurStyle->exts_sideOverlapOtherTypes[s][t], &ov);
1571 		ExtCurStyle->exts_sideOverlapOtherPlanes[s][t] |=
1572 				PlaneNumToMaskBit(plane2);
1573 		cnew = (EdgeCap *) mallocMagic((unsigned) (sizeof (EdgeCap)));
1574 		cnew->ec_cap = capVal;
1575 		cnew->ec_far = shields;		/* Types that shield */
1576 		cnew->ec_near = ov;		/* Types we create cap with */
1577 		cnew->ec_pmask = PlaneNumToMaskBit(plane2);
1578 		cnew->ec_next = ExtCurStyle->exts_sideOverlapCap[s][t];
1579 		ExtCurStyle->exts_sideOverlapCap[s][t] = cnew;
1580 
1581 		for (r = TT_TECHDEPBASE; r < DBNumTypes; r++)
1582 		    if (TTMaskHasType(&ov, r))
1583 			ExtCurStyle->exts_sideOverlapShieldPlanes[s][r] |= pshield;
1584 	    }
1585 	}
1586 
1587 	/* There is no "reverse case".  Overlap from A->B will be different */
1588 	/* than B->A because it depends on the thickness of A and B.  For   */
1589 	/* the reverse case, the defaultsideoverlap statement must be	    */
1590 	/* repeated with the correct capacitance.			    */
1591     }
1592 }
1593 
1594 /*
1595  * ----------------------------------------------------------------------------
1596  *
1597  * ExtTechLine --
1598  *
1599  * Process a line from the "extract" section of a technology file.
1600  *
1601  * Each line in the extract section of a technology begins
1602  * with a keyword that identifies the format of the rest of
1603  * the line.
1604  *
1605  * The following three kinds of lines are used to define the resistance
1606  * and parasitic capacitance to substrate of each tile type:
1607  *
1608  *	resist	 types resistance
1609  *	areacap	 types capacitance
1610  *	perimcap inside outside capacitance
1611  *
1612  * where 'types', 'inside', and 'outside' are comma-separated lists
1613  * of tile types, 'resistance' is an integer giving the resistance
1614  * per square in milli-ohms, and 'capacitance' is an integer giving
1615  * capacitance (per square lambda for areacap, or per lambda perimeter
1616  * for perimcap) in attofarads.
1617  *
1618  * The perimeter (sidewall) capacitance depends both on the types
1619  * inside and outside the perimeter.  For a given 'perimcap' line,
1620  * any segment of perimeter with a type in 'inside' inside the
1621  * perimeter and a type in 'outside' ontside the perimeter will
1622  * have the indicated capacitance.
1623  *
1624  * Both area and perimeter capacitance computed from the information
1625  * above apply between a given node and the substrate beneath it, as
1626  * determined by extSubstrate[].
1627  *
1628  * Contact resistances are specified by:
1629  *
1630  *	contact	type	minsize	resistance
1631  *
1632  * where type is the type of contact tile, minsize is chosen so that contacts
1633  * that are integer multiples of minsize get an additional contact cut for each
1634  * increment of minsize, and resistance is in milliohms.
1635  *
1636  * Overlap coupling capacitance is specified by:
1637  *
1638  *	overlap	 toptypes bottomtypes capacitance [shieldtypes]
1639  *
1640  * where 'toptypes' and 'bottomtypes' are comma-separated lists of tile types,
1641  * and 'capacitance' is an integer giving capacitance in attofarads per
1642  * square lambda of overlap.  The sets 'toptypes' and 'bottomtypes' should
1643  * be disjoint.  Also, the union of the planes of 'toptypes' should be disjoint
1644  * from the union of the planes of 'bottomtypes'.  If 'shieldtypes' are
1645  * present, they should also be a comma-separated list of types, on
1646  * planes disjoint from those of either 'toptypes' or 'bottomtypes'.
1647  *
1648  * Whenever a tile of a type in 'toptypes' overlaps one of a type in
1649  * 'bottomtypes', we deduct the capacitance to substrate of the 'toptypes'
1650  * tile for the area of the overlap, and create an overlap capacitance
1651  * between the two nodes based on 'capacitance'.  When material in
1652  * 'shieldtypes' appears over any of this overlap area, however, we
1653  * only deduct the substrate capacitance; we don't create an overlap
1654  * capacitor.
1655  *
1656  * Sidewall coupling capacitance is specified by:
1657  *
1658  *	sidewall  intypes outtypes neartypes fartypes capacitance
1659  *
1660  * where 'intypes', 'outtypes', 'neartypes', and 'fartypes' are all comma-
1661  * separated lists of types, and 'capacitance' is an integer giving capacitance
1662  * in attofarads.  All of the tiles in all four lists should be on the same
1663  * plane.
1664  *
1665  * Whenever an edge of the form i|j is seen, where 'i' is in intypes and
1666  * 'j' is in outtypes, we search on the 'j' side for a distance of
1667  * ExtCurStyle->exts_sideCoupleHalo for edges with 'neartypes' on the
1668  * close side and 'fartypes' on the far side.  We create a capacitance
1669  * equal to the length of overlap, times capacitance, divided by the
1670  * separation between the edges (poor approximation, but better than
1671  * none).
1672  *
1673  * Sidewall overlap coupling capacitance is specified by:
1674  *
1675  *	sideoverlap  intypes outtypes ovtypes capacitance
1676  *
1677  * where 'intypes', 'outtypes', and 'ovtypes' are comma-separated lists
1678  * of types, and 'capacitance' is an integer giving capacitance in attofarads
1679  * per lambda.  Both intypes and outtypes should be in the same plane, and
1680  * ovtypes should be in a different plane from intypes and outtypes.
1681  *
1682  * The next kind of line describes transistors:
1683  *
1684  *	fet	 types terminals min-#terminals names substrate gscap gccap
1685  *
1686  * where 'types' and 'terminals' are comma-separated lists of tile types.
1687  * The meaning is that each type listed in 'types' is a transistor, whose
1688  * source and drain connect to any of the types listed in 'terminals'.
1689  * These transistors must have exactly min-#terminals terminals, in addition
1690  * to the gate (whose connectivity is specified in the system-wide connectivity
1691  * table in the "connect" section of the .tech file).  Currently gscap and
1692  * gccap are unused, but refer to the gate-source (or gate-drain) capacitance
1693  * and the gate-channel capacitance in units of attofarads per lambda and
1694  * attofarads per square lambda respectively.
1695  *
1696  * The resistances of transistors is specified by:
1697  *
1698  *	fetresist type region ohms
1699  *
1700  * where type is a type of tile that is a fet, region is a string ("linear"
1701  * is treated specially), and ohms is the resistance per square of the fet
1702  * type while operating in "region".  The values of fets in the "linear"
1703  * region are stored in a separate table.
1704  *
1705  * Results:
1706  *	Returns TRUE normally, or FALSE if the line from the
1707  *	technology file is so malformed that Magic should abort.
1708  *	Currently, we always return TRUE.
1709  *
1710  * Side effects:
1711  *	Initializes the per-technology variables that appear at the
1712  *	beginning of this file.
1713  *
1714  * ----------------------------------------------------------------------------
1715  */
1716 
1717 #define MAXSD 6
1718 
1719     /*ARGSUSED*/
1720 bool
ExtTechLine(sectionName,argc,argv)1721 ExtTechLine(sectionName, argc, argv)
1722     char *sectionName;
1723     int argc;
1724     char *argv[];
1725 {
1726     int n, l, i, j, size, val, p1, p2, p3, nterm, iterm, class;
1727     PlaneMask pshield, pov;
1728     CapValue capVal, gscap, gccap;
1729     TileTypeBitMask types1, types2, termtypes[MAXSD];
1730     TileTypeBitMask near, far, ov, shield, subsTypes, idTypes;
1731     char *subsName, *transName, *cp, *endptr, *paramName;
1732     TileType s, t, r, o;
1733     keydesc *kp, *dv;
1734     bool isLinear;
1735     HashEntry *he;
1736     EdgeCap *cnew;
1737     ExtKeep *es, *newStyle;
1738     ParamList *subcktParams, *newParam;
1739     ExtDevice *devptr;
1740     int refcnt;
1741     double dhalo;
1742     bool bad;
1743 
1744     if (argc < 1)
1745     {
1746 	TechError("Each line must begin with a keyword\n");
1747 	return (TRUE);
1748     }
1749 
1750     n = LookupStruct(argv[0], (LookupTable *) keyTable, sizeof keyTable[0]);
1751     if (n < 0)
1752     {
1753 	TechError("Illegal keyword.  Legal keywords are:\n\t");
1754 	for (n = 0; keyTable[n].k_name; n++)
1755 	    TxError(" %s", keyTable[n].k_name);
1756 	TxError("\n");
1757 	return (TRUE);
1758     }
1759 
1760     kp = &keyTable[n];
1761     if (argc < kp->k_minargs)
1762 	goto usage;
1763 
1764     /* Handle maxargs for DEVICE type separately */
1765     if ((argc > kp->k_maxargs) && (kp->k_key != DEVICE))
1766 	goto usage;
1767 
1768     else if (argc >= 2) l = strlen(argv[1]);
1769 
1770     /* If ExtCurStyle is NULL, this is a first pass, and we should	*/
1771     /* immediately load this style as default.  Otherwise, check if	*/
1772     /* the style name is in the table of styles, and add it if it is	*/
1773     /* not.								*/
1774 
1775     if (kp->k_key == STYLE)
1776     {
1777 	if (argc != 2)
1778 	    if ((argc != 4) || (strncmp(argv[2], "variant", 7)))
1779 		goto usage;
1780 
1781 	for (newStyle = ExtAllStyles; newStyle != NULL;
1782 		newStyle = newStyle->exts_next)
1783 	{
1784 	    if (!strncmp(newStyle->exts_name, argv[1], l))
1785 		break;
1786 	}
1787 	if (newStyle == NULL)
1788 	{
1789 	    if (argc == 2)
1790 	    {
1791 		newStyle = (ExtKeep *)mallocMagic(sizeof(ExtKeep));
1792 		newStyle->exts_next = NULL;
1793 		newStyle->exts_name = StrDup((char **) NULL, argv[1]);
1794 
1795 		if (ExtAllStyles == NULL)
1796 		    ExtAllStyles = newStyle;
1797 		else
1798 		{
1799 	            /* Append to end of style list */
1800 	            for (es = ExtAllStyles; es->exts_next; es = es->exts_next);
1801 	            es->exts_next = newStyle;
1802 		}
1803 	    }
1804 	    else	/* Handle style variants */
1805 	    {
1806 		ExtKeep *saveStyle = NULL;
1807 		char *tptr, *cptr;
1808 
1809 		/* 4th argument is a comma-separated list of variants.	*/
1810 		/* In addition to the default name recorded above,	*/
1811 		/* record each of the variants.				*/
1812 
1813 		tptr = argv[3];
1814 		while (*tptr != '\0')
1815 		{
1816 		    cptr = strchr(tptr, ',');
1817 		    if (cptr != NULL) *cptr = '\0';
1818 		    newStyle = (ExtKeep *)mallocMagic(sizeof(ExtKeep));
1819 		    newStyle->exts_next = NULL;
1820 		    newStyle->exts_name = (char *)mallocMagic(l
1821 				+ strlen(tptr) + 1);
1822 		    sprintf(newStyle->exts_name, "%s%s", argv[1], tptr);
1823 
1824 		    /* Remember the first variant as the default */
1825 		    if (saveStyle == NULL) saveStyle= newStyle;
1826 
1827 		    /* Append to end of style list */
1828 		    if (ExtAllStyles == NULL)
1829 			ExtAllStyles = newStyle;
1830 		    else
1831 		    {
1832 			for (es = ExtAllStyles; es->exts_next; es = es->exts_next);
1833 			es->exts_next = newStyle;
1834 		    }
1835 
1836 		    if (cptr == NULL)
1837 			break;
1838 		    else
1839 			tptr = cptr + 1;
1840 		}
1841 		newStyle = saveStyle;
1842 	    }
1843 	}
1844 
1845 	/* Load style as default extraction style if this is the first	*/
1846 	/* style encountered.  Otherwise, if we are changing styles, 	*/
1847 	/* load this style only if the name matches that in ExtCurStyle.*/
1848 
1849 	if (ExtCurStyle == NULL)
1850 	{
1851 	    ExtCurStyle = extTechStyleNew();
1852 	    ExtCurStyle->exts_name = newStyle->exts_name;
1853 	    ExtCurStyle->exts_status = TECH_PENDING;
1854 	}
1855 	else if ((ExtCurStyle->exts_status == TECH_PENDING) ||
1856 		(ExtCurStyle->exts_status == TECH_SUSPENDED))
1857 	    /* Finished loading; stop */
1858 	    ExtCurStyle->exts_status = TECH_LOADED;
1859 	else if (ExtCurStyle->exts_status == TECH_NOT_LOADED)
1860 	{
1861 	    if (ExtCurStyle->exts_name == NULL)
1862 	        return (FALSE);		/* Don't know what to load! */
1863 	    else if (argc == 2)
1864 	    {
1865 		if (!strcmp(argv[1], ExtCurStyle->exts_name))
1866 		     ExtCurStyle->exts_status = TECH_PENDING; 	/* load pending */
1867 	    }
1868 	    else if (argc == 4)
1869 	    {
1870 		/* Verify that the style matches one variant */
1871 		char *tptr, *cptr;
1872 		if (!strncmp(ExtCurStyle->exts_name, argv[1], l))
1873 		{
1874 		    tptr = argv[3];
1875 		    while (*tptr != '\0')
1876 		    {
1877 			cptr = strchr(tptr, ',');
1878 			if (cptr != NULL) *cptr = '\0';
1879 			if (!strcmp(ExtCurStyle->exts_name + l, tptr))
1880 			{
1881 			    ExtCurStyle->exts_status = TECH_PENDING;
1882 			    return TRUE;
1883 			}
1884 			if (cptr == NULL)
1885 			    return TRUE;
1886 			else
1887 			    tptr = cptr + 1;
1888 		    }
1889 		}
1890 	    }
1891 	}
1892 	return (TRUE);
1893     }
1894 
1895     /* Only continue past this point if we are loading the extraction style */
1896     if (ExtCurStyle == NULL) return FALSE;
1897     if ((ExtCurStyle->exts_status != TECH_PENDING) &&
1898 		(ExtCurStyle->exts_status != TECH_SUSPENDED))
1899 	return TRUE;
1900 
1901     /* Process "variant" lines next */
1902 
1903     if (kp->k_key == VARIANT)
1904     {
1905 	int l;
1906 	char *cptr, *tptr;
1907 
1908 	/* If our style variant is not one of the ones declared */
1909 	/* on the line, then we ignore all input until we 	*/
1910 	/* either reach the end of the style, the end of the	*/
1911 	/* section, or another "variant" line.			*/
1912 
1913 	if (argc != 2) goto usage;
1914 	tptr = argv[1];
1915 	while (*tptr != '\0')
1916 	{
1917 	    cptr = strchr(tptr, ',');
1918 	    if (cptr != NULL)
1919 	    {
1920 		*cptr = '\0';
1921 		for (j = 1; isspace(*(cptr - j)); j++)
1922 		    *(cptr - j) = '\0';
1923 	    }
1924 
1925 	    if (*tptr == '*')	/* Wildcard for "all variants" */
1926 	    {
1927 		ExtCurStyle->exts_status = TECH_PENDING;
1928 		return TRUE;
1929 	    }
1930 	    else
1931 	    {
1932 		l = strlen(ExtCurStyle->exts_name) - strlen(tptr);
1933 		if (!strcmp(tptr, ExtCurStyle->exts_name + l))
1934 		{
1935 		    ExtCurStyle->exts_status = TECH_PENDING;
1936 		    return TRUE;
1937 		}
1938 	    }
1939 
1940 	    if (cptr == NULL)
1941 		break;
1942 	    else
1943 		tptr = cptr + 1;
1944 	}
1945 	ExtCurStyle->exts_status = TECH_SUSPENDED;
1946     }
1947 
1948     /* Anything below this line is not parsed if we're in TECH_SUSPENDED mode */
1949     if (ExtCurStyle->exts_status != TECH_PENDING) return TRUE;
1950 
1951     switch (kp->k_key)
1952     {
1953 	case AREAC:
1954 	case CONTACT:
1955 	case FET:
1956 	case FETRESIST:
1957 	case HEIGHT:
1958 	case ANTENNA:
1959 	case TIEDOWN:
1960 	case OVERC:
1961 	case PERIMC:
1962 	case RESIST:
1963 	case SIDEWALL:
1964 	case SIDEOVERLAP:
1965 	case SUBSTRATE:
1966 	    DBTechNoisyNameMask(argv[1], &types1);
1967 	    break;
1968 	case DEVICE:
1969 	    DBTechNoisyNameMask(argv[3], &types1);
1970 	    break;
1971 	case PLANEORDER:
1972 	case NOPLANEORDER:
1973 	default:
1974 	    break;
1975     }
1976 
1977     switch (kp->k_key)
1978     {
1979 	case AREAC:
1980 	    capVal = aToCap(argv[2]);
1981 	    for (t = TT_TECHDEPBASE; t < DBNumTypes; t++)
1982 		if (TTMaskHasType(&types1, t))
1983 		    ExtCurStyle->exts_areaCap[t] = capVal;
1984 	    break;
1985 	case CONTACT:
1986 	    /* Contact size, border, spacing deprecated (now taken from	*/
1987 	    /* cifoutput "squares" generation parameters).		*/
1988 	    if (argc != 3)
1989 	    {
1990 		if (argc == 4)
1991 		    TxPrintf("Contact size value ignored "
1992 				"(using GDS generation rules).\n");
1993 		else
1994 		    TxPrintf("Contact size, spacing, and border values ignored "
1995 				"(using GDS generation rules).\n");
1996 	    }
1997 
1998 	    if (!StrIsInt(argv[argc - 1]))
1999 	    {
2000 		TechError("Contact resistivity %s must be an integer value "
2001 			"(in milliohms/square).\n", argv[argc - 1]);
2002 		break;
2003 	    }
2004 	    val = atoi(argv[argc - 1]);
2005 	    for (t = TT_TECHDEPBASE; t < DBNumTypes; t++)
2006 		if (TTMaskHasType(&types1, t))
2007 		    ExtCurStyle->exts_viaResist[t] = val;
2008 	    break;
2009 	case CSCALE:
2010 	    ExtCurStyle->exts_capScale = strtol(argv[1], &endptr, 10);
2011 	    if (endptr == argv[1])
2012 	    {
2013 		TechError("Cannot parse cap scale value \"%s\"\n", argv[1]);
2014 		ExtCurStyle->exts_capScale = 1;
2015 	    }
2016 	    break;
2017 	case FET:
2018 
2019 	    /* Original FET format, kept for backwards compatibility */
2020 
2021 	    DBTechNoisyNameMask(argv[2], &termtypes[0]);
2022 	    nterm = atoi(argv[3]);
2023 	    transName = argv[4];
2024 	    subsName = argv[5];
2025 
2026 	    // From magic version 8.1, subs name can be a nonfunctional
2027 	    // throwaway (e.g., "error"), so don't throw a warning.
2028 
2029 	    cp = strchr(subsName, '!');
2030 	    if (cp == NULL || cp[1] != '\0')
2031 	    {
2032 		if (strcasecmp(subsName, "error"))
2033 		{
2034 		    TechError("Fet substrate node %s is not a global name\n",
2035 				subsName);
2036 		}
2037 	    }
2038 
2039 	    subsTypes = DBZeroTypeBits;
2040 	    if (sscanf(argv[6], "%lf", &capVal) != 1)
2041 	    {
2042 		DBTechNoisyNameMask(argv[6], &subsTypes);
2043 		gscap = aToCap(argv[7]);
2044 		gccap = (argc > 8) ? aToCap(argv[8]) : (CapValue) 0;
2045 	    }
2046 	    else
2047 	    {
2048 		gscap = aToCap(argv[6]);
2049 		gccap = (argc > 7) ? aToCap(argv[7]) : (CapValue) 0;
2050 	    }
2051 
2052 	    TTMaskSetMask(&ExtCurStyle->exts_deviceMask, &types1);
2053 	    for (t = TT_TECHDEPBASE; t < DBNumTypes; t++)
2054 		if (TTMaskHasType(&types1, t))
2055 		{
2056 		    devptr = (ExtDevice *)mallocMagic(sizeof(ExtDevice));
2057 		    devptr->exts_deviceSDTypes = (TileTypeBitMask *)
2058 				mallocMagic(2 * sizeof(TileTypeBitMask));
2059 		    devptr->exts_deviceSDTypes[0] = termtypes[0];
2060 		    devptr->exts_deviceSDTypes[1] = DBZeroTypeBits;
2061 		    devptr->exts_deviceSDCount = nterm;
2062 		    devptr->exts_deviceSDCap = gscap;
2063 		    devptr->exts_deviceGateCap = gccap;
2064 		    devptr->exts_deviceClass = DEV_FET;
2065 		    devptr->exts_deviceName = StrDup((char **) NULL, transName);
2066 		    devptr->exts_deviceSubstrateName =
2067 			    StrDup((char **) NULL, subsName);
2068 		    devptr->exts_deviceSubstrateTypes = subsTypes;
2069 		    devptr->exts_deviceIdentifierTypes = DBZeroTypeBits;
2070 		    devptr->exts_deviceParams = (ParamList *) NULL;
2071 		    devptr->exts_deviceResist.ht_table = (HashEntry **) NULL;
2072 		    HashInit(&devptr->exts_deviceResist, 8, HT_STRINGKEYS);
2073 
2074 		    TTMaskSetMask(ExtCurStyle->exts_deviceConn + t, &types1);
2075 
2076 		    devptr->exts_next = ExtCurStyle->exts_device[t];
2077 		    ExtCurStyle->exts_device[t] = devptr;
2078 #ifdef ARIEL
2079 		    {
2080 			int z;
2081 
2082 			for (z = TT_TECHDEPBASE; z < DBNumTypes; z++)
2083 			{
2084 			    if (TTMaskHasType(&subsTypes, z))
2085 				TTMaskSetType(&ExtCurStyle->exts_subsTransistorTypes[z],
2086 					t);
2087 			}
2088 		    }
2089 #endif
2090 		}
2091 	    break;
2092 
2093 	case DEFAULTAREACAP:
2094 	    ExtTechSimpleAreaCap(argc, argv);
2095 	    break;
2096 	case DEFAULTOVERLAP:
2097 	    ExtTechSimpleOverlapCap(argv);
2098 	    break;
2099 	case DEFAULTPERIMETER:
2100 	    ExtTechSimplePerimCap(argc, argv);
2101 	    break;
2102 	case DEFAULTSIDEOVERLAP:
2103 	    ExtTechSimpleSideOverlapCap(argv);
2104 	    break;
2105 	case DEFAULTSIDEWALL:
2106 	    ExtTechSimpleSidewallCap(argv);
2107 	    break;
2108 	case DEVICE:
2109 
2110 	    /* Parse second argument for device type */
2111 
2112 	    n = LookupStruct(argv[1], (LookupTable *)devTable, sizeof devTable[0]);
2113 	    if (n < 0)
2114 	    {
2115 		TechError("Illegal device.  Legal devices are:\n\t");
2116 		for (n = 0; devTable[n].k_name; n++)
2117 		    TxError(" %s", devTable[n].k_name);
2118 		TxError("\n");
2119 		return (TRUE);
2120 	    }
2121 
2122 	    dv = &devTable[n];
2123 	    if ((argc - 1) < dv->k_minargs)
2124 		goto usage;
2125 
2126 	    /* Parse parameters from the end of the argument list.	*/
2127 	    /* Parameters may be provided for any device.		*/
2128 
2129 	    /* Check final arguments for "x=y" statements showing what	*/
2130 	    /* parameter names the device uses.				*/
2131 
2132 	    subcktParams = NULL;
2133 	    while ((paramName = strchr(argv[argc - 1], '=')) != NULL)
2134 	    {
2135 		char *mult;
2136 
2137 		paramName++;
2138 		newParam = (ParamList *)mallocMagic(sizeof(ParamList));
2139 		newParam->pl_count = 0;
2140 		newParam->pl_param[0] = *argv[argc - 1];
2141 		newParam->pl_param[1] = '\0';
2142 
2143 		if (paramName - argv[argc - 1] == 3)
2144 		    newParam->pl_param[1] = *(argv[argc - 1] + 1);
2145 
2146 		else if (paramName - argv[argc - 1] > 3)
2147 		    TechError("Parameter name %s can be no more than"
2148 			"two characters.\n", argv[argc - 1]);
2149 
2150 		// Parameter syntax "<type>=<name>*<scale>" indicates
2151 		// that the subcircuit has internal scaling, and the
2152 		// extractor should multiply the parameter by this value
2153 		// before passing it to the subcircuit.
2154 
2155 		if ((mult = strchr(paramName, '*')) != NULL)
2156 		{
2157 		    *mult = '\0';
2158 		    mult++;
2159 		    newParam->pl_scale = atof(mult);
2160 		}
2161 		else
2162 		    newParam->pl_scale = 1.0;
2163 
2164 		newParam->pl_name = StrDup((char **)NULL, paramName);
2165 		newParam->pl_next = subcktParams;
2166 		subcktParams = newParam;
2167 		argc--;
2168 	    }
2169 
2170 	    /* If the last entry before any parameters starts with '+',	*/
2171 	    /* then use it to set the identity marker.	Otherwise, the	*/
2172 	    /* identity marker is NULL.					*/
2173 
2174 	    idTypes = DBZeroTypeBits;
2175 	    if (*argv[argc - 1] == '+')
2176 	    {
2177 		if ((DBTechNameMask(argv[argc - 1] + 1, &idTypes)) == 0)
2178 		    idTypes = DBZeroTypeBits;
2179 		argc--;
2180 	    }
2181 
2182 	    /* Check the number of arguments after splitting out	*/
2183 	    /* parameter entries.  There is no limit on arguments in	*/
2184 	    /* DEV_SUBCKT and DEV_MSUBCKT.				*/
2185 
2186 	    class = dv->k_key;
2187 	    switch (class)
2188 	    {
2189 		case DEV_SUBCKT:
2190 		case DEV_MSUBCKT:
2191 		    break;
2192 		default:
2193 		    /* If parameters were saved but the	*/
2194 		    /* argument list indicates a bad	*/
2195 		    /* device entry, then free up the	*/
2196 		    /* parameters.			*/
2197 
2198 		    if ((argc - 1) > dv->k_maxargs)
2199 		    {
2200 			while (subcktParams != NULL)
2201 			{
2202 			    freeMagic(subcktParams->pl_name);
2203 			    freeMagic(subcktParams);
2204 			    subcktParams = subcktParams->pl_next;
2205 			}
2206 			goto usage;
2207 		    }
2208 		    break;
2209 	    }
2210 
2211 	    gscap = (CapValue) 0;
2212 	    gccap = (CapValue) 0;
2213 	    subsName = NULL;
2214 	    subsTypes = DBZeroTypeBits;
2215 	    transName = argv[2];
2216 
2217 	    switch (dv->k_key)
2218 	    {
2219 		case DEV_BJT:
2220 		    DBTechNoisyNameMask(argv[4], &termtypes[0]); /* emitter */
2221 		    termtypes[1] = DBZeroTypeBits;
2222 		    DBTechNoisyNameMask(argv[5], &subsTypes);	 /* collector */
2223 		    nterm = 1;	/* emitter is the only "terminal type" expected */
2224 		    break;
2225 		case DEV_MOSFET:
2226 		    if ((argc > 7) && (!StrIsNumeric(argv[7])))
2227 		    {
2228 			/* Asymmetric device with different source and drain types */
2229 
2230 			DBTechNoisyNameMask(argv[4], &termtypes[0]); /* source */
2231 			DBTechNoisyNameMask(argv[5], &termtypes[1]); /* drain */
2232 			TTMaskAndMask3(&termtypes[2], &termtypes[0], &termtypes[1]);
2233 
2234 			if (TTMaskEqual(&termtypes[0], &termtypes[1]))
2235 			    termtypes[1] = DBZeroTypeBits;	/* Make it symmetric */
2236 			else if (!TTMaskIsZero(&termtypes[2]))
2237 			{
2238 			    class = DEV_ASYMMETRIC;
2239 			    TechError("Device mosfet %s has overlapping drain"
2240 				" and source types!\n", transName);
2241 			    /* Should this device be disabled? */
2242 			}
2243 			else
2244 			    class = DEV_ASYMMETRIC;
2245 			termtypes[2] = DBZeroTypeBits;
2246 			if (strcmp(argv[6], "None"))
2247 		    	DBTechNoisyNameMask(argv[6], &subsTypes);   /* substrate */
2248 			subsName = argv[7];
2249 			if (argc > 8) gscap = aToCap(argv[8]);
2250 			if (argc > 9) gccap = aToCap(argv[9]);
2251 			nterm = 2;
2252 		    }
2253 		    else
2254 		    {
2255 			/* Normal symmetric device with swappable source/drain */
2256 
2257 			DBTechNoisyNameMask(argv[4], &termtypes[0]); /* source/drain */
2258 			termtypes[1] = DBZeroTypeBits;
2259 			if (strcmp(argv[5], "None"))
2260 			    DBTechNoisyNameMask(argv[5], &subsTypes);   /* substrate */
2261 			if (argc > 6) subsName = argv[6];
2262 			if (argc > 7) gscap = aToCap(argv[7]);
2263 			if (argc > 8) gccap = aToCap(argv[8]);
2264 			/* nterm = 1; */	/* Symmetric devices can be MOScaps */
2265 			nterm = 2;
2266 		    }
2267 		    break;
2268 
2269 		case DEV_DIODE:
2270 		case DEV_PDIODE:
2271 		case DEV_NDIODE:
2272 		    DBTechNoisyNameMask(argv[4], &termtypes[0]); /* negative types */
2273 		    termtypes[1] = DBZeroTypeBits;
2274 		    nterm = 1;
2275 		    if ((argc > 4) && strcmp(argv[4], "None"))
2276 			DBTechNoisyNameMask(argv[4], &subsTypes);   /* substrate */
2277 		    else
2278 			subsTypes = DBZeroTypeBits;
2279 		    if (argc > 5) subsName = argv[5];
2280 		    break;
2281 
2282 		case DEV_RES:
2283 		    DBTechNoisyNameMask(argv[4], &termtypes[0]); /* terminals */
2284 		    termtypes[1] = DBZeroTypeBits;
2285 		    nterm = 2;
2286 		    if ((argc > 5) && strcmp(argv[5], "None"))
2287 			DBTechNoisyNameMask(argv[5], &subsTypes);   /* substrate */
2288 		    else
2289 			subsTypes = DBZeroTypeBits;
2290 		    if (argc > 6) subsName = argv[6];
2291 		    break;
2292 
2293 		case DEV_CAP:
2294 		case DEV_CAPREV:
2295 		    DBTechNoisyNameMask(argv[4], &termtypes[0]); /* bottom */
2296 		    termtypes[1] = DBZeroTypeBits;
2297 
2298 		    if (argc > 5)
2299 			gccap = aToCap(argv[argc - 1]);		/* area cap */
2300 		    if ((argc > 6) && StrIsNumeric(argv[argc - 2]))
2301 		    {
2302 			gscap = aToCap(argv[argc - 2]);		/* perimeter cap */
2303 			argc--;
2304 		    }
2305 		    nterm = 1;
2306 
2307 		    if ((argc > 6) && strcmp(argv[5], "None"))
2308 			DBTechNoisyNameMask(argv[5], &subsTypes);   /* substrate */
2309 		    else
2310 			subsTypes = DBZeroTypeBits;
2311 		    if (argc > 7) subsName = argv[6];
2312 		    break;
2313 
2314 		case DEV_SUBCKT:
2315 		case DEV_MSUBCKT:
2316 		    // Determine if [substrate, name] optional arguments
2317 		    // are present by checking if the last argument
2318 		    // parses as a layer list.
2319 
2320 		    if (DBTechNameMask(argv[argc - 1], &termtypes[0]) <= 0)
2321 		    {
2322 			if (strcmp(argv[argc - 2], "None"))
2323 			    DBTechNoisyNameMask(argv[argc - 2], &subsTypes);
2324 			else
2325 			    subsTypes = DBZeroTypeBits;
2326 			subsName = argv[argc - 1];
2327 			argc -= 2;
2328 		    }
2329 
2330 		    if (StrIsInt(argv[4]))
2331 		    {
2332 			nterm = atoi(argv[4]);
2333 			iterm = 5;
2334 			if (nterm > argc - 5)
2335 			{
2336 			    TechError("Not enough terminals for subcircuit, "
2337 					"%d were required, %d found.\n",
2338 					nterm, argc - 5);
2339 			    nterm = argc - 5;
2340 			}
2341 		    }
2342 		    else
2343 		    {
2344 			nterm = argc - 4;
2345 			iterm = 4;
2346 		    }
2347 
2348 		    /* terminals */
2349 		    for (i = iterm; i < iterm + nterm; i++)
2350 			DBTechNoisyNameMask(argv[i], &termtypes[i - iterm]);
2351 		    termtypes[nterm] = DBZeroTypeBits;
2352 
2353 		    if (nterm == 0) i++;
2354 
2355 		    // Type MSUBCKT:  If source and drain are symmetric (both
2356 		    // have the same types), then they must both be declared,
2357 		    // but only one is used (same policy as "device mosfet").
2358 
2359 		    if ((nterm == 2) && TTMaskEqual(&termtypes[nterm - 1],
2360 				&termtypes[nterm - 2]))
2361 			termtypes[nterm - 1] = DBZeroTypeBits;
2362 
2363 		    break;
2364 
2365 		case DEV_RSUBCKT:
2366 		case DEV_CSUBCKT:
2367 		    nterm = (dv->k_key == DEV_RSUBCKT) ? 2 : 1;
2368 		    DBTechNoisyNameMask(argv[4], &termtypes[0]);	/* terminals */
2369 		    termtypes[1] = DBZeroTypeBits;
2370 
2371 		    if ((argc > 5) && strcmp(argv[5], "None"))
2372 			DBTechNoisyNameMask(argv[5], &subsTypes);   /* substrate */
2373 		    else
2374 			subsTypes = DBZeroTypeBits;
2375 		    if (argc > 6) subsName = argv[6];
2376 		    break;
2377 	    }
2378 
2379 	    TTMaskSetMask(&ExtCurStyle->exts_deviceMask, &types1);
2380 
2381 	    for (t = TT_TECHDEPBASE; t < DBNumTypes; t++)
2382 	    {
2383 		if (TTMaskHasType(&types1, t))
2384 		{
2385 		    devptr = (ExtDevice *)mallocMagic(sizeof(ExtDevice));
2386 
2387 		    for (i = 0; !TTMaskIsZero(&termtypes[i]); i++);
2388 		    devptr->exts_deviceSDTypes = (TileTypeBitMask *)
2389 					mallocMagic((i + 1) * sizeof(TileTypeBitMask));
2390 
2391 		    for (i = 0; !TTMaskIsZero(&termtypes[i]); i++)
2392 			devptr->exts_deviceSDTypes[i] = termtypes[i];
2393 		    devptr->exts_deviceSDTypes[i] = DBZeroTypeBits;
2394 
2395 		    devptr->exts_deviceSDCount = nterm;
2396 		    devptr->exts_deviceSDCap = gscap;
2397 		    devptr->exts_deviceGateCap = gccap;
2398 		    devptr->exts_deviceClass = class;
2399 		    devptr->exts_deviceName = StrDup((char **) NULL, transName);
2400 		    if (subsName != NULL)
2401 			devptr->exts_deviceSubstrateName =
2402 				StrDup((char **) NULL, subsName);
2403 		    else
2404 			devptr->exts_deviceSubstrateName = (char *)NULL;
2405 		    devptr->exts_deviceSubstrateTypes = subsTypes;
2406 		    devptr->exts_deviceIdentifierTypes = idTypes;
2407 		    devptr->exts_deviceParams = (ParamList *) NULL;
2408 		    if (subcktParams != NULL)
2409 		    {
2410 			devptr->exts_deviceParams = subcktParams;
2411 			subcktParams->pl_count++;
2412 		    }
2413 		    devptr->exts_deviceResist.ht_table = (HashEntry **) NULL;
2414 		    HashInit(&devptr->exts_deviceResist, 8, HT_STRINGKEYS);
2415 
2416 		    devptr->exts_next = ExtCurStyle->exts_device[t];
2417 		    ExtCurStyle->exts_device[t] = devptr;
2418 
2419 		    TTMaskSetMask(ExtCurStyle->exts_deviceConn + t, &types1);
2420 #ifdef ARIEL
2421 		    {
2422 			int z;
2423 
2424 			for (z = TT_TECHDEPBASE; z < DBNumTypes; z++)
2425 			{
2426 			    if (TTMaskHasType(&subsTypes, z))
2427 				TTMaskSetType(&ExtCurStyle->
2428 					exts_subsTransistorTypes[z], t);
2429 			}
2430 		    }
2431 #endif
2432 		}
2433 	    }
2434 	    break;
2435 
2436 	case FETRESIST:
2437 	    if (!StrIsInt(argv[3]))
2438 	    {
2439 		TechError("Fet resistivity %s must be numeric\n", argv[3]);
2440 		break;
2441 	    }
2442 	    val = atoi(argv[3]);
2443 	    isLinear = (strcmp(argv[2], "linear") == 0);
2444 	    for (t = TT_TECHDEPBASE; t < DBNumTypes; t++)
2445 	    {
2446 		ExtDevice *devptr;
2447 		if (TTMaskHasType(&types1, t))
2448 		{
2449 		    for (devptr = ExtCurStyle->exts_device[t]; devptr; devptr = devptr->exts_next)
2450 		    {
2451 			he = HashFind(&devptr->exts_deviceResist, argv[2]);
2452 			HashSetValue(he, (spointertype)val);
2453 			if (isLinear)
2454 			    devptr->exts_linearResist = val;
2455 		    }
2456 		}
2457 	    }
2458 	    break;
2459 	case HEIGHT: {
2460 	    float height, thick;
2461 
2462 	    if (!StrIsNumeric(argv[2]))
2463 	    {
2464 		TechError("Layer height %s must be numeric\n", argv[2]);
2465 		break;
2466 	    }
2467 	    if (!StrIsNumeric(argv[3]))
2468 	    {
2469 		TechError("Layer thickness %s must be numeric\n", argv[3]);
2470 		break;
2471 	    }
2472 	    height = (float)strtod(argv[2], NULL);
2473 	    thick = (float)strtod(argv[3], NULL);
2474 	    for (t = TT_TECHDEPBASE; t < DBNumTypes; t++)
2475 		if (TTMaskHasType(&types1, t))
2476 		{
2477 		    ExtCurStyle->exts_height[t] = height;
2478 		    ExtCurStyle->exts_thick[t] = thick;
2479 		}
2480 	    }
2481 	    break;
2482 	case ANTENNA: {
2483 	    float antennaratio;
2484 	    char areaType;
2485 	    bool hasModel = FALSE;
2486 	    int argidx = 2;
2487 
2488 	    if (!StrIsNumeric(argv[2]))
2489 	    {
2490 		if (!strcmp(argv[2], "surface") || !strcmp(argv[2], "area"))
2491 		{
2492 		    areaType = ANTENNAMODEL_SURFACE;
2493 		    hasModel = TRUE;
2494 		}
2495 		else if (!strcmp(argv[2], "sidewall") || !strcmp(argv[2], "perimeter"))
2496 		{
2497 		    areaType = ANTENNAMODEL_SIDEWALL;
2498 		    hasModel = TRUE;
2499 		}
2500 		else
2501 		{
2502 		    TechError("Error in layer antenna calculation type \"%s\"; "
2503 			    " must be \"surface\" or \"sidewall\"\n", argv[2]);
2504 		    break;
2505 		}
2506 	    }
2507 	    if (hasModel == FALSE)
2508 	    {
2509 		if (ExtCurStyle->exts_antennaModel & ANTENNAMODEL_SURFACE)
2510 		    areaType = ANTENNAMODEL_SURFACE;
2511 		else if (ExtCurStyle->exts_antennaModel & ANTENNAMODEL_SIDEWALL)
2512 		    areaType = ANTENNAMODEL_SIDEWALL;
2513 		else
2514 		    TechError("No antenna calculation type given for layer(s) %s "
2515 			    " and no default calculation type found.\n", argv[1]);
2516 	    }
2517 
2518 	    for (t = TT_TECHDEPBASE; t < DBNumTypes; t++)
2519 		if (TTMaskHasType(&types1, t))
2520 		    ExtCurStyle->exts_antennaRatio[t].areaType = areaType;
2521 
2522 	    if (hasModel == TRUE) argidx = 3;
2523 
2524 	    if (!StrIsNumeric(argv[argidx]))
2525 	    {
2526 		TechError("Gate layer antenna ratio %s must be numeric\n", argv[argidx]);
2527 		break;
2528 	    }
2529 	    antennaratio = (float)strtod(argv[argidx], NULL);
2530 
2531 	    for (t = TT_TECHDEPBASE; t < DBNumTypes; t++)
2532 		if (TTMaskHasType(&types1, t))
2533 		    ExtCurStyle->exts_antennaRatio[t].ratioGate = antennaratio;
2534 
2535 	    argidx++;
2536 	    if (!StrIsNumeric(argv[argidx]))
2537 	    {
2538 		if (!strcasecmp(argv[argidx], "none"))
2539 		    antennaratio = INFINITY;
2540 		else
2541 		{
2542 		    TechError("Diff layer antenna ratio %s must be numeric\n",
2543 			    argv[argidx]);
2544 		    break;
2545 		}
2546 	    }
2547 	    else
2548 		antennaratio = (float)strtod(argv[argidx], NULL);
2549 
2550 	    for (t = TT_TECHDEPBASE; t < DBNumTypes; t++)
2551 		if (TTMaskHasType(&types1, t))
2552 		    ExtCurStyle->exts_antennaRatio[t].ratioDiffB = antennaratio;
2553 
2554 	    argidx++;
2555 	    if (argidx < argc)
2556 	    {
2557 		if (!StrIsNumeric(argv[argidx]))
2558 		{
2559 		    TechError("Diff layer antenna ratio %s must be numeric\n",
2560 				argv[argidx]);
2561 		    break;
2562 		}
2563 		antennaratio = (float)strtod(argv[argidx], NULL);
2564 	    }
2565 	    else
2566 		antennaratio = 0;
2567 
2568 	    for (t = TT_TECHDEPBASE; t < DBNumTypes; t++)
2569 		if (TTMaskHasType(&types1, t))
2570 		    ExtCurStyle->exts_antennaRatio[t].ratioDiffA = antennaratio;
2571 
2572 	    break;
2573 	}
2574 	case MODEL:
2575 	    if (!strcmp(argv[1], "partial"))
2576 		ExtCurStyle->exts_antennaModel |= ANTENNAMODEL_PARTIAL;
2577 	    else if (!strcmp(argv[1], "cumulative"))
2578 		ExtCurStyle->exts_antennaModel |= ANTENNAMODEL_CUMULATIVE;
2579 	    else
2580 		TxError("Unknown antenna model \"%s\":  Use \"partial\" or "
2581 			    "\"cumulative\"");
2582 
2583 	    if (argc > 2)
2584 	    {
2585 		if (!strcmp(argv[2], "surface") || !strcmp(argv[2], "area"))
2586 		    ExtCurStyle->exts_antennaModel |= ANTENNAMODEL_SURFACE;
2587 		else if (!strcmp(argv[2], "sidewall") || !strcmp(argv[2], "perimeter"))
2588 		    ExtCurStyle->exts_antennaModel |= ANTENNAMODEL_SIDEWALL;
2589 		else
2590 		    TxError("Unknown antenna model \"%s\":  Use \"surface\" or "
2591 				    "\"sidewall\"");
2592 	    }
2593 	    break;
2594 
2595 	case TIEDOWN:
2596 	    TTMaskSetMask(&ExtCurStyle->exts_antennaTieTypes, &types1);
2597 	    break;
2598 	case UNITS:
2599 	    if (!strcmp(argv[1], "microns"))
2600 		doConvert = TRUE;
2601 	    else if (!strcmp(argv[1], "um"))
2602 		doConvert = TRUE;
2603 	    else if (strcmp(argv[1], "lambda"))
2604 	 	TechError("Units must be microns or lambda.  Using the "
2605 			"default value (lambda).\n");
2606 	    break;
2607 	case LAMBDA:
2608 	    ExtCurStyle->exts_unitsPerLambda = (float)atof(argv[1]);
2609 	    break;
2610 	case OVERC:
2611 	    DBTechNoisyNameMask(argv[2], &types2);
2612 	    capVal = aToCap(argv[3]);
2613 	    bad = FALSE;
2614 	    shield = DBZeroTypeBits;
2615 	    if (argc > 4)
2616 		DBTechNoisyNameMask(argv[4], &shield);
2617 	    for (s = TT_TECHDEPBASE; s < DBNumTypes; s++)
2618 	    {
2619 		if (!TTMaskHasType(&types1, s)) continue;
2620 
2621 		/* Contact overlap caps are determined from residues */
2622 		if (DBIsContact(s)) continue;
2623 
2624 		for (t = TT_TECHDEPBASE; t < DBNumTypes; t++)
2625 		{
2626 		    if (!TTMaskHasType(&types2, t)) continue;
2627 
2628 		    /* Contact overlap caps are determined from residues */
2629 		    if (DBIsContact(t)) continue;
2630 
2631 		    if (s == t)
2632 		    {
2633 			TechError("Can't have overlap capacitance between"
2634 				" tiles of the same type (%s)\n",
2635 				DBTypeLongName(s));
2636 			bad = TRUE;
2637 			continue;
2638 		    }
2639   		    p1 = DBPlane(s), p2 = DBPlane(t);
2640 		    if (p1 == p2)
2641 		    {
2642 			TechError("Can't have overlap capacitance between"
2643 				" tiles on the same plane (%s, %s)\n",
2644 				DBTypeLongName(s), DBTypeLongName(t));
2645 			bad = TRUE;
2646 			continue;
2647 		    }
2648 		    if (ExtCurStyle->exts_overlapCap[s][t] > (CapValue) 0)
2649 		    {
2650 			TechError("Only one of \"overlap %s %s\" or"
2651 				" \"overlap %s %s\" allowed\n",
2652 				DBTypeLongName(s), DBTypeLongName(t),
2653 				DBTypeLongName(t), DBTypeLongName(s));
2654 			bad = TRUE;
2655 			continue;
2656 		    }
2657 		    ExtCurStyle->exts_overlapCap[s][t] = capVal;
2658 		    ExtCurStyle->exts_overlapPlanes |= PlaneNumToMaskBit(p1);
2659 		    ExtCurStyle->exts_overlapOtherPlanes[s]
2660 			    |= PlaneNumToMaskBit(p2);
2661 		    TTMaskSetType(&ExtCurStyle->exts_overlapTypes[p1], s);
2662 		    TTMaskSetType(&ExtCurStyle->exts_overlapOtherTypes[s], t);
2663 		    if (argc == 4) continue;
2664 
2665 		    /* Shielding */
2666 		    pshield = 0;
2667 		    for (r = TT_TECHDEPBASE; r < DBNumTypes; r++)
2668 		    {
2669 			if (TTMaskHasType(&shield, r))
2670 			{
2671 			    /* Shielding types are determined from residues */
2672 			    if (DBIsContact(r)) continue;
2673 
2674 			    p3 = DBPlane(r);
2675 			    if (p3 == p1 || p3 == p2)
2676 			    {
2677 				TechError("Shielding type (%s) must be on a"
2678 					" different plane from shielded types.\n",
2679 					DBTypeLongName(r));
2680 				bad = TRUE;
2681 				continue;
2682 			    }
2683 			    pshield |= PlaneNumToMaskBit(p3);
2684 			}
2685 		    }
2686 		    ExtCurStyle->exts_overlapShieldPlanes[s][t] = pshield;
2687 		    ExtCurStyle->exts_overlapShieldTypes[s][t] = shield;
2688 		}
2689 	    }
2690 	    if (bad)
2691 		return (TRUE);
2692 	    break;
2693 	case SIDEOVERLAP:
2694 	    bad = FALSE;
2695 	    DBTechNoisyNameMask(argv[2], &types2);
2696 	    pov = DBTechNoisyNameMask(argv[3], &ov);
2697 	    capVal = aToCap(argv[4]);
2698 	    shield = DBZeroTypeBits;
2699 	    if (argc == 6) DBTechNoisyNameMask(argv[5], &shield);
2700 	    if (TTMaskHasType(&types1, TT_SPACE))
2701 		TechError("Can't have space on inside of edge [ignored]\n");
2702 	    /* It's ok to have the overlap be to space as long as a plane is */
2703 	    /* specified.						     */
2704 	    if (TTMaskHasType(&ov, TT_SPACE))
2705 	    {
2706 		if ((cp = strchr(argv[3],'/')) == NULL)
2707 		{
2708 		    TechError("Must specify plane for sideoverlap to space\n");
2709 		}
2710 		cp++;
2711 		p3 = (spointertype) dbTechNameLookup(cp, &dbPlaneNameLists);
2712 		if (p3 < 0)
2713 		    TechError("Unknown overlap plane %s\n",argv[3]);
2714 		else
2715 		    pov = PlaneNumToMaskBit(p3);
2716 	    }
2717 	    for (s = TT_TECHDEPBASE; s < DBNumTypes; s++)
2718 	    {
2719 		if (!TTMaskHasType(&types1, s))
2720 		    continue;
2721 
2722 		/* Side overlap computed from residues */
2723 		if (DBIsContact(s)) continue;
2724 
2725 		p1 = DBPlane(s);
2726 		if (PlaneMaskHasPlane(pov, p1))
2727 		    goto diffplane;
2728 		ExtCurStyle->exts_sidePlanes |= PlaneNumToMaskBit(p1);
2729 		TTMaskSetType(&ExtCurStyle->exts_sideTypes[p1], s);
2730 		TTMaskSetMask(&ExtCurStyle->exts_sideEdges[s], &types2);
2731 		for (t = 0; t < DBNumTypes; t++)
2732 		{
2733 		    if (!TTMaskHasType(&types2, t))
2734 			continue;
2735 
2736 		    /* Side overlap computed from residues */
2737 		    if (DBIsContact(t)) continue;
2738 
2739 		    p2 = DBPlane(t);
2740 		    if (t != TT_SPACE && PlaneMaskHasPlane(pov, p2))
2741 			goto diffplane;
2742 		    TTMaskSetMask(&ExtCurStyle->exts_sideOverlapOtherTypes[s][t], &ov);
2743 		    ExtCurStyle->exts_sideOverlapOtherPlanes[s][t] |= pov;
2744 		    cnew = (EdgeCap *) mallocMagic((unsigned) (sizeof (EdgeCap)));
2745 		    cnew->ec_cap = capVal;
2746 		    cnew->ec_far = shield; /* Really types that shield */
2747 		    cnew->ec_near = ov;  /* Really types we create cap with */
2748 		    cnew->ec_pmask = pov;
2749 		    cnew->ec_next = ExtCurStyle->exts_sideOverlapCap[s][t];
2750 		    ExtCurStyle->exts_sideOverlapCap[s][t] = cnew;
2751 
2752 		    /* Shielding */
2753 		    pshield = 0;
2754 		    for (r = TT_TECHDEPBASE; r < DBNumTypes; r++)
2755 		    {
2756 			if (TTMaskHasType(&shield, r))
2757 			{
2758 			    /* Side overlap shielding computed from residues */
2759 			    if (DBIsContact(r)) continue;
2760 
2761 			    p3 = DBPlane(r);
2762 			    if (p3 == p1 || p3 == p2)
2763 			    {
2764 				TechError("Shielding type (%s) must be on"
2765 					" a different plane from shielded types.\n",
2766 					DBTypeLongName(r));
2767 				bad = TRUE;
2768 				continue;
2769 			    }
2770 			    pshield |= PlaneNumToMaskBit(p3);
2771 			}
2772 		    }
2773 		    for (o = TT_TECHDEPBASE; o < DBNumTypes; o++)
2774 		    {
2775 			if (TTMaskHasType(&ov, o))
2776 			{
2777 			    ExtCurStyle->exts_sideOverlapShieldPlanes[s][o] |= pshield;
2778 			}
2779 		    }
2780 		}
2781 	    }
2782 	    if (bad)
2783 		return (TRUE);
2784 	    break;
2785 	case SIDEWALL:
2786 	    DBTechNoisyNameMask(argv[2], &types2);
2787 	    DBTechNoisyNameMask(argv[3], &near);
2788 	    DBTechNoisyNameMask(argv[4], &far);
2789 	    if (TTMaskHasType(&types1, TT_SPACE))
2790 		TechError("Can't have space on inside of edge [ignored]\n");
2791 	    capVal = aToCap(argv[5]);
2792 	    for (s = TT_TECHDEPBASE; s < DBNumTypes; s++)
2793 	    {
2794 		if (!TTMaskHasType(&types1, s))
2795 		    continue;
2796 		ExtCurStyle->exts_sidePlanes |= PlaneNumToMaskBit(DBPlane(s));
2797 		TTMaskSetType(&ExtCurStyle->exts_sideTypes[DBPlane(s)], s);
2798 		TTMaskSetMask(&ExtCurStyle->exts_sideEdges[s], &types2);
2799 		for (t = 0; t < DBNumTypes; t++)
2800 		{
2801 		    if (!TTMaskHasType(&types2, t))
2802 			continue;
2803 		    TTMaskSetMask(&ExtCurStyle->exts_sideCoupleOtherEdges[s][t], &far);
2804 		    cnew = (EdgeCap *) mallocMagic((unsigned) (sizeof (EdgeCap)));
2805 		    cnew->ec_cap = capVal;
2806 		    cnew->ec_near = near;
2807 		    cnew->ec_far = far;
2808 		    cnew->ec_next = ExtCurStyle->exts_sideCoupleCap[s][t];
2809 		    cnew->ec_pmask = 0;
2810 		    ExtCurStyle->exts_sideCoupleCap[s][t] = cnew;
2811 		}
2812 	    }
2813 	    break;
2814 	case SIDEHALO:
2815 	    /* Allow floating-point and increase by factor of 1000      */
2816 	    /* to accommodate "units microns".                          */
2817 
2818 	    /* Warning:  Due to some gcc bug with an i686 FPU, using a	*/
2819 	    /* result from atof() with a static value like 1000		*/
2820 	    /* produces a NaN result!  sscanf() seems to be safe. . .	*/
2821 
2822 	    sscanf(argv[1], "%lg", &dhalo);
2823 	    dhalo *= (double)1000.0;
2824 	    ExtCurStyle->exts_sideCoupleHalo = (int)dhalo;
2825 	    break;
2826 	case PERIMC:
2827 	    DBTechNoisyNameMask(argv[2], &types2);
2828 	    capVal = aToCap(argv[3]);
2829 	    if (capVal == (CapValue) 0)
2830 		break;
2831 	    for (s = TT_TECHDEPBASE; s < DBNumTypes; s++)
2832 		for (t = 0; t < DBNumTypes; t++)
2833 		    if (TTMaskHasType(&types1, s) && TTMaskHasType(&types2, t))
2834 		    {
2835 			ExtCurStyle->exts_perimCap[s][t] = capVal;
2836 			TTMaskSetType(&ExtCurStyle->exts_perimCapMask[s], t);
2837 		    }
2838 	    break;
2839 	case RESIST: {
2840 	    float chop = 1.0;
2841 
2842 	    if (!StrIsInt(argv[2]))
2843 	    {
2844 		if (!strcmp(argv[2], "None"))
2845 		{
2846 		    for (t = TT_TECHDEPBASE; t < DBNumTypes; t++)
2847 			if (TTMaskHasType(&types1, t))
2848 			    TTMaskClearType(&ExtCurStyle->exts_activeTypes, t);
2849 		    break;
2850 		}
2851 		else
2852 		{
2853 		    TxError("Resist argument must be integer or \"None\".\n");
2854 		    break;
2855 		}
2856 	    }
2857 	    else
2858 		val = atoi(argv[2]);
2859 
2860 	    if (argc == 4)
2861 		chop = atof(argv[3]);
2862 	    class = ExtCurStyle->exts_numResistClasses++;
2863 	    for (t = TT_TECHDEPBASE; t < DBNumTypes; t++)
2864 		if (TTMaskHasType(&types1, t))
2865 		{
2866 		    ExtCurStyle->exts_sheetResist[t] = val;
2867 		    ExtCurStyle->exts_cornerChop[t] = chop;
2868 		    ExtCurStyle->exts_typeToResistClass[t] = class;
2869 		}
2870 	    ExtCurStyle->exts_resistByResistClass[class] = val;
2871 	    ExtCurStyle->exts_typesByResistClass[class] = types1;
2872 	    }
2873 	    break;
2874 	case RSCALE:
2875 	    ExtCurStyle->exts_resistScale = atoi(argv[1]);
2876 	    break;
2877 	case STEP:
2878 	    val = (int)atof(argv[1]);
2879 	    if (val <= 0)
2880 	    {
2881 		TechError("Hierarchical interaction step size must be > 0\n");
2882 		return (FALSE);
2883 	    }
2884 	    ExtCurStyle->exts_stepSize = val;
2885 	    break;
2886 	case SUBSTRATE:
2887 	    /* If the last entry starts with '-', then use it to set	*/
2888 	    /* the shield types.   Otherwise, the shield types mask is	*/
2889 	    /* NULL.							*/
2890 
2891 	    idTypes = DBZeroTypeBits;
2892 	    if (*argv[argc - 1] == '-')
2893 	    {
2894 		if ((DBTechNameMask(argv[argc - 1] + 1, &idTypes)) == 0)
2895 		    idTypes = DBZeroTypeBits;
2896 		argc--;
2897 	    }
2898 
2899 	    TTMaskZero(&ExtCurStyle->exts_globSubstrateTypes);
2900 	    TTMaskZero(&ExtCurStyle->exts_globSubstrateShieldTypes);
2901 	    TTMaskSetMask(&ExtCurStyle->exts_globSubstrateTypes, &types1);
2902 	    ExtCurStyle->exts_globSubstrateShieldTypes = idTypes;
2903 	    ExtCurStyle->exts_globSubstratePlane = DBTechNoisyNamePlane(argv[2]);
2904 
2905 	    /* Handle optional substrate node name */
2906 	    if (argc == 4)
2907 		ExtCurStyle->exts_globSubstrateName = StrDup((char **)NULL, argv[3]);
2908 
2909 	    break;
2910 	case NOPLANEORDER: {
2911 	     if ( ExtCurStyle->exts_planeOrderStatus == seenPlaneOrder )
2912 		TechError("\"noplaneordering\" specified after \"planeorder\".\n");
2913 	     else
2914 		ExtCurStyle->exts_planeOrderStatus = noPlaneOrder ;
2915 	    }
2916 	    break ;
2917 	case PLANEORDER: {
2918 	    int pnum = (spointertype) dbTechNameLookup(argv[1], &dbPlaneNameLists);
2919 	    int pos = atoi(argv[2]);
2920 
2921 	    if ( ExtCurStyle->exts_planeOrderStatus == noPlaneOrder ) {
2922 		TechError("\"planeorder\" specified after \"noplaneordering\".\n");
2923 	    }
2924 	    ExtCurStyle->exts_planeOrderStatus = seenPlaneOrder ;
2925 	    if (pnum < 0)
2926 		TechError("Unknown planeorder plane %s\n", argv[1]);
2927 	    else if (pos < 0 || pos >= DBNumPlanes-PL_TECHDEPBASE)
2928 		TechError("Planeorder index must be [0..%d]\n",
2929 		    DBNumPlanes-PL_TECHDEPBASE-1);
2930 	    else
2931 		ExtCurStyle->exts_planeOrder[pnum] = pos;
2932 	    }
2933 	    break;
2934     }
2935     return (TRUE);
2936 
2937 usage:
2938     TechError("Malformed line for keyword %s.  Correct usage:\n\t%s %s\n",
2939 		    kp->k_name, kp->k_name, kp->k_usage);
2940     return (TRUE);
2941 
2942 diffplane:
2943     TechError("Overlapped types in \"sideoverlap\" rule must be on a\n"
2944 		"\tdifferent plane from intypes and outtypes.\n");
2945     return (TRUE);
2946 }
2947 
2948 
2949 /*
2950  * ----------------------------------------------------------------------------
2951  *
2952  * ExtTechFinal --
2953  *
2954  * Postprocess the technology specific information for extraction.
2955  * Builds the connectivity tables exts_nodeConn[], exts_resistConn[],
2956  * and exts_deviceConn[].
2957  *
2958  * Results:
2959  *	None.
2960  *
2961  * Side effects:
2962  *	Initializes the tables mentioned above.
2963  *	Leaves ExtCurStyle pointing to the first style in the list
2964  *	ExtAllStyles.
2965  *
2966  * ----------------------------------------------------------------------------
2967  */
2968 
2969 void
ExtTechFinal()2970 ExtTechFinal()
2971 {
2972     ExtStyle *es;
2973 
2974     /* Create a "default" style if there isn't one */
2975     if (ExtAllStyles == NULL)
2976     {
2977 	ExtAllStyles = (ExtKeep *)mallocMagic(sizeof(ExtKeep));
2978 	ExtAllStyles->exts_next = NULL;
2979 	ExtAllStyles->exts_name = StrDup((char **) NULL, "default");
2980 
2981 	ExtCurStyle = extTechStyleNew();
2982 	ExtCurStyle->exts_name = ExtAllStyles->exts_name;
2983 	ExtCurStyle->exts_status = TECH_LOADED;
2984     }
2985     extTechFinalStyle(ExtCurStyle);
2986 }
2987 
2988 
2989 void
extTechFinalStyle(style)2990 extTechFinalStyle(style)
2991     ExtStyle *style;
2992 {
2993     TileTypeBitMask maskBits;
2994     TileType r, s, t;
2995     int p, p1, missing, conflict;
2996     int indicis[NP];
2997 
2998     for (r = TT_TECHDEPBASE; r < DBNumTypes; r++)
2999     {
3000 	maskBits = style->exts_nodeConn[r] = DBConnectTbl[r];
3001 	if (!TTMaskHasType(&style->exts_deviceMask, r))
3002 	{
3003 	     TTMaskZero(&style->exts_deviceConn[r]);
3004 	}
3005 	for (s = TT_TECHDEPBASE; s < DBNumTypes; s++)
3006 	{
3007 	    if (TTMaskHasType(&maskBits, s))
3008 		if (style->exts_typeToResistClass[s]
3009 			!= style->exts_typeToResistClass[r])
3010 		    TTMaskClearType(&maskBits, s);
3011 	}
3012 	style->exts_resistConn[r] = maskBits;
3013     }
3014 
3015     /* r ranges over types, s over resistance entries */
3016     for (r = TT_TECHDEPBASE; r < DBNumTypes; r++)
3017     {
3018 	s = style->exts_typeToResistClass[r];
3019 	if (s >= 0)
3020 	    TTMaskClearMask(&style->exts_typesResistChanged[r],
3021 			&style->exts_typesByResistClass[s]);
3022     }
3023 
3024     /*
3025      * Residue check:
3026      * We have ignored all contact types when parsing parasitic
3027      * capacitances.  Now we need to add them.  For each contact
3028      * type, add the contact type to the types lists accordingly.
3029      * Note that we don't have to record any cap values, since the
3030      * extraction routine dissolves contacts into their residue
3031      * types when computing the parasitics.  But, the type must be
3032      * in the type lists or contact tiles will be passed over during
3033      * searches.
3034      */
3035 
3036     for (s = TT_TECHDEPBASE; s < DBNumTypes; s++)
3037     {
3038 	TileTypeBitMask rmask;
3039 	PlaneMask pMask;
3040 	TileType q;
3041 
3042 	if (!DBIsContact(s)) continue;
3043 
3044 	pMask = DBTypePlaneMaskTbl[s];
3045 	for (p = 0; p < DBNumPlanes; p++)
3046 	{
3047 	    if (PlaneMaskHasPlane(pMask, p))
3048 	    {
3049 		TTMaskSetType(&style->exts_overlapTypes[p], s);
3050 		TTMaskSetType(&style->exts_sideTypes[p], s);
3051 	    }
3052 	}
3053 	DBFullResidueMask(s, &rmask);
3054 	for (r = TT_TECHDEPBASE; r < DBNumUserLayers; r++)
3055 	{
3056 	    if (!TTMaskHasType(&rmask, r)) continue;
3057 
3058 	    TTMaskSetMask(&style->exts_sideEdges[s], &style->exts_sideEdges[r]);
3059 
3060 	    for (q = TT_TECHDEPBASE; q < DBNumUserLayers; q++)
3061 	    {
3062 		if (TTMaskHasType(&style->exts_overlapOtherTypes[q], r))
3063 		    TTMaskSetType(&style->exts_overlapOtherTypes[q], s);
3064 
3065 	        for (t = TT_TECHDEPBASE; t < DBNumUserLayers; t++)
3066 		    if (TTMaskHasType(&style->exts_overlapShieldTypes[q][t], r)
3067 				&& !TTMaskHasType(&rmask, q)
3068 				&& !TTMaskHasType(&rmask, t))
3069 			TTMaskSetType(&style->exts_overlapShieldTypes[q][t], s);
3070 
3071 		/* For sideOverlap, t is "outtypes" and includes space, so we	*/
3072 		/* must count from TT_SPACE, not TT_TECHDEPBASE.		*/
3073 
3074 	        for (t = TT_SPACE; t < DBNumUserLayers; t++)
3075 		    if (TTMaskHasType(&style->exts_sideOverlapOtherTypes[q][t], r))
3076 			TTMaskSetType(&style->exts_sideOverlapOtherTypes[q][t], s);
3077 	    }
3078 	}
3079     }
3080 
3081     /*
3082      * Consistency check:
3083      * If a type R shields S from T, make sure that R is listed as
3084      * being in the list of overlapped types for S, even if there
3085      * was no overlap capacitance explicitly specified for this
3086      * pair of types in an "overlap" line.  This guarantees that
3087      * R will shield S from substrate even if there is no capacitance
3088      * associated with the overlap.
3089      */
3090     for (s = TT_TECHDEPBASE; s < DBNumTypes; s++)
3091 	for (t = TT_TECHDEPBASE; t < DBNumTypes; t++)
3092 	{
3093 	    if (style->exts_overlapShieldPlanes[s][t] == 0)
3094 		continue;
3095 	    for (r = TT_TECHDEPBASE; r < DBNumTypes; r++)
3096 	    {
3097 		if (!TTMaskHasType(&style->exts_overlapShieldTypes[s][t], r))
3098 		    continue;
3099 		p1 = DBPlane(s);
3100 		style->exts_overlapPlanes |= PlaneNumToMaskBit(p1);
3101 		style->exts_overlapOtherPlanes[s]
3102 			|= PlaneNumToMaskBit(DBPlane(r));
3103 		TTMaskSetType(&style->exts_overlapTypes[p1], s);
3104 		TTMaskSetType(&style->exts_overlapOtherTypes[s], r);
3105 	    }
3106 	}
3107 
3108     /* Finally, for all coupling type masks, remove those types	 */
3109     /* that have been declared not to participate in extraction. */
3110 
3111     for (s = TT_TECHDEPBASE; s < DBNumTypes; s++)
3112     {
3113 	TTMaskAndMask(&style->exts_overlapOtherTypes[s], &style->exts_activeTypes);
3114 	TTMaskAndMask(&style->exts_perimCapMask[s], &style->exts_activeTypes);
3115 
3116 	for (t = TT_TECHDEPBASE; t < DBNumTypes; t++)
3117 	{
3118 	    TTMaskAndMask(&style->exts_overlapShieldTypes[s][t],
3119 			&style->exts_activeTypes);
3120 	    TTMaskAndMask(&style->exts_sideOverlapOtherTypes[s][t],
3121 			&style->exts_activeTypes);
3122 	    TTMaskAndMask(&style->exts_sideCoupleOtherEdges[s][t],
3123 			&style->exts_activeTypes);
3124 	}
3125     }
3126 
3127     for (p = 0; p < DBNumPlanes; p++)
3128     {
3129 	TTMaskAndMask(&style->exts_overlapTypes[p], &style->exts_activeTypes);
3130 	TTMaskAndMask(&style->exts_sideTypes[p], &style->exts_activeTypes);
3131     }
3132 
3133     if ( style->exts_planeOrderStatus == noPlaneOrder )
3134     	return /* no need to check */ ;
3135     /* Else Check to make sure the plane order is a permutation of the
3136        numbers 0..DBNumPlanes-DBNumPlanes-1 */
3137     for (p1 = PL_TECHDEPBASE; p1 < DBNumPlanes; p1++) {
3138 	indicis[p1] = 0;
3139     }
3140     for (p1 = PL_TECHDEPBASE; p1 < DBNumPlanes; p1++) {
3141 	int pn = style->exts_planeOrder[p1]+PL_TECHDEPBASE;
3142 	if (pn >= PL_TECHDEPBASE && pn < DBNumPlanes)
3143 	    indicis[pn]++;
3144     }
3145     conflict = FALSE;
3146     missing = FALSE;
3147     for (p1 = PL_TECHDEPBASE; p1 < DBNumPlanes; p1++) {
3148 	if (indicis[p1] > 1) conflict = TRUE ;
3149 	if (indicis[p1] < 1) missing = TRUE ;
3150     }
3151     if (!conflict && !missing)		/* Everything was ok */
3152 	goto zinit;
3153 
3154     TxError ("\nWarning: Extraction Style %s\n", style -> exts_name);
3155     if (conflict) {
3156 	TxError ("  Conflicting planeorder for plane(s):\n   ");
3157 	for (p1 = PL_TECHDEPBASE; p1 < DBNumPlanes; p1++) {
3158 	    if (indicis[p1] > 1)
3159 		TxError (" %s,", DBPlaneLongNameTbl[p1]);
3160 	}
3161     	TxError("\n");
3162     }
3163     if (missing) {
3164 	TxError ("  Missing planeorder for plane(s):\n   ");
3165 	for (p1 = PL_TECHDEPBASE; p1 < DBNumPlanes; p1++) {
3166 	    if (indicis[p1] < 1)
3167 		TxError (" %s,", DBPlaneLongNameTbl[p1]);
3168 	}
3169     	TxError("\n");
3170     }
3171     TxError("  Magic will use the default planeorder for this style:\n   ");
3172     for (p1 = PL_TECHDEPBASE; p1 < DBNumPlanes; p1++) {
3173     	style->exts_planeOrder[p1] = p1 - PL_TECHDEPBASE ;
3174 	TxError(" %s=%d,",DBPlaneLongNameTbl[p1], style->exts_planeOrder[p1]);
3175     }
3176     TxError("\n");
3177 
3178     /* Now that we have a plane ordering, we can apply default height	*/
3179     /* and thickness values for those layers.				*/
3180 
3181 zinit:
3182     for (r = TT_TECHDEPBASE; r < DBNumTypes; r++)
3183     {
3184 	if (style->exts_thick[r] == 0)
3185 	    style->exts_thick[r] = 0.05;
3186 	if (style->exts_height[r] == 0)
3187 	    style->exts_height[r] = 0.1 * style->exts_planeOrder[DBPlane(r)];
3188     }
3189 
3190     /* If global variable "doConvert" is TRUE, then we convert from	*/
3191     /* microns to lambda and microns^2 to lambda^2.			*/
3192 
3193     if (doConvert)
3194     {
3195 	/* Use current CIF output scale for determining the scale	*/
3196 	/* factor between micron units in the extract section and 	*/
3197 	/* lambda units of the database (conversion from lambda to	*/
3198 	/* internal units is done separately).				*/
3199 
3200 	float dscale = CIFGetOutputScale(1000);
3201 
3202 	CapValue scalefac = (CapValue)dscale;
3203 	CapValue sqfac = scalefac * scalefac;
3204 
3205 	for (r = 0; r < DBNumTypes; r++)
3206 	{
3207 	    ExtDevice *devptr;
3208 
3209 	    for (devptr = style->exts_device[r]; devptr; devptr = devptr->exts_next)
3210 	    {
3211 		devptr->exts_deviceSDCap *= sqfac;
3212 		devptr->exts_deviceGateCap *= sqfac;
3213 	    }
3214 
3215 	    style->exts_areaCap[r] *= sqfac;
3216 	    for (s = 0; s < DBNumTypes; s++)
3217 	    {
3218 		EdgeCap *ec;
3219 
3220 		style->exts_perimCap[r][s] *= scalefac;
3221 		style->exts_overlapCap[r][s] *= sqfac;
3222 		for (ec = style->exts_sideOverlapCap[r][s]; ec != NULL;
3223 				ec = ec->ec_next)
3224 		    ec->ec_cap *= scalefac;
3225 
3226 		// Note that because sidewall caps are referred to
3227 		// a specific distance, the value (run / separation)
3228 		// is unscaled, so the capacitance does not get
3229 		// modified by the scalefactor.  However, the lambda
3230 		// reference for sidewall cap is 2 lambda, so if
3231 		// the reference is to be interpreted as 1 micron,
3232 		// the value needs to be divided by 2 (the factor of
3233 		// 2 is made up by the fact that the sidewall is
3234 		// independently accumulated on each plate of the
3235 		// capacitor)
3236 
3237 		for (ec = style->exts_sideCoupleCap[r][s]; ec != NULL;
3238 				ec = ec->ec_next)
3239 		    ec->ec_cap *= 0.5;
3240 	    }
3241 
3242 	    /* Layer thickness and height are in microns, but are floating-point */
3243 	    style->exts_thick[r] /= dscale;
3244 	    style->exts_height[r] /= dscale;
3245 	}
3246 
3247 	/* side halo and step size are also in microns */
3248 
3249 	style->exts_sideCoupleHalo = (int)(((float)style->exts_sideCoupleHalo
3250 		/ dscale) + 0.5);
3251 	style->exts_stepSize = (int)(((float)style->exts_stepSize
3252 		/ dscale) + 0.5);
3253     }
3254 
3255     /* Avoid setting stepSize to zero, or extraction will hang! */
3256     if (style->exts_stepSize <= 0)
3257     {
3258 	TxError("Warning:  zero step size!  Resetting to default.\n");
3259 	style->exts_stepSize = 100;		/* Revert to default */
3260     }
3261 
3262     /* We had multiplied sideCoupleHalo by 1000 to accommodate a 	*/
3263     /* floating-point value in microns, whether or not doConvert was	*/
3264     /* needed, so normalize it back to lambda units.			*/
3265 
3266     style->exts_sideCoupleHalo /= 1000;
3267 }
3268 
3269 /*
3270  * ----------------------------------------------------------------------------
3271  * ExtTechScale --
3272  *
3273  *	Scale all extraction values appropriately when rescaling the grid.
3274  * ----------------------------------------------------------------------------
3275  */
3276 
3277 void
ExtTechScale(scalen,scaled)3278 ExtTechScale(scalen, scaled)
3279     int scalen;			/* Scale numerator */
3280     int scaled;			/* Scale denominator */
3281 {
3282     ExtStyle *style = ExtCurStyle;
3283     EdgeCap *ec;
3284     int i, j;
3285     float sqn, sqd;
3286 
3287     if (style == NULL) return;
3288 
3289     sqn = (float)(scalen * scalen);
3290     sqd = (float)(scaled * scaled);
3291 
3292     style->exts_unitsPerLambda = style->exts_unitsPerLambda * (float)scalen
3293 		/ (float)scaled;
3294     DBScaleValue(&style->exts_sideCoupleHalo, scaled, scalen);
3295     DBScaleValue(&style->exts_stepSize, scaled, scalen);
3296 
3297     for (i = 0; i < DBNumTypes; i++)
3298     {
3299 	ExtDevice *devptr;
3300 
3301 	style->exts_areaCap[i] *= sqn;
3302 	style->exts_areaCap[i] /= sqd;
3303 
3304 	for (devptr = style->exts_device[i]; devptr; devptr = devptr->exts_next)
3305 	{
3306 	    devptr->exts_deviceSDCap *= sqn;
3307 	    devptr->exts_deviceSDCap /= sqd;
3308 	    devptr->exts_deviceGateCap *= sqn;
3309 	    devptr->exts_deviceGateCap /= sqd;
3310 	}
3311 
3312 	style->exts_height[i] *= scaled;
3313 	style->exts_height[i] /= scalen;
3314 	style->exts_thick[i] *= scaled;
3315 	style->exts_thick[i] /= scalen;
3316 
3317 	for (j = 0; j < DBNumTypes; j++)
3318 	{
3319 	    style->exts_perimCap[i][j] *= scalen;
3320 	    style->exts_perimCap[i][j] /= scaled;
3321 	    style->exts_overlapCap[i][j] *= sqn;
3322 	    style->exts_overlapCap[i][j] /= sqd;    /* Typo fixed in 7.2.57 */
3323 
3324 	    // Do not scale sidewall cap, for while the value is
3325 	    // per distance, the distance is referred to a separation
3326 	    // distance in the same units, so the cap never scales.
3327 
3328 	    // for (ec = style->exts_sideCoupleCap[i][j]; ec != NULL;
3329 	    //			ec = ec->ec_next)
3330 	    // {
3331 	    //	ec->ec_cap *= scalen;
3332 	    //	ec->ec_cap /= scaled;
3333 	    // }
3334 	    for (ec = style->exts_sideOverlapCap[i][j]; ec != NULL;
3335 				ec = ec->ec_next)
3336 	    {
3337 		ec->ec_cap *= scalen;
3338 		ec->ec_cap /= scaled;
3339 	    }
3340 	}
3341     }
3342 
3343     return;
3344 }
3345 
3346