1 /*--------------------------------------------------------------*/
2 /* qconfig.c -- .cfg file read/write for route                 	*/
3 /*--------------------------------------------------------------*/
4 /* Written by Steve Beccue 2003					*/
5 /*--------------------------------------------------------------*/
6 /* Modified by Tim Edwards, June 2011.  The route.cfg file is	*/
7 /* no longer the main configuration file but is supplementary	*/
8 /* to the LEF and DEF files.  Various configuration items that	*/
9 /* do not appear in the LEF and DEF formats, such as route	*/
10 /* costing, appear in this file, as well as a filename pointer	*/
11 /* to the LEF file with information on standard cell macros.	*/
12 /*--------------------------------------------------------------*/
13 
14 #define _GNU_SOURCE	// for strcasestr(), see man page
15 
16 #include <ctype.h>
17 #include <stdio.h>
18 #include <math.h>
19 #include <stdarg.h>
20 #include <stdlib.h>
21 #include <string.h>
22 
23 #include "qrouter.h"
24 #include "qconfig.h"
25 #include "lef.h"
26 
27 int    CurrentPin = 0;
28 int    Firstcall = TRUE;
29 int    PinNumber = 0;
30 
31 int     Num_layers   = MAX_LAYERS;	// layers to use to route
32 
33 double  PathWidth[MAX_LAYERS];		// width of the paths
34 int     GDSLayer[MAX_TYPES];		// GDS layer number
35 int     GDSCommentLayer = 1;		// for dummy wires, etc.
36 char    CIFLayer[MAX_TYPES][50];	// CIF layer name
37 double  PitchX;				// Horizontal wire pitch of layer
38 double  PitchY;				// Vertical wire pitch of layer
39 int     NumChannelsX;			// number of wire channels in X on layer
40 int     NumChannelsY;			// number of wire channels in Y on layer
41 int     Vert[MAX_LAYERS];		// 1 if vertical, 0 if horizontal
42 int     Numpasses = 10;			// number of times to iterate in route_segs
43 char	StackedContacts = MAX_LAYERS;	// Value is number of contacts that may
44 					// be stacked on top of each other.
45 
46 double  Xlowerbound=0.0;		// Bounding Box of routes, in microns
47 double  Xupperbound=0.0;
48 double  Ylowerbound=10.0;
49 double  Yupperbound=10.0;
50 
51 int     SegCost = 1;               // Route cost of a segment
52 int     ViaCost = 5;               // Cost of via between adjacent layers
53 int     JogCost = 10;              // Cost of 1 grid off-direction jog
54 int     XverCost = 4;              // Cost of a crossover
55 int     BlockCost = 25;            // Cost of a crossover when node has
56 				   // only one tap point
57 int	OffsetCost = 50;	   // Cost per micron of a node offset
58 int 	ConflictCost = 50;	   // Cost of shorting another route
59 				   // during the rip-up and reroute stage
60 
61 char    *ViaXX[MAX_LAYERS];
62 char    *ViaXY[MAX_LAYERS];
63 char    *ViaYX[MAX_LAYERS];
64 char    *ViaYY[MAX_LAYERS];
65 
66 /*--------------------------------------------------------------*/
67 /* init_config ---						*/
68 /*								*/
69 /* Initialize arrays						*/
70 /*--------------------------------------------------------------*/
71 
72 void
init_config()73 init_config()
74 {
75     int i;
76 
77     for (i = 0; i < MAX_LAYERS; i++) {
78 	ViaXX[i] = NULL;
79 	ViaXY[i] = NULL;
80 	ViaYX[i] = NULL;
81 	ViaYY[i] = NULL;
82     }
83 }
84 
85 /*--------------------------------------------------------------*/
86 /* post_config ---						*/
87 /*								*/
88 /* Resolve PitchX and PitchY, which are the minimum pitches	*/
89 /* that determine the underlying route grid.			*/
90 /*								*/
91 /* If "noprint" is TRUE, then do not print diagnostic info.	*/
92 /*--------------------------------------------------------------*/
93 
94 void
post_config(u_char noprint)95 post_config(u_char noprint)
96 {
97     int i, h, v;
98     double rpitchx, rpitchy;
99 
100     // Make sure that Num_layers does not exceed the number of
101     // routing layers defined by the LEF file (or the config
102     // file).
103 
104     i = LefGetMaxRouteLayer();
105     if (i < Num_layers) Num_layers = i;
106 
107     // Make sure all layers have a pitch in both X and Y even if not
108     // specified separately in the configuration or def files.
109     for (i = 0; i < Num_layers; i++) {
110        rpitchx = LefGetRoutePitchX(i);
111        rpitchy = LefGetRoutePitchY(i);
112        if ((PitchX == 0.0) || ((rpitchx != 0.0) && (rpitchx + EPS < PitchX)))
113 	  PitchX = rpitchx;
114        if ((PitchY == 0.0) || ((rpitchy != 0.0) && (rpitchy + EPS < PitchY)))
115 	  PitchY = rpitchy;
116     }
117 
118     // This is mostly arbitrary.  Generally, all route layer
119     // pitches except for the smallest X and Y pitches will
120     // be ignored, and the actual route pitches will be multiples
121     // of the smallest value, and determined by width and spacing
122     // rules rather than using any value in the technology LEF.
123 
124     for (i = 0; i < Num_layers; i++) {
125 	if (LefGetRoutePitchX(i) == 0.0) {
126 	    if (Vert[i])
127 		LefSetRoutePitchX(i, PitchX);
128 	    else if (i > 0)
129 		LefSetRoutePitchX(i, LefGetRoutePitchX(i - 1));
130 	    else
131 		LefSetRoutePitchX(i, LefGetRoutePitchX(i + 1));
132 	}
133 	if (LefGetRoutePitchY(i) == 0.0) {
134 	    if (!Vert[i])
135 		LefSetRoutePitchY(i, PitchY);
136 	    else if (i > 0)
137 		LefSetRoutePitchY(i, LefGetRoutePitchY(i - 1));
138 	    else
139 		LefSetRoutePitchY(i, LefGetRoutePitchY(i + 1));
140 	}
141     }
142 
143     if (noprint == FALSE) {
144 	for (i = 0; i < Num_layers; i++) {
145 	    rpitchx = LefGetRoutePitchX(i);
146 	    rpitchy = LefGetRoutePitchY(i);
147 	    if ((PitchX != 0.0) && (PitchX + EPS < rpitchx)) {
148 		Fprintf(stdout, "Vertical route layer at non-minimum pitch"
149 			" %g.  Using smaller pitch %g, will route on"
150 			" 1-of-%d tracks for layer %s.\n",
151 			rpitchx, PitchX, (int)(ceil(rpitchx / PitchX)),
152 			LefGetRouteName(i));
153 	    }
154 	    if ((PitchY != 0.0) && (PitchY + EPS < rpitchy)) {
155 		Fprintf(stdout, "Horizontal route layer at non-minimum pitch"
156 			" %g.  Using smaller pitch %g, will route on"
157 			" 1-of-%d tracks for layer %s.\n",
158 			rpitchy, PitchY, (int)(ceil(rpitchy / PitchY)),
159 			LefGetRouteName(i));
160 	    }
161 	}
162     }
163 } /* post_config() */
164 
165 /*--------------------------------------------------------------*/
166 /* Append to a string						*/
167 /*--------------------------------------------------------------*/
168 
string_list_append(STRING * lst,const char * s)169 void string_list_append(STRING *lst, const char *s)
170 {
171     STRING n, strl;
172 
173     n = (STRING)malloc(sizeof(struct string_));
174     n->name = strdup(s);
175     n->next = NULL;
176     while (*lst) lst = &(*lst)->next;
177     *lst = n;
178 }
179 
180 /*--------------------------------------------------------------*/
181 /* read_config - read in the config file        		*/
182 /*								*/
183 /*         ARGS: the filename (normally route.cfg)		*/
184 /*      RETURNS: number of lines successfully read		*/
185 /* SIDE EFFECTS: loads Global configuration variables		*/
186 /*								*/
187 /* "is_info" indicates if qrouter was called with the -i option	*/
188 /* in which case the config file read should stop before any	*/
189 /* def file is read.						*/
190 /*--------------------------------------------------------------*/
191 
read_config(FILE * fconfig,int is_info)192 int read_config(FILE *fconfig, int is_info)
193 {
194     int count, lines, i, OK;
195     int iarg, iarg2;
196     char carg;
197     double darg, darg2, darg3, darg4;
198     char sarg[MAX_LINE_LEN];
199     char   line[MAX_LINE_LEN];
200     char  *lineptr;
201     STRING dnr;               // Do Not Route nets
202     STRING cn;                // critical nets
203     STRING strl;
204     GATE   gateinfo = NULL;   // gate information, pin location, etc
205     DSEG   drect;
206 
207     if (Firstcall) {
208 	for (i = 0; i < MAX_LAYERS; i++) {
209 	    sprintf(line, "via%d%d", i + 1, i + 2);
210 	    ViaXX[i] = strdup(line);
211 	    ViaXY[i] = NULL;
212 	    ViaYX[i] = NULL;
213 	    ViaYY[i] = NULL;
214 	}
215 
216 	DontRoute = (STRING)NULL;
217 	CriticalNet = (STRING)NULL;
218         GateInfo = (GATE)NULL;
219 	Nlgates = (GATE)NULL;
220 	UserObs = (DSEG)NULL;
221 
222 	PitchX = PitchY = 0.0;
223 	Firstcall = 0;
224     }
225 
226     if (!fconfig) return -1;
227 
228     count = 0;
229     lines = 0;
230 
231     while (!feof(fconfig)) {
232 	if (fgets(line, MAX_LINE_LEN, fconfig) == NULL) break;
233 	lines++;
234 	lineptr = line;
235 	while (isspace(*lineptr)) lineptr++;
236 
237 	if (!strncasecmp(lineptr, "lef", 3) || !strncmp(lineptr, "read_lef", 8)) {
238 	    int mscale;
239 	    if ((i = sscanf(lineptr, "%*s %s\n", sarg)) == 1) {
240 	       // Argument is a filename of a LEF file from which we
241 	       // should get the information about gate pins & obstructions
242 	       OK = 1;
243 	       mscale = LefRead(sarg);
244 	       update_mscale(mscale);
245 	    }
246 	}
247 
248 	// The remainder of the statements is not case sensitive.
249 
250 	for (i = 0; line[i] && i < MAX_LINE_LEN - 1; i++) {
251 	    line[i] = (char)tolower(line[i]);
252 	}
253 
254 	if ((i = sscanf(lineptr, "num_layers %d", &iarg)) == 1) {
255 	    OK = 1; Num_layers = iarg;
256 	}
257 	else if ((i = sscanf(lineptr, "layers %d", &iarg)) == 1) {
258 	    OK = 1; Num_layers = iarg;
259 	}
260 
261 	if ((i = sscanf(lineptr, "layer_%d_name %s", &iarg2, sarg)) == 2) {
262 	    if (iarg2 > 0 && iarg2 <= MAX_LAYERS) {
263 	       OK = 1; strcpy(CIFLayer[iarg2 - 1], sarg);
264 	    }
265 	}
266 
267 	if ((i = sscanf(lineptr, "gds_layer_%d %d", &iarg2, &iarg)) == 2) {
268 	    if (iarg2 > 0 && iarg2 <= MAX_TYPES) {
269 	        OK = 1; GDSLayer[iarg2 - 1] = iarg;
270 	    }
271 	}
272 	if ((i = sscanf(lineptr, "gds_comment_layer %d", &iarg)) == 1) {
273 	    OK = 1; GDSCommentLayer = iarg;
274 	}
275 
276 	if ((i = sscanf(lineptr, "layer_1_width %lf", &darg)) == 1) {
277 	    OK = 1; PathWidth[0] = darg;
278 	}
279 	if ((i = sscanf(lineptr, "layer_2_width %lf", &darg)) == 1) {
280 	    OK = 1; PathWidth[1] = darg;
281 	}
282 	if ((i = sscanf(lineptr, "layer_3_width %lf", &darg)) == 1) {
283 	    OK = 1; PathWidth[2] = darg;
284 	}
285 	if ((i = sscanf(lineptr, "layer_4_width %lf", &darg)) == 1) {
286 	    OK = 1; PathWidth[3] = darg;
287 	}
288 	if ((i = sscanf(lineptr, "layer_5_width %lf", &darg)) == 1) {
289 	    OK = 1; PathWidth[4] = darg;
290 	}
291 	if ((i = sscanf(lineptr, "layer_6_width %lf", &darg)) == 1) {
292 	    OK = 1; PathWidth[5] = darg;
293 	}
294 	if ((i = sscanf(lineptr, "layer_7_width %lf", &darg)) == 1) {
295 	    OK = 1; PathWidth[6] = darg;
296 	}
297 	if ((i = sscanf(lineptr, "layer_8_width %lf", &darg)) == 1) {
298 	    OK = 1; PathWidth[7] = darg;
299 	}
300 	if ((i = sscanf(lineptr, "layer_9_width %lf", &darg)) == 1) {
301 	    OK = 1; PathWidth[8] = darg;
302 	}
303 
304 	if ((i = sscanf(lineptr, "x lower bound %lf", &darg)) == 1) {
305 	    OK = 1; Xlowerbound = darg;
306 	}
307 	if ((i = sscanf(lineptr, "x upper bound %lf", &darg)) == 1) {
308 	    OK = 1; Xupperbound = darg;
309 	}
310 	if ((i = sscanf(lineptr, "y lower bound %lf", &darg)) == 1) {
311 	    OK = 1; Ylowerbound = darg;
312 	}
313 	if ((i = sscanf(lineptr, "y upper bound %lf", &darg)) == 1) {
314 	    OK = 1; Yupperbound = darg;
315 	}
316 
317 	if ((i = sscanf(lineptr, "layer %d wire pitch %lf\n", &iarg, &darg)) == 2) {
318 	    OK = 1;
319 	    if (Vert[iarg - 1]) {
320 		if ((PitchX == 0) || (darg < PitchX)) PitchX = darg;
321 	    }
322 	    else {
323 		if ((PitchY == 0) || (darg < PitchY)) PitchY = darg;
324 	    }
325 	}
326 	else if (i == 1) {
327 	   if ((i = sscanf(lineptr, "layer %*d vertical %d\n", &iarg2)) == 1) {
328 	      OK = 1; Vert[iarg - 1] = iarg2;
329 	   }
330 	   else if ((i = sscanf(lineptr, "layer %*d %c\n", &carg)) == 1) {
331 	      if (tolower(carg) == 'v') {
332 		 OK = 1; Vert[iarg - 1] = 1;
333 	      }
334 	      else if (tolower(carg) == 'h') {
335 		 OK = 1; Vert[iarg - 1] = 0;
336 	      }
337 	   }
338 	}
339 
340 	if ((i = sscanf(lineptr, "num passes %d\n", &iarg)) == 1) {
341 	    OK = 1;
342 	    Numpasses = iarg;
343 	}
344 	else if ((i = sscanf(lineptr, "passes %d\n", &iarg)) == 1) {
345 	    OK = 1;
346 	    Numpasses = iarg;
347 	}
348 
349 	if ((i = sscanf(lineptr, "route segment cost %d", &iarg)) == 1) {
350 	    OK = 1; SegCost = iarg;
351 	}
352 
353 	if ((i = sscanf(lineptr, "route via cost %d", &iarg)) == 1) {
354 	    OK = 1; ViaCost = iarg;
355 	}
356 
357 	if ((i = sscanf(lineptr, "route jog cost %d", &iarg)) == 1) {
358 	    OK = 1; JogCost = iarg;
359 	}
360 
361 	if ((i = sscanf(lineptr, "route crossover cost %d", &iarg)) == 1) {
362 	    OK = 1; XverCost = iarg;
363 	}
364 
365 	if ((i = sscanf(lineptr, "route offset cost %d", &iarg)) == 1) {
366 	    OK = 1; OffsetCost = iarg;
367 	}
368 	if ((i = sscanf(lineptr, "route block cost %d", &iarg)) == 1) {
369 	    OK = 1; BlockCost = iarg;
370 	}
371 
372 	if ((i = sscanf(lineptr, "do not route node %s\n", sarg)) == 1) {
373 	    OK = 1;
374 	    string_list_append(&DontRoute, sarg);
375 	}
376 
377 	if ((i = sscanf(lineptr, "route priority %s\n", sarg)) == 1) {
378 	    OK = 1;
379 	    string_list_append(&CriticalNet, sarg);
380 	}
381 
382 	if ((i = sscanf(lineptr, "critical net %s\n", sarg)) == 1) {
383 	    OK = 1;
384 	    string_list_append(&CriticalNet, sarg);
385 	}
386 
387 	// Search for "no stack".  This allows variants like "no stacked
388 	// contacts", "no stacked vias", or just "no stacking", "no stacks",
389 	// etc.
390 
391 	if (strcasestr(lineptr, "no stack") != NULL) {
392 	    OK = 1; StackedContacts = 1;
393 	}
394 
395 	// Search for "stack N", where "N" is the largest number of vias
396 	// that can be stacked upon each other.  Values 0 and 1 are both
397 	// equivalent to specifying "no stack".
398 
399 	if ((i = sscanf(lineptr, "stack %d", &iarg)) == 1) {
400 	    OK = 1; StackedContacts = iarg;
401 	    // Can't let StackedContacts be zero because qrouter would
402 	    // believe that all contacts are disallowed, leading to a
403 	    // lot of wasted processing time while it determines that's
404 	    // not possible. . .
405 	    if (StackedContacts == 0) StackedContacts = 1;
406 	}
407 	else if ((i = sscanf(lineptr, "via stack %d", &iarg)) == 1) {
408 	    OK = 1; StackedContacts = iarg;
409 	    if (StackedContacts == 0) StackedContacts = 1;
410 	}
411 
412 	if ((i = sscanf(lineptr, "obstruction %lf %lf %lf %lf %s\n",
413 			&darg, &darg2, &darg3, &darg4, sarg)) == 5) {
414 	    OK = 1;
415 	    drect = (DSEG)malloc(sizeof(struct dseg_));
416 	    drect->x1 = darg;
417 	    drect->y1 = darg2;
418 	    drect->x2 = darg3;
419 	    drect->y2 = darg4;
420 	    drect->layer = LefFindLayerNum(sarg);
421 	    if (drect->layer < 0) {
422 		if ((i = sscanf(sarg, "%lf", &darg)) == 1) {
423 		    i = (int)(darg + EPS);
424 		    if (i >= 0 && i < Num_layers) {
425 		        drect->layer = i;
426 		    }
427 		}
428 	    }
429 	    if (drect->layer >= 0) {
430 		drect->next = UserObs;
431 		UserObs = drect;
432 	    }
433 	    else {
434 		free(drect);
435 	    }
436 	}
437 
438 	if ((i = sscanf(lineptr, "gate %s %lf %lf\n", sarg, &darg, &darg2)) == 3) {
439 	    OK = 1;
440 	    CurrentPin = 0;
441 	    gateinfo = (GATE)malloc(sizeof(struct gate_));
442 	    gateinfo->gatename = strdup(sarg);
443 	    gateinfo->gatetype = NULL;
444 	    gateinfo->width = darg;
445 	    gateinfo->height = darg2;
446 	    gateinfo->placedX = 0.0;	// implicit cell origin
447 	    gateinfo->placedY = 0.0;
448             gateinfo->nodes = 0;
449 	    gateinfo->next = GateInfo;	// prepend to linked gate list
450 
451             // Allocate memory for up to 10 pins
452 	    gateinfo->taps = (DSEG *)malloc(10 * sizeof(DSEG));
453 	    gateinfo->noderec = (NODE *)malloc(10 * sizeof(NODE));
454 	    gateinfo->netnum = (int *)malloc(10 * sizeof(int));
455 	    gateinfo->node = (char **)malloc(10 * sizeof(char *));
456 	    // Initialize first entry
457 	    gateinfo->taps[0] = NULL;
458 	    gateinfo->noderec[0] = NULL;
459 	    gateinfo->netnum[0] = -1;
460 	    gateinfo->node[0] = NULL;
461 
462 	    GateInfo = gateinfo;
463 	}
464 
465         if ((i = sscanf(lineptr, "endgate %s\n", sarg)) == 1) {
466 	    OK = 1;
467 	    gateinfo->nodes = CurrentPin;
468 
469 	    // This syntax does not include declaration of obstructions
470 	    gateinfo->obs = (DSEG)NULL;
471 	    CurrentPin = 0;
472         }
473 
474 	if ((i = sscanf(lineptr, "pin %s %lf %lf\n", sarg, &darg, &darg2)) == 3) {
475 	    OK = 1;
476 	    gateinfo->node[CurrentPin] = strdup(sarg);
477 
478 	    // These style gates have only one tap per gate;  LEF file reader
479 	    // allows multiple taps per gate node.
480 
481 	    drect = (DSEG)malloc(sizeof(struct dseg_));
482 	    gateinfo->taps[CurrentPin] = drect;
483 	    drect->x1 = drect->x2 = darg;
484 	    drect->y1 = drect->y2 = darg2;
485 
486 	    // This syntax always defines pins on layer 0;  LEF file reader
487 	    // allows pins on all layers.
488 
489 	    drect->layer = 0;
490 	    drect->next = (DSEG)NULL;
491 	    CurrentPin++;
492 
493             if (CurrentPin % 10 == 0) {
494 		// Allocate memory for 10 more pins
495                 gateinfo->taps = (DSEG *)realloc(gateinfo->taps,
496 				(CurrentPin + 10) * sizeof(DSEG));
497                 gateinfo->noderec = (NODE *)realloc(gateinfo->noderec,
498 				(CurrentPin + 10) * sizeof(NODE));
499                 gateinfo->netnum = (int *)realloc(gateinfo->netnum,
500 				(CurrentPin + 10) * sizeof(int));
501                 gateinfo->node = (char **)realloc(gateinfo->node,
502 				(CurrentPin + 10) * sizeof(char *));
503 	    }
504 	}
505 
506 	if (OK == 0) {
507 	    if (!(lineptr[0] == '\n' || lineptr[0] == '#' || lineptr[0] == 0)) {
508 		if (!is_info)	// Don't report errors on info file generation
509 		    Fprintf(stderr, "line not understood: %s\n", line);
510 	    }
511 	}
512 	OK = 0;
513 	line[0] = line[1] = '\0';
514 
515     }
516     post_config(FALSE);
517     return count;
518 
519 } /* read_config() */
520