1 /*
2 * Copyright (C) 1989-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: output.c
42 DESCRIPTION:output the placement information.
43 CONTENTS: output()
44 final_free_up()
45 create_cel_file()
46 DATE: Mar 27, 1989
47 REVISIONS: July 15, 1989
48 Oct 2, 1990 - removed elim_unused feeds and
49 added check for clength == 0.
50 Wed Jan 16 14:25:22 PST 1991 - commented out free
51 of pairArrayG.
52 Wed Jan 23 02:43:33 PST 1991 - output at density.
53 Sat May 4 13:47:58 EDT 1991 - now output row field
54 similar to global routing definition.
55 Tue Aug 13 12:47:54 CDT 1991 - fixed create new
56 cell file.
57 ----------------------------------------------------------------- */
58
59 /* #define DEC */
60 /* added on 06/01/90 Sury */
61 /* #define NSC */
62
63 #include "standard.h"
64 #include "groute.h"
65 #include "main.h"
66 #include "readpar.h"
67 #include "config.h"
68 #include "pads.h"
69 #include <string.h>
70 #include <yalecad/debug.h>
71 #include <yalecad/message.h>
72
73 /* external functions */
74 char *strtok(); /* added 06/01/90 sury */
75 INT comparex() ;
76
77 /* global variables */
78 extern INT spacer_widthG ;
79 extern INT actual_feed_thru_cells_addedG ;
80 extern BOOL output_at_densityG ;
81 extern BOOL create_new_cel_fileG ;
82 extern BOOL unused_feed_name_twspacerG ;
83 extern BOOL stand_cell_as_gate_arrayG ;
84
85 /* static definitions */
86 static char a_lineS[LRECL] ;
87
88 INT load_a_lineS(FILE *fp);
89 void create_cel_file();
90 void add_new_line( INT x_rel , INT block , char *fixed_ptr , FILE *fp );
91
output()92 void output()
93 {
94
95 FILE *fpp1 , *fpp2 ;
96 INT locx , locy , height , width ;
97 INT xloc , i , cell , block , orient ;
98 INT num ;
99 INT xloc2 , yloc2 , yloc ;
100 INT *array , desire , k , limit ;
101 INT left , right , bottom , top , end ;
102 INT *deleted_feeds ;
103 INT eliminated_feeds ;
104 char filename[LRECL] , ctmp[32] ;
105 CBOXPTR cellptr ;
106 TIBOXPTR tptr ;
107 PADBOXPTR pptr ;
108 /* added on 06/01/90 Sury */
109 INT length;
110 INT row ;
111 char instance_name[LRECL], tmp_name[LRECL], *tmp_string;
112
113
114 deleted_feeds = (INT *) Ysafe_malloc( numcellsG * sizeof(INT) ) ;
115 eliminated_feeds = 0 ;
116
117 sprintf( filename , "%s.pl1" , cktNameG ) ;
118 fpp1 = TWOPEN( filename , "w", ABORT ) ;
119
120 sprintf( filename , "%s.pl2" , cktNameG ) ;
121 fpp2 = TWOPEN( filename , "w", ABORT ) ;
122
123 for( block = 1 ; block <= numRowsG ; block++ ) {
124
125 left = barrayG[block]->bxcenter + barrayG[block]->bleft ;
126 right = barrayG[block]->bxcenter + barrayG[block]->bright ;
127 bottom = barrayG[block]->bycenter + barrayG[block]->bbottom ;
128 top = barrayG[block]->bycenter + barrayG[block]->btop ;
129
130 if( restartG == 0 && costonlyG == 1 ) {
131 desire = barrayG[block]->desire ;
132 } else {
133 if( pairArrayG[block][0] > 0 ) {
134 cell = pairArrayG[block][ pairArrayG[block][0] ] ;
135 end = carrayG[cell]->cxcenter + carrayG[cell]->tileptr
136 ->right ;
137 desire = end - left ;
138 } else {
139 desire = 0 ;
140 }
141 }
142
143 if( barrayG[block]->borient > 0 ) {
144 fprintf(fpp2,"%d %d %d %d %d 0 0\n", block ,
145 left, bottom, left + desire, top ) ;
146 } else {
147 fprintf(fpp2,"%d %d %d %d %d 0 0\n", block ,
148 left, bottom, right, bottom + desire ) ;
149 }
150
151 num = pairArrayG[block][0] ;
152 if( num == 0 ) {
153 continue ;
154 }
155 array = pairArrayG[block] + 1 ;
156
157 for( i = 0 ; i < num ; i++ ) {
158 cell = array[ i ] ;
159 cellptr = carrayG[ cell ] ;
160 if( cellptr->clength == 0 ){
161 continue ;
162 }
163 if( strcmp( cellptr->cname , "TW_EXCEPT" ) == 0 ) {
164 continue ;
165 }
166 if( stand_cell_as_gate_arrayG ) {
167 if( strcmp( cellptr->cname , "GATE_ARRAY_SPACER" ) == 0 ) {
168 continue ;
169 }
170 }
171 if( unused_feed_name_twspacerG ) {
172 if( strncmp(cellptr->cname,"twfeed",6) == STRINGEQ ) {
173 if( tearrayG[cellptr->imptr->terminal] == NULL ) {
174 strcpy( ctmp , cellptr->cname ) ;
175 cellptr->cname = (char *) Ysafe_realloc(
176 cellptr->cname, (strlen(cellptr->cname)+3) *
177 sizeof(char) ) ;
178 sprintf( cellptr->cname , "%s%s" , "twspacer",
179 strpbrk(ctmp, "0123456789") ) ;
180 }
181 }
182 }
183 orient = cellptr->corient ;
184
185 xloc = cellptr->cxcenter + cellptr->tileptr->left ;
186 yloc = cellptr->cycenter + cellptr->tileptr->bottom ;
187
188 xloc2 = cellptr->tileptr->right -
189 cellptr->tileptr->left ;
190 yloc2 = cellptr->tileptr->top -
191 cellptr->tileptr->bottom ;
192
193 /* The following code was added on 06/01/90 Sury */
194 #ifdef NSC
195 strcpy( tmp_name , cellptr->cname ) ;
196 length = strcspn( tmp_name , ":" ) ;
197 if( length < strlen( tmp_name ) ) {
198 tmp_string = strtok( tmp_name , ":" ) ;
199 tmp_string = strtok( NULL , ":" ) ;
200 sprintf( instance_name, "%s" , tmp_string ) ;
201 } else {
202 sprintf( instance_name , "%s" , tmp_name ) ;
203 }
204 fprintf(fpp1,"%s %d %d %d %d %d %d\n",
205 instance_name,
206 xloc, yloc, xloc + xloc2,
207 yloc + yloc2, orient, block ) ;
208 #else
209 fprintf(fpp1,"%s %d %d %d %d %d %d\n",
210 cellptr->cname ,
211 xloc, yloc, xloc + xloc2,
212 yloc + yloc2, orient, block ) ;
213 #endif
214 }
215 }
216
217 if( deleted_feeds[0] > 0 ) {
218 fprintf(fpoG,"Confirming number of eliminated feeds:%d\n",
219 eliminated_feeds ) ;
220 }
221
222 /* now output the pads and macros */
223 for( i = numcellsG + 1 ; i <= lastpadG ; i++ ) {
224 cellptr = carrayG[ i ] ;
225 orient = cellptr->corient ;
226 tptr = cellptr->tileptr ;
227 left = tptr->left ;
228 right = tptr->right ;
229 bottom = tptr->bottom ;
230 top = tptr->top ;
231 YtranslateT( &left, &bottom, &right, &top, orient ) ;
232 locx = cellptr->cxcenter + left ;
233 locy = cellptr->cycenter + bottom ;
234 height = top - bottom ;
235 width = right - left ;
236 /* determine row */
237 pptr = cellptr->padptr ;
238 if( pptr->macroNotPad ){
239 row = 0 ;
240 } else {
241 switch( pptr->padside ){
242 case L:
243 row = - 1 ;
244 break ;
245 case T:
246 row = -4 ;
247 break ;
248 case R:
249 row = - 2 ;
250 break ;
251 case B:
252 row = - 3 ;
253 break ;
254 default:
255 M(ERRMSG,"output", "Unknown padside\n" ) ;
256 }
257 }
258
259
260 #ifndef DEC
261 /* The following code was added on 06/01/90 Sury */
262 #ifdef NSC
263 strcpy( tmp_name , cellptr->cname ) ;
264 length = strcspn( tmp_name , ":" ) ;
265 if( length < strlen( tmp_name ) ) {
266 tmp_string = strtok( tmp_name , ":" ) ;
267 tmp_string = strtok( NULL , ":" ) ;
268 sprintf( instance_name, "%s" , tmp_string ) ;
269 } else {
270 sprintf( instance_name , "%s" , tmp_name ) ;
271 }
272 fprintf(fpp1,"%s %d %d %d %d %d %d\n", instance_name,
273 locx, locy, locx + width,
274 locy + height, orient, row ) ;
275 fprintf(fpp2,"%s %d %d %d %d %d %d\n", instance_name,
276 locx, locy, locx + width,
277 locy + height, orient, row ) ;
278 #else
279 /* normal case */
280 fprintf(fpp1,"%s %d %d %d %d %d %d\n", cellptr->cname ,
281 locx, locy, locx + width,
282 locy + height, orient, row ) ;
283 fprintf(fpp2,"%s %d %d %d %d %d %d\n", cellptr->cname ,
284 locx, locy, locx + width,
285 locy + height, orient, row ) ;
286 #endif
287 #else
288 /* DEC case */
289 fprintf(fpp1,"%s %d %d %d %d %d %d\n", cellptr->cname ,
290 locx, locy, locx + width,
291 locy + height, orient, -cellptr->padside ) ;
292 fprintf(fpp2,"%s %d %d %d %d %d %d\n", cellptr->cname ,
293 locx, locy, locx + width,
294 locy + height, orient, -cellptr->padside ) ;
295 #endif
296
297 }
298 TWCLOSE( fpp1 ) ;
299 TWCLOSE( fpp2 ) ;
300
301 if( create_new_cel_fileG ) {
302 create_cel_file() ;
303 }
304
305 Ysafe_free( deleted_feeds ) ;
306
307 return ;
308 }
309
310
311
312
313
final_free_up()314 void final_free_up()
315 {
316 INT i, j, k, row, pin, net, cell, chan, track ;
317 CBOXPTR cellptr ;
318 DBOXPTR dimptr ;
319 PINBOXPTR ptr, nextptr ;
320 ADJASEGPTR adj, nextadj ;
321 SEGBOXPTR segptr, nextseg ;
322 CHANGRDPTR gdptr, nextgrd ;
323 DENSITYPTR *hdptr ;
324 IPBOXPTR imptr ;
325 FEED_DATA *feedptr ;
326
327 Ysafe_free( FeedInRowG ) ;
328 for( row = 1 ; row <= numRowsG ; row++ ) {
329 Ysafe_free( impFeedsG[row] ) ;
330 }
331 Ysafe_free( impFeedsG ) ;
332
333 for( i = 1 ; i <= numRowsG ; i++ ) {
334 feedptr = feedpptrG[i] ;
335 for( j = 1 ; j <= chan_node_noG ; j++ ) {
336 Ysafe_free( feedptr[j] ) ;
337 }
338 Ysafe_free( feedpptrG[i] ) ;
339 }
340 Ysafe_free( feedpptrG ) ;
341
342 k = max_tdensityG + 100 ;
343 for( chan = 1 ; chan <= numChansG ; chan++ ) {
344 Ysafe_free( BeginG[chan]->netptr ) ;
345 Ysafe_free( EndG[chan]->netptr ) ;
346 for( gdptr = BeginG[chan] ; gdptr ; gdptr = nextgrd ) {
347 nextgrd = gdptr->nextgrd ;
348 Ysafe_free( gdptr->dptr ) ;
349 Ysafe_free( gdptr ) ;
350 }
351
352 hdptr = DboxHeadG[chan] ;
353 for( track = 0 ; track <= k ; track++ ) {
354 Ysafe_free( hdptr[track] ) ;
355 }
356 Ysafe_free( DboxHeadG[chan] ) ;
357 }
358 Ysafe_free( BeginG ) ;
359 Ysafe_free( EndG ) ;
360 Ysafe_free( DboxHeadG ) ;
361 Ysafe_free( maxTrackG ) ;
362 Ysafe_free( nmaxTrackG ) ;
363
364 k = maxtermG + 2 * numChansG ;
365 for( pin = 1 ; pin <= k ; pin++ ) {
366 Ysafe_free( TgridG[pin] ) ;
367 }
368 Ysafe_free( TgridG ) ;
369
370 /*
371 Not needed as this is done in findunlap.c
372 for( i = 1 ; i <= numRowsG ; i++ ) {
373 Ysafe_free( pairArrayG[i] ) ;
374 }
375 Ysafe_free( pairArrayG ) ;
376 pairArrayG = NULL ;
377 */
378
379 for( cell = 1 ; cell <= numcellsG ; cell++ ) {
380 cellptr = carrayG[cell] ;
381 imptr = cellptr->imptr ;
382 if( imptr ) {
383 for( ; imptr->next; imptr = imptr->next ) {
384 if( imptr->next->cell != cell ) break ;
385 }
386 imptr->next = NULL ;
387 }
388 }
389 fprintf( fpoG,"Actual # of Feed Cells Added:\t%d\n\n\n",
390 actual_feed_thru_cells_addedG ) ;
391 k = numcellsG + numtermsG + actual_feed_thru_cells_addedG ;
392 for( cell = numcellsG + numtermsG + 1 ; cell <= k ; cell++ ) {
393 cellptr = carrayG[cell] ;
394 cellptr->imptr->next = NULL ;
395 Ysafe_free( cellptr->cname ) ;
396 Ysafe_free( cellptr->tileptr ) ;
397 Ysafe_free( cellptr->imptr->pinname ) ;
398 Ysafe_free( cellptr->imptr->eqpinname ) ;
399 Ysafe_free( cellptr->imptr ) ;
400 Ysafe_free( carrayG[cell] ) ;
401 carrayG[cell] = NULL ;
402 }
403 actual_feed_thru_cells_addedG = 0 ;
404
405 for( net = 1 ; net <= numnetsG ; net++ ) {
406 for( segptr = netsegHeadG[net] ; segptr ; segptr = nextseg ) {
407 nextseg = segptr->next ;
408 Ysafe_free( segptr ) ;
409 }
410 dimptr = netarrayG[net] ;
411 if( !dimptr->pins ) {
412 continue ;
413 }
414 if( dimptr->pins->terminal > TotRegPinsG ) {
415 for( ptr = dimptr->pins ; ptr ; ptr = nextptr ) {
416 nextptr = ptr->next ;
417 for( adj = ptr->adjptr ; adj ; adj = nextadj ) {
418 nextadj = adj->next ;
419 Ysafe_free( adj ) ;
420 }
421 Ysafe_free( ptr->eqptr ) ;
422 if( nextptr->terminal <= TotRegPinsG ) break ;
423 }
424 dimptr->pins = nextptr ;
425 }
426 for( ptr = dimptr->pins ; ptr ; ptr = ptr->next ) {
427 for( adj = ptr->adjptr->next ; adj ; adj = nextadj ) {
428 nextadj = adj->next ;
429 Ysafe_free( adj ) ;
430 }
431 ptr->adjptr->next = NULL ;
432 }
433 }
434 Ysafe_free( netsegHeadG ) ;
435
436 }
437
438
439
440
create_cel_file()441 void create_cel_file()
442 {
443
444
445 FILE *fpoG2 , *fp ;
446 char *token , fixed_string[32] , filename[256] ;
447 char cell_name[32] ;
448 INT ignore_line , block , offset , test , carrayG_index , is_a_cell ;
449
450
451 if( rowsG > 0 ) {
452 sprintf( filename , "%s.scel" , cktNameG ) ;
453 fp = TWOPEN( filename, "r" , ABORT ) ;
454 } else {
455 sprintf( filename , "%s.cel" , cktNameG ) ;
456 fp = TWOPEN( filename, "r" , ABORT ) ;
457 }
458 sprintf( filename , "%s.ncel" , cktNameG ) ;
459 fpoG2 = TWOPEN( filename, "w" , ABORT ) ;
460
461 strcpy( fixed_string , "" ) ;
462 carrayG_index = 0 ;
463 while( load_a_lineS(fp) ) {
464 ignore_line = 0 ;
465 if( (token = strtok( a_lineS , " " )) != NULL ) {
466 if( strcmp( token , "cell" ) == 0 ) {
467 is_a_cell = 1 ;
468 fprintf(fpoG2, "%s ", token ) ;
469 token = strtok( NULL , " " ) ;
470 fprintf(fpoG2, "%s ", token ) ;
471 strcpy( cell_name , strtok( NULL , " " ) ) ;
472 fprintf(fpoG2, "%s ", cell_name ) ;
473 do {
474 test = strcmp( carrayG[ ++carrayG_index ]->cname,
475 cell_name ) ;
476 } while( test != 0 ) ;
477 } else if( strcmp( token , "left" ) == 0 ) {
478 if( is_a_cell ) {
479 block = carrayG[carrayG_index]->cblock ;
480 offset = carrayG[carrayG_index]->cxcenter +
481 carrayG[carrayG_index]->tileptr->left -
482 (barrayG[block]->bxcenter +
483 barrayG[block]->bleft) ;
484
485 if( strcmp( fixed_string , "" ) != 0 ) {
486 add_new_line( offset , block , fixed_string , fpoG2 ) ;
487 strcpy( fixed_string , "" ) ;
488 } else {
489 add_new_line( offset , block , "nonfixed" , fpoG2 ) ;
490 }
491 }
492 fprintf(fpoG2, "%s ", token ) ;
493 is_a_cell = 0 ;
494 } else if( strcmp( token , "initially" ) == 0 ) {
495 ignore_line = 1 ;
496 strcpy( fixed_string , strtok( NULL , " " ) ) ;
497 } else if( strcmp( token , "\n" ) != 0 ) {
498 fprintf(fpoG2, "%s ", token ) ;
499 }
500 while( (token = strtok( NULL , " " )) != NULL ) {
501 if( !ignore_line ) {
502 fprintf(fpoG2, "%s ", token ) ;
503 }
504 }
505 }
506 if( !ignore_line ) {
507 fprintf(fpoG2, "\n");
508 }
509 }
510 TWCLOSE(fp) ;
511 TWCLOSE(fpoG2) ;
512 }
513
514
515
add_new_line(INT x_rel,INT block,char * fixed_ptr,FILE * fp)516 void add_new_line( INT x_rel , INT block , char *fixed_ptr , FILE *fp )
517 {
518
519 fprintf(fp, "initially %s %d from left of block %d\n",
520 fixed_ptr , x_rel , block ) ;
521 return ;
522 }
523
524
525
load_a_lineS(FILE * fp)526 INT load_a_lineS(FILE *fp)
527 {
528
529 INT i ;
530 char tmp ;
531
532 if( (int) (tmp = fgetc(fp)) != EOF ) {
533 a_lineS[0] = tmp ;
534 i = 1 ;
535 if( tmp != '\n' ) {
536 while( (a_lineS[i] = fgetc(fp)) != '\n' ) {
537 i++ ;
538 }
539 }
540 a_lineS[i] = '\0' ;
541 return(1) ;
542 } else {
543 return(0) ;
544 }
545 }
546
547 /* ******************************************************************** */
density()548 void density()
549 {
550 /* set all the cells at density */
551 INT row ;
552 INT cell ;
553 INT block ;
554 INT rowtop ;
555 INT corient ;
556 INT rowcenter ;
557 CBOXPTR cellptr ;
558 PINBOXPTR pin ;
559
560 /* first update all the y coordinates of rows */
561 if (maxTrackG){ /* only perform if global routing is performed */
562 for( row = 1 ; row <= numRowsG ; row++ ) {
563 if( row == 1 ){
564 rowcenter = barrayG[1]->bheight / 2 +
565 maxTrackG[1]*track_pitchG + route2actG ;
566 } else {
567 rowcenter = rowtop + barrayG[row]->bheight / 2 +
568 maxTrackG[row]*track_pitchG + route2actG ;
569 }
570 rowtop = rowcenter + barrayG[row]->bheight -
571 barrayG[row]->bheight / 2;
572 D( "twsc/buildDensityArray",
573 fprintf( stderr, "row:%d oldy:%d newy:%d tracks:%d\n",
574 row, barrayG[row]->bycenter, rowcenter,
575 maxTrackG[row] ) ;
576 ) ;
577 barrayG[row]->bycenter = rowcenter ;
578 }
579 } else {
580 return ;
581 }
582
583 for( cell = 1; cell <= numcellsG; cell++ ){
584 cellptr = carrayG[cell] ;
585 block = cellptr->cblock ;
586 corient = cellptr->corient ;
587 if( block != 0 ){
588 cellptr->cycenter = barrayG[block]->bycenter ;
589 /* update the y positions on this cell */
590 for( pin = cellptr->pins;pin;pin=pin->nextpin ) {
591 pin->ypos = pin->typos[corient%2] + cellptr->cycenter;
592 }
593 }
594 }
595
596 } /* end density */
597