summaryrefslogtreecommitdiff
path: root/def.c
diff options
context:
space:
mode:
Diffstat (limited to 'def.c')
-rw-r--r--def.c104
1 files changed, 95 insertions, 9 deletions
diff --git a/def.c b/def.c
index 6376b67..b2af479 100644
--- a/def.c
+++ b/def.c
@@ -32,6 +32,7 @@
#include "lef.h"
#include "def.h"
+TRACKS *Tracks = NULL;
int numSpecial = 0; /* Tracks number of specialnets */
#ifndef TCL_QROUTER
@@ -178,6 +179,27 @@ DefHashNet(NET net)
/*
*------------------------------------------------------------
*
+ * DefGetTracks --
+ *
+ * Get tracks information for the given layer.
+ * If no TRACKS were specified for the layer, NULL will be
+ * returned.
+ *
+ *------------------------------------------------------------
+ */
+
+TRACKS
+DefGetTracks(int layer)
+{
+ if (Tracks)
+ return Tracks[layer];
+ else
+ return NULL;
+}
+
+/*
+ *------------------------------------------------------------
+ *
* DefAddRoutes --
*
* Parse a network route statement from the DEF file.
@@ -214,9 +236,6 @@ DefAddRoutes(FILE *f, float oscale, NET net, char special)
refp.x1 = 0;
refp.y1 = 0;
- /* Set pitches and allocate memory for Obs[] if we haven't yet. */
- set_num_channels();
-
/* Don't create obstructions or routes on routed specialnets inputs */
/* except for power and ground nets. */
noobstruct = ((special == (char)1) && (!(net->flags & NET_IGNORED)) &&
@@ -630,6 +649,7 @@ DefReadGatePin(NET net, NODE node, char *instname, char *pinname, double *home)
if (gridx < 0) gridx = 0;
while (1) {
+ if (gridx >= NumChannelsX) break;
dx = (gridx * PitchX) + Xlowerbound;
if (dx > drect->x2 + home[drect->layer] - EPS) break;
if (dx < drect->x1 - home[drect->layer] + EPS) {
@@ -640,6 +660,7 @@ DefReadGatePin(NET net, NODE node, char *instname, char *pinname, double *home)
if (gridy < 0) gridy = 0;
while (1) {
+ if (gridy >= NumChannelsY) break;
dy = (gridy * PitchY) + Ylowerbound;
if (dy > drect->y2 + home[drect->layer] - EPS) break;
if (dy < drect->y1 - home[drect->layer] + EPS) {
@@ -747,6 +768,9 @@ DefReadNets(FILE *f, char *sname, float oscale, char special, int total)
NULL
};
+ /* Set pitches and allocate memory for Obs[] if we haven't yet. */
+ set_num_channels();
+
if (Numnets == 0)
{
// Initialize net and node records
@@ -896,9 +920,12 @@ DefReadNets(FILE *f, char *sname, float oscale, char special, int total)
while (token && (*token != ';'))
token = DefAddRoutes(f, oscale, net, special);
// Treat power and ground nets in specialnets as fixed
- if (subkey == DEF_NETPROP_ROUTED && special == (char)1)
+ if ((subkey == DEF_NETPROP_ROUTED ||
+ subkey == DEF_NETPROP_FIXED) &&
+ special == (char)1) {
if (net->netnum == VDD_NET || net->netnum == GND_NET)
fixed++;
+ }
break;
}
}
@@ -933,8 +960,8 @@ DefReadNets(FILE *f, char *sname, float oscale, char special, int total)
if (processed == total) {
if (Verbose > 0)
- Fprintf(stdout, " Processed %d%s nets total.\n", processed,
- (special) ? " special" : "");
+ Fprintf(stdout, " Processed %d%s nets total (%d fixed).\n",
+ processed, (special) ? " special" : "", fixed);
}
else
LefError(DEF_WARNING, "Warning: Number of nets read (%d) does not match "
@@ -971,7 +998,7 @@ DefReadLocation(gate, f, oscale)
int keyword;
char *token;
float x, y;
- char mxflag, myflag;
+ char mxflag, myflag, r90flag;
static char *orientations[] = {
"N", "S", "E", "W", "FN", "FS", "FE", "FW"
@@ -994,7 +1021,7 @@ DefReadLocation(gate, f, oscale)
return -1;
}
- mxflag = myflag = (char)0;
+ mxflag = myflag = r90flag = (char)0;
switch (keyword)
{
@@ -1011,10 +1038,20 @@ DefReadLocation(gate, f, oscale)
myflag = 1;
break;
case DEF_EAST:
+ r90flag = 1;
+ break;
case DEF_WEST:
+ r90flag = 1;
+ mxflag = 1;
+ myflag = 1;
+ break;
case DEF_FLIPPED_EAST:
+ r90flag = 1;
+ mxflag = 1;
+ break;
case DEF_FLIPPED_WEST:
- LefError(DEF_ERROR, "Error: Cannot handle 90-degree rotated components!\n");
+ r90flag = 1;
+ myflag = 1;
break;
}
@@ -1024,6 +1061,7 @@ DefReadLocation(gate, f, oscale)
gate->orient = MNONE;
if (mxflag) gate->orient |= MX;
if (myflag) gate->orient |= MY;
+ if (r90flag) gate->orient |= R90;
}
return 0;
@@ -1760,6 +1798,18 @@ DefReadComponents(FILE *f, char *sname, float oscale, int total)
drect->y2 -= gateginfo->placedY;
// handle rotations and orientations here
+ if (gate->orient & R90) {
+ tmp = drect->y1;
+ drect->y1 = -drect->x1;
+ drect->y1 += gateginfo->width;
+ drect->x1 = tmp;
+
+ tmp = drect->y2;
+ drect->y2 = -drect->x2;
+ drect->y2 += gateginfo->width;
+ drect->x2 = tmp;
+ }
+
if (gate->orient & MX) {
tmp = drect->x1;
drect->x1 = -drect->x2;
@@ -1803,6 +1853,18 @@ DefReadComponents(FILE *f, char *sname, float oscale, int total)
drect->y2 -= gateginfo->placedY;
// handle rotations and orientations here
+ if (gate->orient & R90) {
+ tmp = drect->y1;
+ drect->y1 = -drect->x1;
+ drect->y1 += gateginfo->width;
+ drect->x1 = tmp;
+
+ tmp = drect->y2;
+ drect->y2 = -drect->x2;
+ drect->y2 += gateginfo->width;
+ drect->x2 = tmp;
+ }
+
if (gate->orient & MX) {
tmp = drect->x1;
drect->x1 = -drect->x2;
@@ -2060,6 +2122,30 @@ DefRead(char *inName, float *retscale)
if (!strcmp(token, "LAYER")) {
curlayer = LefReadLayer(f, FALSE);
}
+ if (curlayer < 0) {
+ LefError(DEF_ERROR, "Failed to read layer; cannot parse TRACKS.");
+ LefEndStatement(f);
+ break;
+ }
+ else if (curlayer >= Num_layers) {
+ LefError(DEF_WARNING, "Ignoring TRACKS above number of "
+ "specified route layers.");
+ LefEndStatement(f);
+ break;
+ }
+ if (Tracks && (Tracks[curlayer] != NULL)) {
+ LefError(DEF_ERROR, "Only one TRACKS line per layer allowed; "
+ "last one is used.");
+ }
+ else {
+ if (Tracks == NULL)
+ Tracks = (TRACKS *)calloc(Num_layers, sizeof(TRACKS));
+ Tracks[curlayer] = (TRACKS)malloc(sizeof(struct tracks_));
+ }
+ Tracks[curlayer]->start = start / oscale;
+ Tracks[curlayer]->ntracks = channels;
+ Tracks[curlayer]->pitch = step / oscale;
+
if (corient == 'x') {
Vert[curlayer] = 1;
locpitch = step / oscale;