diff options
author | Ruben Undheim <ruben.undheim@gmail.com> | 2019-03-29 00:00:11 +0100 |
---|---|---|
committer | Ruben Undheim <ruben.undheim@gmail.com> | 2019-03-29 00:00:11 +0100 |
commit | 6089b1f3dab7b7d60a8ea4bcec47bdec3560c5b4 (patch) | |
tree | ccf9fe6e50c78dcfd6e2b1f63b0bdfd8c7ab7d3f /qconfig.c | |
parent | 865a8002848550990b963870cca74c0a51426047 (diff) |
New upstream version 1.4.49
Diffstat (limited to 'qconfig.c')
-rw-r--r-- | qconfig.c | 159 |
1 files changed, 88 insertions, 71 deletions
@@ -30,19 +30,17 @@ int PinNumber = 0; int Num_layers = MAX_LAYERS; // layers to use to route double PathWidth[MAX_LAYERS]; // width of the paths -int GDSLayer[MAX_LAYERS]; // GDS layer number +int GDSLayer[MAX_TYPES]; // GDS layer number int GDSCommentLayer = 1; // for dummy wires, etc. -char CIFLayer[MAX_LAYERS][50]; // CIF layer name -double PitchX[MAX_LAYERS]; // Horizontal wire pitch of layer -double PitchY[MAX_LAYERS]; // Vertical wire pitch of layer -int NumChannelsX[MAX_LAYERS]; // number of wire channels in X on layer -int NumChannelsY[MAX_LAYERS]; // number of wire channels in Y on layer +char CIFLayer[MAX_TYPES][50]; // CIF layer name +double PitchX; // Horizontal wire pitch of layer +double PitchY; // Vertical wire pitch of layer +int NumChannelsX; // number of wire channels in X on layer +int NumChannelsY; // number of wire channels in Y on layer int Vert[MAX_LAYERS]; // 1 if vertical, 0 if horizontal int Numpasses = 10; // number of times to iterate in route_segs char StackedContacts = MAX_LAYERS; // Value is number of contacts that may // be stacked on top of each other. -char ViaPattern = VIA_PATTERN_NONE; // Patterning to be used for vias based - // on grid position (i.e., checkerboarding) double Xlowerbound=0.0; // Bounding Box of routes, in microns double Xupperbound=0.0; @@ -59,80 +57,99 @@ int OffsetCost = 50; // Cost per micron of a node offset int ConflictCost = 50; // Cost of shorting another route // during the rip-up and reroute stage -char *ViaX[MAX_LAYERS]; -char *ViaY[MAX_LAYERS]; +char *ViaXX[MAX_LAYERS]; +char *ViaXY[MAX_LAYERS]; +char *ViaYX[MAX_LAYERS]; +char *ViaYY[MAX_LAYERS]; /*--------------------------------------------------------------*/ /* post_config --- */ /* */ -/* The following code ensures that the layer grids align. */ -/* For now, all PitchX[i] and PitchY[i] should be the same */ -/* for all layers. Hopefully this restriction can be lifted */ -/* sometime, but it will necessarily be a royal pain. */ +/* Resolve PitchX and PitchY, which are the minimum pitches */ +/* that determine the underlying route grid. */ +/* */ +/* If "noprint" is TRUE, then do not print diagnostic info. */ /*--------------------------------------------------------------*/ void -post_config(void) +post_config(u_char noprint) { int i, h, v; + double rpitchx, rpitchy; // Make sure that Num_layers does not exceed the number of // routing layers defined by the LEF file (or the config // file). - i = LefGetMaxLayer(); + i = LefGetMaxRouteLayer(); if (i < Num_layers) Num_layers = i; - h = v = -1; + // Make sure all layers have a pitch in both X and Y even if not + // specified separately in the configuration or def files. for (i = 0; i < Num_layers; i++) { - if (!Vert[i]) { - h = i; - PitchY[i] = PitchX[i]; - PitchX[i] = 0.0; - } - else - v = i; + rpitchx = LefGetRoutePitchX(i); + rpitchy = LefGetRoutePitchY(i); + if ((PitchX == 0.0) || ((rpitchx != 0.0) && (rpitchx + EPS < PitchX))) + PitchX = rpitchx; + if ((PitchY == 0.0) || ((rpitchy != 0.0) && (rpitchy + EPS < PitchY))) + PitchY = rpitchy; } - // In case all layers are listed as horizontal or all - // as vertical, we should still handle it gracefully - - if (h == -1) h = v; - else if (v == -1) v = h; + // This is mostly arbitrary. Generally, all route layer + // pitches except for the smallest X and Y pitches will + // be ignored, and the actual route pitches will be multiples + // of the smallest value, and determined by width and spacing + // rules rather than using any value in the technology LEF. for (i = 0; i < Num_layers; i++) { - if (PitchX[i] != 0.0 && PitchX[i] != PitchX[v]) { - Fprintf(stderr, "Multiple vertical route layers at different" - " pitches. Using smaller pitch %g, will route on" - " 1-of-N tracks if necessary.\n", - PitchX[i]); - PitchX[v] = PitchX[i]; - } - if (PitchY[i] != 0.0 && PitchY[i] != PitchY[h]) { - Fprintf(stderr, "Multiple horizontal route layers at different" - " pitches. Using smaller pitch %g, will route on" - " 1-of-N tracks if necessary.\n", - PitchY[i]); - PitchY[h] = PitchY[i]; - } + if (LefGetRoutePitchX(i) == 0.0) { + if (Vert[i]) + LefSetRoutePitchX(i, PitchX); + else if (i > 0) + LefSetRoutePitchX(i, LefGetRoutePitchX(i - 1)); + else + LefSetRoutePitchX(i, LefGetRoutePitchX(i + 1)); + } + if (LefGetRoutePitchY(i) == 0.0) { + if (!Vert[i]) + LefSetRoutePitchY(i, PitchY); + else if (i > 0) + LefSetRoutePitchY(i, LefGetRoutePitchY(i - 1)); + else + LefSetRoutePitchY(i, LefGetRoutePitchY(i + 1)); + } } - // 2nd pass: Make sure all layers have a pitch in both X and Y - // even if not specified separately in the configuration or def files. - for (i = 0; i < Num_layers; i++) { - if (PitchX[i] == 0.0) PitchX[i] = PitchX[v]; - if (PitchY[i] == 0.0) PitchY[i] = PitchY[h]; + if (noprint == FALSE) { + for (i = 0; i < Num_layers; i++) { + rpitchx = LefGetRoutePitchX(i); + rpitchy = LefGetRoutePitchY(i); + if ((PitchX != 0.0) && (PitchX + EPS < rpitchx)) { + Fprintf(stdout, "Vertical route layer at non-minimum pitch" + " %g. Using smaller pitch %g, will route on" + " 1-of-%d tracks for layer %s.\n", + rpitchx, PitchX, (int)(ceil(rpitchx / PitchX)), + LefGetRouteName(i)); + } + if ((PitchY != 0.0) && (PitchY + EPS < rpitchy)) { + Fprintf(stdout, "Horizontal route layer at non-minimum pitch" + " %g. Using smaller pitch %g, will route on" + " 1-of-%d tracks for layer %s.\n", + rpitchy, PitchY, (int)(ceil(rpitchy / PitchY)), + LefGetRouteName(i)); + } + } } - } /* post_config() */ /*--------------------------------------------------------------*/ -/* Append to string list */ +/* Append to a string */ /*--------------------------------------------------------------*/ void string_list_append(STRING *lst, const char *s) { STRING n, strl; + n = (STRING)malloc(sizeof(struct string_)); n->name = strdup(s); n->next = NULL; @@ -170,8 +187,10 @@ int read_config(FILE *fconfig, int is_info) if (Firstcall) { for (i = 0; i < MAX_LAYERS; i++) { sprintf(line, "via%d%d", i + 1, i + 2); - ViaX[i] = strdup(line); - ViaY[i] = NULL; + ViaXX[i] = strdup(line); + ViaXY[i] = NULL; + ViaYX[i] = NULL; + ViaYY[i] = NULL; } DontRoute = (STRING)NULL; @@ -180,9 +199,7 @@ int read_config(FILE *fconfig, int is_info) Nlgates = (GATE)NULL; UserObs = (DSEG)NULL; - for (i = 0; i < MAX_LAYERS; i++) - PitchX[i] = PitchY[i] = 0.0; - + PitchX = PitchY = 0.0; Firstcall = 0; } @@ -198,11 +215,13 @@ int read_config(FILE *fconfig, int is_info) while (isspace(*lineptr)) lineptr++; if (!strncasecmp(lineptr, "lef", 3) || !strncmp(lineptr, "read_lef", 8)) { + int mscale; if ((i = sscanf(lineptr, "%*s %s\n", sarg)) == 1) { // Argument is a filename of a LEF file from which we // should get the information about gate pins & obstructions OK = 1; - LefRead(sarg); + mscale = LefRead(sarg); + if (mscale > Scales.mscale) Scales.mscale = mscale; } } @@ -220,13 +239,13 @@ int read_config(FILE *fconfig, int is_info) } if ((i = sscanf(lineptr, "layer_%d_name %s", &iarg2, sarg)) == 2) { - if (iarg2 > 0 && iarg2 < 10) { + if (iarg2 > 0 && iarg2 <= MAX_LAYERS) { OK = 1; strcpy(CIFLayer[iarg2 - 1], sarg); } } if ((i = sscanf(lineptr, "gds_layer_%d %d", &iarg2, &iarg)) == 2) { - if (iarg2 > 0 && iarg2 < 10) { + if (iarg2 > 0 && iarg2 <= MAX_TYPES) { OK = 1; GDSLayer[iarg2 - 1] = iarg; } } @@ -276,7 +295,13 @@ int read_config(FILE *fconfig, int is_info) } if ((i = sscanf(lineptr, "layer %d wire pitch %lf\n", &iarg, &darg)) == 2) { - OK = 1; PitchX[iarg-1] = darg; + OK = 1; + if (Vert[iarg - 1]) { + if ((PitchX == 0) || (darg < PitchX)) PitchX = darg; + } + else { + if ((PitchY == 0) || (darg < PitchY)) PitchY = darg; + } } else if (i == 1) { if ((i = sscanf(lineptr, "layer %*d vertical %d\n", &iarg2)) == 1) { @@ -364,14 +389,6 @@ int read_config(FILE *fconfig, int is_info) if (StackedContacts == 0) StackedContacts = 1; } - // Look for via patterning specifications - if (strcasestr(lineptr, "via pattern") != NULL) { - if (strcasestr(lineptr + 12, "normal") != NULL) - ViaPattern = VIA_PATTERN_NORMAL; - else if (strcasestr(lineptr + 12, "invert") != NULL) - ViaPattern = VIA_PATTERN_INVERT; - } - if ((i = sscanf(lineptr, "obstruction %lf %lf %lf %lf %s\n", &darg, &darg2, &darg3, &darg4, sarg)) == 5) { OK = 1; @@ -457,11 +474,11 @@ int read_config(FILE *fconfig, int is_info) // Allocate memory for 10 more pins gateinfo->taps = (DSEG *)realloc(gateinfo->taps, (CurrentPin + 10) * sizeof(DSEG)); - gateinfo->noderec = (NODE *)realloc(gateinfo->taps, + gateinfo->noderec = (NODE *)realloc(gateinfo->noderec, (CurrentPin + 10) * sizeof(NODE)); - gateinfo->netnum = (int *)realloc(gateinfo->taps, + gateinfo->netnum = (int *)realloc(gateinfo->netnum, (CurrentPin + 10) * sizeof(int)); - gateinfo->node = (char **)realloc(gateinfo->taps, + gateinfo->node = (char **)realloc(gateinfo->node, (CurrentPin + 10) * sizeof(char *)); } } @@ -476,7 +493,7 @@ int read_config(FILE *fconfig, int is_info) line[0] = line[1] = '\0'; } - post_config(); + post_config(FALSE); return count; } /* read_config() */ |