1 /*
2  * DBtcontact.c --
3  *
4  * Management of contacts.
5  * This file makes a distinction between the following two terms:
6  *
7  *  Layer	-- Logical type as specified in "types" section of .tech
8  *		   file.  A layer may consist of many TileTypes, as is the
9  *		   case when it is a contact.
10  *  Type	-- TileType stored in a tile
11  *
12  *     *********************************************************************
13  *     * Copyright (C) 1985, 1990 Regents of the University of California. *
14  *     * Permission to use, copy, modify, and distribute this              *
15  *     * software and its documentation for any purpose and without        *
16  *     * fee is hereby granted, provided that the above copyright          *
17  *     * notice appear in all copies.  The University of California        *
18  *     * makes no representations about the suitability of this            *
19  *     * software for any purpose.  It is provided "as is" without         *
20  *     * express or implied warranty.  Export of this software outside     *
21  *     * of the United States of America may require an export license.    *
22  *     *********************************************************************
23  */
24 
25 #ifndef lint
26 static char rcsid[] __attribute__ ((unused)) = "$Header: /usr/cvsroot/magic-8.0/database/DBtcontact.c,v 1.3 2008/09/05 13:56:25 tim Exp $";
27 #endif  /* not lint */
28 
29 #include <stdio.h>
30 #include <string.h>
31 #include <ctype.h>
32 
33 #include "utils/magic.h"
34 #include "utils/geometry.h"
35 #include "utils/utils.h"
36 #include "utils/malloc.h"
37 #include "tiles/tile.h"
38 #include "utils/hash.h"
39 #include "database/database.h"
40 #include "database/databaseInt.h"
41 #include "utils/tech.h"
42 #include "textio/textio.h"
43 
44 /* type-to-bitmask conversion (1 bit per entry) */
45 TileTypeBitMask DBLayerTypeMaskTbl[NT];
46 
47 /* Filled in after contact types have been generated */
48 TileTypeBitMask DBPlaneTypes[PL_MAXTYPES];
49 TileTypeBitMask DBHomePlaneTypes[PL_MAXTYPES];
50 PlaneMask        DBTypePlaneMaskTbl[NT];
51 
52 /* --------------------- Data local to this file ---------------------- */
53 
54 /* Table of the properties of all layers */
55 LayerInfo dbLayerInfo[NT];
56 
57 /* Array of pointers to the entries in above table for contacts only */
58 LayerInfo *dbContactInfo[NT];
59 int dbNumContacts;
60 
61 /* Forward declaration */
62 void dbTechMatchResidues();
63 void dbTechAddStackedContacts();
64 int dbTechAddOneStackedContact();
65 
66 
67 /*
68  * ----------------------------------------------------------------------------
69  *
70  * DBTechInitContact --
71  *
72  * Mark all types as being non-contacts initially.
73  *
74  * Results:
75  *	None.
76  *
77  * Side effects:
78  *	Initializes dbLayerInfo.
79  *
80  * ----------------------------------------------------------------------------
81  */
82 
83 void
DBTechInitContact()84 DBTechInitContact()
85 {
86     TileType t;
87     LayerInfo *lp;
88 
89     for (t = 0; t < TT_MAXTYPES; t++)
90     {
91 	lp = &dbLayerInfo[t];
92 	lp->l_type = t;
93 	lp->l_isContact = FALSE;
94 	lp->l_pmask = 0;
95 	TTMaskZero(&lp->l_residues);
96 	TTMaskSetOnlyType(&DBLayerTypeMaskTbl[t], t);
97     }
98 
99     dbNumContacts = 0;
100 }
101 
102 /*
103  * ----------------------------------------------------------------------------
104  *
105  * DBTechAddContact --
106  *
107  * Add the definition of a new contact type.
108  * The syntax of each line in the "contact" section is:
109  *
110  *	contactType res1 res2 [res3...]
111  *
112  * where res1, res2, res3, etc. are the residue types on the planes
113  * connected by the contact.  The home plane of the contact (the
114  * plane specified in the "types" section for the type contactType)
115  * must be the lowest-numbered plane in the list of residues.  Each
116  * listed residue must be on a different plane. There are no other
117  * restrictions on contacts.
118  *
119  * Magic-7.3 additional syntax:
120  *
121  *	stackable type1 [type2 [alias12] [type3 [alias13] ...]]
122  *
123  * where type1 and type2 are contact types, allows type1 and type2
124  * to be drawn on top of one other by generating an extra contact
125  * type to represent the union of type1 and type2 on the shared
126  * plane.  If more than two types are specified, then type1 will be
127  * set to be stackable with each of the indicated types.  If only
128  * type1 is specified, then type1 will be made stackable with all
129  * other (existing) contact types.  Wherever a layer name exists
130  * after a known type that is not a known layer name, it is
131  * considered to be an alias name for the stacked type.  e.g.,
132  * "stackable pc via pm12contact" is valid if "pc" and "via" are
133  * defined types.  Thie provides compatibility with layout files
134  * created with technology files that explicitly define stacked
135  * contact types, especially those from magic-7.2 and earlier
136  * versions.
137  *
138  *	stackable
139  *
140  * allows all contact types to stack, where applicable.  This
141  * statement overrides any other "stackable" statement.
142  *
143  * Notes:
144  *	All indicated types must have been declared in the "contact"
145  *	section prior to use of the "stackable" keyword.  The 1- and
146  *	2-argument variants will create stacking types with all
147  *	previously-declared contact types.
148  *
149  * Expanded syntax:
150  *	Now allows the section "image" with statements "contact" and
151  *	"device".  Statements beginning with the layer name are
152  *	backwardly-compatible with the original syntax.  "contact"
153  *	statements are equivalent to the original syntax after skipping
154  *	the keyword "contact".  "device" statements have the same
155  *	syntax as the "contact" statement but describe a composite
156  *	image such as a transistor or capacitor formed by layers on
157  *	different planes.
158  *
159  * Results:
160  *	FALSE on error, TRUE if successful.
161  *
162  * Side effects:
163  *	Adds the definition of a new contact type.
164  *
165  * ----------------------------------------------------------------------------
166  */
167 
168 bool
DBTechAddContact(sectionName,argc,argv)169 DBTechAddContact(sectionName, argc, argv)
170     char *sectionName;
171     int argc;
172     char *argv[];
173 {
174     TileType contactType;
175     int nresidues;
176 
177     if ((contactType = DBTechNameType(*argv)) < 0)
178     {
179 	if (!strcmp(*argv, "contact") || !strcmp(*argv, "device"))
180 	{
181 	    argc--;
182 	    argv++;
183 	    if ((contactType = DBTechNameType(*argv)) < 0)
184 	    {
185 		DBTechNoisyNameType(*argv);
186 		return FALSE;
187 	    }
188 	}
189 	else if (!strcmp(*argv, "stackable"))
190 	{
191 	    TileType stackType, newType = -1;
192 	    LayerInfo *lim, *lin;
193 
194 	    if (argc == 1)
195 		dbTechAddStackedContacts();
196 	    else
197 	    {
198 		contactType = DBTechNoisyNameType(*++argv);
199 		if (contactType < 0)
200 		    return FALSE;
201 		else if (argc == 2)
202 		{
203 		    int n, result;
204 
205 		    lim = &dbLayerInfo[contactType];
206 
207 		    for (n = 0; n < dbNumContacts; n++)
208 		    {
209 			lin = dbContactInfo[n];
210 			if (lim == lin) continue;
211 		 	result = dbTechAddOneStackedContact(lim->l_type, lin->l_type);
212 			if (result == -3)
213 			    return FALSE;	/* overran tiletype maximum number */
214 		    }
215 		}
216 		else
217 		{
218 		    TileType lastType = TT_SPACE;
219 		    char *primary;
220 
221 		    while (--argc > 1)
222 		    {
223 			stackType = DBTechNameType(*++argv);
224 			if (stackType >= 0)
225 			{
226 			    newType = dbTechAddOneStackedContact(contactType,
227 					stackType);
228 			    if (newType == -1)
229 				TechError("Contact types %s and %s do not stack\n",
230 					DBTypeLongNameTbl[contactType],
231 					DBTypeLongNameTbl[stackType]);
232 			    lastType = stackType;
233 			}
234 			else if (lastType >= TT_SPACE)
235 			{
236 			    /* (*argv) becomes an alias name for layer newType */
237 			    if (newType < 0)
238 				TechError("Contact type %s unknown or contact "
239 					"missing in stackable statement\n", *argv);
240 			    else
241 				DBTechAddNameToType(*argv, newType, FALSE);
242 			    lastType = TT_SPACE;
243 			}
244 			else
245 			{
246 			    DBTechNoisyNameType(*argv);
247 			    lastType = TT_SPACE;
248 			}
249 		    }
250 		}
251 	    }
252 	    return TRUE;
253 	}
254 	else
255 	{
256 	    DBTechNoisyNameType(*argv);
257 	    return FALSE;
258 	}
259     }
260 
261     /* Read the contact residues and check them for validity */
262     nresidues = dbTechContactResidues(--argc, ++argv, contactType);
263     if (nresidues < 0)
264 	return FALSE;
265 
266     /* Remember this as a paintable contact */
267     dbContactInfo[dbNumContacts++] = &dbLayerInfo[contactType];
268 
269     return TRUE;
270 }
271 
272 /*
273  * ----------------------------------------------------------------------------
274  * dbTechAddStackedContacts --
275  *
276  *	Generate new contact types where existing contact types share a
277  *	residue.  These contact types will exist only on the planes
278  *	shared between the two contact types.  This method allows contacts
279  *	to be stacked without requiring a declaration of every combination
280  *	in the techfile.
281  *
282  *	When searching for contact types with shared planes, we want to
283  *	make sure that no existing contact exactly matches the stacked
284  *	type, in case stacked contacts are explicitly called out in the
285  *	tech file (e.g., pm12contact).
286  *
287  * Results:
288  *	None.
289  *
290  * Side effects:
291  *	Adds to the tiletype database.
292  *
293  * ----------------------------------------------------------------------------
294  */
295 
296 void
dbTechAddStackedContacts()297 dbTechAddStackedContacts()
298 {
299     int m, n;
300     LayerInfo *lim, *lin;
301     int dbNumUserContacts = dbNumContacts;
302     int result;
303 
304     for (m = 0; m < dbNumUserContacts; m++)
305     {
306 	lim = dbContactInfo[m];
307 	for (n = m + 1; n < dbNumUserContacts; n++)
308 	{
309 	    lin = dbContactInfo[n];
310 	    result = dbTechAddOneStackedContact(lim->l_type, lin->l_type);
311 	    if (result == -3)
312 		return;		/* overran tiletype maximum number */
313 	}
314     }
315 
316     /* Diagnostic */
317     /* fprintf(stderr, "DBNumUserLayers = %d, DBNumTypes = %d\n",
318 		DBNumUserLayers, DBNumTypes);
319     fflush(stderr); */
320 }
321 
322 /*
323  * ----------------------------------------------------------------------------
324  * dbTechAddOneStackedContact --
325  *
326  *	Generate one new stacked contact type representing the union of
327  *	types "type1" and "type2" on their shared plane(s) (normally
328  *	one, but not necessarily).
329  *
330  * Results:
331  *	tile type of new stacked contact if successful, -1 if stacking
332  *	not allowed, -2 if a contact type already exists which stacks
333  *	type1 and type2, or -3 on overrun of the total number of layers.
334  * ----------------------------------------------------------------------------
335  */
336 
337 int
dbTechAddOneStackedContact(type1,type2)338 dbTechAddOneStackedContact(type1, type2)
339     TileType type1, type2;
340 {
341     LayerInfo *lim, *lin, *lp;
342     TileTypeBitMask ttshared, ttall, mmask;
343     TileType stackedType, sres;
344 
345     lim = &dbLayerInfo[type1];
346     lin = &dbLayerInfo[type2];
347 
348     /* Both types must be contacts */
349     if (!lim->l_isContact || !lin->l_isContact) return -1;
350 
351     /* Contacts do not stack if they share more than one plane */
352     /* if (lim->l_pmask == lin->l_pmask) return -1; */
353     if (((lim->l_pmask & lin->l_pmask) & ((lim->l_pmask & lin->l_pmask) - 1))
354 		!= 0)
355 	return -1;
356 
357     TTMaskAndMask3(&ttshared, &lim->l_residues, &lin->l_residues);
358 
359     if (!TTMaskEqual(&ttshared, &DBZeroTypeBits))
360     {
361 	/* Find if there exists an image with the same residue	*/
362 	/* mask as the combination of these two contact types.  */
363 
364 	TTMaskZero(&ttall);
365 	TTMaskSetMask3(&ttall, &lim->l_residues, &lin->l_residues);
366 
367 	dbTechMatchResidues(&ttall, &mmask, TRUE);
368 
369 	if (!TTMaskEqual(&mmask, &DBZeroTypeBits))
370 	    return -2; /* Contact type exists, so don't create one. */
371 
372 	/* Also check if there is a stacking type made of these contact */
373 	/* images.  If we already have one, don't re-make it.		*/
374 
375 	else if (DBTechFindStacking(type1, type2) != -1)
376 	    return -2; /* Stacking type exists, so don't create one. */
377 
378 	/* All clear to set the residue bitmask for this contact type */
379 
380 	/* Diagnostic */
381 	/* fprintf(stderr, "Stackable %s and %s\n",
382 		DBTypeLongName(lim->l_type),
383 		DBTypeLongName(lin->l_type));
384 	fflush(stderr); */
385 
386 	stackedType = dbTechNewStackedType(lim->l_type, lin->l_type);
387 
388 	/* Error condition (usually, reached max. no. tile types) */
389 	if (stackedType < 0) return -3;
390 
391 	/* fill in layer info */
392 
393 	lp = &dbLayerInfo[stackedType];
394 	lp->l_isContact = TRUE;
395 
396 	/* The residue of a stacked contact is the two contacts	*/
397 	/* which make it up.  Residues which are contact types	*/
398 	/* are unique to stacking types.			*/
399 
400 	TTMaskZero(&lp->l_residues);
401 	TTMaskSetType(&lp->l_residues, lim->l_type);
402 	TTMaskSetType(&lp->l_residues, lin->l_type);
403 	lp->l_pmask = lin->l_pmask | lim->l_pmask;
404 
405 	/* The home plane of the contact is the plane of the	*/
406 	/* first shared residue found.				*/
407 
408 	for (sres = TT_TECHDEPBASE; sres < DBNumUserLayers; sres++)
409 	    if (TTMaskHasType(&ttshared, sres))
410 	    {
411 		DBPlane(stackedType) = DBPlane(sres);
412 		break;
413 	    }
414 
415 	/* Remember this as a paintable contact */
416 	dbContactInfo[dbNumContacts++] = &dbLayerInfo[stackedType];
417 
418 	return (int)stackedType;	/* success */
419     }
420     return -1;
421 }
422 
423 /*
424  * ----------------------------------------------------------------------------
425  *
426  * DBPlaneToResidue --
427  *
428  * For the given tile type and plane, return the residue of that type on the
429  * plane.
430  *
431  * Results:
432  *	A tile type.
433  *
434  * Side effects:
435  *	None.
436  *
437  * ----------------------------------------------------------------------------
438  */
439 
440 TileType
DBPlaneToResidue(type,plane)441 DBPlaneToResidue(type, plane)
442     TileType type;
443     int plane;
444 {
445     TileType rt, rt2;
446     LayerInfo *lp = &dbLayerInfo[type], *lr;
447 
448     for (rt = TT_TECHDEPBASE; rt < DBNumUserLayers; rt++)
449 	if (TTMaskHasType(&lp->l_residues, rt))
450 	{
451 	    if (type >= DBNumUserLayers)	/* Stacked type */
452 	    {
453 		lr = &dbLayerInfo[rt];
454 		for (rt2 = TT_TECHDEPBASE; rt2 < DBNumUserLayers; rt2++)
455 		    if (TTMaskHasType(&lr->l_residues, rt2))
456 			if (DBPlane(rt2) == plane)
457 			    return rt2;
458 	    }
459 	    else if (DBPlane(rt) == plane)	/* Normal type */
460 		return rt;
461 	}
462 
463     return TT_SPACE;	/* no residue on plane */
464 }
465 
466 /*
467  * ----------------------------------------------------------------------------
468  *
469  * DBMaskAddStacking ---
470  *
471  * A general-purpose routine to add stacked types containing types that are
472  * already in the mask.
473  *
474  * ----------------------------------------------------------------------------
475  */
476 
477 void
DBMaskAddStacking(mask)478 DBMaskAddStacking(mask)
479     TileTypeBitMask *mask;
480 {
481     TileType ttype;
482     TileTypeBitMask *rMask;
483 
484     for (ttype = DBNumUserLayers; ttype < DBNumTypes; ttype++)
485     {
486 	rMask = DBResidueMask(ttype);
487 	if (TTMaskIntersect(rMask, mask))
488 	    TTMaskSetType(mask, ttype);
489     }
490 }
491 
492 
493 /*
494  * ----------------------------------------------------------------------------
495  *
496  * dbTechContactResidues --
497  *
498  * Process an argc/argv vector of contact residue type names, creating
499  * image types for each, and ensuring that:
500  *	No residue is itself a contact
501  *	One of the residues is on the home plane of contactType.
502  *
503  * Results:
504  *	Returns the number of residues in the contact,
505  *	or -1 in the event of an error.
506  *
507  * Side effects:
508  *	Adds to database of layer types.
509  *
510  * ----------------------------------------------------------------------------
511  */
512 
513 int
dbTechContactResidues(argc,argv,contactType)514 dbTechContactResidues(argc, argv, contactType)
515     int argc;
516     char **argv;
517     TileType contactType;
518 {
519     int       homePlane, residuePlane, nresidues;
520     PlaneMask pMask;
521     TileType  residueType, imageType;
522     bool      residueOnHome;
523     LayerInfo *lp;
524     TileTypeBitMask rmask, mmask;
525 
526     nresidues = 0;
527     pMask = 0;
528     residueOnHome = FALSE;
529 
530     TTMaskZero(&rmask);
531     homePlane = DBPlane(contactType);
532     for ( ; argc > 0; argc--, argv++)
533     {
534 	if ((residueType = DBTechNoisyNameType(*argv)) < 0)
535 	    return -1;
536 
537 	if (IsContact(residueType))
538 	{
539 	    TechError("Residue type %s is a contact itself\n",
540 		DBTypeLongName(residueType));
541 	    return -1;
542 	}
543 
544 	/*
545 	 * Make sure the residue is on the same or an adjacent plane
546 	 * to the contact's home type.
547 	 */
548 	residuePlane = DBPlane(residueType);
549 	if (residuePlane < 0)
550 	{
551 	    TechError("Residue type %s doesn't have a home plane\n",
552 		DBTypeLongName(residueType));
553 	    return -1;
554 	}
555 
556 	/* Enforce a single residue per plane */
557 	if (PlaneMaskHasPlane(pMask, residuePlane))
558 	{
559 	    TechError("Contact residues (%s) must be on different planes\n",
560 		DBTypeLongName(residueType));
561 	    return -1;
562 	}
563 	pMask |= PlaneNumToMaskBit(residuePlane);
564 	if (homePlane == residuePlane)
565 	    residueOnHome = TRUE;
566 
567 	TTMaskSetType(&rmask, residueType);
568     }
569 
570     if (!residueOnHome)
571     {
572 	TechError("Contact type %s missing a residue on its home plane\n",
573 		DBTypeLongName(contactType));
574 	return -1;
575     }
576 
577     /*
578      * See if there are any other contact types with identical residues;
579      * if so, disallow contactType.
580      *
581      * Can this restriction be lifted?  ---Tim 07/24/03
582      * This restriction is partially lifted, as one can create a non-stacked
583      * type such as "pad" having the same residues as one stacked type,
584      * such as "m123c".  Due to the way magic handles stacked types, these
585      * will not be confused.	---Tim 05/11/04
586      *
587      * Restriction entirely lifted 6/18/04.  Error message left as a warning
588      * until it is clear that there are no unwanted side effects of having
589      * two contact types with identical residues.
590      */
591 
592     /* Find if there exists an image with the same residue mask */
593 
594     dbTechMatchResidues(&rmask, &mmask, TRUE);
595 
596     /* Ignore self */
597 
598     TTMaskClearType(&mmask, contactType);
599 
600     if (!TTMaskEqual(&mmask, &DBZeroTypeBits))
601     {
602 	TxPrintf("Contact residues for %s identical to those for ",
603 		DBTypeLongName(contactType));
604 
605 	for (imageType = TT_TECHDEPBASE; imageType < DBNumTypes; imageType++)
606 	    if (TTMaskHasType(&mmask, imageType))
607 		TxPrintf("%s ", DBTypeLongName(imageType));
608 
609 	TxPrintf("\n");
610     }
611 
612     /* All clear to set the residue bitmask for this contact type */
613 
614     lp = &dbLayerInfo[contactType];
615 
616     lp->l_isContact = TRUE;
617     TTMaskSetMask(&lp->l_residues, &rmask);
618     lp->l_pmask = pMask;
619 
620     return nresidues;
621 }
622 
623 /*
624  * ----------------------------------------------------------------------------
625  *
626  * dbTechMatchResidues --
627  *
628  * Find the types whose residues match those of the supplied inMask.
629  *
630  * All this masking about is rather subtle, so pay attention:  Each TYPE
631  * has a RESIDUAL, which for a contact is (generally) the type which surrounds
632  * each contact image on its plane (remember, there is one contact image per
633  * plane contacted).  So when creating the paint/erase tables, we want to
634  * knock out planes from the residual mask of a contact and see if what's
635  * left is another kind of contact.  So from the original contact TYPE, we
636  * make a mask of RESIDUALS, then this routine compares that to the mask
637  * of residuals for all other (contact) types, then create another mask of
638  * all the types which had matching residual masks, and return it.  Grok
639  * that?
640  *
641  * Note that the stacked contact mechanism returns the stacked type where
642  * residues of two types match.  This is required when composing paint
643  * rules for contacts on contacts.
644  *
645  * Results:
646  *	None.
647  *
648  * Side effects:
649  *      Yet another TileType bitmask pointer, outMask, is filled in with
650  *	the matching types.
651  *
652  * ----------------------------------------------------------------------------
653  */
654 
655 void
dbTechMatchResidues(inMask,outMask,contactsOnly)656 dbTechMatchResidues(inMask, outMask, contactsOnly)
657     TileTypeBitMask *inMask, *outMask;
658     bool contactsOnly;
659 {
660     TileType type;
661     LayerInfo *li;
662 
663     TTMaskZero(outMask);
664     for (type = TT_TECHDEPBASE; type < DBNumUserLayers; type++)
665     {
666 	li = &dbLayerInfo[type];
667 	if (!li->l_isContact && contactsOnly)
668 	    continue;
669 
670 	if (TTMaskEqual(inMask, &li->l_residues))
671 	    TTMaskSetType(outMask, type);
672     }
673 }
674 
675 
676 /*
677  * ----------------------------------------------------------------------------
678  * DBTechFindStacking --
679  *
680  *	Find a stacking tile type which connects the two indicated types.
681  * Stacking types have the l_residues field of the LayerInfo entry filled
682  * with the mask of the two types which make up the stacked contact type.
683  *
684  * Results:
685  *	The stacking tile type, if it exists, or -1 if there's no stacking
686  *	type connecting type1 and type2.
687  *
688  * Side effects:
689  *	None.
690  * ----------------------------------------------------------------------------
691  */
692 
693 TileType
DBTechFindStacking(type1,type2)694 DBTechFindStacking(type1, type2)
695     TileType type1, type2;
696 {
697     TileType rtype, rtype1, rtype2, stackType;
698     LayerInfo *li;
699 
700     for (stackType = DBNumUserLayers; stackType < DBNumTypes; stackType++)
701     {
702 	rtype1 = rtype2 = -1;
703 	li = &dbLayerInfo[stackType];
704 	for (rtype = TT_TECHDEPBASE; rtype < DBNumUserLayers; rtype++)
705 	    if (TTMaskHasType(&li->l_residues, rtype))
706 	    {
707 		rtype1 = rtype;
708 		break;
709 	    }
710 	for (++rtype; rtype < DBNumUserLayers; rtype++)
711 	    if (TTMaskHasType(&li->l_residues, rtype))
712 	    {
713 		rtype2 = rtype;
714 		break;
715 	    }
716 
717 	if (((rtype1 == type1) && (rtype2 == type2)) ||
718 		((rtype1 == type2) && (rtype2 == type1)))
719 	    return stackType;
720 
721     }
722     return -1;
723 }
724 
725 /*
726  * ----------------------------------------------------------------------------
727  *
728  * DBTechFinalContact --
729  *
730  * Conclude reading the "contact" section of a technology file.
731  * At this point, all tile types are known so we can call dbTechInitPaint()
732  * to fill in the default paint/erase tables, and dbTechInitMasks() to fill
733  * in the various exported TileTypeBitMasks.
734  *
735  * Results:
736  *	None.
737  *
738  * Side effects:
739  *	Fills in the dbLayerInfo table for non-contacts.
740  *	Sets DBLayerTypeMaskTbl to its final value.
741  *	Initializes DBTypePlaneMaskTbl[] and DBPlaneTypes[].
742  *
743  * ----------------------------------------------------------------------------
744  */
745 
746 void
DBTechFinalContact()747 DBTechFinalContact()
748 {
749     TileType primaryType;
750     LayerInfo *lp;
751     int pNum;
752 
753     /* Fill in plane and residue info for non-contact types */
754 
755     for (primaryType = 0; primaryType < DBNumTypes; primaryType++)
756     {
757 	lp = &dbLayerInfo[primaryType];
758 	pNum = DBPlane(primaryType);
759 	if (!lp->l_isContact && (pNum > 0))
760 	{
761 	    lp->l_pmask = PlaneNumToMaskBit(pNum);
762 	    TTMaskSetOnlyType(&lp->l_residues, primaryType);
763 	}
764     }
765 
766     /*
767      * Initialize the masks of planes on which each type appears.
768      * It will contain all planes (except router) for space,
769      * the home plane for each type up to DBNumTypes, and no
770      * planes for undefined types.  Also update the mask of
771      * types visible on each plane.
772      */
773 
774     DBTypePlaneMaskTbl[TT_SPACE] = ~(PlaneNumToMaskBit(PL_ROUTER));
775     for (primaryType = 0; primaryType < DBNumTypes; primaryType++)
776     {
777 	pNum = DBPlane(primaryType);
778 	if (pNum > 0)
779 	{
780 	    DBTypePlaneMaskTbl[primaryType] = PlaneNumToMaskBit(pNum);
781 	    if (!IsContact(primaryType))
782 		TTMaskSetType(&DBPlaneTypes[pNum], primaryType);
783 	    else
784 	    {
785 		lp = &dbLayerInfo[primaryType];
786 
787 		/* if (primaryType < DBNumUserLayers) */
788 		    DBTypePlaneMaskTbl[primaryType] |= lp->l_pmask;
789 
790 		for (pNum = PL_TECHDEPBASE; pNum < DBNumPlanes; pNum++)
791 		    if (PlaneMaskHasPlane(lp->l_pmask, pNum))
792 			TTMaskSetType(&DBPlaneTypes[pNum], primaryType);
793 	    }
794 	}
795     }
796 
797     /* Create a mask for which each type only appears on one plane.     */
798     /* This is useful for non-redundant searches.                       */
799 
800     for (pNum = 0;  pNum < PL_MAXTYPES;  pNum++)
801 	TTMaskZero(&DBHomePlaneTypes[pNum]);
802 
803     for (primaryType = TT_SPACE + 1; primaryType < DBNumTypes; primaryType++)
804 	TTMaskSetType(&DBHomePlaneTypes[DBPlane(primaryType)], primaryType);
805 }
806 
807 /*
808  * ----------------------------------------------------------------------------
809  * DBTechTypesOnPlane --
810  *
811  * Given a tile type bitmask and a plane index, check if all types in the
812  * bitmask have an image on the indicated plane.
813  *
814  * Results:
815  *	TRUE if all types in "src" have at least one image on plane.
816  *	FALSE if any type in "src" does not contain any image in plane.
817  *
818  * Side effects:
819  *	None.
820  * ----------------------------------------------------------------------------
821  */
822 
823 bool
DBTechTypesOnPlane(src,plane)824 DBTechTypesOnPlane(src, plane)
825     TileTypeBitMask *src;
826     int plane;
827 {
828     int i;
829     PlaneMask pmask;
830 
831     for (i = 0; i < DBNumTypes; i++)
832 	if (TTMaskHasType(src, i))
833 	    if (!PlaneMaskHasPlane(DBTypePlaneMaskTbl[i], plane))
834 		return FALSE;
835 
836     return TRUE;
837 }
838 
839 /*
840  * ----------------------------------------------------------------------------
841  *
842  * DBTechGetContact --
843  *
844  * Given two tile types, determine the corresponding contact type.
845  * (Or rather, for two types, get the first contact type connecting
846  * the two planes on which those types lie. . . not quite the same
847  * thing.)
848  *
849  * Results:
850  *	Returns a contact type.
851  *
852  * Side effects:
853  *	Prints stuff if it can't find a contact type.
854  *
855  * ----------------------------------------------------------------------------
856  */
857 
858 TileType
DBTechGetContact(type1,type2)859 DBTechGetContact(type1, type2)
860     TileType type1, type2;
861 {
862     int pmask;
863     LayerInfo *lp;
864     TileType t;
865 
866     pmask = DBTypePlaneMaskTbl[type1] | DBTypePlaneMaskTbl[type2];
867     for (t = TT_TECHDEPBASE; t < DBNumTypes; t++)
868     {
869 	lp = &dbLayerInfo[t];
870 	if (lp->l_isContact)
871 	    if (lp->l_pmask == pmask)
872 		return t;
873     }
874 
875     TxPrintf("No contact type for %d %d\n", type1, type2);
876     return (TileType) -1;
877 }
878 
879 /*
880  * ----------------------------------------------------------------------------
881  *
882  * DBIsContact --
883  *
884  *   Like IsContact(), except as a subroutine, not a macro.  For export
885  *   to other routines.
886  *
887  * ----------------------------------------------------------------------------
888  */
889 
890 bool
DBIsContact(type)891 DBIsContact(type)
892     TileType type;
893 {
894     if (IsContact(type)) return TRUE;
895     return FALSE;
896 }
897 
898 /*
899  * ----------------------------------------------------------------------------
900  *
901  * DBResidueMask --
902  *
903  *   Get the residue mask of the specified type.  For export to other
904  *   routines.
905  * ----------------------------------------------------------------------------
906  */
907 
908 TileTypeBitMask *
DBResidueMask(type)909 DBResidueMask(type)
910     TileType type;
911 {
912     LayerInfo *li = &dbLayerInfo[type];
913     return (&li->l_residues);
914 }
915 
916 /*
917  * ----------------------------------------------------------------------------
918  *
919  * DBFullResidueMask --
920  *
921  *   Get the residue mask of the specified type.  For stacking contacts,
922  *   decompose the contact residues into their component residue layers.
923  *
924  * Results:
925  *	None.
926  *
927  * Side Effects:
928  *	"rmask" is a pointer to a TileTypeBitMask.  The result is placed
929  *	in this location.
930  * ----------------------------------------------------------------------------
931  */
932 
933 void
DBFullResidueMask(type,rmask)934 DBFullResidueMask(type, rmask)
935     TileType type;
936     TileTypeBitMask *rmask;
937 {
938     TileType t;
939     TileTypeBitMask *lmask;
940     LayerInfo *li, *lr;
941 
942     li = &dbLayerInfo[type];
943     lmask = &li->l_residues;
944     TTMaskZero(rmask);
945 
946     if (type < DBNumUserLayers)
947     {
948 	TTMaskSetMask(rmask, &li->l_residues);
949     }
950     else
951     {
952 	for (t = TT_TECHDEPBASE; t < DBNumUserLayers; t++)
953 	    if (TTMaskHasType(lmask, t))
954 	    {
955 		lr = &dbLayerInfo[t];
956 		TTMaskSetMask(rmask, &lr->l_residues);
957 	    }
958     }
959 }
960 
961 /*
962  * ----------------------------------------------------------------------------
963  *
964  * dbTechPrintContacts --
965  *
966  * DEBUGGING.
967  * Print a list of the contact types to which each possible contact image
968  * belongs.
969  *
970  * Results:
971  *	None.
972  *
973  * Side effects:
974  *	Prints stuff.
975  *
976  * ----------------------------------------------------------------------------
977  */
978 
979 void
dbTechPrintContacts()980 dbTechPrintContacts()
981 {
982     LayerInfo *lpImage;
983     TileType t;
984     int m, pNum;
985 
986     for (m = 0; m < dbNumContacts; m++)
987     {
988 	lpImage = dbContactInfo[m];
989 	TxPrintf("Contact %s (on %s) ",
990 		DBTypeLongName(lpImage->l_type),
991 		DBPlaneLongName(DBPlane(lpImage->l_type)));
992 
993 	TxPrintf(" connects:");
994 	for (t = TT_TECHDEPBASE; t < DBNumTypes; t++)
995 	    if ( TTMaskHasType(&DBConnectTbl[lpImage->l_type], t) )
996 		TxPrintf(" %s", DBTypeLongName(t));
997 
998 	TxPrintf(" planes:");
999 	for ( pNum = PL_TECHDEPBASE; pNum < PL_MAXTYPES; pNum++ )
1000 	    if ( PlaneNumToMaskBit(pNum) & DBConnPlanes[lpImage->l_type] )
1001 		TxPrintf(" %s", DBPlaneLongName(pNum));
1002 
1003 	TxPrintf(" residues:");
1004 	for ( t = TT_TECHDEPBASE; t < DBNumTypes; t++ )
1005 	    if (TTMaskHasType(&lpImage->l_residues, t))
1006 		TxPrintf(" %s on plane %s\n",
1007 				DBTypeLongName(t),
1008 				DBPlaneLongName(DBPlane(t)));
1009 
1010 	TxPrintf("\n");
1011     }
1012 }
1013 
1014