1 /*
2  *   Copyright (C) 1988-1991 Yale University
3  *
4  *   This work is distributed in the hope that it will be useful; you can
5  *   redistribute it and/or modify it under the terms of the
6  *   GNU General Public License as published by the Free Software Foundation;
7  *   either version 2 of the License,
8  *   or any later version, on the following conditions:
9  *
10  *   (a) YALE MAKES NO, AND EXPRESSLY DISCLAIMS
11  *   ALL, REPRESENTATIONS OR WARRANTIES THAT THE MANUFACTURE, USE, PRACTICE,
12  *   SALE OR
13  *   OTHER DISPOSAL OF THE SOFTWARE DOES NOT OR WILL NOT INFRINGE UPON ANY
14  *   PATENT OR
15  *   OTHER RIGHTS NOT VESTED IN YALE.
16  *
17  *   (b) YALE MAKES NO, AND EXPRESSLY DISCLAIMS ALL, REPRESENTATIONS AND
18  *   WARRANTIES
19  *   WHATSOEVER WITH RESPECT TO THE SOFTWARE, EITHER EXPRESS OR IMPLIED,
20  *   INCLUDING,
21  *   BUT NOT LIMITED TO, WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A
22  *   PARTICULAR
23  *   PURPOSE.
24  *
25  *   (c) LICENSEE SHALL MAKE NO STATEMENTS, REPRESENTATION OR WARRANTIES
26  *   WHATSOEVER TO
27  *   ANY THIRD PARTIES THAT ARE INCONSISTENT WITH THE DISCLAIMERS BY YALE IN
28  *   ARTICLE
29  *   (a) AND (b) above.
30  *
31  *   (d) IN NO EVENT SHALL YALE, OR ITS TRUSTEES, DIRECTORS, OFFICERS,
32  *   EMPLOYEES AND
33  *   AFFILIATES BE LIABLE FOR DAMAGES OF ANY KIND, INCLUDING ECONOMIC DAMAGE OR
34  *   INJURY TO PROPERTY AND LOST PROFITS, REGARDLESS OF WHETHER YALE SHALL BE
35  *   ADVISED, SHALL HAVE OTHER REASON TO KNOW, OR IN FACT SHALL KNOW OF THE
36  *   POSSIBILITY OF THE FOREGOING.
37  *
38  */
39 
40 /* -----------------------------------------------------------------
41 FILE:	    outgeo.c
42 DESCRIPTION:Routine dumps the placement of the cells for channel graph
43 	    program.
44 CONTENTS:
45 DATE:	    Jan 30, 1988
46 REVISIONS:  Jul 30, 1988 - made compile switch for blocking pads.
47 	    I need to get cell name for mighty interface.
48 	    Aug 15, 1988 - decide blocking of pads always needed.
49 		eliminated blocking compile switch.  Blocking
50 		avoids channels between pads .
51 	    Jan 15, 1988 - modified output so softcells would work
52 		correctly for compaction.
53 	    Jan 17, 1988 - added dummy macro blocks for pads if
54 		pads don't exist on a side.  This fixes a problem
55 		with the channel graph generator program.
56 	    Mar 03, 1989 - fixed problem with bottom macro.
57 	    Sep 12, 1989 - added new unbust algorithm.
58 	    Sep 16, 1989 - fixed problem with unbust.  Multiple tile
59 		cells should use tile count as argument since tiles
60 		need to be seamed together.
61 	    Sep 19, 1989 - fixed dummy macro block coordinates for
62 		the case of no pads.
63 	    Oct 15, 1989 - now output pad macros are placed at
64 		density using store pad location.
65 	    Sun Dec 16 00:29:59 EST 1990 - now use library version of
66 		buster.
67 	    Wed Jun  5 16:30:30 CDT 1991 - eliminated unbust.
68 ----------------------------------------------------------------- */
69 
70 #include <custom.h>
71 #include <yalecad/debug.h>
72 #include <yalecad/buster.h>
73 #include <yalecad/file.h>
74 #include <yalecad/relpos.h>
75 #include <pads.h>
76 
77 
78 
79 static void store_pad_loc();
80 
81 
82 
83 
outgeo()84 void outgeo()
85 {
86 
87 FILE *fp ;
88 INT cell ;
89 INT l, b, r, t, x , y , xc , yc ;
90 char filename[LRECL] ;
91 CELLBOXPTR cellptr ;
92 BOUNBOXPTR bounptr ;
93 INT padmacroCounter ;
94 INT  left_side, right_side, bottom_side, top_side ;
95 
96 sprintf( filename, "%s.mgeo", cktNameG ) ;
97 fp = TWOPEN( filename , "w", ABORT) ;
98 
99 padmacroCounter = numcellsG ;
100 for( cell = 1 ; cell <= numcellsG ; cell++ ) {
101 
102     cellptr = cellarrayG[cell] ;
103     fprintf(fp,"cell %s \n", cellptr->cname ) ;
104     fprintf(fp,"%d vertices ", cellptr->numsides ) ;
105     output_vertices( fp, cellptr ) ;
106 }
107 
108 /* find core extent in case pads don't exist on a side */
109 find_core_boundary( &left_side, &right_side, &bottom_side, &top_side ) ;
110 
111 /* block all the pads into the four side cells */
112 /* first find left pad macro */
113 l = INT_MAX ;
114 b = INT_MAX ;
115 r = INT_MIN ;
116 t = INT_MIN ;
117 for( cell = endsuperG + 1 ; cell <= numcellsG + numpadsG ; cell++ ) {
118     cellptr = cellarrayG[cell] ;
119     if( cellptr->padptr->padside != L ) {
120 	continue ;
121     }
122     xc = cellptr->xcenter ;
123     yc = cellptr->ycenter ;
124     bounptr = cellptr->bounBox[ cellptr->orient ] ;
125 
126     if( xc + bounptr->l < l ) {
127 	l = xc + bounptr->l ;
128     }
129     if( xc + bounptr->r > r ) {
130 	r = xc + bounptr->r ;
131     }
132     if( yc + bounptr->b < b ) {
133 	b = yc + bounptr->b ;
134     }
135     if( yc + bounptr->t > t ) {
136 	t = yc + bounptr->t ;
137     }
138 }
139 if( t == INT_MIN ) {
140     /* make dummy pads for left */
141     /* use coordinates found from find_core_boundary */
142     l = left_side - 2 * track_spacingXG ;
143     b = bottom_side + 2 * track_spacingYG ;
144     r = left_side - track_spacingXG ;
145     t = top_side - 2 * track_spacingYG ;
146 }
147 fprintf(fp,"cell %s \n", "pad.macro.l" ) ;
148 fprintf(fp,"4 vertices ") ;
149 fprintf(fp," %d %d %d %d %d %d %d %d\n", l, b, l, t, r, t, r, b ) ;
150 setPadMacroNum( L, ++padmacroCounter ) ;
151 cellptr = cellarrayG[endpadgrpsG + L] ;
152 store_pad_loc( cellptr, l, r, b, t ) ;
153 
154 /* find pads on top of core */
155 l = INT_MAX ;
156 b = INT_MAX ;
157 r = INT_MIN ;
158 t = INT_MIN ;
159 for( cell = endsuperG + 1 ; cell <= numcellsG + numpadsG ; cell++ ) {
160     cellptr = cellarrayG[cell] ;
161     if( cellptr->padptr->padside != T ) {
162 	continue ;
163     }
164     xc = cellptr->xcenter ;
165     yc = cellptr->ycenter ;
166     bounptr = cellptr->bounBox[ cellptr->orient ] ;
167 
168     if( xc + bounptr->l < l ) {
169 	l = xc + bounptr->l ;
170     }
171     if( xc + bounptr->r > r ) {
172 	r = xc + bounptr->r ;
173     }
174     if( yc + bounptr->b < b ) {
175 	b = yc + bounptr->b ;
176     }
177     if( yc + bounptr->t > t ) {
178 	t = yc + bounptr->t ;
179     }
180 }
181 if( t == INT_MIN ) {
182     /* make dummy pads for top */
183     l = left_side + 2 * track_spacingXG ;
184     b = top_side + track_spacingYG ;
185     r = right_side - 2 * track_spacingXG ;
186     t = top_side + 2 * track_spacingYG ;
187 }
188 fprintf(fp,"cell %s \n", "pad.macro.t" ) ;
189 fprintf(fp,"4 vertices ") ;
190 fprintf(fp," %d %d %d %d %d %d %d %d\n", l, b, l, t, r, t, r, b ) ;
191 setPadMacroNum( T, ++padmacroCounter ) ;
192 cellptr = cellarrayG[endpadgrpsG + T] ;
193 store_pad_loc( cellptr, l, r, b, t ) ;
194 
195 
196 l = INT_MAX ;
197 b = INT_MAX ;
198 r = INT_MIN ;
199 t = INT_MIN ;
200 for( cell = endsuperG + 1 ; cell <= numcellsG + numpadsG ; cell++ ) {
201     cellptr = cellarrayG[cell] ;
202     if( cellptr->padptr->padside != R ) {
203 	continue ;
204     }
205     xc = cellptr->xcenter ;
206     yc = cellptr->ycenter ;
207     bounptr = cellptr->bounBox[ cellptr->orient ] ;
208 
209     if( xc + bounptr->l < l ) {
210 	l = xc + bounptr->l ;
211     }
212     if( xc + bounptr->r > r ) {
213 	r = xc + bounptr->r ;
214     }
215     if( yc + bounptr->b < b ) {
216 	b = yc + bounptr->b ;
217     }
218     if( yc + bounptr->t > t ) {
219 	t = yc + bounptr->t ;
220     }
221 }
222 if( t == INT_MIN ) {
223     /* make dummy pads for right */
224     l = right_side + track_spacingXG ;
225     b = bottom_side + 2 * track_spacingYG ;
226     r = right_side + 2 * track_spacingXG ;
227     t = top_side - 2 * track_spacingYG ;
228 }
229 fprintf(fp,"cell %s \n", "pad.macro.r" ) ;
230 fprintf(fp,"4 vertices ") ;
231 fprintf(fp," %d %d %d %d %d %d %d %d\n", l, b, l, t, r, t, r, b ) ;
232 setPadMacroNum( R, ++padmacroCounter ) ;
233 cellptr = cellarrayG[endpadgrpsG + R] ;
234 store_pad_loc( cellptr, l, r, b, t ) ;
235 
236 l = INT_MAX ;
237 b = INT_MAX ;
238 r = INT_MIN ;
239 t = INT_MIN ;
240 for( cell = endsuperG + 1 ; cell <= numcellsG + numpadsG ; cell++ ) {
241     cellptr = cellarrayG[cell] ;
242     if( cellptr->padptr->padside != B ) {
243 	continue ;
244     }
245     xc = cellptr->xcenter ;
246     yc = cellptr->ycenter ;
247     bounptr = cellptr->bounBox[ cellptr->orient ] ;
248 
249     if( xc + bounptr->l < l ) {
250 	l = xc + bounptr->l ;
251     }
252     if( xc + bounptr->r > r ) {
253 	r = xc + bounptr->r ;
254     }
255     if( yc + bounptr->b < b ) {
256 	b = yc + bounptr->b ;
257     }
258     if( yc + bounptr->t > t ) {
259 	t = yc + bounptr->t ;
260     }
261 }
262 if( t == INT_MIN ) {
263     /* make dummy pads for bottom */
264     l = left_side + 2 * track_spacingXG ;
265     b = bottom_side - 2 * track_spacingYG ;
266     r = right_side - 2 * track_spacingXG ;
267     t = bottom_side - track_spacingYG ;
268 }
269 fprintf(fp,"cell %s \n", "pad.macro.b" ) ;
270 fprintf(fp,"4 vertices ") ;
271 fprintf(fp," %d %d %d %d %d %d %d %d\n", l, b, l, t, r, t, r, b ) ;
272 setPadMacroNum( B, ++padmacroCounter ) ;
273 cellptr = cellarrayG[endpadgrpsG + B] ;
274 store_pad_loc( cellptr, l, r, b, t ) ;
275 
276 TWCLOSE( fp ) ;
277 return ;
278 
279 } /* end outgeo */
280 
store_pad_loc(cellptr,l,r,b,t)281 static void store_pad_loc( cellptr, l, r, b, t )
282 CELLBOXPTR cellptr ;
283 INT l, r, b, t ;
284 {
285     TILEBOXPTR tptr ;
286 
287     tptr = cellptr->tiles ;
288     cellptr->xcenter = (l + r) / 2 ;
289     cellptr->ycenter = (b + t) / 2 ;
290     tptr->orig_left = tptr->left = l - cellptr->xcenter ;
291     tptr->orig_right = tptr->right = r - cellptr->xcenter ;
292     tptr->orig_bottom = tptr->bottom = b - cellptr->ycenter ;
293     tptr->orig_top = tptr->top = t - cellptr->ycenter ;
294 } /* end static store_pad_loc */
295