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