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