1 /*--------------------------------------------------------------*/
2 /* oa.c -- */
3 /* OpenAccess database support for magic */
4 /* */
5 /* Written by R. Timothy Edwards 4/22/04 */
6 /* Open Circuit Design, Inc. for */
7 /* MultiGiG, Inc. */
8 /*--------------------------------------------------------------*/
9
10 #ifdef MAGIC_WRAPPER
11 #ifdef OPENACCESS
12
13 #include "tcltk/tclmagic.h"
14 #include "utils/geometry.h"
15 #include "utils/magic.h"
16 #include "tiles/tile.h"
17 #include "utils/hash.h"
18 #include "database/database.h"
19 #include "oa/oa.h"
20
21 /*
22 *-----------------------------------------------------------------------------
23 *
24 * OAInit --
25 *
26 * Initialize variables required by the OpenAccess module.
27 *
28 *-----------------------------------------------------------------------------
29 */
30
31 void
OAInit()32 OAInit()
33 {
34 /* This generates the TCL commands for magicoa */
35 Magicoa_Init(magicinterp);
36 }
37
38 /*
39 *-----------------------------------------------------------------------------
40 *
41 * OACellSearch --
42 *
43 * The OpenAccess equivalent of DBTreeSrCells. This function is called by
44 * DBTreeSrCells when the cell def has the flag CDOPENACCESS set.
45 *
46 * The procedure should be of the following form:
47 * int
48 * func(scx, cdarg)
49 * SearchContext *scx;
50 * ClientData cdarg;
51 * {
52 * }
53 *
54 * In the above, the transform scx->scx_trans is from coordinates of
55 * the def of scx->scx_use to the "root". The array indices
56 * scx->scx_x and scx->scx_y identify this element if it is a
57 * component of an array. Func normally returns 0. If func returns
58 * 1, then the search is aborted. If func returns 2, then all
59 * remaining elements of the current array are skipped, but the
60 * search is not aborted.
61 *
62 * Each element of an array is returned separately.
63 *
64 * Results:
65 * 0 is returned if the search terminated normally. 1 is
66 * returned if it was aborted.
67 *
68 * Side effects:
69 * Whatever side effects are brought about by applying the
70 * procedure supplied.
71 *
72 * Warnings:
73 * The OpenAccess routines should only be used when (*func)()
74 * is read-only; that is, the function should not attempt to
75 * alter the cell structure.
76 *-----------------------------------------------------------------------------
77 */
78
79 int
OACellSearch(scx,xMask,func,cdarg)80 OACellSearch(scx, xMask, func, cdarg)
81 SearchContext *scx; /* Pointer to search context specifying a cell use to
82 * search, an area in the coordinates of the cell's
83 * def, and a transform back to "root" coordinates.
84 */
85 int xMask; /* All subcells are visited recursively until we
86 * encounter uses whose flags, when anded with
87 * xMask, are not equal to xMask. Func is called
88 * for these cells. A zero mask means all cells in
89 * the root use are considered not to be expanded,
90 * and hence are passed to func.
91 */
92 int (*func)(); /* Function to apply to each qualifying cell */
93 ClientData cdarg; /* Client data for above function */
94 {
95 TreeContext context;
96 TreeFilter filter;
97 char *instname;
98
99 filter.tf_xmask = xMask;
100 filter.tf_func = func;
101 filter.tf_arg = cdarg;
102
103 context.tc_scx = scx;
104 context.tc_filter = &filter;
105
106 /* Get the name of the instance, which should have been set by */
107 /* rexlite when the OpenAccess database was opened under magic. */
108
109 instname = scx->scx_use->cu_id;
110
111 /* Query the OpenAccess database. For each cell overlapping the
112 * area scx->scx_area, call the function (*func)() with client
113 * data cdarg. Currently, xMask is not used (assumed to be 0).
114 */
115
116 /* The rexlite function is tentatively called REXSearchInstances(): */
117 /* REXSearchInstances(name, func, arg) { */
118 /* char *name; */
119 /* (int)(*func)(); */
120 /* ClientData arg; */
121 /* */
122 /* This function should return 0 normally, 1 in case of error. */
123 /* For each cell instance which is in the hierarchy of "instname", */
124 /* REXSearchInstances() should call "func" with arguments: */
125 /* */
126 /* (int)(*func)(char *iname, char *dname, int llx, int lly, */
127 /* int urx, int urx, ClientData arg); */
128 /* */
129 /* where "iname" is the name of the instance, "dname" is the name */
130 /* of the master cell, and "llx", "lly", "urx", and "ury" are the */
131 /* bounding box coordinates. "arg" is passed on from above. */
132 /* If func() returns 0, then the database search should continue. */
133 /* If func() returns 1, then the database search should stop and */
134 /* REXSearchInstances() should return 1. */
135
136 /* return REXSearchInstances(instname, oaTreeCellSrFunc, (ClientData)&context); */
137 return 0; /* placeholder */
138 }
139
140 /*
141 * Callback function called from REXSearchInstances() for each instance
142 * encountered in the cell search.
143 *
144 * For the time being, we pass back a minimal amount of information: The
145 * instance name and the bounding box. The bounding box will be compared
146 * against the search area to check for overlap, and the function buried
147 * in the TreeContext structure (passed as a generic client data pointer)
148 * will be called.
149 */
150
151 int
oaTreeCellSrFunc(instname,defname,llx,lly,urx,ury,cdarg)152 oaTreeCellSrFunc(instname, defname, llx, lly, urx, ury, cdarg)
153 char *instname;
154 char *defname;
155 int llx, lly, urx, ury;
156 ClientData cdarg;
157 {
158 TreeContext *context = (TreeContext *)cdarg;
159 TreeFilter *filter = context->tc_filter;
160 SearchContext newscx, *scx = context->tc_scx;
161 int fres;
162 Rect r, *area = &scx->scx_area;
163 CellUse newuse;
164
165 /* Check for area overlap */
166 r.r_xbot = llx;
167 r.r_xtop = urx;
168 r.r_ybot = lly;
169 r.r_ytop = ury;
170
171 /* Transform---for now, assuming that llx, etc., are relative to */
172 /* the top-level coordinate system. */
173
174 /* Check for area overlap */
175 if (!GEO_OVERLAP(area, &r))
176 return 0; /* Don't call function but keep the search going */
177
178 newuse.cu_id = instname;
179 newuse.cu_bbox = r;
180 /* Need to fill in more of the CellUse structure! */
181
182 newscx.scx_use = &newuse;
183 newscx.scx_area = scx->scx_area;
184 /* Need to fill in more of the SearchContext structure! */
185
186 /* Call the function */
187 fres = (*(filter->tf_func))(newscx, (ClientData)filter->tf_arg);
188 return fres; /* keep the search going */
189 }
190
191 #endif /* OPENACCESS */
192 #endif /* MAGIC_WRAPPER */
193