1 
2 #ifndef lint
3 static char rcsid[] __attribute__ ((unused)) = "$Header: /usr/cvsroot/magic-8.0/resis/ResJunct.c,v 1.1.1.1 2008/02/03 20:43:50 tim Exp $";
4 #endif  /* not lint */
5 
6 #include <stdio.h>
7 #include <string.h>
8 #include <ctype.h>
9 #include <math.h>
10 
11 #include "utils/magic.h"
12 #include "utils/geometry.h"
13 #include "utils/geofast.h"
14 #include "tiles/tile.h"
15 #include "utils/hash.h"
16 #include "database/database.h"
17 #include "database/databaseInt.h"
18 #include "utils/malloc.h"
19 #include "textio/textio.h"
20 #include "extract/extract.h"
21 #include "extract/extractInt.h"
22 #include "windows/windows.h"
23 #include "dbwind/dbwind.h"
24 #include "utils/stack.h"
25 #include "utils/tech.h"
26 #include "textio/txcommands.h"
27 #include "resis/resis.h"
28 
29 /*
30  *-------------------------------------------------------------------------
31  *
32  * ResNewSDDevice -- called when a device is reached via a piece of
33  *			 diffusion. (Devices  reached via poly, i.e.
34  *			 gates, are handled by ResEachTile.)
35  *
36  * Results:none
37  *
38  * Side Effects: determines to which terminal (source or drain) node
39  * is connected. Makes new node if node hasn't already been created .
40  * Allocates breakpoint in current tile for device.
41  *
42  *-------------------------------------------------------------------------
43  */
44 
45 void
ResNewSDDevice(tile,tp,xj,yj,direction,PendingList)46 ResNewSDDevice(tile, tp, xj, yj, direction, PendingList)
47     Tile 	*tile, *tp;
48     int 	xj, yj, direction;
49     resNode	**PendingList;
50 {
51     resNode	*resptr;
52     resDevice	*resDev;
53     tElement	*tcell;
54     int		newnode;
55     tileJunk	*j;
56 
57     newnode = FALSE;
58     j = (tileJunk *) tp->ti_client;
59     resDev = j->deviceList;
60     if ((j->sourceEdge & direction) != 0)
61     {
62 	if (resDev->rd_fet_source == (resNode *) NULL)
63 	{
64 	    resptr = (resNode *) mallocMagic((unsigned)(sizeof(resNode)));
65 	    newnode = TRUE;
66 	    resDev->rd_fet_source = resptr;
67 	}
68 	else
69 	{
70 	    resptr = resDev->rd_fet_source;
71 	}
72     }
73     else
74     {
75 	if (resDev->rd_fet_drain == (resNode *) NULL)
76 	{
77 	    resptr = (resNode *) mallocMagic((unsigned)(sizeof(resNode)));
78 	    newnode = TRUE;
79 	    resDev->rd_fet_drain = resptr;
80 	}
81 	else
82 	{
83 	    resptr = resDev->rd_fet_drain;
84 	}
85     }
86     if (newnode)
87     {
88 	tcell = (tElement *) mallocMagic((unsigned)(sizeof(tElement)));
89 	tcell->te_nextt = NULL;
90 	tcell->te_thist = j->deviceList;
91 	InitializeNode(resptr, xj, yj, RES_NODE_DEVICE);
92 	resptr->rn_te = tcell;
93 	ResAddToQueue(resptr, PendingList);
94     }
95     NEWBREAK(resptr, tile, xj, yj, NULL);
96 }
97 
98 /*
99  *-------------------------------------------------------------------------
100  *
101  * ResNewSubDevice -- called when a device is reached via a substrate.
102  *
103  * Results:none
104  *
105  * Side Effects: Makes new node if node hasn't already been created.
106  * Allocates breakpoint in current tile for device.
107  *
108  *-------------------------------------------------------------------------
109  */
110 
111 void
ResNewSubDevice(tile,tp,xj,yj,direction,PendingList)112 ResNewSubDevice(tile, tp, xj, yj, direction, PendingList)
113     Tile 	*tile, *tp;
114     int 	xj, yj, direction;
115     resNode	**PendingList;
116 {
117     resNode	*resptr;
118     resDevice	*resDev;
119     tElement	*tcell;
120     int		newnode;
121     tileJunk	*j;
122 
123     newnode = FALSE;
124     j = (tileJunk *) tp->ti_client;
125     resDev = j->deviceList;
126 
127     if (resDev->rd_fet_subs == (resNode *) NULL)
128     {
129 	    resptr = (resNode *) mallocMagic((unsigned)(sizeof(resNode)));
130 	    newnode = TRUE;
131 	    resDev->rd_fet_subs = resptr;
132     }
133     else
134     {
135 	    resptr = resDev->rd_fet_subs;
136     }
137 
138     if (newnode)
139     {
140 	tcell = (tElement *) mallocMagic((unsigned)(sizeof(tElement)));
141 	tcell->te_nextt = NULL;
142 	tcell->te_thist = j->deviceList;
143 	InitializeNode(resptr, xj, yj, RES_NODE_DEVICE);
144 	resptr->rn_te = tcell;
145 	ResAddToQueue(resptr, PendingList);
146     }
147     NEWBREAK(resptr, tile, xj, yj, NULL);
148 }
149 
150 /*
151  *-------------------------------------------------------------------------
152  *
153  * ResProcessJunction-- Called whenever a tile  connecting to the tile being
154  *	worked on is found. If a junction is already present, its address is
155  *      returned. Otherwise, a new junction is made.
156  *
157  * Results: None.
158  *
159  * Side Effects: Junctions may be created.
160  *
161  *-------------------------------------------------------------------------
162  */
163 
164 void
ResProcessJunction(tile,tp,xj,yj,NodeList)165 ResProcessJunction(tile, tp, xj, yj, NodeList)
166     Tile 	*tile, *tp;
167     int		xj, yj;
168     resNode	**NodeList;
169 {
170     ResJunction *junction;
171     resNode	*resptr;
172     jElement    *jcell;
173     tileJunk	*j0 = (tileJunk *)tile->ti_client;
174     tileJunk	*j2 = (tileJunk *)tp->ti_client;
175 
176 #ifdef PARANOID
177     if (tile == tp)
178     {
179 	TxError("Junction being made between tile and itself \n");
180 	return;
181     }
182 #endif
183     if (j2->tj_status & RES_TILE_DONE) return;
184     resptr = (resNode *) mallocMagic((unsigned)(sizeof(resNode)));
185     resptr->rn_te = (tElement *) NULL;
186     junction = (ResJunction *) mallocMagic((unsigned)(sizeof(ResJunction)));
187     jcell = (jElement *) mallocMagic((unsigned)(sizeof(jElement)));
188     InitializeNode(resptr, xj, yj, RES_NODE_JUNCTION);
189     resptr->rn_je = jcell;
190     ResAddToQueue(resptr, NodeList);
191 
192     jcell->je_thisj = junction;
193     jcell->je_nextj = NULL;
194     junction->rj_status = FALSE;
195     junction->rj_jnode = resptr;
196     junction->rj_Tile[0] = tile;
197     junction->rj_Tile[1] = tp;
198     junction->rj_loc.p_x =xj;
199     junction->rj_loc.p_y =yj;
200     junction->rj_nextjunction[0] = j0->junctionList;
201     j0->junctionList = junction;
202     junction->rj_nextjunction[1] = j2->junctionList;
203     j2->junctionList = junction;
204 
205     NEWBREAK(junction->rj_jnode,tile, junction->rj_loc.p_x,
206 		    junction->rj_loc.p_y, NULL);
207 
208     NEWBREAK(junction->rj_jnode,tp, junction->rj_loc.p_x,
209 		    junction->rj_loc.p_y, NULL);
210 
211 }
212