1 /*
2  *   Copyright (C) 1989-1992 Yale University
3  *   Copyright (C) 2013 Tim Edwards <tim@opencircuitdesign.com>
4  *
5  *   This work is distributed in the hope that it will be useful; you can
6  *   redistribute it and/or modify it under the terms of the
7  *   GNU General Public License as published by the Free Software Foundation;
8  *   either version 2 of the License,
9  *   or any later version, on the following conditions:
10  *
11  *   (a) YALE MAKES NO, AND EXPRESSLY DISCLAIMS
12  *   ALL, REPRESENTATIONS OR WARRANTIES THAT THE MANUFACTURE, USE, PRACTICE,
13  *   SALE OR
14  *   OTHER DISPOSAL OF THE SOFTWARE DOES NOT OR WILL NOT INFRINGE UPON ANY
15  *   PATENT OR
16  *   OTHER RIGHTS NOT VESTED IN YALE.
17  *
18  *   (b) YALE MAKES NO, AND EXPRESSLY DISCLAIMS ALL, REPRESENTATIONS AND
19  *   WARRANTIES
20  *   WHATSOEVER WITH RESPECT TO THE SOFTWARE, EITHER EXPRESS OR IMPLIED,
21  *   INCLUDING,
22  *   BUT NOT LIMITED TO, WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A
23  *   PARTICULAR
24  *   PURPOSE.
25  *
26  *   (c) LICENSEE SHALL MAKE NO STATEMENTS, REPRESENTATION OR WARRANTIES
27  *   WHATSOEVER TO
28  *   ANY THIRD PARTIES THAT ARE INCONSISTENT WITH THE DISCLAIMERS BY YALE IN
29  *   ARTICLE
30  *   (a) AND (b) above.
31  *
32  *   (d) IN NO EVENT SHALL YALE, OR ITS TRUSTEES, DIRECTORS, OFFICERS,
33  *   EMPLOYEES AND
34  *   AFFILIATES BE LIABLE FOR DAMAGES OF ANY KIND, INCLUDING ECONOMIC DAMAGE OR
35  *   INJURY TO PROPERTY AND LOST PROFITS, REGARDLESS OF WHETHER YALE SHALL BE
36  *   ADVISED, SHALL HAVE OTHER REASON TO KNOW, OR IN FACT SHALL KNOW OF THE
37  *   POSSIBILITY OF THE FOREGOING.
38  *
39  */
40 
41 /* -----------------------------------------------------------------
42 FILE:	    readpar.c
43 DESCRIPTION:read parameter file.
44 CONTENTS:   readParFile()
45 	    yaleIntro(message)
46 		char *message ;
47 DATE:	    Mar 27, 1989
48 REVISIONS:  Nov 23, 1990 - now use new readpar library function.
49 		Only need to read one of two .par or .spar
50 	    Thu Feb  7 00:11:36 EST 1991 - added new.pin.format.
51 	    Sun Feb 17 21:05:03 EST 1991 - added min_pad_spacing.
52 	    Sat Feb 23 00:30:06 EST 1991 - now handle wildcarding.
53 	    Wed Mar 13 13:46:21 CST 1991 - made the new format
54 		the default.
55 	    Thu Apr 18 01:56:45 EDT 1991 - added new parameter
56 		functions for design rules.
57 	    Wed Jun  5 16:47:12 CDT 1991 - added default for
58 		vertical_wire_weight.
59 	    Thu Jun 13 11:48:40 CDT 1991 - changed to no.graphics.
60 	    Wed Jul  3 13:51:21 CDT 1991 - added print_pins.
61 	    Fri Sep  6 15:18:00 CDT 1991 - added no_feed_est for
62 		emergencies.
63 	    Thu Sep 19 14:15:51 EDT 1991 - added equal width cell
64 		capability.
65 	    Fri Nov  8 01:13:18 EST 1991 - added even the rows
66 		maximally.
67 ----------------------------------------------------------------- */
68 
69 #define READPAR_VARS
70 #define NOTSPECIFIED -1
71 #define COMMENT '#'
72 
73 #include "standard.h"
74 #include "main.h"
75 #include "parser.h"
76 #include "readpar.h"
77 #include "groute.h"
78 #include "feeds.h"
79 #include "config.h"
80 #include "pads.h"
81 #include <yalecad/message.h>
82 #include <yalecad/string.h>
83 #include <yalecad/yreadpar.h>
84 
85 /* globals variable definitions */
86 INT attprcelG ;
87 INT core_widthG ;
88 INT core_heightG ;
89 INT core_xstartG ;
90 INT core_ystartG ;
91 INT spacer_widthG = -1 ;
92 INT *spacer_feedsG ;
93 INT vertical_pitchG = 0 ;
94 INT total_row_lengthG ;
95 INT vertical_track_pitchG = 0 ;
96 INT horizontal_track_pitchG = 0 ;
97 INT approximately_fixed_factorG = 1 ;
98 INT global_routing_iterationsG = 0 ;
99 BOOL no_feed_estG = TRUE ;
100 BOOL placement_improveG = TRUE ;
101 BOOL intel_debugG = FALSE ;
102 BOOL do_fast_globalG = FALSE ;
103 BOOL new_row_formatG = FALSE ;
104 BOOL no_feed_at_endG ;
105 BOOL call_row_evenerG = FALSE ;
106 BOOL turn_off_checksG = FALSE ;
107 BOOL min_peak_densityG = FALSE ;
108 BOOL do_not_even_rowsG = FALSE ;
109 BOOL min_total_densityG = FALSE ;
110 BOOL ignore_crossbusesG = FALSE ;
111 BOOL output_at_densityG = FALSE ;
112 BOOL spacer_name_twfeedG = FALSE ;
113 BOOL create_new_cel_fileG = FALSE ;
114 BOOL rigidly_fixed_cellsG = FALSE ;
115 BOOL exclude_noncrossbus_padsG = TRUE ;
116 BOOL stand_cell_as_gate_arrayG = FALSE ;
117 BOOL good_initial_placementG = FALSE ;
118 BOOL glob_route_only_crit_netsG = FALSE ;
119 BOOL unused_feed_name_twspacerG = FALSE ;
120 BOOL absolute_minimum_feedsG = FALSE ;
121 BOOL ignore_feedsG = FALSE ;
122 BOOL vertical_track_on_cell_edgeG ;
123 BOOL route_padnets_outsideG ;
124 BOOL prop_rigid_cellsG = FALSE ;
125 BOOL even_rows_maximallyG = FALSE ;
126 DOUBLE indentG ;
127 DOUBLE metal2_pitchG ;
128 
129 /* globals variable references */
130 extern BOOL orientation_optimizationG ;
131 extern BOOL doubleback_rows_start_at_oneG ;
132 
133 /* static variables */
134 static BOOL abortS = FALSE ;
135 static BOOL readparamS = FALSE ;
136 
137 static void init_read_par();
138 static void readparam();
139 static void process_readpar();
140 static void err_msg();
141 
readParFile()142 void readParFile()
143 {
144     init_read_par() ;
145     readparam( TWSC ) ;
146     readparam( USER ) ;
147     process_readpar() ;
148 }
149 
init_read_par()150 static void init_read_par()
151 {
152     /* initialization of variables */
153     SGGRG = FALSE ;
154     gate_arrayG = FALSE ;
155     try_not_to_add_explicit_feedsG = FALSE ;
156     vertical_track_on_cell_edgeG = FALSE ;
157     no_feed_at_endG = TRUE ;
158     spacer_feedsG = (INT *) Ysafe_malloc( 101 * sizeof(INT) ) ;
159     spacer_feedsG[0] = 0 ;
160     metal2_pitchG = 0.0 ;
161     core_widthG  = 0 ;
162     core_heightG = 0 ;
163     core_xstartG = 0 ;
164     core_ystartG = 0 ;
165     vertical_wire_weightG = -1.0 ;
166     vertical_path_weightG = -1.0 ;
167     horizontal_path_weightG = 1.0 ;
168     swap_netG = FALSE ;
169     case_unequiv_pinG = FALSE ;
170     swappable_gates_existG = FALSE ;
171     min_pad_spacingG = 0 ;
172     Equal_Width_CellsG = FALSE ;
173     file_conversionG = FALSE ;
174 } /* end init_read_par */
175 
readparam(parfile)176 static void readparam( parfile )
177 INT parfile ;
178 {
179 
180     INT test ;
181     INT speed ;
182     INT pins ;
183     INT spacer_tmp ;
184     INT line ;
185     INT numtokens ;
186     BOOL onNotOff ;
187     BOOL wildcard ;
188     char **tokens ;
189     char *lineptr ;
190 
191     Yreadpar_init( cktNameG, parfile, TWSC, FALSE ) ;
192 
193     OUT1( "\n\n" ) ;
194 
195     while( tokens = Yreadpar_next( &lineptr, &line, &numtokens,
196 	&onNotOff, &wildcard )){
197 	readparamS = TRUE ;
198 	if( numtokens == 0 ){
199 	    /* skip over empty lines */
200 	    continue ;
201 
202 	} else if( strcmp( tokens[0],"fast") == STRINGEQ ){
203 	    if( numtokens == 2 ) {
204 		tw_fastG = atoi( tokens[1] ) ;
205 	    } else {
206 		err_msg("fast") ;
207 	    }
208 	} else if( strcmp( tokens[0],"slow") == STRINGEQ ){
209 	    if( numtokens == 2 ) {
210 		tw_slowG = atoi( tokens[1] ) ;
211 	    } else {
212 		err_msg("slow") ;
213 	    }
214         } else if( strcmp( tokens[0], "equal_width_cells" ) == STRINGEQ ){
215               if( onNotOff ){
216 		  Equal_Width_CellsG = TRUE ;
217 	      } else {
218         	  Equal_Width_CellsG = FALSE ;
219 	      }
220 	/*--------------------------------------------------------------*/
221 	} else if( strcmp( tokens[0],"file_conversion_only") == STRINGEQ ){
222               if( onNotOff ){
223 		  file_conversionG = TRUE ;
224 	      } else {
225 		  file_conversionG = FALSE ;
226 	      }
227 	} else if( strcmp( tokens[0],"even_rows_maximally") == STRINGEQ ){
228               if( onNotOff ){
229 		even_rows_maximallyG = TRUE ;
230 	      } else {
231 		even_rows_maximallyG = FALSE ;
232 	      }
233 
234 	} else if( strcmp( tokens[0],"vertical_wire_weight") == STRINGEQ ){
235 	    if( numtokens == 2 ) {
236 		vertical_wire_weightG = atof( tokens[1] ) ;
237 	    } else {
238 		err_msg("vertical_wire_weight") ;
239 	    }
240 	} else if( strcmp( tokens[0],"vertical_path_weight") == STRINGEQ ){
241 	    if( numtokens == 2 ) {
242 		vertical_path_weightG = atof( tokens[1] ) ;
243 		if( vertical_wire_weightG < 0.0 ){
244 		    vertical_wire_weightG = vertical_path_weightG ;
245 		}
246 	    } else {
247 		err_msg("vertical_path_weight") ;
248 	    }
249 	} else if( strcmp( tokens[0],"horizontal_path_weight") == STRINGEQ ){
250 	    if( numtokens == 2 ) {
251 		horizontal_path_weightG = atof( tokens[1] ) ;
252 	    } else {
253 		err_msg("horizontal_path_weight") ;
254 	    }
255 	} else if( strcmp( tokens[0],"approximately_fixed_factor") == STRINGEQ ){
256 	    if( numtokens == 2 ) {
257 		approximately_fixed_factorG = atoi( tokens[1] ) ;
258 	    } else {
259 		err_msg("approximately_fixed_factor") ;
260 	    }
261 	    if( approximately_fixed_factorG < 1 ) {
262 		err_msg("approximately_fixed_factor") ;
263 	    }
264 	} else if( strcmp( tokens[0],"turn_off_checks") == STRINGEQ ){
265 	    if( onNotOff ){
266 		turn_off_checksG = TRUE ;
267 	    } else {
268 		turn_off_checksG = FALSE ;
269 	    }
270 	} else if( strcmp( tokens[0],"gr_placement_improve") == STRINGEQ ){
271 	    if( onNotOff ){
272 		placement_improveG = TRUE ;
273 	    } else {
274 		placement_improveG = FALSE ;
275 	    }
276 	} else if( strcmp( tokens[0],"route_only_critical_nets") == STRINGEQ ){
277 	    if( onNotOff ){
278 		glob_route_only_crit_netsG = TRUE ;
279 	    } else {
280 		glob_route_only_crit_netsG = FALSE ;
281 	    }
282 	} else if( strcmp( tokens[0],"min_peak_density") == STRINGEQ ){
283 	    if( onNotOff ){
284 		min_peak_densityG = TRUE ;
285 	    } else {
286 		min_peak_densityG = FALSE ;
287 	    }
288 	} else if( strcmp( tokens[0],"min_total_density") == STRINGEQ ){
289 	    if( onNotOff ){
290 		min_total_densityG = TRUE ;
291 	    } else {
292 		min_total_densityG = FALSE ;
293 	    }
294 	} else if( strcmp( tokens[0],"call_row_evener") == STRINGEQ ){
295 	    if( onNotOff ){
296 		call_row_evenerG = TRUE ;
297 	    } else {
298 		call_row_evenerG = FALSE ;
299 	    }
300 	} else if( strcmp( tokens[0],"create_new_cel_file") == STRINGEQ ){
301 	    if( onNotOff ){
302 		create_new_cel_fileG = TRUE ;
303 	    } else {
304 		create_new_cel_fileG = FALSE ;
305 	    }
306 	} else if( strcmp( tokens[0],"unused_feed_name_twspacer") == STRINGEQ ){
307 	    if( onNotOff ){
308 		unused_feed_name_twspacerG = TRUE ;
309 	    } else {
310 		unused_feed_name_twspacerG = FALSE ;
311 	    }
312 	} else if( strcmp( tokens[0],"spacer_name_twfeed") == STRINGEQ ){
313 	    if( onNotOff ){
314 		spacer_name_twfeedG = TRUE ;
315 	    } else {
316 		spacer_name_twfeedG = FALSE ;
317 	    }
318 	} else if( strcmp( tokens[0],"new_row_format") == STRINGEQ ){
319 	    if( onNotOff ){
320 		new_row_formatG = TRUE ;
321 	    } else {
322 		new_row_formatG = FALSE ;
323 	    }
324 	} else if( strcmp( tokens[0],"good_initial_placement") == STRINGEQ ){
325 	    if( numtokens == 2 ) {
326 		good_initial_placementG = atoi( tokens[1] ) ;
327 	    } else {
328 		err_msg("good_initial_placement") ;
329 	    }
330 	} else if( strcmp( tokens[0],"orientation_optimization") == STRINGEQ ){
331 	    if( onNotOff ){
332 		orientation_optimizationG = TRUE ;
333 	    } else {
334 		orientation_optimizationG = FALSE ;
335 	    }
336 	} else if( strcmp( tokens[0],"do_not_even_rows") == STRINGEQ ){
337 	    if( onNotOff ){
338 		do_not_even_rowsG = TRUE ;
339 	    } else {
340 		do_not_even_rowsG = FALSE ;
341 	    }
342 	} else if( strcmp( tokens[0],"absolute_minimum_feeds") == STRINGEQ ){
343 	    if( onNotOff ){
344 		absolute_minimum_feedsG = TRUE ;
345 	    } else {
346 		absolute_minimum_feedsG = FALSE ;
347 	    }
348 	} else if( strcmp( tokens[0],"ignore_feeds") == STRINGEQ ){
349 	    if( onNotOff ){
350 		ignore_feedsG = TRUE ;
351 	    } else {
352 		ignore_feedsG = FALSE ;
353 	    }
354 	} else if( strcmp( tokens[0],"pin_layers_given") == STRINGEQ ){
355 	    if( onNotOff ){
356 		pin_layers_givenG = TRUE ;
357 	    } else {
358 		pin_layers_givenG = FALSE ;
359 	    }
360 	} else if( strcmp( tokens[0],"no_explicit_feeds") == STRINGEQ ){
361 	    if( onNotOff ){
362 		try_not_to_add_explicit_feedsG = TRUE ;
363 	    } else {
364 		try_not_to_add_explicit_feedsG = FALSE ;
365 	    }
366 	} else if( strcmp( tokens[0],"no_feed_at_end") == STRINGEQ ){
367 	    if( onNotOff ){
368 		no_feed_at_endG = TRUE ;
369 	    } else {
370 		no_feed_at_endG = FALSE ;
371 	    }
372 	} else if( strcmp( tokens[0],"intel_debug") == STRINGEQ ){
373 	    if( onNotOff ){
374 		intel_debugG = TRUE ;
375 	    } else {
376 		intel_debugG = FALSE ;
377 	    }
378 	} else if( strcmp( tokens[0],"exclude_noncrossbus_pads") == STRINGEQ ){
379 	    if( onNotOff ){
380 		exclude_noncrossbus_padsG = TRUE ;
381 	    } else {
382 		exclude_noncrossbus_padsG = FALSE ;
383 	    }
384 	} else if( strcmp( tokens[0],"proportionally_space_rigid_cells") == STRINGEQ ){
385 	    if( onNotOff ){
386 		prop_rigid_cellsG = TRUE ;
387 	    } else {
388 		prop_rigid_cellsG = FALSE ;
389 	    }
390 	} else if( strcmp( tokens[0],"ignore_crossbuses") == STRINGEQ ){
391 	    if( onNotOff ){
392 		ignore_crossbusesG = TRUE ;
393 	    } else {
394 		ignore_crossbusesG = FALSE ;
395 	    }
396 	} else if( strcmp( tokens[0],"connection_machine") == STRINGEQ ){
397 	    if( numtokens == 2 ) {
398 		connection_machineG = atoi( tokens[1] ) ;
399 	    } else {
400 		err_msg("connection_machine") ;
401 	    }
402 	} else if( strcmp( tokens[0],"doubleback_rows_start_at_one") == STRINGEQ ){
403 	    if( onNotOff ){
404 		intelG = TRUE ;
405 		no_feed_estG = TRUE ;
406 		doubleback_rows_start_at_oneG = TRUE ;
407 	    } else {
408 		intelG = FALSE ;
409 		no_feed_estG = TRUE ;
410 		doubleback_rows_start_at_oneG = FALSE ;
411 	    }
412 	} else if( strcmp( tokens[0],"doubleback_rows_start_at_two") == STRINGEQ ){
413 	    if( onNotOff ){
414 		intelG = TRUE ;
415 		no_feed_estG = TRUE ;
416 		doubleback_rows_start_at_oneG = FALSE ;
417 	    } else {
418 		intelG = FALSE ;
419 		no_feed_estG = TRUE ;
420 		doubleback_rows_start_at_oneG = FALSE ;
421 	    }
422 	} else if( strcmp( tokens[0],"vertical_track_on_cell_edge") == STRINGEQ ){
423 	    if( onNotOff ){
424 		vertical_track_on_cell_edgeG = TRUE ;
425 	    } else {
426 		vertical_track_on_cell_edgeG = FALSE ;
427 	    }
428 	} else if( strcmp( tokens[0],"cost_only") == STRINGEQ ){
429 	    if( onNotOff ){
430 		costonlyG = TRUE ;
431 	    } else {
432 		costonlyG = FALSE ;
433 	    }
434 	} else if( strcmp( tokens[0],"no_feed_est") == STRINGEQ ){
435 	    if( onNotOff ){
436 		no_feed_estG = TRUE ;
437 	    } else {
438 		no_feed_estG = TRUE ;
439 	    }
440 	} else if( strcmp( tokens[0],"only.do.global.route") == STRINGEQ ){
441 	    if( onNotOff ){
442 		doglobalG = TRUE ;
443 		costonlyG = TRUE ;
444 		resume_runG = YES ;
445 	    } else {
446 		doglobalG = FALSE ;
447 		costonlyG = FALSE ;
448 		resume_runG = NO ;
449 	    }
450 	} else if( strcmp( tokens[0],"SGGR") == STRINGEQ ){
451 	    if( onNotOff ){
452 		SGGRG = TRUE ;
453 	    } else {
454 		SGGRG = FALSE ;
455 	    }
456 	} else if( strcmp( tokens[0],"global_routing_iterations") == STRINGEQ ){
457 	    if( numtokens == 2 ) {
458 		global_routing_iterationsG = atoi( tokens[1] ) ;
459 	    } else {
460 		err_msg("global_routing_iterations") ;
461 	    }
462 	} else if( strcmp( tokens[0],"do.global.route") == STRINGEQ ){
463 	    if( onNotOff ){
464 		doglobalG = TRUE ;
465 	    } else {
466 		doglobalG = FALSE ;
467 	    }
468 	} else if( strcmp( tokens[0],"standard_cell_as_gate_array") == STRINGEQ ){
469 	    if( onNotOff ){
470 		stand_cell_as_gate_arrayG = TRUE ;
471 	    } else {
472 		stand_cell_as_gate_arrayG = FALSE ;
473 	    }
474 	} else if( strcmp( tokens[0], "print_pins" ) == STRINGEQ ){
475 	    if( numtokens == 2 ) {
476 		pins = atoi( tokens[1] ) ;
477 		set_print_pin( pins ) ;
478 	    } else {
479 		err_msg("print_pins") ;
480 	    }
481 	} else if( strcmp( tokens[0],"do.fast.global.route") == STRINGEQ ){
482 	    if( onNotOff ){
483 		do_fast_globalG = TRUE ;
484 		doglobalG = TRUE ;
485 	    } else {
486 		do_fast_globalG = FALSE ;
487 		doglobalG = FALSE ;
488 	    }
489 	} else if( strcmp( tokens[0],"feedThruWidth") == STRINGEQ ){
490 	    if( numtokens == 2 ) {
491 		fdWidthG = atoi( tokens[1] ) ;
492 	    } else if( numtokens == 4 ) {
493 		pin_layers_givenG = TRUE ;
494 		fdWidthG = atoi( tokens[1] ) ;
495 		feedLayerG = atoi( tokens[3] ) ;
496 		if( feedLayerG == 0 ){
497 		    feedLayerG = 1 ;
498 		} else if( feedLayerG == 0 ){
499 		    err_msg("layer") ;
500 		}
501 	    } else {
502 		err_msg("feedThruWidth") ;
503 	    }
504 	} else if( strcmp( tokens[0],"total_row_length") == STRINGEQ ){
505 	    if( numtokens == 2 ) {
506 		total_row_lengthG = atoi( tokens[1] ) ;
507 	    } else {
508 		err_msg("total_row_length") ;
509 	    }
510 	} else if( strcmp( tokens[0],"spacer_width") == STRINGEQ ){
511 	    if( numtokens == 2 ) {
512 		spacer_widthG = atoi( tokens[1] ) ;
513 	    } else {
514 		err_msg("spacer_width") ;
515 	    }
516 	    gate_arrayG = TRUE ;
517 	    try_not_to_add_explicit_feedsG = TRUE ;
518 	} else if( strcmp( tokens[0],"spacer_feed_from_left") == STRINGEQ ){
519 	    if( numtokens == 2 ) {
520 		spacer_tmp = atoi( tokens[1] ) ;
521 	    } else {
522 		err_msg("spacer_feed_from_left") ;
523 	    }
524 	    spacer_feedsG[ ++spacer_feedsG[0] ] = spacer_tmp ;
525 	} else if( strcmp( tokens[0],"metal2_pitch") == STRINGEQ ){
526 	    if( numtokens == 2 ) {
527 		metal2_pitchG = atof( tokens[1] ) ;
528 	    } else {
529 		err_msg("metal2_pitch") ;
530 	    }
531 	} else if( strcmp( tokens[0],"vertical.pitch") == STRINGEQ ){
532 	    if( numtokens == 2 ) {
533 		vertical_pitchG = atoi( tokens[1] ) ;
534 	    } else {
535 		err_msg("vertical.pitch") ;
536 	    }
537 	} else if( strcmp( tokens[0],"core_width") == STRINGEQ ){
538 	    if( numtokens == 2 ) {
539 		core_widthG = atoi( tokens[1] ) ;
540 	    } else {
541 		err_msg("core_width") ;
542 	    }
543 	} else if( strcmp( tokens[0],"core_height") == STRINGEQ ){
544 	    if( numtokens == 2 ) {
545 		core_heightG = atoi( tokens[1] ) ;
546 	    } else {
547 		err_msg("core_height") ;
548 	    }
549 	} else if( strcmp( tokens[0],"core_xstart_relative_to_left_edge_of_rows") == STRINGEQ ){
550 	    if( numtokens == 2 ) {
551 		core_xstartG = atoi( tokens[1] ) ;
552 	    } else {
553 		err_msg("core_xstart_relative_to_left_edge_of_rows") ;
554 	    }
555 	} else if( strcmp( tokens[0],"core_ystart_relative_to_bottom_of_first_row") == STRINGEQ ){ if( numtokens == 2 ) {
556 		core_ystartG = atoi( tokens[1] ) ;
557 	    } else {
558 		err_msg("core_ystart_relative_to_bottom_of_first_row") ;
559 	    }
560 	} else if( strcmp( tokens[0],"addFeeds") == STRINGEQ ){
561 	    /* don't do anything for old keyword */
562 	} else if( strcmp( tokens[0],"indent") == STRINGEQ ){
563 	    if( numtokens != 2 ) {
564 		err_msg("indent") ;
565 	    }
566 	    indentG = 1.0 ;
567 	    /*  indent should always be 1.0 now  */
568 	} else if( strcmp( tokens[0],"random.seed") == STRINGEQ ){
569 	    if( numtokens == 2 ) {
570 		randomSeedG = (UNSIGNED_INT) atoi( tokens[1] ) ;
571 	    } else {
572 		err_msg("random.seed") ;
573 	    }
574 	} else if( strcmp( tokens[0],"rowSep") == STRINGEQ ){
575 	    if( numtokens >= 2 ) {
576 		rowSepG = atof( tokens[1] ) ;
577 		rowSepAbsG = (numtokens == 3) ? (INT) atof( tokens[2] ) : 0 ;
578 	    } else {
579 		err_msg("rowSep") ;
580 	    }
581 	} else if( strcmp( tokens[0],"restart") == STRINGEQ ){
582 	    if( onNotOff ){
583 		resume_runG = YES ;
584 	    } else {
585 		resume_runG = NO ;
586 	    }
587 	} else if( strcmp( tokens[0],"uneven.cell.height") == STRINGEQ ){
588 	    if( onNotOff ){
589 		uneven_cell_heightG = TRUE ;
590 	    } else {
591 		uneven_cell_heightG = FALSE ;
592 	    }
593 	} else if( strcmp( tokens[0],"route.to.active") == STRINGEQ ){
594 	    /* route2act is the routing layer to active cell minimum spacing */
595 	    if( numtokens == 2 ) {
596 		route2actG = atoi( tokens[1] ) ;
597 	    } else {
598 		err_msg("route.to.active") ;
599 	    }
600 	} else if( strcmp( tokens[0],"output.at.density") == STRINGEQ ){
601 	    if( onNotOff ){
602 		output_at_densityG = TRUE ;
603 	    } else {
604 		output_at_densityG = FALSE ;
605 	    }
606 	} else if( strcmp( tokens[0],"one.pin.feedthru") == STRINGEQ ){
607 	    if( onNotOff ){
608 		one_pin_feedthruG = TRUE ;
609 	    } else {
610 		one_pin_feedthruG = FALSE ;
611 	    }
612 	} else if( strcmp( tokens[0],"route_padnets_outside") == STRINGEQ ){
613 	    if( onNotOff ){
614 		route_padnets_outsideG = TRUE ;
615 	    } else {
616 		route_padnets_outsideG = FALSE ;
617 	    }
618 	} else if( strcmp( tokens[0],"lambda") == STRINGEQ ){
619 	} else if( strcmp( tokens[0],"no.graphics") == STRINGEQ ){
620 	    if( onNotOff ){
621 		doGraphicsG = FALSE ;
622 	    } else {
623 		doGraphicsG = TRUE ;
624 	    }
625 	} else if( strcmp( tokens[0],"no.graphics.update") == STRINGEQ ){
626 	    if( onNotOff ){
627 		G( set_update( FALSE ) ) ;
628 	    } else {
629 		G( set_update( TRUE ) ) ;
630 	    }
631 	} else if( strcmp( tokens[0],"graphics.wait") == STRINGEQ ){
632 	} else if( strcmp( tokens[0],"old.pin.format") == STRINGEQ ){
633 	    if( onNotOff ){
634 		set_pin_format( TRUE ) ;
635 	    } else {
636 		set_pin_format( FALSE ) ;
637 	    }
638 	} else if( strcmp( tokens[0], "contiguous_pad_groups" ) == STRINGEQ ){
639 	    if( onNotOff ){
640 		contiguousG = TRUE ;
641 	    } else {
642 		contiguousG = FALSE ;
643 	    }
644 	} else if( strcmp( tokens[0], "minimum_pad_space" ) == STRINGEQ ){
645 	    if( numtokens == 2 ) {
646 		min_pad_spacingG = atoi( tokens[1] );
647 	    } else {
648 		err_msg("minimum space between pads") ;
649 	    }
650 	} else if( strcmp( tokens[0], "padspacing" ) == STRINGEQ ){
651 	    if( numtokens == 2 ) {
652 		if( strcmp( tokens[1] , "uniform" ) == STRINGEQ ) {
653 		    padspacingG = UNIFORM_PADS ;
654 		} else if( strcmp( tokens[1] , "variable" ) == STRINGEQ ) {
655 		    padspacingG = VARIABLE_PADS ;
656 		} else if( strcmp( tokens[1] , "abut" ) == STRINGEQ ) {
657 		    padspacingG = ABUT_PADS ;
658 		} else if( strcmp( tokens[1] , "exact" ) == STRINGEQ ) {
659 		    padspacingG = EXACT_PADS ;
660 		} else {
661 		    OUT1("Unexpected padspacing keyword in the .par file\n");
662 		    abortS = TRUE ;
663 		}
664 	    } else {
665 		err_msg("padspacing") ;
666 	    }
667 
668 	/*** catch all ***/
669 	} else if(!(wildcard)){
670 	    if( parfile == USER ){
671 		OUT4("ERROR[readpar]:unexpected keyword in the %s.par file at line:%d\n\t%s\n",
672 		cktNameG, line, lineptr );
673 	    } else {
674 		OUT4("ERROR[readpar]:Unexpected keyword in the %s.spar file at line:%d\n\t%s\n",
675 		cktNameG, line, lineptr );
676 	    }
677 	    Ymessage_error_count() ;
678 	    abortS = TRUE ;
679 	}
680     }
681 } /* end  readparam */
682 
683 
process_readpar()684 static void process_readpar()
685 {
686 
687 char *layer ;             /* name of layer */
688 INT i ;                   /* counter */
689 INT pitch ;               /* the pitch of the layer */
690 INT numv_layers ;         /* number of vertical   layers */
691 INT numh_layers ;         /* number of horizontal layers */
692 INT num_layers ;          /* total number of layers */
693 
694 if( abortS ){
695     OUT1( "Errors found in the .par file.  Must exit\n\n" ) ;
696     YexitPgm(PGMFAIL);
697 }
698 if( !(readparamS)){
699     M( ERRMSG, "process_readpar",
700 	"No parameter files found. Must exit\n\n") ;
701     YexitPgm(PGMFAIL);
702 }
703 
704 
705 if( vertical_wire_weightG < 0 ) {
706     fprintf( fpoG, "vertical_wire_weight ") ;
707     fprintf( fpoG, "was NOT found in the .par file\n");
708     YexitPgm(PGMFAIL);
709 }
710 if( vertical_path_weightG < 0 ) {
711     fprintf( fpoG, "vertical_path_weight ") ;
712     fprintf( fpoG, "was NOT found in the .par file\n");
713     YexitPgm(PGMFAIL);
714 }
715 
716 
717 if( spacer_widthG == -1 ) {
718     spacer_feedsG[0] = 1 ;
719     spacer_feedsG[1] = fdWidthG / 2 ;
720     spacer_widthG = fdWidthG ;
721 }
722 
723 numv_layers = 0 ;
724 numh_layers = 0 ;
725 num_layers = Yreadpar_numlayers() ;
726 for( i = 1; i <= num_layers; i++ ){
727     layer = Yreadpar_id2layer( i ) ;
728     pitch = Yreadpar_pitch( layer ) ;
729     if( Yreadpar_layer_HnotV( layer ) ){
730 	horizontal_track_pitchG += pitch ;
731 	numh_layers++ ;
732     } else {
733 	vertical_track_pitchG += pitch ;
734 	numv_layers++ ;
735     }
736 }
737 /* get the average pitch of all the layers */
738 if( numv_layers > 0 ){
739     vertical_track_pitchG /= numv_layers ;
740     if( vertical_track_pitchG == 0 ){
741 	vertical_track_pitchG == 1 ;
742     }
743 }
744 if( numh_layers > 0 ){
745     horizontal_track_pitchG++ ; /* to account for the -1 initialization */
746     horizontal_track_pitchG /= numh_layers ;
747     if( horizontal_track_pitchG == 0 ){
748 	horizontal_track_pitchG == 1 ;
749     }
750     track_pitchG = horizontal_track_pitchG ; /* these are the same var. */
751 }
752 
753 if( vertical_track_pitchG == 0 || horizontal_track_pitchG == 0 ) {
754     if( vertical_track_pitchG == 0 ) {
755 	M( ERRMSG, "readpar",
756 	"Vertical track pitch could not be calculated from design rules\n");
757 	M( ERRMSG, NULL, "Check the design rules in parameter file\n\n") ;
758     }
759     if( horizontal_track_pitchG == 0 ) {
760 	M( ERRMSG, "readpar",
761 	"Horizontal track pitch could not be calculated from design rules\n");
762 	M( ERRMSG, NULL, "Check the design rules in parameter file\n\n") ;
763     }
764     YexitPgm(PGMFAIL);
765 }
766 
767 #ifdef INTEL
768 if( 0 /* intel */ ) {
769     doglobalG = 0 ;
770     if( metal2_pitchG == 0.0 ) {
771 	fprintf( fpoG,"metal2_pitch was not entered in the .par file\n");
772 	YexitPgm(PGMFAIL);
773     } else {
774 	fprintf( fpoG, "metal2_pitch: %f\n" , metal2_pitchG ) ;
775     }
776 }
777 #endif /* INTEL */
778 
779 if( doglobalG ) {
780     fprintf(fpoG,"TimberWolf will perform a global route step\n");
781 }
782 if( doglobalG == TRUE  &&  fdWidthG == -1 ) {
783     fprintf(fpoG,"feedThruWidth was not entered in the .par file\n");
784     YexitPgm(PGMFAIL);
785 } else {
786     fprintf( fpoG, "feedThruWidth: %d\n" , fdWidthG ) ;
787 }
788 
789 /* make sure track pitch has been specified for uneven cell heights */
790 if( uneven_cell_heightG ){
791     if( track_pitchG == NOTSPECIFIED ){
792 	fprintf( fpoG, "TimberWolfSC cannot perform uneven cell");
793 	fprintf( fpoG, "height calculations without track pitch\n");
794 	fprintf( fpoG, "Enter track.pitch in the .par file\n");
795     }
796 }
797 
798 if( track_pitchG != NOTSPECIFIED ) {
799     fprintf( fpoG, "track.pitch: %d\n" , track_pitchG ) ;
800     if( route2actG == NOTSPECIFIED ){
801 	fprintf( fpoG, "route2act was not entered in the .par file\n");
802 	fprintf( fpoG, "route2act defaulted to track.pitch\n");
803 	route2actG = track_pitchG ;
804     }
805     fprintf( fpoG, "route2act: %d\n" , route2actG ) ;
806 
807 } else {
808     fprintf( fpoG, "track.pitch was not specified in par file\n" ) ;
809     fprintf( fpoG, "TimberWolfSC will output cell locations according\n");
810     fprintf( fpoG, "to user supplied row separation.\n" ) ;
811 
812 }
813 
814 return ;
815 } /* end process_readpar */
816 
yaleIntro()817 void yaleIntro()
818 {
819     INT i ;
820 
821     fprintf(fpoG,"\n%s\n",YmsgG) ;
822     fprintf(fpoG,"Row-Based Placement and Global Routing Program\n");
823     fprintf(fpoG,"Authors: Carl Sechen, Kai-Win Lee, and Bill Swartz,\n");
824     fprintf(fpoG,"         Yale University\n");
825 
826     printf("%s\n",YmsgG) ;
827     printf("Row-Based Placement and Global Routing Program\n");
828     printf("Authors: Carl Sechen, Kai-Win Lee, and Bill Swartz,\n");
829     printf("         Yale University\n");
830 
831     /* inialize variables */
832     randomSeedG  = (unsigned) Yrandom_seed() ;
833 
834     fixarrayG = (INT *) NULL ;
835     ffeedsG = 0 ;
836     macspaceG = (DOUBLE *) Ysafe_malloc( 24 * sizeof(DOUBLE) ) ;
837     for( i = 1 ; i <= 15 ; i++ ) {
838 	macspaceG[i] = -1.0 ;
839     }
840     costonlyG = FALSE ;
841     fdthrusG = FALSE ;
842     doglobalG = FALSE ;
843 
844     attprcelG = 0 ;
845 
846     fdWidthG  = -1 ;
847     track_pitchG = -1 ;
848     route2actG = -1 ;
849     rowSepG = -1.0 ;
850     rowSepAbsG = 0 ;
851     indentG = 1.0 ;
852     numSegsG = 0 ;
853     resume_runG = NO ;
854     pin_layers_givenG = TRUE ;
855     no_feeds_side_netsG = FALSE ;
856     feedLayerG = 0 ;
857     tw_fastG = 0 ;
858     tw_slowG = 0 ;
859     estimate_feedsG = TRUE ;
860     connection_machineG = 0 ;
861     route_padnets_outsideG = FALSE ;
862 
863 } /* end yaleIntro */
864 
err_msg(keyword)865 static void err_msg( keyword )
866 char *keyword ;
867 {
868     OUT2("The value for %s was", keyword );
869     OUT1(" not properly entered in the .par file\n");
870     abortS = TRUE ;
871 }/* end err_msg */
872