1 /* gcrShowFlags.c -
2  *
3  *	Code to highlight areas flagged by the router.
4  *
5  *     *********************************************************************
6  *     * Copyright (C) 1985, 1990 Regents of the University of California. *
7  *     * Permission to use, copy, modify, and distribute this              *
8  *     * software and its documentation for any purpose and without        *
9  *     * fee is hereby granted, provided that the above copyright          *
10  *     * notice appear in all copies.  The University of California        *
11  *     * makes no representations about the suitability of this            *
12  *     * software for any purpose.  It is provided "as is" without         *
13  *     * express or implied warranty.  Export of this software outside     *
14  *     * of the United States of America may require an export license.    *
15  *     *********************************************************************
16  */
17 
18 #ifndef lint
19 static char rcsid[] __attribute__ ((unused)) = "$Header: /usr/cvsroot/magic-8.0/gcr/gcrShwFlgs.c,v 1.1.1.1 2008/02/03 20:43:50 tim Exp $";
20 #endif  /* not lint */
21 
22 #include <stdio.h>
23 #include <string.h>
24 
25 #include "utils/magic.h"
26 #include "utils/geometry.h"
27 #include "utils/hash.h"
28 #include "tiles/tile.h"
29 #include "database/database.h"
30 #include "windows/windows.h"
31 #include "dbwind/dbwind.h"
32 #include "gcr/gcr.h"
33 #include "utils/heap.h"
34 #include "router/router.h"
35 #include "utils/main.h"
36 #include "utils/styles.h"
37 #include "textio/textio.h"
38 
39 #define MAXFLAGS 17
40 
41 char * GCRFlagNames[]=
42     {"blkb", "blkm", "blkp", "cc",  "ce",  "r",  "tc", "te", "u",
43      "v2",   "vl",   "vd",   "vm",  "vr",  "vu", "x",  "z",  0};
44 
45 int GCRFlagValue[]=
46     {   3,  1,     2,   256,  1024,     8,  128, 512, 4,
47        64, 32, 32768,  2048,  8192, 16384,   16,  4096};
48 
49 char * GCRFlagDescr[]={
50 	"3     Both layers are blocked",
51 	"1     Location is blocked with metal",
52 	"2     Location is blocked with poly",
53 	"256   Column contact needed",
54 	"1024  Column ends beyond this point",
55 	"8     Connect to the right",
56 	"128   Track contact needed",
57 	"512   Track ends right of this point",
58 	"4     Connect from track upwards",
59 	"64    Vacate track due to 2-layer obstacle",
60 	"32    Vacate track from left",
61 	"32768 Vacate track from down",
62 	"2048  Vertical poly changed to metal",
63 	"8192  Vacate track from right",
64 	"16384 Vacate track from up",
65 	"16    Metal/poly contact",
66 	"4096  Via not deleted"
67     };
68 
69 CellDef * gcrShowCell = (CellDef *) NULL;
70 
71 /*
72  * ----------------------------------------------------------------------------
73  *
74  * gcrShow --
75  *
76  * 	Fields commands of the form :*seeflags <FIELD> to display the router
77  *	flags in the channel under the point.  If no arguments, then turn
78  *	off highlighting.
79  *
80  * Results:
81  *	None.
82  *
83  * Side effects:
84  *	Displays various router flags as feedback.  Existing feedback
85  *	is cleared.
86  *
87  * ----------------------------------------------------------------------------
88  */
89 
90 void
GCRShow(point,arg)91 GCRShow(point, arg)
92     Point   * point;
93     char    * arg;
94 {
95     GCRChannel * ch;
96     HashEntry  * he;
97     Rect	 box;
98     int		 dx, dy, track, col, mask;
99     short      * colBits;
100     char	msg[100];
101     Tile * tile;
102     void	 gcrDumpChannel();
103 
104 /* Figure out which channel is selected */
105 
106     if(RtrChannelPlane == NULL)
107     {
108 	TxError("Sorry.  You must route before looking at flags!\n");
109 	return;
110     }
111     tile = TiSrPoint((Tile *) NULL, RtrChannelPlane, point);
112     if(TiGetType(tile) != 0)
113     {
114 	TxError("Point to the channel you want to highlight.\n");
115 	return;
116     }
117     he = HashLookOnly(&RtrTileToChannel, (char *) tile);
118     if(he == (HashEntry *) NULL)
119     {
120 	TxError("No channel under point.  Have you already routed?\n");
121 	return;
122     }
123     ch = (GCRChannel *) HashGetValue(he);
124 
125 /* Translate the command argument to the bit mask for the flag */
126     mask = Lookup(arg, GCRFlagNames);
127     if ( mask < 0 )
128     {
129 	if(strcmp(arg, "dump") == 0)
130 	{
131 	    gcrDumpChannel(ch);
132 	    return;
133 	}
134 	if(strcmp(arg, "help") == 0)
135 	    TxError("Legal values are:\n");
136 	else
137 	if (mask == -1)
138 	    TxError("%s:  ambiguous.  Legal values are:\n", arg);
139 	else
140 	    TxError("%s:  not found.  Legal values are:\n", arg);
141 	for(col=0; col<MAXFLAGS; col++)
142 	    TxError("	%s	%s\n", GCRFlagNames[col], GCRFlagDescr[col]);
143 	return;
144     }
145     mask =  GCRFlagValue[mask];
146     (void) sprintf(msg, "Channel flag \"%s\"", arg);
147 
148     if(ch->gcr_result == (short **) NULL)
149     {
150 	TxError("Oops.  Somebody deleted the results array.\n");
151 	return;
152     }
153 
154 /* Scan the routing grid, create feedback areas for each grid location
155  * where the mask bit is set.
156  */
157 
158     dx = ch->gcr_origin.p_x - 2;
159     for(col = 0; col <= ch->gcr_length; col++)
160     {
161 	if((colBits = ch->gcr_result[col]) == (short *) NULL)
162 	{
163 	    TxError("Oops.  Result array column %d is missing.\n", col);
164 	    return;
165 	}
166 	dy = ch->gcr_origin.p_y - 2;
167 	for(track = 0; track <= ch->gcr_width; track++)
168 	{
169 	    if((colBits[track] & mask) == mask)
170 	    {
171 		box.r_xbot = dx;
172 		box.r_ybot = dy;
173 		box.r_xtop = dx + RtrGridSpacing;
174 		box.r_ytop = dy + RtrGridSpacing;
175 		DBWFeedbackAdd(&box, msg, EditCellUse->cu_def, 1,
176 		    STYLE_PALEHIGHLIGHTS);
177 	    }
178 	    dy += RtrGridSpacing;
179 	}
180 	dx += RtrGridSpacing;
181     }
182 }
183 
184 /*
185  * ----------------------------------------------------------------------------
186  *
187  * gcrDumpChannel --
188  *
189  * 	Create a file called "channel.XXXX" where XXXX is the hex address
190  *	of the channel.  The file contains the routing problem for the
191  *	channel, complete with obstacles.
192  *
193  * Results:
194  *	None.
195  *
196  * Side effects:
197  *	Creates a file.
198  *
199  * ----------------------------------------------------------------------------
200  */
201 
202 void
gcrDumpChannel(ch)203 gcrDumpChannel(ch)
204     GCRChannel * ch;
205 {
206     char name[20];
207     int track, col, netCount = 0, gcrNetName();
208     short res;
209     GCRNet * net, * netNames[500];
210     FILE * fp, * fopen();
211 
212     netNames[0]=(GCRNet *) 0;
213     (void) sprintf(name, "channel.%p", ch);
214     if((fp = fopen(name, "w")) == NULL)
215     {
216 	TxError("Can't open file %s to dump channel.\n", name);
217 	return;
218     }
219     fprintf(fp, "* %d %d\n", ch->gcr_width, ch->gcr_length);
220     for(track=1; track<=ch->gcr_width; track++)
221     {
222 	net = ch->gcr_lPins[track].gcr_pId;
223 	fprintf(fp, "%4d", gcrNetName(netNames, &netCount, net));
224     }
225     fprintf(fp, "\n");
226     for(col=1; col<=ch->gcr_length; col++)
227     {
228 	net = ch->gcr_bPins[col].gcr_pId;
229 	fprintf(fp, "%4d", gcrNetName(netNames, &netCount, net));
230 	for(track=1; track<=ch->gcr_width; track++)
231 	{
232 	    res = ch->gcr_result[col][track];
233 	    if((res & GCRBLKM) && (res & GCRBLKP))
234 		fprintf(fp, "  X");
235 	    else
236 	    if(res & GCRBLKM)
237 		fprintf(fp, "  M");
238 	    else
239 	    if(res & GCRBLKP)
240 		fprintf(fp, "  P");
241 	    else
242 		fprintf(fp, "  .");
243 	}
244 	net = ch->gcr_tPins[col].gcr_pId;
245 	fprintf(fp, "%4d", gcrNetName(netNames, &netCount, net));
246 	fprintf(fp, "\n");
247     }
248     for(track=1; track<=ch->gcr_width; track++)
249     {
250 	net = ch->gcr_rPins[track].gcr_pId;
251 	fprintf(fp, "%4d", gcrNetName(netNames, &netCount, net));
252     }
253     fprintf(fp, "\n");
254     fclose(fp);
255 }
256 
257 int
gcrNetName(netNames,netCount,net)258 gcrNetName(netNames, netCount, net)
259     GCRNet * netNames[];
260     int * netCount;
261     GCRNet * net;
262 {
263     int i;
264     for(i=0; i<= *netCount; i++)
265 	if(netNames[i]==net) return(i);
266     *netCount = *netCount + 1;
267     netNames[*netCount]=net;
268     return(*netCount);
269 }
270