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: initialize.c
42 DESCRIPTION:This file contains the utility routines called from the
43 parser to set up the TimberWolfMC data structures.
44 CONTENTS:
45 setErrorFlag()
46 DATE: Aug 7, 1988
47 REVISIONS: Oct 27, 1988 - added add_cell_to_group, initializeCorner
48 and modified fixCell in order to handle group cells.
49 Jan 20, 1989 - added build_soft_array call.
50 Jan 29, 1989 - changed msg to YmsgG and added \n's.
51 Feb 28, 1989 - added initialization to tile weights.
52 Mar 7, 1989 - added cell instances.
53 - added cell hash table for instance names.
54 Apr 5, 1989 - added multiple tiles for softcells and
55 added instance handling. Instances are handled by
56 disturbing routines as little as possible and using
57 pointer swaps to switch in a new instance as much as
58 possible.
59 Apr 9, 1989 - added sortpin to cleanupCells for incremental
60 bounding box scheme.
61 Apr 30, 1989 - changed exchange class for group cells.
62 - fixed problem with pad group children.
63 May 1, 1989 - orient the pads correctly.
64 May 11, 1989 - now use the orientList[HOWMANYORIENT] to
65 specify the number of valid orientations.
66 May 12, 1989 - added layer information.
67 May 25, 1989 - changed tiles list to FIFO from LIFO for
68 cell gridding..
69 Jul 19, 1989 - added numstdcells to save work for partition case
70 with no hard or soft cells.
71 Sep 29, 1989 - remove max tile limit by making dynamic.
72 Oct 18, 1989 - Added tile to pad macros for density calc.
73 Apr 15, 1990 - Modified cur_inst fields. Added vertices
74 fields to cell box for placing pins. Moved pintype
75 field to PINBOX from SOFTBOX. Made fixed field of
76 GROUPBOX a pointer.
77 Apr 17, 1990 - added load_soft_pins which verifies
78 user input and correctly sets up wire estimator.
79 Apr 23, 1990 - now handle pingroup instances and also
80 fixed wire area estimator for instances by looking
81 at all instances when calculating the perimeter.
82 Apr 26, 1990 - distinguish arbitrarily assigned layer
83 information using negative numbers.
84 May 2, 1990 - Now all pins on softcells have softinfo
85 records to avoid access violations. Added error
86 checking to processCorners to catch points not entered
87 in a CW fashion.
88 Jun 21, 1990 - moved the location of genorient so that
89 the pins will be in the correct orientation before the
90 check.
91 Oct 1, 1990 - updated analog input data structures.
92 Sun Dec 16 00:38:44 EST 1990 - reworked analog data
93 structures and added check for rectilinear pins.
94 Tue Dec 18 01:29:30 EST 1990 - make sure the buster
95 check error messages go to screen properly.
96 Wed Dec 19 23:58:12 EST 1990 - added check_pos.
97 Dec 21, 1990 - added set_pin_pos and rewrote addPin
98 to make pins more general.
99 Thu Jan 17 00:55:28 PST 1991 - added numpins initialization.
100 Wed Jan 23 14:42:30 PST 1991 - added findsidestr in order
101 to make language context free.
102 Fri Jan 25 18:05:56 PST 1991 - now scale data correctly.
103 Wed Jan 30 14:13:36 EST 1991 - now left justify orientation
104 rotations.
105 Mon Feb 4 02:10:28 EST 1991 - made changes to make new pin
106 placement code work and fixed numsides bug.
107 Wed Feb 13 23:52:38 EST 1991 - modified for new pad code.
108 Sat Feb 23 00:21:10 EST 1991 - updated for new pad placement
109 code.
110 Thu Apr 18 01:34:59 EDT 1991 - added more error checking
111 and fixed problem with initial orientation.
112 Sat Apr 27 01:15:05 EDT 1991 - now detect doPartition case
113 automatically.
114 Thu Aug 22 22:10:09 CDT 1991 - fixed problem with
115 fixed cells moving during pairwise flips.
116 Fri Oct 18 00:06:37 EDT 1991 - moved buster code to library
117 and updated for new NIL definition.
118 ----------------------------------------------------------------- */
119
120 #include <string.h>
121 #include <custom.h>
122 #include <pads.h>
123 #include <analog.h>
124 #include <initialize.h>
125 #include <yalecad/buster.h>
126 #include <yalecad/hash.h>
127 #include <yalecad/debug.h>
128 #include <yalecad/string.h>
129 #include <findside.h>
130
131
132 /* below is what we expect to be a large floorplanning input */
133 /* user may change parameters if they wish. Subject to change */
134 #define EXPECTEDNUMCELLS 500
135 #define EXPECTEDNUMNETS 1000
136 #define EXPECTEDNUMUNCON 100
137 #define EXPECTEDNUMPADS 10
138 #define EXPECTEDCORNERS 8
139 #define EXPECTEDINSTANCES 1
140 #define EXPECTEDPINGRP 1
141
142 #define PIN (BOOL) TRUE /* for pinFlag below */
143 #define EQUIV (BOOL) FALSE
144 #define NUMPADMACROS 4 /* there are always 4 pad macros */
145 #define INITIALIZE (BOOL) TRUE /* for updateFixedCells */
146
147 /* ERRORABORT is a macro which forces routines not to do any work */
148 /* when we find a syntax error in the input routine. */
149 #define ERRORABORT() \
150 { \
151 if( errorFlagS ){ \
152 return ; /* don't do any work for errors */ \
153 } \
154 } \
155
156 #define ERRORABORTINT() \
157 { \
158 if( errorFlagS ){ \
159 return -1; /* don't do any work for errors */ \
160 } \
161 } \
162
163 /* ###################### STATIC definitions ######################### */
164 static INT curCellTypeS ; /* current cell type - ie, softcell,pad etc.*/
165 static INT cellinstanceS ; /* number of instances of current cell */
166 static INT cornerCountS ; /* current number of corners */
167 static INT tileptAllocS ; /* allocation allotted to tile structures */
168 static INT xcenterS, ycenterS ;/* current cell center coordinates */
169 static INT minxS, minyS ; /* bounding box of current cell */
170 static INT maxxS, maxyS ; /* bounding box of current cell */
171 static INT totPinS ; /* total number of pins over all instances */
172 static INT netAllocS ; /* current space in netarray */
173 static INT cellAllocS ; /* current space in cellarray */
174 static INT childAllocS ; /* current space in current pptr->children */
175 static INT instAllocS ; /* current number of instance allocated */
176 static INT equivpinS ; /* total number of equivs for the current pin */
177 static INT totxS, totyS ; /* counters for equiv pin postions */
178 static INT numchildrenS ; /* # of children in current pad or pingroup */
179 static INT numpingroupS ; /* # of pingroups for this cell */
180 static INT cur_restrict_objS ; /* set by set_restrict type */
181 static char *curCellNameS ; /* current cell name */
182 static char *curPinNameS ; /* current pin name */
183 static BOOL portFlagS ; /* tells whether port(TRUE) or not(FALSE) */
184 static BOOL errorFlagS ; /* switch allow us to find multiple errors */
185 static BOOL analog_errorS ; /* whether an analog error occurs */
186 static DOUBLE scaleS ; /* how to scale the data */
187 static CELLBOXPTR ptrS ; /* pointer to current cell box */
188 static PADBOXPTR pptrS ; /* pointer to current pad box */
189 static YBUSTBOXPTR cornerArrayS;/* holds array of pts for cell boundary */
190 static YHASHPTR netTableS ; /* hash table for cross referencing nets */
191 static YHASHPTR cellTableS ; /* hash table for referencing cells */
192 static PSIDEBOX *pSideArrayS;/* used to calc the side weighs of cell */
193 static KBOXPTR kArrayS ; /* used in making sides for softpins */
194 static GROUPBOXPTR curGroupS ; /* pointer to current group record */
195 static PINBOXPTR pinS ; /* current active pin of cell */
196 static PINBOXPTR softpinS ; /* current active softpin of cell */
197 static PINBOXPTR pingroupS ; /* current pin group record */
198 static ANALOGPTR analogS ; /* current analog record */
199 static SOFTBOXPTR spinptrS ; /* current softpin record */
200 static INSTBOXPTR instS ; /* pointer to current inst record */
201 PINBOXPTR findTerminal() ;
202 /* ################## END STATIC definitions ########################## */
203
204
205
206 static void check_pos();
207
208
209
210 /* set processing switch to avoid work when an error is found */
setErrorFlag()211 void setErrorFlag()
212 {
213 errorFlagS = TRUE ;
214 } /* end setErrorFlag */
215 /* ***************************************************************** */
216
217 /* return the net hash table */
getNetTable()218 YHASHPTR getNetTable()
219 {
220 return( netTableS ) ;
221 } /* end getNetTable */
222 /* ***************************************************************** */
223
224 /* initialize global and static information */
initCellInfo()225 void initCellInfo()
226 {
227 numcellsG = 0 ;
228 numnetsG = 0 ;
229 numsoftG = 0 ;
230 numstdcellG = 0 ;
231 numpadsG = 0 ;
232 numpadgroupsG = 0 ;
233 numsupercellsG = 0 ;
234 numinstancesG = 0 ;
235 numpinsG = 0 ;
236 totalcellsG = 0 ;
237 totalpadsG = 0 ;
238 errorFlagS = FALSE ;
239 analog_errorS = FALSE ;
240 totPinS = 0 ;
241 unique_classG = 0 ;
242 net_cap_matchG = NIL(INT **) ;
243 net_res_matchG = NIL(INT **) ;
244 scaleS = (DOUBLE) scale_dataG ;
245 cornerCountS = 0 ;
246 tileptAllocS = EXPECTEDCORNERS ;
247 cornerArrayS = ( YBUSTBOXPTR )
248 Ysafe_malloc( tileptAllocS * sizeof( YBUSTBOX ) );
249 pSideArrayS = (PSIDEBOX *) Ysafe_malloc( tileptAllocS * sizeof( PSIDEBOX ) ) ;
250 kArrayS = (KBOXPTR) Ysafe_calloc( (MAXSITES + 1), sizeof( KBOX ));
251 /* make hash table for nets */
252 netTableS = Yhash_table_create( EXPECTEDNUMNETS ) ;
253 /* make hash table for cells */
254 cellTableS = Yhash_table_create( EXPECTEDNUMCELLS ) ;
255 netAllocS = EXPECTEDNUMNETS ;
256 netarrayG = (NETBOXPTR *) Ysafe_malloc( netAllocS * sizeof(NETBOXPTR));
257 cellAllocS = EXPECTEDNUMCELLS ;
258 cellarrayG = (CELLBOXPTR *)Ysafe_malloc(cellAllocS*sizeof(CELLBOXPTR));
259 } /* end initCellInfo */
260 /* ***************************************************************** */
261
262 /* cleanup operations at the end of readcells */
cleanupReadCells()263 void cleanupReadCells()
264 {
265 INT cell ; /* cell counter */
266 PADBOXPTR padptr ; /* current pad */
267 CELLBOXPTR ptr ; /* current pad cell */
268
269 if( errorFlagS || analog_errorS ){
270 /* we found all our syntax errors so abort */
271 closegraphics() ;
272 YexitPgm( FAIL ) ;
273 }
274
275 /* the last cells - create pad macros for channel graph generator */
276 addCell("pad.macro.l",PADMACROTYPE ) ;
277 /* add a tile for processing borders */
278 ptrS->tiles = (TILEBOXPTR) Ysafe_calloc( 1, sizeof(TILEBOX) ) ;
279 endCell() ;
280 addCell("pad.macro.t",PADMACROTYPE ) ;
281 /* add a tile for processing borders */
282 ptrS->tiles = (TILEBOXPTR) Ysafe_calloc( 1, sizeof(TILEBOX) ) ;
283 endCell() ;
284 addCell("pad.macro.r",PADMACROTYPE ) ;
285 /* add a tile for processing borders */
286 ptrS->tiles = (TILEBOXPTR) Ysafe_calloc( 1, sizeof(TILEBOX) ) ;
287 endCell() ;
288 addCell("pad.macro.b",PADMACROTYPE ) ;
289 /* add a tile for processing borders */
290 ptrS->tiles = (TILEBOXPTR) Ysafe_calloc( 1, sizeof(TILEBOX) ) ;
291 endCell() ;
292
293 /* reallocate arrays to correct size */
294 netarrayG = (NETBOXPTR *)
295 Ysafe_realloc( netarrayG, (numnetsG+1) * sizeof(NETBOXPTR) ) ;
296 /* allocate and initialize terminal array */
297 termarrayG = (PINBOXPTR *)
298 Ysafe_calloc( (numpinsG + 1), sizeof( PINBOXPTR ) );
299 /* now trim cellarray to proper size */
300 endsuperG = numcellsG + numsupercellsG ;
301 endpadsG = endsuperG + numpadsG ;
302 endpadgrpsG = endpadsG + numpadgroupsG ;
303 ASSERT( totalcellsG == endpadgrpsG+NUMPADMACROS,"cleanupReadCells",
304 "cells don't add up" ) ;
305 cellarrayG = (CELLBOXPTR *)
306 Ysafe_realloc( cellarrayG,(totalcellsG+1)* sizeof(CELLBOXPTR) ) ;
307
308 /* build the pad arrays */
309 padarrayG = (PADBOXPTR *) Yvector_alloc(1,totalpadsG,sizeof(PADBOXPTR)) ;
310 sortarrayG = (PADBOXPTR *) Yvector_alloc(1,totalpadsG,sizeof(PADBOXPTR));
311 placearrayG = (PADBOXPTR *) Yvector_alloc( 1,numpadsG,sizeof(PADBOXPTR)) ;
312 for( cell = 1; cell <= totalpadsG; cell++ ){
313 ptr = cellarrayG[endsuperG + cell] ;
314 padptr = ptr->padptr ;
315 sortarrayG[cell] = padarrayG[cell] = padptr ;
316 if( padptr->padtype == PADCELLTYPE ){
317 placearrayG[cell] = padptr ;
318 }
319 }
320
321 /* set loop index range variables for cellarray */
322 pinsPerLenG = (DOUBLE) totPinS / (DOUBLE) perimG ;
323 setpwates() ;
324 sortpins() ;
325 prnt_netinfo() ; /* tell user net information */
326 genorient(1,endpadsG ) ;
327 updateFixedCells( INITIALIZE ) ;
328 loadTermArray() ;
329 build_active_array() ;
330 build_soft_array() ;
331 set_up_pinplace() ; /* for soft cell pin placement */
332 update_pins(TRUE) ; /* initial pin placement */
333
334 /* free memory */
335 Ysafe_free(cornerArrayS) ;
336 Ysafe_free(pSideArrayS) ;
337 Ysafe_cfree(kArrayS) ;
338 Ybuster_free() ;
339
340 } /* end cleanupReadCells */
341 /* ***************************************************************** */
342
343 /* add another cell to cell list and initialize fields */
addCell(char * cellName,CELLTYPE cellType)344 void addCell( char * cellName, CELLTYPE cellType )
345 {
346 INT i ;
347 INT *data ;
348
349 curCellNameS = cellName ; /* for error messages */
350 curCellTypeS = cellType ;
351 ERRORABORT() ;
352
353 /* check memory of cell array */
354 if( ++totalcellsG >= cellAllocS ){
355 cellAllocS += EXPECTEDNUMCELLS ;
356 cellarrayG = (CELLBOXPTR *)
357 Ysafe_realloc( cellarrayG, cellAllocS*sizeof(CELLBOXPTR) );
358 }
359 ptrS = cellarrayG[totalcellsG] = (CELLBOXPTR)
360 Ysafe_malloc( sizeof(CELLBOX) ) ;
361
362 /* add cell to hash table */
363 data = (INT *) Ysafe_malloc( sizeof(INT) ) ;
364 *data = totalcellsG ;
365 if( Yhash_search( cellTableS, curCellNameS, (char *) data, ENTER ) ){
366 sprintf( YmsgG, "Cellnames not unique:%s\n", curCellNameS ) ;
367 M(ERRMSG,"addCell",YmsgG ) ;
368 Ysafe_free( data ) ;
369 errorFlagS = TRUE ;
370 }
371 ptrS->cname = cellName ; /* memory allocation in yylex */
372 ptrS->celltype = cellType ;
373 ptrS->xcenter = 0 ;
374 ptrS->ycenter = 0 ;
375 ptrS->orient = 0 ;
376 ptrS->numtiles = 0 ;
377 ptrS->numpins = 0 ;
378 ptrS->cur_inst = 0 ;
379 ptrS->fixed = NULL ;
380 ptrS->group_nested = FALSE ;
381 ptrS->paths = NULL ;
382 ptrS->aspect = 1.0 ;
383 ptrS->aspUB = 1.0 ;
384 ptrS->aspLB = 1.0 ;
385 ptrS->pinptr = NULL ;
386 ptrS->softpins = NULL ;
387 ptrS->instptr = NULL ;
388 ptrS->padptr = NULL ;
389 ptrS->group = NULL ;
390 ptrS->tiles = NULL ;
391 ptrS->bounBox = NULL ;
392 ptrS->nets = NULL ;
393 ptrS->orientList[HOWMANYORIENT] = 0 ;
394 if( cellType == SOFTCELLTYPE || cellType == CUSTOMCELLTYPE ||
395 cellType == STDCELLTYPE ){
396 for( i = 0 ; i < 8 ; i++ ) {
397 ptrS->orientList[i] = FALSE ;
398 }
399 } else {
400 /* for pads all orientations are valid */
401 for( i = 0 ; i < 8 ; i++ ) {
402 ptrS->orientList[i] = TRUE ;
403 }
404 }
405 if( cellType == SOFTCELLTYPE ){
406 ptrS->padptr = NULL ;
407 ptrS->softflag = TRUE ;
408 /* allocate space for uncommitted pins array */
409 numcellsG++ ;
410 numsoftG++ ;
411 numpingroupS = 0 ;
412 } else if( cellType == STDCELLTYPE ){
413 ptrS->padptr = NULL ;
414 ptrS->softflag = TRUE ;
415 /* allocate space for uncommitted pins array */
416 numcellsG++ ;
417 numstdcellG++ ;
418 doPartitionG = TRUE ;
419 } else if( cellType == CUSTOMCELLTYPE){
420 ptrS->softflag = FALSE ;
421 ptrS->padptr = NULL ;
422 numcellsG++ ;
423 } else if( cellType == PADCELLTYPE || cellType == PADGROUPTYPE){
424 ptrS->softflag = FALSE ;
425 pptrS =ptrS->padptr =
426 (PADBOXPTR) Ysafe_malloc( sizeof(PADBOX) ) ;
427 pptrS->fixed = FALSE ;
428 pptrS->padside = ALL ;
429 pptrS->permute = FALSE ;
430 pptrS->ordered = FALSE ;
431 pptrS->lowerbound = 0.0 ;
432 pptrS->upperbound = 1.0 ;
433 pptrS->padtype = cellType ;
434 pptrS->cellnum = totalcellsG ;
435 pptrS->valid_side[0] = TRUE ;
436 pptrS->valid_side[1] = FALSE ;
437 pptrS->valid_side[2] = FALSE ;
438 pptrS->valid_side[3] = FALSE ;
439 pptrS->valid_side[4] = FALSE ;
440 totalpadsG++ ;
441 if( cellType == PADGROUPTYPE ){
442 numchildrenS = 0 ;
443 childAllocS = EXPECTEDNUMPADS ;
444 pptrS->children = (INT *)
445 Ysafe_malloc((childAllocS)*sizeof(INT));
446 pptrS->hierarchy = ROOT;
447 numpadgroupsG++ ;
448 } else { /* PADCELLTYPE */
449 pptrS->children = NULL;
450 pptrS->hierarchy = NONE;
451 numpadsG++ ;
452 }
453 } else if( cellType == SUPERCELLTYPE || cellType == GROUPCELLTYPE ){
454 numsupercellsG++ ;
455 unique_classG-- ;/* start new exchange class for group cells */
456 /* allocate group record and set static */
457 curGroupS =ptrS->group =
458 (GROUPBOXPTR) Ysafe_malloc( sizeof(GROUPBOX) ) ;
459 curGroupS->fixed = (FIXEDBOXPTR) Ysafe_calloc( 1,sizeof(FIXEDBOX) ) ;
460 curGroupS->cells = NULL ;
461 } else if( cellType == PADMACROTYPE ){
462 /* do nothing right now */
463 }
464 cellinstanceS = 0 ; /* beginning of possible instancelist */
465
466 /* save cellnumber */
467 ptrS->cellnum = totalcellsG ;
468
469 /* reset xmin, ymax, etc. counters */
470 minxS = INT_MAX ;
471 minyS = INT_MAX ;
472 maxxS = INT_MIN ;
473 maxyS = INT_MIN ;
474 cornerCountS = 0 ;
475 portFlagS = FALSE ;
476
477 } /* end addCell */
478 /* ***************************************************************** */
479
480 /* perform cleanup operations on a cell */
endCell()481 void endCell()
482 {
483 ERRORABORT() ;
484
485 /* set the pSideArray for the softpins */
486 load_soft_pins( ptrS, pSideArrayS ) ;
487
488 if( curCellTypeS == CUSTOMCELLTYPE || curCellTypeS == SOFTCELLTYPE ||
489 curCellTypeS == STDCELLTYPE ){
490 watesides( ptrS, pSideArrayS ) ;
491 }
492 if( curCellTypeS == SOFTCELLTYPE || curCellTypeS == STDCELLTYPE ){
493 } else if( curCellTypeS == PADGROUPTYPE){
494 /* realloc size of children array to final size */
495 pptrS->children = (INT *)
496 Ysafe_realloc( pptrS->children,(numchildrenS+1) * sizeof(INT));
497 pptrS->children[HOWMANY] = numchildrenS ;
498 }
499 if( cellinstanceS ){
500 /* first save values to instance arrays */
501 instS->tile_inst[cellinstanceS] = ptrS->tiles ;
502 instS->vert_inst[cellinstanceS] = ptrS->vertices ;
503 instS->numtile_inst[cellinstanceS] = ptrS->numtiles ;
504 instS->name_inst[cellinstanceS] = ptrS->cname ;
505 instS->bounBox[cellinstanceS] = ptrS->bounBox ;
506 instS->numsides[cellinstanceS] = ptrS->numsides ;
507 ptrS->cur_inst = cellinstanceS ;
508 }
509
510 } /* end function endCell */
511
512 /* ***************************************************************** */
findsidestr(side,direction)513 static INT findsidestr( side, direction )
514 char *side ;
515 BOOL direction ;
516 {
517 if( direction == TRUE ){
518 /* BT case */
519 if( strcmp( side, "B" ) == STRINGEQ ){
520 return( TRUE ) ;
521 } else if( strcmp( side, "T" ) == STRINGEQ ){
522 return( FALSE ) ;
523 }
524 } else {
525 /* LR case */
526 if( strcmp( side, "L" ) == STRINGEQ ){
527 return( TRUE ) ;
528 } else if( strcmp( side, "R" ) == STRINGEQ ){
529 return( FALSE ) ;
530 }
531 }
532 sprintf( YmsgG, "Unknown side:%s\n", side ) ;
533 M(ERRMSG,"findside", YmsgG ) ;
534 setErrorFlag() ;
535 return( FALSE ) ;
536 } /* end findsidestr */
537
538 /* ***************************************************************** */
539
fixCell(INT fixedType,INT xloc,char * lorR,INT yloc,char * borT,INT xloc2,char * lorR2,INT yloc2,char * borT2)540 void fixCell( INT fixedType, INT xloc, char *lorR, INT yloc, char *borT, INT xloc2, char *lorR2, INT yloc2, char *borT2 )
541 //INT fixedType ; /* valid types - neighborhood. point, group */
542 {
543
544 INT leftOrRight, bottomOrTop ;
545 INT leftOrRight2, bottomOrTop2 ;
546 FIXEDBOXPTR fixptr ;
547
548 if( scale_dataG ){
549 xloc = (INT) ( (DOUBLE) xloc / scaleS ) ;
550 yloc = (INT) ( (DOUBLE) yloc / scaleS ) ;
551 xloc2 = (INT) ( (DOUBLE) xloc2 / scaleS ) ;
552 yloc2 = (INT) ( (DOUBLE) yloc2 / scaleS ) ;
553 }
554
555 leftOrRight = findsidestr( lorR, FALSE ) ; /* left right */
556 bottomOrTop = findsidestr( borT, TRUE ) ; /* bottom top */
557 leftOrRight2 = findsidestr( lorR2, FALSE ) ; /* left right */
558 bottomOrTop2 = findsidestr( borT2, TRUE ) ; /* bottom top */
559
560 if( fixedType == GROUPFLAG || fixedType == FIXEDGROUPFLAG ){
561 fixptr = ptrS->group->fixed ;
562 if( fixedType == FIXEDGROUPFLAG ){
563 /* note that this cell has been fixed */
564 ptrS->fixed = (FIXEDBOXPTR) TRUE ;
565 }
566 } else {
567 fixptr =ptrS->fixed = (FIXEDBOXPTR)
568 Ysafe_malloc( sizeof(FIXEDBOX) ) ;
569 }
570 fixptr->fixedType = fixedType ;
571 fixptr->xcenter = xloc ;
572 fixptr->ycenter = yloc ;
573 if( leftOrRight == TRUE ){
574 fixptr->leftNotRight = TRUE ;
575 } else if( leftOrRight == FALSE ){
576 fixptr->leftNotRight = FALSE ;
577 } else {
578 M(ERRMSG,"fixCell", "Problem passing arguments to function\n" ) ;
579 setErrorFlag() ;
580 }
581
582 if( bottomOrTop == TRUE ){
583 fixptr->bottomNotTop = TRUE ;
584 } else if( bottomOrTop == FALSE ){
585 fixptr->bottomNotTop = FALSE ;
586 } else {
587 M(ERRMSG,"fixCell", "Problem passing arguments to function\n" ) ;
588 setErrorFlag() ;
589 }
590 if( fixedType != POINTFLAG ){
591 fixptr->xloc1 = xloc ;
592 fixptr->yloc1 = yloc ;
593 fixptr->xloc2 = xloc2 ;
594 fixptr->yloc2 = yloc2 ;
595 if( leftOrRight2 == TRUE ){
596 fixptr->leftNotRight2 = TRUE ;
597 } else if( leftOrRight2 == FALSE ){
598 fixptr->leftNotRight2 = FALSE ;
599 } else {
600 M(ERRMSG,"fixCell","Problem passing arguments to function\n");
601 setErrorFlag() ;
602 }
603
604 if( bottomOrTop2 == TRUE ){
605 fixptr->bottomNotTop2 = TRUE ;
606 } else if( bottomOrTop2 == FALSE ){
607 fixptr->bottomNotTop2 = FALSE ;
608 } else {
609 M(ERRMSG,"fixCell","Problem passing arguments to function\n");
610 setErrorFlag() ;
611 }
612 }
613
614 } /* end fixCell */
615
processCorners(INT numcorners)616 void processCorners( INT numcorners )
617 {
618 char *buster_msg ; /* message string to used by buster */
619 INT xx1, yy1, xx2, yy2 ; /* temp points */
620 INT k ; /* point counter */
621 INT xsum, ysum ; /* used to truncate cell correctly */
622 TILEBOXPTR tile ;
623 YBUSTBOXPTR busterptr ; /* return record for busting routine */
624 VERTBOXPTR vert ; /* ptr to record of vertices of cell */
625 BOUNBOXPTR bounptr, /* ptr to bounBox[0] */
626 bounptr_orig ; /* ptr to bounBox[8] - original bbox */
627
628
629 /* +++++++++++++++++++ perform error checking +++++++++++++++++++ */
630 ERRORABORT() ;
631 if( cornerCountS != numcorners ){
632 sprintf( YmsgG, "Incorrect number of corners for cell:%s\n",
633 curCellNameS ) ;
634 M(ERRMSG,"processCorners", YmsgG ) ;
635 setErrorFlag() ;
636 }
637 if( scale_dataG ){
638 if( maxxS - minxS <= 1 || maxyS - minyS <= 1 ){
639 sprintf( YmsgG,
640 "Cell:%s smaller than given scale data - resized to portsize.\n",
641 curCellNameS ) ;
642 M( WARNMSG, "processCorners", YmsgG ) ;
643 /* make into a port instead of a possible 0 width object */
644 numcorners = cornerCountS = 4 ;
645 cornerArrayS[1].x = -1 ; cornerArrayS[1].y = -1 ;
646 cornerArrayS[2].x = -1 ; cornerArrayS[2].y = 1 ;
647 cornerArrayS[3].x = 1 ; cornerArrayS[3].y = 1 ;
648 cornerArrayS[4].x = 1 ; cornerArrayS[4].y = -1 ;
649 minxS = -1 ; maxxS = 1;
650 minyS = -1 ; maxyS = 1;
651 /* set portFlag to true so we can move pins to boundary */
652 portFlagS = TRUE ;
653 }
654 }
655 xsum = minxS + maxxS ;
656 ysum = minyS + maxyS ;
657 xcenterS = xsum / 2 ;
658 ycenterS = ysum / 2 ;
659 if( xsum < 0 && xsum % 2 ){
660 /* cell is asymmetrical and negative */
661 xcenterS-- ;
662 }
663 if( ysum < 0 && ysum % 2 ){
664 /* cell is asymmetrical and negative */
665 ycenterS-- ;
666 }
667
668 /* save the number of sides */
669 ptrS->numsides = numcorners ;
670
671 Ybuster_init() ;
672 sprintf( YmsgG, " (cell:%s) ", curCellNameS ) ;
673 buster_msg = Ystrclone( YmsgG ) ;
674
675 for( k = 1 ; k <= numcorners ; k++ ) {
676 xx1 = cornerArrayS[k].x ;
677 yy1 = cornerArrayS[k].y ;
678 Ybuster_addpt( xx1, yy1 ) ;
679 if( k == numcorners ) {
680 xx2 = cornerArrayS[1].x ;
681 yy2 = cornerArrayS[1].y ;
682 } else {
683 xx2 = cornerArrayS[ k + 1 ].x ;
684 yy2 = cornerArrayS[ k + 1 ].y ;
685 }
686 }
687 if(!(Ybuster_verify( buster_msg ))){
688 setErrorFlag() ;
689 return ;
690 }
691 Ysafe_free( buster_msg ) ;
692
693 /* +++++++++++++++++++ end perform error checking +++++++++++++++++++ */
694 /* This data structure allow quick change between x and x_new */
695 /* since placepin always uses the x fields and not x_new */
696 vert = ptrS->vertices = (VERTBOXPTR) Ysafe_malloc( sizeof(VERTBOX) ) ;
697 /* the members of the structure */
698 vert->x = (INT *) Ysafe_malloc( (numcorners+1)*sizeof(INT) ) ;
699 vert->x_orig = (INT *) Ysafe_malloc( (numcorners+1)*sizeof(INT) ) ;
700 vert->x_new = (INT *) Ysafe_malloc( (numcorners+1)*sizeof(INT) ) ;
701 vert->y = (INT *) Ysafe_malloc( (numcorners+1)*sizeof(INT) ) ;
702 vert->y_orig = (INT *) Ysafe_malloc( (numcorners+1)*sizeof(INT) ) ;
703 vert->y_new = (INT *) Ysafe_malloc( (numcorners+1)*sizeof(INT) ) ;
704 vert->numpins = (FLOAT *) Yvector_alloc( 1,numcorners,sizeof(FLOAT) ) ;
705 for( k = 1 ; k <= numcorners ; k++ ) {
706 vert->x[k] = vert->x_orig[k] = cornerArrayS[k].x - xcenterS ;
707 vert->y[k] = vert->y_orig[k] = cornerArrayS[k].y - ycenterS ;
708 }
709 if( curCellTypeS == SOFTCELLTYPE || curCellTypeS == CUSTOMCELLTYPE ||
710 curCellTypeS == STDCELLTYPE ){
711 /* calculate total cell perimeter before bust operation */
712 /* calculate over all instances */
713 perimG += perimeter( cornerArrayS, numcorners ) ;
714 /* load pSideArray for weighing cells in dynamic wiring estimator */
715 for( k = 1 ; k <= numcorners ; k++ ) {
716 if( k < numcorners ) {
717 if( k % 2 == 1 ) {
718 pSideArrayS[k].length =
719 ABS(cornerArrayS[k + 1].y - cornerArrayS[k].y) ;
720 pSideArrayS[k].vertical = 1 ;
721 pSideArrayS[k].pincount = 0 ;
722 pSideArrayS[k].position = cornerArrayS[k].x ;
723 } else {
724 pSideArrayS[k].length =
725 ABS(cornerArrayS[k + 1].x - cornerArrayS[k].x) ;
726 pSideArrayS[k].vertical = 0 ;
727 pSideArrayS[k].pincount = 0 ;
728 pSideArrayS[k].position = cornerArrayS[k].y ;
729 }
730 } else {
731 pSideArrayS[k].length =
732 ABS(cornerArrayS[1].x - cornerArrayS[k].x) ;
733 pSideArrayS[k].vertical = 0 ;
734 pSideArrayS[k].pincount = 0 ;
735 pSideArrayS[k].position = cornerArrayS[k].y ;
736 }
737 } /* end for loop */
738 }
739 /* -----------------now build tiles for cell---------------------- */
740
741 /* create bounding box of cell bounding box has 8 view for all cells*/
742 /* plus 9 field for original view of the bounding box */
743 ptrS->bounBox = (BOUNBOXPTR *)
744 Ysafe_malloc( 9 * sizeof( BOUNBOXPTR ) ) ;
745 for( k=0;k<=8;k++){
746 ptrS->bounBox[k] = (BOUNBOXPTR)
747 Ysafe_malloc(sizeof( BOUNBOX ) ) ;
748 }
749 ptrS->boun_valid = FALSE ;
750 /* now save the original bounding box for uaspect in 8 */
751 bounptr = ptrS->bounBox[0] ;
752 bounptr_orig = ptrS->bounBox[8] ;
753 bounptr_orig->l = bounptr->l = minxS - xcenterS ;
754 bounptr_orig->r = bounptr->r = maxxS - xcenterS ;
755 bounptr_orig->b = bounptr->b = minyS - ycenterS ;
756 bounptr_orig->t = bounptr->t = maxyS - ycenterS ;
757 ptrS->xcenter = xcenterS ;
758 ptrS->ycenter = ycenterS ;
759
760 tile = NIL(TILEBOXPTR) ;
761 while( busterptr = Ybuster() ){
762 /* l = busterptr[1].x */
763 /* r = busterptr[4].x */
764 /* b = busterptr[1].y */
765 /* t = busterptr[2].y */
766 if( tile ){
767 tile->next = (TILEBOXPTR) Ysafe_malloc( sizeof( TILEBOX ));
768 tile = tile->next ;
769 } else {
770 tile = ptrS->tiles =
771 (TILEBOXPTR) Ysafe_malloc( sizeof( TILEBOX ));
772 }
773 tile->next = NULL ;
774 ptrS->numtiles++ ;
775 tile->left = tile->orig_left = busterptr[1].x - xcenterS ;
776 tile->right = tile->orig_right = busterptr[4].x - xcenterS ;
777 tile->bottom = tile->orig_bottom = busterptr[1].y - ycenterS ;
778 tile->top = tile->orig_top = busterptr[2].y - ycenterS ;
779 tile->lweight = 0.0 ;
780 tile->rweight = 0.0 ;
781 tile->bweight = 0.0 ;
782 tile->tweight = 0.0 ;
783 }
784
785 /* add aspect ratio to design */
786 ptrS->orig_aspect = ptrS->aspect =
787 (DOUBLE)(maxyS - minyS) / (DOUBLE)(maxxS - minxS);
788
789 /* -----------------end build tiles for cell---------------------- */
790 } /* end processCorners */
791 /* ***************************************************************** */
792
addCorner(INT xpos,INT ypos)793 void addCorner( INT xpos, INT ypos )
794 {
795 if( ++cornerCountS >= tileptAllocS ){
796 tileptAllocS = cornerCountS + 1 ;
797 cornerArrayS = ( YBUSTBOXPTR )
798 Ysafe_realloc( cornerArrayS, tileptAllocS * sizeof( YBUSTBOX ) );
799 pSideArrayS = (PSIDEBOX *)
800 Ysafe_realloc( pSideArrayS, tileptAllocS * sizeof( PSIDEBOX ) ) ;
801 }
802 if( scale_dataG ){
803 if( portFlagS ){
804 /* port pins need to be on boundary for global router */
805 xpos = 0 ;
806 ypos = 1 ;
807 } else {
808 xpos = (INT) ( (DOUBLE) xpos / scaleS ) ;
809 ypos = (INT) ( (DOUBLE) ypos / scaleS ) ;
810 }
811 }
812 cornerArrayS[cornerCountS].x = xpos ;
813 cornerArrayS[cornerCountS].y = ypos ;
814 minxS = MIN( minxS, xpos ) ;
815 maxxS = MAX( maxxS, xpos ) ;
816 minyS = MIN( minyS, ypos ) ;
817 maxyS = MAX( maxyS, ypos ) ;
818 } /* end addCorner */
819 /* ***************************************************************** */
820
initializeCorner(INT cell)821 void initializeCorner( INT cell )
822 {
823 ptrS = cellarrayG[cell] ;
824 curCellTypeS = ptrS->celltype ;
825 cornerCountS = 0 ;
826 } /* end initializeCorner */
827 /* ***************************************************************** */
828
addClass(INT class)829 void addClass( INT class )
830 {
831 ERRORABORT() ;
832
833 if( ptrS->class >= 0 ){
834 /* this test is necessary since fix neighborhood may set it negative */
835 /* and we will not want to touch the value of it */
836 ptrS->class = class ;
837 }
838 } /* end addClass */
839 /* ***************************************************************** */
840
841 /* first in the list is the initial orientation */
initOrient(orient)842 void initOrient( orient )
843 INT orient ;
844 {
845 ERRORABORT() ;
846
847 ptrS->orient = - orient ;
848 addOrient( orient ) ;
849 } /* end initOrient */
850 /* ***************************************************************** */
851
852 /* addOrient sets orientation valid for this cell */
addOrient(INT orient)853 void addOrient( INT orient )
854 {
855 ERRORABORT() ;
856
857 ptrS->orientList[orient] = TRUE ; /* allow this orientation */
858 ptrS->orientList[HOWMANYORIENT]++ ;
859 } /* end addOrient */
860 /* ***************************************************************** */
861
862 /* if this routine is called it means we are reading the input of
863 a previous TimberWolf run.
864 */
set_cur_orient(INT orient)865 int set_cur_orient( INT orient )
866 {
867 ERRORABORTINT() ;
868
869 ptrS->orient = orient ;
870 } /* end set_cur_orient */
871 /* ***************************************************************** */
872
873 /* load aspect ratios */
addAspectBounds(lowerBound,upperBound)874 void addAspectBounds( lowerBound, upperBound )
875 DOUBLE lowerBound, upperBound ;
876 {
877 ERRORABORT() ;
878
879 ptrS->aspLB = lowerBound ;
880 ptrS->aspUB = upperBound ;
881
882 } /* end addAspectBounds */
883 /* ***************************************************************** */
884
addPinAndNet(pinName,signal)885 PINBOXPTR addPinAndNet( pinName, signal )
886 char *pinName, *signal ;
887 {
888 static PINBOXPTR botpinS ; /* keep track of end of list */
889 INT *data, netx ;
890 BOOL notInTable ;
891 PINBOXPTR pinptr ;
892 NETBOXPTR netptr ;
893
894 notInTable = TRUE ;
895 totPinS++ ; /* count the pins over all instances */
896 if( data = (INT *) Yhash_search( netTableS, signal, NULL, FIND ) ){
897 netx = *data ;
898 notInTable = FALSE ;
899 } else {
900 /* else a new net load data holder */
901 data = (INT *) Ysafe_malloc( sizeof(INT) ) ;
902 *data = netx = ++numnetsG ;
903 if( Yhash_search( netTableS, signal, (char*) data, ENTER )){
904 sprintf( YmsgG, "Trouble adding signal:%s to hash table\n",
905 signal ) ;
906 M(ERRMSG,"addPinAndNet",YmsgG ) ;
907 errorFlagS = TRUE ;
908 }
909 }
910 if( cellinstanceS ){
911 if( notInTable ){
912 sprintf(YmsgG,"No match for net:%s in primary instance:%s\n",
913 pinName, *ptrS->cname ) ;
914 M( ERRMSG, "addPinAndNet", YmsgG ) ;
915 errorFlagS = TRUE ;
916 }
917 /* at this point we are done */
918 return( NULL ) ;
919 }
920 /* increment number of pins */
921 numpinsG++ ;
922 /* check memory of netarray */
923 if( numnetsG >= netAllocS ){
924 netAllocS += EXPECTEDNUMNETS ;
925 netarrayG = (NETBOXPTR *)
926 Ysafe_realloc( netarrayG, netAllocS * sizeof(NETBOXPTR) ) ;
927 }
928
929 /* see if this is the first time for this signal */
930 if( notInTable ){
931 netptr = netarrayG[netx] =
932 (NETBOXPTR) Ysafe_malloc( sizeof(NETBOX) ) ;
933 netptr->nname = signal ; /* allocated by yylex */
934 netptr->pins = NULL ; /* initialize list */
935 netptr->paths = NULL ; /* initialize list */
936 netptr->skip = 0 ; /* initialize list */
937 netptr->driveFactor = (FLOAT) 0.0 ; /* initialize timing */
938 netptr->max_driver = (FLOAT) 1.0 ; /* initialize timing */
939 netptr->min_driver = (FLOAT) 1.0 ; /* initialize timing */
940 netptr->analog_info = NIL(ANETPTR) ;
941 } else {
942 Ysafe_free( signal ) ; /* no need to keep this copy */
943 netptr = netarrayG[netx] ;
944 }
945 /* create list of pins on the net */
946 pinptr = (PINBOXPTR) Ysafe_malloc( sizeof(PINBOX) );
947 pinptr->next = netptr->pins ;
948 netptr->pins = pinptr ;
949
950 /* create a list of pins for this cell in order as given */
951 if( ptrS->pinptr ){ /* list has already been started */
952 botpinS->nextpin = pinptr ;
953 } else { /* start new list */
954 ptrS->pinptr = pinptr ;
955 }
956 pinptr->nextpin = NULL ;
957 botpinS = pinptr ;
958
959 /* now initialize data */
960 pinptr->pinname = pinName ; /* allocated by yylex */
961 pinptr->pin = numpinsG ;
962 pinptr->net = netx ;
963 pinptr->cell = totalcellsG ;
964 pinptr->xpos = 0 ;
965 pinptr->ypos = 0 ;
966 pinptr->instance = cellinstanceS ;
967 /* allocate only size for one instance by default */
968 pinptr->txpos = 0 ;
969 pinptr->typos = 0 ;
970 pinptr->txpos_orig = (INT *) Ysafe_malloc( sizeof(INT) ) ;
971 pinptr->typos_orig = (INT *) Ysafe_malloc( sizeof(INT) ) ;
972 pinptr->newx = 0 ;
973 pinptr->newy = 0 ;
974 pinptr->flag = 0 ;
975 pinptr->skip = 0 ;
976 pinptr->eqptr = NULL ;
977 pinptr->analog = NIL(ANALOGPTR) ;
978
979 return( pinptr ) ;
980
981 } /* add pin and net */
982 /* ***************************************************************** */
983
addPin(pinName,signal,layer,pinType)984 void addPin( pinName, signal, layer, pinType )
985 char *pinName ;
986 char *signal ;
987 INT layer ;
988 INT pinType ;
989 {
990 INT side ;
991 INT howmany ; /* number of children - equivs */
992 SOFTBOXPTR sptr ; /* current soft information */
993
994
995 curPinNameS = pinName ;
996 analogS = NIL(ANALOGPTR) ;
997 ERRORABORT() ;
998
999 if( pinType == SOFTEQUIVTYPE ){
1000 /* get signal name from soft pin */
1001 signal = Ystrclone( netarrayG[softpinS->net]->nname ) ;
1002 }
1003
1004 pinS = addPinAndNet( pinName, signal ) ;
1005
1006 equivpinS = 1 ;
1007
1008 /* Note: initial pin positions will be last instance */
1009 if( pinS ){
1010 ptrS->numpins++ ;
1011 pinS->type = pinType ;
1012 pinS->layer = layer ;
1013 } else if( cellinstanceS ){
1014 if(!(pinS = findTerminal( pinName, totalcellsG))){
1015 sprintf(YmsgG,"No match for pin:%s in primary instance:%s\n",
1016 pinName, cellarrayG[totalcellsG]->cname ) ;
1017 M( ERRMSG, "addHardPin", YmsgG ) ;
1018 errorFlagS = TRUE ;
1019 return ;
1020 }
1021 /* reallocate space if necessary */
1022 pinS->txpos_orig = (INT *)
1023 Ysafe_realloc( pinS->txpos_orig,(cellinstanceS+1)*sizeof(INT));
1024 pinS->typos_orig = (INT *)
1025 Ysafe_realloc( pinS->typos_orig,(cellinstanceS+1)*sizeof(INT));
1026 pinS->txpos = pinS->txpos_orig[cellinstanceS] = 0 ;
1027 pinS->typos = pinS->typos_orig[cellinstanceS] = 0 ;
1028 }
1029
1030 /* now handle soft pin information */
1031 if( ptrS->softflag ){
1032 /* allocate space for array of instances */
1033 if( cellinstanceS == 0 ){
1034 pinS->soft_inst = (SOFTBOXPTR *)
1035 Ysafe_malloc( sizeof(SOFTBOXPTR) );
1036 pinS->layer = layer ;
1037 } else {
1038 pinS->soft_inst = (SOFTBOXPTR *) Ysafe_realloc(
1039 pinS->soft_inst,instAllocS * sizeof(SOFTBOXPTR) );
1040 }
1041 /* now allocate space for this instance */
1042 spinptrS = pinS->soft_inst[cellinstanceS] = pinS->softinfo =
1043 (SOFTBOXPTR) Ysafe_malloc(sizeof(SOFTBOX)) ;
1044 spinptrS->children = NULL ;
1045 spinptrS->hierarchy = NONE ;
1046 spinptrS->parent = NULL ;
1047 /* build the restrict field and initialize HOWMANY [0] to 0 */
1048 spinptrS->restrict1 = (INT *) Ysafe_calloc( 1, sizeof(INT) ) ;
1049 spinptrS->permute = FALSE ;
1050 spinptrS->fixed = FALSE ;
1051 spinptrS->ordered = FALSE ;
1052 spinptrS->lowerbound = 0.0 ;
1053 spinptrS->upperbound = 1.0 ;
1054 }
1055
1056 if( pinType == SOFTPINTYPE ){
1057 /* save the main softpin for future equiv use */
1058 softpinS = pinS ;
1059 } else if( pinType == SOFTEQUIVTYPE ){
1060 /* add to this pin's children */
1061 sptr = softpinS->softinfo ;
1062 if( sptr->children ){
1063 howmany = (INT) sptr->children[HOWMANY] ;
1064 sptr->children = (PINBOXPTR *)
1065 Ysafe_realloc( sptr->children,
1066 (++howmany+1) * sizeof(PINBOXPTR) ) ;
1067 } else {
1068 howmany = 1 ;
1069 sptr->children = (PINBOXPTR *)
1070 Ysafe_malloc( (howmany+1) * sizeof(PINBOXPTR) ) ;
1071 }
1072 sptr->children[HOWMANY] = (PINBOXPTR) howmany ;
1073 sptr->children[howmany] = pinS ;
1074 spinptrS->parent = softpinS ;
1075 } else if( !(ptrS->softflag) ){
1076 pinS->softinfo = NULL ;
1077 }
1078
1079 } /* end addPin */
1080 /* ***************************************************************** */
1081
set_pin_pos(xpos,ypos)1082 void set_pin_pos( xpos, ypos )
1083 INT xpos, ypos ;
1084 {
1085 INT side ;
1086 INT howmany ; /* number of children - equivs */
1087
1088 ERRORABORT() ;
1089
1090 if( scale_dataG ){
1091 if( portFlagS ){
1092 xpos = 0 ;
1093 ypos = 1 ;
1094 } else {
1095 xpos = (INT) ( (DOUBLE) xpos / scaleS ) ;
1096 ypos = (INT) ( (DOUBLE) ypos / scaleS ) ;
1097 }
1098 }
1099
1100 check_pos( curPinNameS, xpos, ypos ) ;
1101 side = findside( pSideArrayS, ptrS , xpos , ypos ) ;
1102 loadside( pSideArrayS, side , 1.0 ) ;
1103
1104 totxS = xpos ;
1105 totyS = ypos ;
1106
1107 /* set global coordinates */
1108 pinS->xpos = xpos ;
1109 pinS->ypos = ypos ;
1110
1111 xpos -= xcenterS ;
1112 ypos -= ycenterS ;
1113
1114 /* Note: initial pin positions will be last instance */
1115 pinS->txpos = pinS->txpos_orig[cellinstanceS] = xpos ;
1116 pinS->typos = pinS->typos_orig[cellinstanceS] = ypos ;
1117 } /* end set_pin_pos */
1118 /* ***************************************************************** */
1119
check_pos(pinname,xpos,ypos)1120 static void check_pos( pinname, xpos, ypos )
1121 char *pinname ;
1122 INT xpos, ypos ;
1123 {
1124 if( xpos < minxS || xpos > maxxS || ypos < minyS || ypos > maxyS ){
1125 sprintf( YmsgG, "Pin:%s cell:%s @(%d,%d) is outside cell boundary\n",
1126 pinname, curCellNameS, xpos, ypos ) ;
1127 M( ERRMSG, "check_pos", YmsgG ) ;
1128 setErrorFlag() ;
1129 }
1130 } /* end check_pos */
1131
1132 /* add an equivalent pin-updates the pin position to effective position */
addEquivPin(pinName,layer,xpos,ypos,pinType)1133 void addEquivPin( pinName, layer, xpos, ypos, pinType )
1134 char *pinName ;
1135 INT layer ;
1136 INT xpos, ypos ;
1137 INT pinType ;
1138 {
1139 INT side ;
1140 EQUIVPTR temp, eqptr ;
1141
1142 curPinNameS = pinName ;
1143 ERRORABORT() ;
1144 ASSERTNRETURN( pinS, "addEquivPin", "pinS is NULL" ) ;
1145
1146 if( pinType != ADDEQUIVTYPE ){
1147 if( scale_dataG ){
1148 if( portFlagS ){
1149 xpos = 0 ;
1150 ypos = 1 ;
1151 } else {
1152 xpos = (INT) ( (DOUBLE) xpos / scaleS ) ;
1153 ypos = (INT) ( (DOUBLE) ypos / scaleS ) ;
1154 }
1155 }
1156
1157 if( curCellTypeS == SOFTCELLTYPE ||
1158 curCellTypeS == CUSTOMCELLTYPE ||
1159 curCellTypeS == STDCELLTYPE ){
1160 check_pos( pinName, xpos, ypos ) ;
1161 side = findside( pSideArrayS, ptrS , xpos , ypos ) ;
1162 loadside( pSideArrayS, side , 1.0 ) ;
1163 }
1164 equivpinS++ ;
1165 totPinS++ ;
1166 totxS += xpos ;
1167 totyS += ypos ;
1168
1169 /* average pin positions - note we leave _orig fields untouched */
1170 pinS->txpos = (totxS / equivpinS ) - xcenterS;
1171 pinS->typos = (totyS / equivpinS ) - ycenterS;
1172 } else {
1173 /* get pinname from main soft pin */
1174 pinName = softpinS->pinname ;
1175 }
1176
1177 /* now save locations of equivalent pins for later output */
1178 if( temp = pinS->eqptr ){
1179 eqptr = pinS->eqptr = (EQUIVPTR) Ysafe_malloc(sizeof(EQUIVBOX)) ;
1180 eqptr->next = temp ;
1181 } else {
1182 eqptr = pinS->eqptr = (EQUIVPTR) Ysafe_malloc(sizeof(EQUIVBOX)) ;
1183 eqptr->next = NULL ;
1184 }
1185 if( cellinstanceS ){ /* more than one instance */
1186 eqptr->txpos = (INT *)
1187 Ysafe_realloc( eqptr->txpos,(cellinstanceS+1) * sizeof(INT) ) ;
1188 eqptr->typos = (INT *)
1189 Ysafe_realloc( eqptr->typos,(cellinstanceS+1) * sizeof(INT) ) ;
1190 } else {
1191 /* by default only expect one instance */
1192 eqptr->txpos = (INT *) Ysafe_malloc( sizeof(INT) ) ;
1193 eqptr->typos = (INT *) Ysafe_malloc( sizeof(INT) ) ;
1194 }
1195 /* now load the data */
1196 eqptr->txpos[cellinstanceS] = xpos - xcenterS;
1197 eqptr->typos[cellinstanceS] = ypos - ycenterS;
1198 eqptr->pinname = pinName ;
1199 /* if the user didn't give us any layer set to 2 for now */
1200 if( layer == 0 ){
1201 layer = -2 ;
1202 }
1203 eqptr->layer = layer ;
1204 if( pinType == ADDEQUIVTYPE ){
1205 /* build the restrict field and initialize HOWMANY [0] to 0 */
1206 eqptr->restrict1 = (INT *) Ysafe_calloc( 1, sizeof(INT) ) ;
1207 } else {
1208 eqptr->restrict1 = NULL ;
1209 }
1210
1211 } /* end addEquivPin */
1212 /* ***************************************************************** */
1213
set_restrict_type(object)1214 void set_restrict_type( object )
1215 INT object ;
1216 {
1217 cur_restrict_objS = object ;
1218 }
1219 /* ***************************************************************** */
1220
addSideRestriction(side)1221 void addSideRestriction( side )
1222 INT side ;
1223 {
1224 INT howmany ;
1225 SOFTBOXPTR spin ;
1226 EQUIVPTR eqptr ;
1227
1228 ERRORABORT() ;
1229 if( side < 0 || side > cornerCountS ) {
1230 M(ERRMSG,"addSideRestriction","value of side out of range");
1231 sprintf(YmsgG,"\n\tside:%d range:1 to %d ", side,
1232 cornerCountS ) ;
1233 M(MSG,NULL,YmsgG);
1234 sprintf(YmsgG, "current cell is:%d\n", totalcellsG ) ;
1235 M(MSG,NULL,YmsgG);
1236 setErrorFlag() ;
1237 }
1238
1239 /* this variable set by set_restrict type */
1240 switch( cur_restrict_objS ){
1241 case PINGROUPTYPE:
1242 spin = pingroupS->softinfo ;
1243 howmany = ++(spin->restrict1[HOWMANY]) ;
1244 spin->restrict1 = (INT *) Ysafe_realloc( spin->restrict1,
1245 (howmany+1)*sizeof(INT) ) ;
1246 spin->restrict1[howmany] = side ;
1247 break ;
1248 case SOFTPINTYPE:
1249 case SOFTEQUIVTYPE:
1250 spin = pinS->softinfo ;
1251 howmany = ++(spin->restrict1[HOWMANY]) ;
1252 spin->restrict1 = (INT *) Ysafe_realloc( spin->restrict1,
1253 (howmany+1)*sizeof(INT) ) ;
1254 spin->restrict1[howmany] = side ;
1255 break ;
1256 case ADDEQUIVTYPE:
1257 eqptr = softpinS->eqptr ;
1258 howmany = ++(eqptr->restrict1[HOWMANY]) ;
1259 eqptr->restrict1 = (INT *) Ysafe_realloc( eqptr->restrict1,
1260 (howmany+1)*sizeof(INT) ) ;
1261 eqptr->restrict1[howmany] = side ;
1262 break ;
1263 } /* end switch on current object */
1264
1265 } /* end addSideRestriction *
1266 /* ***************************************************************** */
1267
1268
add_pinspace(lower,upper)1269 void add_pinspace( lower, upper )
1270 DOUBLE lower ;
1271 DOUBLE upper ;
1272 {
1273 char *name ; /* name of current object */
1274 SOFTBOXPTR spin ; /* soft pin information of current pin or pg */
1275
1276 ERRORABORT() ;
1277
1278 switch( cur_restrict_objS ){
1279 case PINGROUPTYPE:
1280 spin = pingroupS->softinfo ;
1281 name = pingroupS->pinname ;
1282 break ;
1283 case SOFTPINTYPE:
1284 case SOFTEQUIVTYPE:
1285 spin = pinS->softinfo ;
1286 name = pinS->pinname ;
1287 break ;
1288 case ADDEQUIVTYPE:
1289 return ;
1290 } /* end switch on current object */
1291
1292 spin->fixed = TRUE ;
1293 if( lower > 1.0 || upper > 1.0 ){
1294 sprintf(YmsgG,
1295 "side space must be less or equal to 1.0 for pin: %s\n", name ) ;
1296 M(ERRMSG,"add_pinspace",YmsgG ) ;
1297 setErrorFlag() ;
1298 }
1299 if( lower < 0.0 || upper < 0.0 ){
1300 sprintf(YmsgG,
1301 "side space must be greater or equal to 0.0 for pin: %s\n",name ) ;
1302 M(ERRMSG,"add_pinspace",YmsgG ) ;
1303 setErrorFlag() ;
1304 }
1305 if( lower > upper ){
1306 sprintf(YmsgG,
1307 "side space upper bound must be greater or equal to lower bound for pin: %s\n",
1308 name ) ;
1309 M(ERRMSG,"add_pinspace",YmsgG ) ;
1310 setErrorFlag() ;
1311 }
1312 spin->lowerbound = lower ;
1313 spin->upperbound = upper ;
1314 } /* end add_pinspace */
1315 /* ***************************************************************** */
1316
add_soft_array()1317 void add_soft_array()
1318 {
1319 INT i ;
1320 PINBOXPTR *sarray ;
1321 PINBOXPTR pin ;
1322
1323 if( cellinstanceS != 0 ){
1324 return ;
1325 }
1326 sarray = ptrS->softpins = (PINBOXPTR *)
1327 Ysafe_malloc( (ptrS->numpins+1) * sizeof(PINBOXPTR) ) ;
1328 i = 0 ;
1329 for( pin = ptrS->pinptr; pin ; pin = pin->nextpin ){
1330 sarray[++i] = pin ;
1331 }
1332 sarray[HOWMANY] = (PINBOXPTR) i ;
1333 }
1334 /* end add_soft_array */
1335
start_pin_group(pingroup,permute)1336 void start_pin_group( pingroup, permute )
1337 char *pingroup ;
1338 BOOL permute ;
1339 {
1340
1341 INT i ;
1342 INT curpingroup ;
1343 INT howmany ;
1344 PINBOXPTR *sarray ;
1345 SOFTBOXPTR spin ;
1346
1347 ERRORABORT() ;
1348
1349 numchildrenS = 0 ;
1350 childAllocS = 1 ;
1351
1352 /* allocate space for array of instances */
1353 if( cellinstanceS == 0 ){
1354 /* pins in array go 1 ... numpins, pingroup1, pingroup2 ... */
1355 curpingroup = ptrS->numpins + ++numpingroupS ;
1356 sarray = ptrS->softpins = (PINBOXPTR *)
1357 Ysafe_realloc( ptrS->softpins,
1358 (curpingroup+1) * sizeof(PINBOXPTR) ) ;
1359
1360 sarray[HOWMANY] = (PINBOXPTR) curpingroup ;
1361
1362 /* allocate space for pingroup */
1363 pingroupS = sarray[curpingroup] = (PINBOXPTR)
1364 Ysafe_calloc( 1, sizeof(PINBOX) );
1365
1366 /* now initialize data */
1367 pingroupS->pinname = pingroup ; /* allocated by yylex */
1368 pingroupS->txpos_orig = (INT *) Ysafe_malloc( sizeof(INT) ) ;
1369 pingroupS->typos_orig = (INT *) Ysafe_malloc( sizeof(INT) ) ;
1370 pingroupS->type = PINGROUPTYPE ;
1371
1372 pingroupS->soft_inst = (SOFTBOXPTR *) Ysafe_malloc( sizeof(SOFTBOXPTR) );
1373 } else {
1374 /* first find pingroup in softpin array */
1375 sarray = ptrS->softpins ;
1376 howmany = (INT) sarray[HOWMANY] ;
1377 pingroupS = NIL(PINBOXPTR) ;
1378 for( i = 1; i <= howmany; i++ ){
1379 if( strcmp( pingroup, sarray[i]->pinname ) == STRINGEQ ){
1380 pingroupS = sarray[i] ;
1381 break ;
1382 }
1383 }
1384 if( pingroupS ){
1385 pingroupS->soft_inst = (SOFTBOXPTR *) Ysafe_realloc(
1386 pingroupS->soft_inst,instAllocS * sizeof(SOFTBOXPTR) );
1387 } else {
1388 sprintf(YmsgG,"No match for pingroup:%s in primary instance:%s\n",
1389 pingroup, cellarrayG[totalcellsG]->cname ) ;
1390 M( ERRMSG, "start_pin_group", YmsgG ) ;
1391 errorFlagS = TRUE ;
1392 return ;
1393 }
1394 }
1395 /* now allocate space for this instance */
1396 pingroupS->soft_inst[cellinstanceS] = pingroupS->softinfo =
1397 (SOFTBOXPTR) Ysafe_calloc( 1, sizeof(SOFTBOX)) ;
1398
1399 spin = pingroupS->softinfo ;
1400 spin->permute = permute ;
1401 spin->fixed = FALSE ;
1402 spin->ordered = FALSE ;
1403 spin->hierarchy = ROOT ;
1404 spin->lowerbound = 0.0 ;
1405 spin->upperbound = 1.0 ;
1406 spin->children = (PINBOXPTR *) Ysafe_malloc( sizeof(PINBOXPTR) ) ;
1407 spin->restrict1 = (INT *) Ysafe_calloc( 1, sizeof(INT) ) ;
1408 spin->parent = NULL ;
1409
1410 } /* end start_pin_group */
1411 /* ***************************************************************** */
1412
1413 /* add this pad to the current pad group */
add2pingroup(pinName,ordered)1414 void add2pingroup( pinName, ordered )
1415 char *pinName ;
1416 BOOL ordered ; /* ordered flag is true if padgroup is fixed */
1417 {
1418
1419 INT i ;
1420 INT howmany ;
1421 PINBOXPTR pin ;
1422 PINBOXPTR cpin ;
1423 SOFTBOXPTR spin ;
1424 SOFTBOXPTR pingroup_spin ;
1425 INT curpingroup ;
1426
1427 ERRORABORT() ;
1428
1429 /* check pads for correctness */
1430 for( pin = ptrS->pinptr ; pin ; pin = pin->nextpin ){
1431 spin = pin->softinfo ;
1432 if( strcmp(pinName, pin->pinname) == STRINGEQ ){
1433
1434 if( spin->hierarchy == LEAF ){
1435 sprintf(YmsgG,
1436 "pin %s was included in more than 1 pin group\n",
1437 pin->pinname);
1438 M(ERRMSG,"add2pingroup",YmsgG ) ;
1439 setErrorFlag() ;
1440 return ;
1441 }
1442 /* check memory of pin array */
1443 pingroup_spin = pingroupS->softinfo ;
1444 if( ++numchildrenS >= childAllocS ){
1445 childAllocS += EXPECTEDPINGRP ;
1446 pingroup_spin->children = (PINBOXPTR *)
1447 Ysafe_realloc( pingroup_spin->children,
1448 childAllocS * sizeof(PINBOXPTR) ) ;
1449 }
1450 pingroup_spin->children[numchildrenS] = pin ;
1451 pingroup_spin->children[HOWMANY] = (PINBOXPTR) numchildrenS ;
1452 spin->parent = pingroupS ;
1453 /* now update any equivalent subpins to leaves */
1454 if( spin->hierarchy == NONE && spin->children ){
1455 howmany = (INT) spin->children[HOWMANY] ;
1456 for( i = 1; i <= howmany; i++ ){
1457 cpin = spin->children[i] ;
1458 if( cpin->type == SOFTEQUIVTYPE ){
1459 cpin->softinfo->hierarchy = LEAF ;
1460 cpin->softinfo->ordered = ordered ;
1461 }
1462 }
1463 }
1464 spin->hierarchy = LEAF ;
1465 spin->ordered = ordered ;
1466 return;
1467 }
1468 }
1469
1470 /* if no match above must be subroot */
1471 curpingroup = ptrS->numpins + numchildrenS ;
1472 for( i = ptrS->numpins ; i < curpingroup; i++ ){
1473 pin = ptrS->softpins[i] ;
1474 spin = pin->softinfo ;
1475 if (strcmp(pinName, pin->pinname) == STRINGEQ) {
1476 if (spin->hierarchy == SUBROOT) {
1477 sprintf(YmsgG,
1478 "pin group %s was included in more than 1 pin group\n",
1479 pin->pinname);
1480 M(ERRMSG,"add2pingroup",YmsgG ) ;
1481 setErrorFlag() ;
1482 return ;
1483 }
1484 pingroup_spin = pingroupS->softinfo ;
1485 if( ++numchildrenS >= childAllocS ){
1486 childAllocS += EXPECTEDPINGRP ;
1487 pingroup_spin->children = (PINBOXPTR *)
1488 Ysafe_realloc( pingroup_spin->children,
1489 childAllocS * sizeof(PINBOXPTR) ) ;
1490 }
1491 pingroup_spin->children[numchildrenS] = pin ;
1492 pingroup_spin->children[HOWMANY] = (PINBOXPTR) numchildrenS ;
1493 spin->parent = pingroupS ;
1494 spin->hierarchy = SUBROOT ;
1495 spin->ordered = ordered ;
1496 return ;
1497 }
1498 }
1499
1500 sprintf(YmsgG,"cannot find pin <%s> for pin_group <%s>\n",
1501 pinName,ptrS->softpins[curpingroup]->pinname );
1502 M(ERRMSG,"add2pingroup",YmsgG ) ;
1503 return ;
1504
1505 } /* end add2pingroup */
1506 /* ***************************************************************** */
1507
addSideSpace(lower,upper)1508 void addSideSpace( lower, upper )
1509 DOUBLE lower ;
1510 DOUBLE upper ;
1511 {
1512 ERRORABORT() ;
1513
1514 pptrS->fixed = TRUE ;
1515 if( lower > 1.0 || upper > 1.0 ){
1516 sprintf(YmsgG,
1517 "side space must be less or equal to 1.0 for pad: %s\n",ptrS->cname ) ;
1518 M(ERRMSG,"addSideSpace",YmsgG ) ;
1519 setErrorFlag() ;
1520 }
1521 if( lower < 0.0 || upper < 0.0 ){
1522 sprintf(YmsgG,
1523 "side space must be greater or equal to 0.0 for pad: %s\n",ptrS->cname ) ;
1524 M(ERRMSG,"addSideSpace",YmsgG ) ;
1525 setErrorFlag() ;
1526 }
1527 if( lower > upper ){
1528 sprintf(YmsgG,
1529 "side space upper bound must be greater or equal to lower bound for pad: %s\n",ptrS->cname ) ;
1530 M(ERRMSG,"addSideSpace",YmsgG ) ;
1531 setErrorFlag() ;
1532 }
1533 pptrS->lowerbound = lower ;
1534 pptrS->upperbound = upper ;
1535 } /* end addSideSpace */
1536 /* ***************************************************************** */
1537
addPadSide(side)1538 void addPadSide( side )
1539 char *side ;
1540 {
1541
1542 INT numsides ; /* length of side restriction string */
1543 INT i ; /* counter */
1544
1545 ERRORABORT() ;
1546
1547 pptrS->valid_side[ALL] = FALSE ;
1548 numsides = strlen( side ) ;
1549 for( i = 0 ; i < numsides; i++ ){
1550 switch( side[i] ){
1551 case 'B' :
1552 pptrS->valid_side[B] = TRUE ;
1553 break ;
1554 case 'L' :
1555 pptrS->valid_side[L] = TRUE ;
1556 break ;
1557 case 'R' :
1558 pptrS->valid_side[R] = TRUE ;
1559 break ;
1560 case 'T' :
1561 pptrS->valid_side[T] = TRUE ;
1562 break ;
1563 default:
1564 sprintf( YmsgG,
1565 "side restriction not specified properly for pad:%s\n",
1566 ptrS->cname );
1567 M(ERRMSG,"addPadSide",YmsgG ) ;
1568 setErrorFlag() ;
1569 } /* end switch */
1570 }
1571
1572 } /* end addPadSide */
1573 /* ***************************************************************** */
1574
1575 /* set whether a pad group can be permuted */
setPermutation(int permuteFlag)1576 void setPermutation( int permuteFlag )
1577 {
1578 ERRORABORT() ;
1579 pptrS->permute = permuteFlag ;
1580 } /* end setPermutation */
1581 /* ***************************************************************** */
1582
1583 /* add this pad to the current pad group */
add2padgroup(padName,ordered)1584 void add2padgroup( padName, ordered )
1585 char *padName ;
1586 BOOL ordered ; /* ordered flag is true if pad is ordered in padgroup */
1587 {
1588 INT i, endofpads, endofgroups, endofcells ;
1589
1590 ERRORABORT() ;
1591 endofpads = numcellsG + numpadsG ;
1592 endofcells = numcellsG + numsupercellsG ;
1593 /* check pads for correctness */
1594 for (i = numcellsG + 1; i <= endofpads; ++i) {
1595 if (strcmp(padName, cellarrayG[i]->cname) == STRINGEQ) {
1596 if (cellarrayG[i]->padptr->hierarchy == LEAF) {
1597 sprintf(YmsgG,
1598 "pad %s was included in more than 1 pad group\n",
1599 cellarrayG[i]->cname);
1600 M(ERRMSG,"add2padgroup",YmsgG ) ;
1601 setErrorFlag() ;
1602 return ;
1603 }
1604 /* check memory of pin array */
1605 if( ++numchildrenS >= childAllocS ){
1606 childAllocS += EXPECTEDNUMPADS ;
1607 pptrS->children = (INT *)
1608 Ysafe_realloc( pptrS->children,
1609 childAllocS * sizeof(INT) ) ;
1610 }
1611 pptrS->children[numchildrenS] = i - endofcells ;
1612 cellarrayG[i]->padptr->hierarchy = LEAF ;
1613 cellarrayG[i]->padptr->ordered = ordered ;
1614 /* total pins of the leaves */
1615 ptrS->numpins += cellarrayG[i]->numpins;
1616 return;
1617 }
1618 }
1619
1620 /* if no match above must be subroot */
1621 endofgroups = numcellsG + numpadsG + numpadgroupsG ;
1622 for (i = endofpads; i <= endofgroups; ++i) {
1623 if (strcmp(padName, cellarrayG[i]->cname) == STRINGEQ) {
1624 if (cellarrayG[i]->padptr->hierarchy == SUBROOT) {
1625 sprintf(YmsgG,"pad group %s was included in more than 1 pad group\n",
1626 cellarrayG[i]->cname);
1627 M(ERRMSG,"add2padgroup",YmsgG ) ;
1628 setErrorFlag() ;
1629 return ;
1630 }
1631 /* check memory of pin array */
1632 if( ++numchildrenS >= childAllocS ){
1633 childAllocS += EXPECTEDNUMPADS ;
1634 pptrS->children = (INT *)
1635 Ysafe_realloc( pptrS->children,
1636 childAllocS * sizeof(INT) ) ;
1637 }
1638 pptrS->children[numchildrenS] = i - endofcells ;
1639 cellarrayG[i]->padptr->hierarchy = SUBROOT ;
1640 cellarrayG[i]->padptr->ordered = ordered ;
1641 /* total pins of the leaves */
1642 ptrS->numpins += cellarrayG[i]->numpins;
1643 return ;
1644 }
1645 }
1646
1647 sprintf(YmsgG,"cannot find pad <%s> for pad_group <%s>\n",
1648 padName,ptrS->cname);
1649 M(ERRMSG,"add2padgroup",YmsgG ) ;
1650 return ;
1651
1652 } /* end add2PadGroup */
1653 /* ***************************************************************** */
add_cell_to_group(cellName)1654 void add_cell_to_group( cellName )
1655 char *cellName ;
1656 {
1657 GLISTPTR tempCell ;
1658 INT cell, *data ;
1659 CELLBOXPTR cptr ;
1660
1661 if(!(data = (INT *) Yhash_search( cellTableS, cellName, NULL, FIND ))){
1662 sprintf( YmsgG, "Couldn't find cellname:%s for group\n",cellName );
1663 M(ERRMSG,"add_cell_to_group",YmsgG ) ;
1664 errorFlagS = TRUE ;
1665 return ;
1666 }
1667 cell = *data ;
1668
1669 if( tempCell = curGroupS->cells ){
1670 curGroupS->cells = (GLISTPTR) Ysafe_malloc( sizeof(GLISTBOX) ) ;
1671 curGroupS->cells->next = tempCell ;
1672 } else { /* start list */
1673 curGroupS->cells = (GLISTPTR) Ysafe_malloc( sizeof(GLISTBOX) ) ;
1674 curGroupS->cells->next = NULL ;
1675 }
1676
1677 cptr = cellarrayG[cell] ;
1678 if( cptr->group_nested ){
1679 /* group_nest field should be NULL if cell is not nested */
1680 sprintf( YmsgG, "cell %d:%s appears in more than one group\n",
1681 cell, cptr->cname ) ;
1682 M(ERRMSG,"add_cell_to_group",YmsgG ) ;
1683 errorFlagS = TRUE ;
1684 } else {
1685 cptr->group = curGroupS ;
1686 /* save cell in generic list */
1687 curGroupS->cells->p.cell = cell ;
1688 cptr->group_nested = TRUE ;
1689 }
1690 /* set exchange class so cells can't leave group thru pairwise swap */
1691 cptr->class = unique_classG ;
1692
1693 } /* end add_cell_to_group */
1694
1695 /* add a cell to the instance array of the defining cell */
add_instance(instName)1696 void add_instance( instName )
1697 char *instName ;
1698 {
1699 if( cellinstanceS++ == 0 ){
1700 /* our first instance we now have two instances */
1701 instS = ptrS->instptr = (INSTBOXPTR) Ysafe_malloc( sizeof(INSTBOX) ) ;
1702 ptrS->cur_inst = 0 ;
1703 instS->numinstances = 1 ;
1704 instAllocS = 2 ; /* default is just two instances */
1705 /* allocate arrays for instances */
1706 instS->tile_inst = (TILEBOXPTR *)
1707 Ysafe_calloc( instAllocS, sizeof(TILEBOXPTR) ) ;
1708 instS->bounBox = (BOUNBOXPTR **)
1709 Ysafe_calloc( instAllocS, sizeof(BOUNBOXPTR *) ) ;
1710 instS->numtile_inst = (INT *)
1711 Ysafe_calloc( instAllocS, sizeof(INT) ) ;
1712 instS->vert_inst = (VERTBOXPTR *)
1713 Ysafe_malloc( instAllocS*sizeof(VERTBOXPTR) ) ;
1714 instS->name_inst = (char **)
1715 Ysafe_malloc( instAllocS*sizeof(char *) ) ;
1716 /* store main instance in element 0 of arrays */
1717 instS->tile_inst[0] = ptrS->tiles ;
1718 instS->bounBox[0] = ptrS->bounBox ;
1719 instS->numtile_inst[0] = ptrS->numtiles ;
1720 instS->vert_inst[0] = ptrS->vertices ;
1721 instS->name_inst[0] = ptrS->cname ;
1722 instS->name_inst[1] = instName ;
1723
1724 /* now for softcells */
1725 /* allocate arrays for instances */
1726 instS->numsides = (INT *)
1727 Ysafe_calloc( instAllocS, sizeof(INT) ) ;
1728 /* store main instance in element 0 of arrays */
1729 instS->numsides[0] = ptrS->numsides ;
1730 } else { /* realloc space for instances */
1731 /* instances are rare and we are only dealing with pointers so */
1732 /* always realloc, leave code general enough to change */
1733 instAllocS += EXPECTEDINSTANCES ;
1734 instS->tile_inst = (TILEBOXPTR *)
1735 Ysafe_realloc(instS->tile_inst,instAllocS*sizeof(TILEBOXPTR));
1736 instS->vert_inst = (VERTBOXPTR *)
1737 Ysafe_realloc(instS->vert_inst,instAllocS*sizeof(VERTBOXPTR));
1738 instS->numtile_inst = (INT *)
1739 Ysafe_realloc( instS->numtile_inst, instAllocS*sizeof(INT) ) ;
1740 instS->bounBox = (BOUNBOXPTR **)
1741 Ysafe_realloc(instS->bounBox,instAllocS*sizeof(BOUNBOXPTR *));
1742 instS->name_inst = (char **)
1743 Ysafe_realloc(instS->name_inst,instAllocS*sizeof(char *) ) ;
1744 instS->numsides = (INT *)
1745 Ysafe_realloc( instS->numsides,instAllocS*sizeof(INT));
1746 }
1747 minxS = INT_MAX ;
1748 minyS = INT_MAX ;
1749 maxxS = INT_MIN ;
1750 maxyS = INT_MIN ;
1751 ptrS->numtiles = 0 ;
1752 cornerCountS = 0 ;
1753 instS->numinstances++ ;
1754 numinstancesG++ ;
1755
1756 } /* end add_cell_instance */
1757
get_tile_count()1758 INT get_tile_count()
1759 {
1760 return( tileptAllocS / 2 ) ;
1761 } /* end get_tile_count() */
1762
add_analog(numcorners)1763 void add_analog( numcorners )
1764 INT numcorners ;
1765 {
1766 ERRORABORT() ;
1767 /* allocate space for array of instances */
1768 if( cellinstanceS == 0 ){
1769 pinS->ainst = (ANALOGPTR *) Ysafe_malloc( sizeof(ANALOGPTR) );
1770 } else {
1771 pinS->ainst = (ANALOGPTR *) Ysafe_realloc( pinS->ainst,
1772 instAllocS * sizeof(ANALOGPTR) );
1773 }
1774 analogS = pinS->analog = (ANALOGPTR) Ysafe_malloc( sizeof(ANALOGBOX) ) ;
1775 pinS->ainst[cellinstanceS] = analogS ;
1776
1777 /* now fill in data */
1778 if( numcorners >= 4 ){
1779 analogS->x_contour = (INT *) Ysafe_malloc( numcorners * sizeof(INT)) ;
1780 analogS->y_contour = (INT *) Ysafe_malloc( numcorners * sizeof(INT)) ;
1781 analogS->num_corners = numcorners ;
1782 cornerCountS = 0 ;
1783 } else {
1784 analogS->x_contour = NIL(INT *) ;
1785 analogS->y_contour = NIL(INT *) ;
1786 analogS->num_corners = 0 ;
1787 }
1788 analogS->current = INIT_CURRENT ;
1789 analogS->power = (FLOAT) 0.0 ;
1790 analogS->no_layer_change = FALSE ;
1791
1792 } /* end add_analog */
1793
add_pin_contour(x,y)1794 void add_pin_contour( x, y )
1795 INT x, y ;
1796 {
1797 if( cornerCountS >= analogS->num_corners ){
1798 sprintf( YmsgG, "Incorrect number of vertices for pin:%s\n",
1799 curPinNameS ) ;
1800 M(ERRMSG,"add_pin_contour", YmsgG ) ;
1801 setErrorFlag() ;
1802 cornerCountS = 0 ; /* reset to avoid numerous error msgs */
1803 }
1804 ERRORABORT() ;
1805 analogS->x_contour[cornerCountS] = x ;
1806 analogS->y_contour[cornerCountS++] = y ;
1807 } /* end start_pin_contour */
1808
1809
add_current(current)1810 void add_current( current )
1811 FLOAT current ;
1812 {
1813 if(!(analogS)){
1814 add_analog( 0 ) ;
1815 }
1816 analogS->current = current ;
1817 } /* end add_current */
1818
add_power(power)1819 void add_power( power )
1820 FLOAT power ;
1821 {
1822 if(!(analogS)){
1823 add_analog( 0 ) ;
1824 }
1825 analogS->power = power ;
1826 } /* end add_power */
1827
no_layer_change()1828 void no_layer_change()
1829 {
1830 if(!(analogS)){
1831 add_analog( 0 ) ;
1832 }
1833 analogS->no_layer_change = TRUE ;
1834 } /* end no_cross_under */
1835
process_pin()1836 void process_pin()
1837 {
1838 INT i ; /* point counter */
1839 INT side ; /* current side for pin */
1840 INT ptx, pty ; /* current point of interest */
1841 INT xpos, ypos ; /* center of pin */
1842 INT minx, miny, maxx, maxy ; /* bounding box of pin contour */
1843 char *buster_msg ; /* message string to used by buster */
1844 INT xx1, yy1, xx2, yy2 ; /* temp points */
1845
1846 ERRORABORT() ;
1847
1848 if(!(analogS) || analogS->num_corners < 4 ){
1849 return ; /* no work to do */
1850 }
1851
1852 /* now check the points to make sure they are good */
1853 sprintf( YmsgG, " (cell:%s pin:%s) ", curCellNameS, pinS->pinname ) ;
1854 buster_msg = Ystrclone( YmsgG ) ;
1855 Ybuster_check_rect_init( buster_msg ) ;
1856 minx = INT_MAX ;
1857 miny = INT_MAX ;
1858 maxx = INT_MIN ;
1859 maxy = INT_MIN ;
1860 for( i = 0 ; i < analogS->num_corners ; i++ ) {
1861 xx1 = analogS->x_contour[i] ;
1862 yy1 = analogS->y_contour[i] ;
1863 if( i == analogS->num_corners-1 ) {
1864 xx2 = analogS->x_contour[0] ;
1865 yy2 = analogS->y_contour[0] ;
1866 } else {
1867 xx2 = analogS->x_contour[ i + 1 ] ;
1868 yy2 = analogS->y_contour[ i + 1 ] ;
1869 }
1870 if( Ybuster_check_rect( xx1, yy1, xx2, yy2 ) ){
1871 analog_errorS = TRUE ;
1872 }
1873
1874 /* find bounding box of pins */
1875 minx = MIN( minx, xx1 ) ;
1876 maxx = MAX( maxx, xx1 ) ;
1877 miny = MIN( miny, yy1 ) ;
1878 maxy = MAX( maxy, yy1 ) ;
1879 }
1880 Ysafe_free( buster_msg ) ;
1881
1882 /* now set the center of the pin to this location */
1883 xpos = (minx + maxx) / 2 ;
1884 ypos = (miny + maxy) / 2 ;
1885
1886 /* now subtract off the cell center */
1887 for( i = 0 ; i < analogS->num_corners ; i++ ) {
1888 analogS->x_contour[i] -= xcenterS ;
1889 analogS->y_contour[i] -= ycenterS ;
1890 }
1891 set_pin_pos( xpos, ypos ) ;
1892
1893 } /* end process_analog_pin */
1894