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: fixcell.c
42 DESCRIPTION:places fixed cells in the correct position during a
43 configuration.
44 CONTENTS: updateFixedCells( initializeFlag )
45 BOOL initializeFlag ;
46 update_fixed_record( fptr )
47 FIXEDBOXPTR fptr ;
48 build_active_array()
49 build_soft_array()
50 determine_origin( x, y, left_not_right, bottom_not_top )
51 INT *x, *y ;
52 BOOL *left_non_right, *bottom_not_top ;
53 DATE: Sept 28, 1988
54 REVISIONS: Oct 27, 1988 - modified update fixed cells so that it
55 could handle the following cases: fixed at a point,
56 cell fixed in a neighborhood, group neighborhood
57 fixed at a point, group neighborhood free.
58 Added build_active_array which holds all active core
59 cell including supercells and groupcells to make uloop
60 more efficient.
61 Jan 20, 1989 - added build_soft_array() to make soft pin
62 moves more efficient.
63 Feb 26, 1989 - added determine_origin for graphics interface.
64 Mar 13, 1989 - split updateFixedCells to update_fixed_record
65 to anticipate group cell moves.
66 Apr 27, 1989 - added stdcell to list of active cells.
67 May 10, 1989 - now use the HOWMANYORIENT field for valid
68 orientation calculation.
69 Apr 17, 1990 - added error checking.
70 May 4, 1990 - fixed for standard cell case.
71 Mon Feb 4 02:06:08 EST 1991 - updated determine origin
72 since arguments changed from BOOL to char *.
73 Sun May 5 14:25:12 EDT 1991 - added prototypes. Fixed
74 missing argument to update_fix_record. Fixed error
75 checking.
76 Wed Jul 24 20:43:22 CDT 1991 - added delete function
77 for fixing cells.
78 ----------------------------------------------------------------- */
79
80 #include <string.h>
81 #include <custom.h>
82 #include <yalecad/base.h>
83 #include <yalecad/debug.h>
84
85
86 /* defined routes for error checking */
87 VOID updateFixedCells( P1(BOOL initializeFlag) ) ;
88 static VOID update_fixed_record( P3(CELLBOXPTR ptr,FIXEDBOXPTR fptr,
89 BOOL initFlag ) ) ;
90 VOID init_fixcell( P4(INT left, INT bottom, INT right, INT top ) ) ;
91 VOID build_active_array() ;
92 VOID build_soft_array() ;
93 VOID determine_origin( P4(INT *x, INT *y,
94 char *left_not_right, char *bottom_not_top ) ) ;
95
96 static INT initialS = FALSE ;
97 static INT newxspanS ;
98 static INT newyspanS ;
99 static INT oldxspanS ;
100 static INT oldyspanS ;
101
updateFixedCells(BOOL initializeFlag)102 VOID updateFixedCells( BOOL initializeFlag )
103 {
104
105 INT i ;
106 CELLBOXPTR ptr ;
107 FIXEDBOXPTR fptr ;
108
109 /* calculate new span of the core region */
110 newxspanS = blockrG - blocklG ;
111 newyspanS = blocktG - blockbG ;
112
113 /* update positions of fixed cells */
114 for( i=1;i<=endsuperG;i++ ){
115 ptr = cellarrayG[i] ;
116 /* for core cells check fixed record */
117 /* for group cells check group record */
118 if( ptr->celltype == GROUPCELLTYPE ){
119 ASSERTNCONT( ptr->group, "updateFixedCells", "pointer null");
120 fptr = ptr->group->fixed ;
121 } else {
122 fptr = ptr->fixed ;
123 }
124 update_fixed_record( ptr, fptr, initializeFlag ) ;
125
126 if( initializeFlag && ptr->celltype == GROUPCELLTYPE ){
127 /* now we can add tiles to group */
128 initializeCorner( i ) ;
129 addCorner( fptr->x1, fptr->y1 ) ; /* lower left */
130 addCorner( fptr->x1, fptr->y2 ) ; /* upper left */
131 addCorner( fptr->x2, fptr->y2 ) ; /* upper right */
132 addCorner( fptr->x2, fptr->y1 ) ; /* lower right */
133 processCorners( 4 ) ;
134 }
135 }
136 } /* end updateFixCells */
137
138 /* update all the variables in the fixed box record - that is the */
139 /* the neighborhood and/or the center of the cell for a fixed point */
update_fixed_record(ptr,fptr,initFlag)140 static VOID update_fixed_record( ptr, fptr, initFlag )
141 CELLBOXPTR ptr ;
142 FIXEDBOXPTR fptr ;
143 BOOL initFlag ;
144 {
145 INT x1, x2, y1, y2 ;
146 BOOL error_flag = FALSE ;
147 DOUBLE temp ;
148
149 if( fptr ){
150 D( "update_fixed_record",
151 fprintf( stderr, "cell:%s\n", ptr->cname ) ;
152 fprintf( stderr, "\tinitialS:%d\n", initialS ) ;
153 fprintf( stderr, "\toldxspanS:%d ", oldxspanS ) ;
154 fprintf( stderr, "\toldyspanS:%d\n", oldyspanS ) ;
155 fprintf( stderr, "\tnewxspanS:%d ", newxspanS ) ;
156 fprintf( stderr, "\tnewyspanS:%d\n", newyspanS ) ;
157 fprintf( stderr, "\txc:%d yc:%d x1:%d y1:%d x2:%d y2:%d\n",
158 fptr->xcenter, fptr->ycenter,
159 fptr->xloc1,fptr->yloc1,fptr->xloc2,fptr->yloc2 ) ;
160 fprintf( stderr, "\tx1:%d y1:%d x2:%d y2:%d\n",
161 fptr->leftNotRight,fptr->bottomNotTop,
162 fptr->leftNotRight2,fptr->bottomNotTop2 ) ;
163 ) ; /* end debug macro */
164
165 if( fptr->fixedType != POINTFLAG ){
166 if( initialS ){
167 /* get two points of neighborhood */
168 /* POINT ONE */
169 temp = (DOUBLE) fptr->xloc1 / oldxspanS * newxspanS ;
170 if( fptr->leftNotRight ){
171 /* from left edge */
172 x1 = blocklG + (INT) temp ;
173 } else {
174 /* from right edge = blockx */
175 x1 = blockrG - (INT) temp ;
176 }
177 temp = (DOUBLE) fptr->yloc1 / oldyspanS * newyspanS ;
178 if( fptr->bottomNotTop ){
179 /* from bottom edge = 0 */
180 y1 = blockbG + (INT) temp ;
181 } else {
182 /* from top edge = blocky */
183 y1 = blocktG - (INT) temp ;
184 }
185 /* POINT TWO */
186 temp = (DOUBLE) fptr->xloc2 / oldxspanS * newxspanS ;
187 if( fptr->leftNotRight2 ){
188 /* from left edge */
189 x2 = blocklG + (INT) temp ;
190 } else {
191 /* from right edge = blockx */
192 x2 = blockrG - (INT) temp ;
193 }
194 temp = (DOUBLE) fptr->yloc2 / oldyspanS * newyspanS ;
195 if( fptr->bottomNotTop2 ){
196 /* from bottom edge = 0 */
197 y2 = blockbG + (INT) temp ;
198 } else {
199 /* from top edge = blocky */
200 y2 = blocktG - (INT) temp ;
201 }
202 } else {
203 /* get two points of neighborhood */
204 /* POINT ONE */
205 if( fptr->leftNotRight ){
206 /* from left edge */
207 x1 = blocklG + fptr->xloc1 ;
208 } else {
209 /* from right edge = blockx */
210 x1 = blockrG - fptr->xloc1 ;
211 }
212 if( fptr->bottomNotTop ){
213 /* from bottom edge = 0 */
214 y1 = blockbG + fptr->yloc1 ;
215 } else {
216 /* from top edge = blocky */
217 y1 = blocktG - fptr->yloc1 ;
218 }
219 /* POINT TWO */
220 if( fptr->leftNotRight2 ){
221 /* from left edge */
222 x2 = blocklG + fptr->xloc2 ;
223 } else {
224 /* from right edge = blockx */
225 x2 = blockrG - fptr->xloc2 ;
226 }
227 if( fptr->bottomNotTop2 ){
228 /* from bottom edge = 0 */
229 y2 = blockbG + fptr->yloc2 ;
230 } else {
231 /* from top edge = blocky */
232 y2 = blocktG - fptr->yloc2 ;
233 }
234 }
235 /* sort points */
236 fptr->x1 = MIN( x1, x2 ) ;
237 fptr->x2 = MAX( x1, x2 ) ;
238 fptr->y1 = MIN( y1, y2 ) ;
239 fptr->y2 = MAX( y1, y2 ) ;
240 if(!(initFlag)){
241 /* check to make sure neighborhood is inside core */
242 if( fptr->x1 < blocklG ){
243 if( iterationG >= 2 ) fptr->x1 = blocklG ;
244 error_flag = TRUE ;
245 }
246 if( fptr->x1 > blockrG ){
247 if( iterationG >= 2 ) fptr->x1 = blockrG ;
248 error_flag = TRUE ;
249 }
250 if( fptr->x2 < blocklG ){
251 if( iterationG >= 2 ) fptr->x2 = blocklG ;
252 error_flag = TRUE ;
253 }
254 if( fptr->x2 > blockrG ){
255 if( iterationG >= 2 ) fptr->x2 = blockrG ;
256 error_flag = TRUE ;
257 }
258 if( fptr->y1 < blockbG ){
259 if( iterationG >= 2 ) fptr->y1 = blockbG ;
260 error_flag = TRUE ;
261 }
262 if( fptr->y1 > blocktG ){
263 if( iterationG >= 2 ) fptr->y1 = blocktG ;
264 error_flag = TRUE ;
265 }
266 if( fptr->y2 < blockbG ){
267 if( iterationG >= 2 ) fptr->y2 = blockbG ;
268 error_flag = TRUE ;
269 }
270 if( fptr->y2 > blocktG ){
271 if( iterationG >= 2 ) fptr->y2 = blocktG ;
272 error_flag = TRUE ;
273 }
274 }
275
276 /* now perform calculations for speed */
277 fptr->xcenter = (fptr->x1 + fptr->x2) / 2 ;
278 fptr->ycenter = (fptr->y1 + fptr->y2) / 2 ;
279 fptr->xspan = ABS(fptr->x1 - fptr->x2) ;
280 fptr->yspan = ABS(fptr->y1 - fptr->y2) ;
281
282 if( error_flag ){
283 sprintf( YmsgG, "cell:%s neighborhood larger than core\n",
284 ptr->cname ) ;
285
286 M( WARNMSG,"update_fixed_cells", YmsgG ) ;
287
288 if( iterationG >= 2 ){
289 /* we can't do anything with this constraint */
290 /* throw it out */
291 if( ptr->celltype == GROUPCELLTYPE ){
292 fptr = ptr->group->fixed ;
293 Ysafe_free( fptr ) ;
294 ptr->group->fixed = NIL(FIXEDBOXPTR) ;
295 } else {
296 fptr = ptr->fixed ;
297 Ysafe_free( fptr ) ;
298 ptr->fixed = NIL(FIXEDBOXPTR) ;
299 }
300 M( WARNMSG,NULL,"\tconstraint ignored...\n" ) ;
301 }
302 }
303
304 } else { /* cell is fixed at a point */
305 if( initialS ){
306 temp = (DOUBLE) fptr->xcenter / oldxspanS * newxspanS ;
307 if( fptr->leftNotRight ){
308 /* from left edge */
309 ptr->xcenter = blocklG + (INT) temp ;
310 } else {
311 /* from right edge = blockx */
312 ptr->xcenter = blockrG - (INT) temp ;
313 }
314 if( fptr->bottomNotTop ){
315 /* from bottom edge = 0 */
316 ptr->ycenter = blockbG + fptr->ycenter ;
317 } else {
318 /* from top edge = blocky */
319 ptr->ycenter = blocktG - fptr->ycenter ;
320 }
321 } else {
322 if( fptr->leftNotRight ){
323 /* from left edge */
324 ptr->xcenter = blocklG + fptr->xcenter ;
325 } else {
326 /* from right edge = blockx */
327 ptr->xcenter = blockrG - fptr->xcenter ;
328 }
329 if( fptr->bottomNotTop ){
330 /* from bottom edge = 0 */
331 ptr->ycenter = blockbG + fptr->ycenter ;
332 } else {
333 /* from top edge = blocky */
334 ptr->ycenter = blocktG - fptr->ycenter ;
335 }
336 }
337 if(!(initFlag)){
338 /* now perform error checking to make sure inside core */
339 if( ptr->xcenter < blocklG ){
340 if( iterationG >= 2 ) ptr->xcenter = blocklG ;
341 error_flag = TRUE ;
342 }
343 if( ptr->xcenter > blockrG ){
344 if( iterationG >= 2 ) ptr->xcenter = blockrG ;
345 error_flag = TRUE ;
346 }
347 if( ptr->ycenter < blockbG ){
348 if( iterationG >= 2 ) ptr->ycenter = blockbG ;
349 error_flag = TRUE ;
350 }
351 if( ptr->ycenter > blockrG ){
352 if( iterationG >= 2 ) ptr->ycenter = blockrG ;
353 error_flag = TRUE ;
354 }
355 }
356 if( error_flag ){
357 sprintf( YmsgG, "cell:%s fix point larger than core\n",
358 ptr->cname ) ;
359
360 M( WARNMSG,"update_fixed_cells", YmsgG ) ;
361
362 if( iterationG >= 2 ){
363 /* we can't do anything with this constraint */
364 /* throw it out */
365 if( ptr->celltype == GROUPCELLTYPE ){
366 fptr = ptr->group->fixed ;
367 Ysafe_free( fptr ) ;
368 ptr->group->fixed = NIL(FIXEDBOXPTR) ;
369 } else {
370 fptr = ptr->fixed ;
371 Ysafe_free( fptr ) ;
372 ptr->fixed = NIL(FIXEDBOXPTR) ;
373 }
374 M( WARNMSG,NULL,"\tconstraint ignored...\n" ) ;
375 }
376 }
377 }
378 } /* end for loop */
379 } /* end function update_fixed_record */
380
init_fixcell(left,bottom,right,top)381 VOID init_fixcell( left, bottom, right, top )
382 INT left, bottom, right, top ;
383 {
384 initialS = TRUE ;
385 oldxspanS = right - left ;
386 oldyspanS = top - bottom ;
387 if( oldxspanS <= 0 ){
388 M( ERRMSG, "init_fixcell", "initial x core span <= 0\n" ) ;
389 initialS = FALSE ;
390 }
391 if( oldyspanS <= 0 ){
392 M( ERRMSG, "init_fixcell", "initial y core span <= 0\n" ) ;
393 initialS = FALSE ;
394 }
395 } /* end init_fixcell */
396
397 /* build active cell list from cells that aren't fixed */
398 VOID
build_active_array()399 build_active_array()
400 {
401 INT i, cell ;
402 CELLBOXPTR cptr ;
403
404 /* first determine number of active cells */
405 activecellsG = 0 ;
406 for( i=1;i<=totalcellsG;i++ ){
407 cptr = cellarrayG[i] ;
408 if( cptr->fixed ){
409 if( cptr->celltype == CUSTOMCELLTYPE ||
410 cptr->celltype == SOFTCELLTYPE ||
411 cptr->celltype == STDCELLTYPE ){
412 /* must check to orientations are all fixed also */
413 if( cptr->orientList[HOWMANYORIENT] >= 2 ){
414 /* cell is not totally inactive it may rotate */
415 activecellsG++ ;
416 }
417 }
418
419 } else if( cptr->celltype == CUSTOMCELLTYPE ||
420 cptr->celltype == SOFTCELLTYPE ||
421 cptr->celltype == SUPERCELLTYPE ||
422 cptr->celltype == STDCELLTYPE ||
423 cptr->celltype == GROUPCELLTYPE ){
424 activecellsG++ ;
425 }
426 }
427 /* now build array */
428 activeCellarrayG = (CELLBOXPTR *)
429 Ysafe_malloc( (activecellsG+1) * sizeof(CELLBOXPTR) ) ;
430 /* now loop again filling in array */
431 cell = 0 ;
432 for( i=1;i<=totalcellsG;i++ ){
433 cptr = cellarrayG[i] ;
434 if( cptr->fixed ){
435 if( cptr->celltype == CUSTOMCELLTYPE ||
436 cptr->celltype == SOFTCELLTYPE ||
437 cptr->celltype == STDCELLTYPE ){
438 if( cptr->orientList[HOWMANYORIENT] >= 2 ){
439 /* cell is not totally inactive it may rotate */
440 activeCellarrayG[++cell] = cptr ;
441 }
442 }
443
444 } else if( cptr->celltype == CUSTOMCELLTYPE ||
445 cptr->celltype == SOFTCELLTYPE ||
446 cptr->celltype == SUPERCELLTYPE ||
447 cptr->celltype == STDCELLTYPE ||
448 cptr->celltype == GROUPCELLTYPE ){
449 activeCellarrayG[++cell] = cptr ;
450 }
451 }
452 ASSERT( cell == activecellsG,"build_active_array",
453 "Problem with count" ) ;
454
455 } /* end build_active_array */
456
457 /* build softPinArrayG so that soft pin moves are more efficient */
458 /* softPinArray will contain the cellptrs of all softcells which */
459 /* have pins that can move. The zeroth element will contain howmany */
460 VOID
build_soft_array()461 build_soft_array()
462 {
463
464 #define HOWMANY 0 /* this tells the size of the array */
465
466 INT i, cell ;
467 CELLBOXPTR cptr ;
468 INT softPins ;
469
470 softPins = 0 ;
471 if( numsoftG > 0 || numstdcellG > 0 ){
472 /* first determine number of softcell with uncommitted pins */
473 for( i=1;i<=totalcellsG;i++ ){
474 cptr = cellarrayG[i] ;
475 if( cptr->celltype == SOFTCELLTYPE ||
476 cptr->celltype == STDCELLTYPE ){
477 if( cptr->numpins > 0 ){
478 softPins++ ;
479 }
480 }
481 }
482
483 /* now build array */
484 softPinArrayG = (CELLBOXPTR *)
485 Ysafe_malloc( (softPins+1) * sizeof(CELLBOXPTR) ) ;
486 /* now loop again filling in array */
487 cell = 0 ;
488 for( i=1;i<=totalcellsG;i++ ){
489 cptr = cellarrayG[i] ;
490 if( cptr->celltype == SOFTCELLTYPE ||
491 cptr->celltype == STDCELLTYPE ){
492 if( cptr->numpins > 0 ){
493 softPinArrayG[++cell] = cptr ;
494 }
495 }
496 }
497 ASSERT( cell == softPins,"build_soft_array",
498 "Problem with count" ) ;
499 softPinArrayG[HOWMANY] = (CELLBOXPTR) softPins ;
500
501 } else {
502 softPinArrayG = (CELLBOXPTR *) Ysafe_malloc( sizeof(CELLBOXPTR) ) ;
503 softPinArrayG[HOWMANY] = (CELLBOXPTR) softPins ; /* zero */
504 }
505
506 } /* end build_soft_array */
507
508 /* In fixing a cell, determine which side of the core to reference */
509 /* cell so that changes to the position of the cell due to core size */
510 /* changes will be minimized. */
determine_origin(INT * x,INT * y,char * left_not_right,char * bottom_not_top)511 VOID determine_origin( INT *x, INT *y, char *left_not_right, char *bottom_not_top )
512 //INT *x, *y ; /* point of reference */
513 {
514 if( *x <= blockmxG ){
515 strcpy( left_not_right, "L" ) ;
516 } else {
517 strcpy( left_not_right, "R" ) ;
518 /* reference to right side need to change x coordinate */
519 *x = blockrG - *x ;
520 }
521 if( *y <= blockmyG ){
522 strcpy( bottom_not_top, "B" ) ;
523 } else {
524 strcpy( bottom_not_top, "T" ) ;
525 /* reference to top side need to change x coordinate */
526 *y = blocktG - *y ;
527 }
528 } /* end determine_origin */
529
delete_fix_constraint(cell)530 void delete_fix_constraint( cell )
531 INT cell ;
532 {
533 CELLBOXPTR ptr ;
534
535 ptr = cellarrayG[cell] ;
536 if( ptr->fixed != (FIXEDBOXPTR)NULL ){
537 Ysafe_free(ptr->fixed) ;
538 }
539 ptr->fixed = NIL(FIXEDBOXPTR) ;
540 ptr->class = 0 ;
541 } /* end delete_fix_constraint */
542