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(¬types, &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(¬types);
1170 TTMaskSetType(¬types, TT_SPACE);
1171 plane1 = DBTechNoisyNamePlane(argv[2]);
1172 TTMaskAndMask(&types, &DBPlaneTypes[plane1]);
1173 TTMaskAndMask(¬types, &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(¬types, 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], ¬types);
1238 for (t = 0; t < DBNumTypes; t++)
1239 {
1240 if (!TTMaskHasType(¬types, 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(¬types, &types);
1490 TTMaskZero(¬types);
1491 TTMaskSetType(¬types, TT_SPACE);
1492
1493 TTMaskAndMask(&types, &DBPlaneTypes[plane1]);
1494 TTMaskAndMask(¬types, &DBPlaneTypes[plane1]);
1495
1496 DBTechNoisyNameMask(argv[3], &ov);
1497 plane2 = DBTechNoisyNamePlane(argv[4]);
1498
1499 // TTMaskCom2(¬ov, &ov);
1500 TTMaskZero(¬ov);
1501 TTMaskSetType(¬ov, TT_SPACE);
1502
1503 TTMaskAndMask(&ov, &DBPlaneTypes[plane2]);
1504 TTMaskAndMask(¬ov, &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], ¬types);
1565 for (t = TT_SPACE; t < DBNumTypes; t++)
1566 {
1567 if (!TTMaskHasType(¬types, 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