193 lines
6.4 KiB
C
193 lines
6.4 KiB
C
/*--------------------------------------------------------------*/
|
|
/* oa.c -- */
|
|
/* OpenAccess database support for magic */
|
|
/* */
|
|
/* Written by R. Timothy Edwards 4/22/04 */
|
|
/* Open Circuit Design, Inc. for */
|
|
/* MultiGiG, Inc. */
|
|
/*--------------------------------------------------------------*/
|
|
|
|
#ifdef MAGIC_WRAPPER
|
|
#ifdef OPENACCESS
|
|
|
|
#include "tcltk/tclmagic.h"
|
|
#include "utils/geometry.h"
|
|
#include "utils/magic.h"
|
|
#include "tiles/tile.h"
|
|
#include "utils/hash.h"
|
|
#include "database/database.h"
|
|
#include "oa/oa.h"
|
|
|
|
/*
|
|
*-----------------------------------------------------------------------------
|
|
*
|
|
* OAInit --
|
|
*
|
|
* Initialize variables required by the OpenAccess module.
|
|
*
|
|
*-----------------------------------------------------------------------------
|
|
*/
|
|
|
|
void
|
|
OAInit()
|
|
{
|
|
/* This generates the TCL commands for magicoa */
|
|
Magicoa_Init(magicinterp);
|
|
}
|
|
|
|
/*
|
|
*-----------------------------------------------------------------------------
|
|
*
|
|
* OACellSearch --
|
|
*
|
|
* The OpenAccess equivalent of DBTreeSrCells. This function is called by
|
|
* DBTreeSrCells when the cell def has the flag CDOPENACCESS set.
|
|
*
|
|
* The procedure should be of the following form:
|
|
* int
|
|
* func(scx, cdarg)
|
|
* SearchContext *scx;
|
|
* ClientData cdarg;
|
|
* {
|
|
* }
|
|
*
|
|
* In the above, the transform scx->scx_trans is from coordinates of
|
|
* the def of scx->scx_use to the "root". The array indices
|
|
* scx->scx_x and scx->scx_y identify this element if it is a
|
|
* component of an array. Func normally returns 0. If func returns
|
|
* 1, then the search is aborted. If func returns 2, then all
|
|
* remaining elements of the current array are skipped, but the
|
|
* search is not aborted.
|
|
*
|
|
* Each element of an array is returned separately.
|
|
*
|
|
* Results:
|
|
* 0 is returned if the search terminated normally. 1 is
|
|
* returned if it was aborted.
|
|
*
|
|
* Side effects:
|
|
* Whatever side effects are brought about by applying the
|
|
* procedure supplied.
|
|
*
|
|
* Warnings:
|
|
* The OpenAccess routines should only be used when (*func)()
|
|
* is read-only; that is, the function should not attempt to
|
|
* alter the cell structure.
|
|
*-----------------------------------------------------------------------------
|
|
*/
|
|
|
|
int
|
|
OACellSearch(scx, xMask, func, cdarg)
|
|
SearchContext *scx; /* Pointer to search context specifying a cell use to
|
|
* search, an area in the coordinates of the cell's
|
|
* def, and a transform back to "root" coordinates.
|
|
*/
|
|
int xMask; /* All subcells are visited recursively until we
|
|
* encounter uses whose flags, when anded with
|
|
* xMask, are not equal to xMask. Func is called
|
|
* for these cells. A zero mask means all cells in
|
|
* the root use are considered not to be expanded,
|
|
* and hence are passed to func.
|
|
*/
|
|
int (*func)(); /* Function to apply to each qualifying cell */
|
|
ClientData cdarg; /* Client data for above function */
|
|
{
|
|
TreeContext context;
|
|
TreeFilter filter;
|
|
char *instname;
|
|
|
|
filter.tf_xmask = xMask;
|
|
filter.tf_func = func;
|
|
filter.tf_arg = cdarg;
|
|
|
|
context.tc_scx = scx;
|
|
context.tc_filter = &filter;
|
|
|
|
/* Get the name of the instance, which should have been set by */
|
|
/* rexlite when the OpenAccess database was opened under magic. */
|
|
|
|
instname = scx->scx_use->cu_id;
|
|
|
|
/* Query the OpenAccess database. For each cell overlapping the
|
|
* area scx->scx_area, call the function (*func)() with client
|
|
* data cdarg. Currently, xMask is not used (assumed to be 0).
|
|
*/
|
|
|
|
/* The rexlite function is tentatively called REXSearchInstances(): */
|
|
/* REXSearchInstances(name, func, arg) { */
|
|
/* char *name; */
|
|
/* (int)(*func)(); */
|
|
/* ClientData arg; */
|
|
/* */
|
|
/* This function should return 0 normally, 1 in case of error. */
|
|
/* For each cell instance which is in the hierarchy of "instname", */
|
|
/* REXSearchInstances() should call "func" with arguments: */
|
|
/* */
|
|
/* (int)(*func)(char *iname, char *dname, int llx, int lly, */
|
|
/* int urx, int urx, ClientData arg); */
|
|
/* */
|
|
/* where "iname" is the name of the instance, "dname" is the name */
|
|
/* of the master cell, and "llx", "lly", "urx", and "ury" are the */
|
|
/* bounding box coordinates. "arg" is passed on from above. */
|
|
/* If func() returns 0, then the database search should continue. */
|
|
/* If func() returns 1, then the database search should stop and */
|
|
/* REXSearchInstances() should return 1. */
|
|
|
|
/* return REXSearchInstances(instname, oaTreeCellSrFunc, (ClientData)&context); */
|
|
return 0; /* placeholder */
|
|
}
|
|
|
|
/*
|
|
* Callback function called from REXSearchInstances() for each instance
|
|
* encountered in the cell search.
|
|
*
|
|
* For the time being, we pass back a minimal amount of information: The
|
|
* instance name and the bounding box. The bounding box will be compared
|
|
* against the search area to check for overlap, and the function buried
|
|
* in the TreeContext structure (passed as a generic client data pointer)
|
|
* will be called.
|
|
*/
|
|
|
|
int
|
|
oaTreeCellSrFunc(instname, defname, llx, lly, urx, ury, cdarg)
|
|
char *instname;
|
|
char *defname;
|
|
int llx, lly, urx, ury;
|
|
ClientData cdarg;
|
|
{
|
|
TreeContext *context = (TreeContext *)cdarg;
|
|
TreeFilter *filter = context->tc_filter;
|
|
SearchContext newscx, *scx = context->tc_scx;
|
|
int fres;
|
|
Rect r, *area = &scx->scx_area;
|
|
CellUse newuse;
|
|
|
|
/* Check for area overlap */
|
|
r.r_xbot = llx;
|
|
r.r_xtop = urx;
|
|
r.r_ybot = lly;
|
|
r.r_ytop = ury;
|
|
|
|
/* Transform---for now, assuming that llx, etc., are relative to */
|
|
/* the top-level coordinate system. */
|
|
|
|
/* Check for area overlap */
|
|
if (!GEO_OVERLAP(area, &r))
|
|
return 0; /* Don't call function but keep the search going */
|
|
|
|
newuse.cu_id = instname;
|
|
newuse.cu_bbox = r;
|
|
/* Need to fill in more of the CellUse structure! */
|
|
|
|
newscx.scx_use = &newuse;
|
|
newscx.scx_area = scx->scx_area;
|
|
/* Need to fill in more of the SearchContext structure! */
|
|
|
|
/* Call the function */
|
|
fres = (*(filter->tf_func))(newscx, (ClientData)filter->tf_arg);
|
|
return fres; /* keep the search going */
|
|
}
|
|
|
|
#endif /* OPENACCESS */
|
|
#endif /* MAGIC_WRAPPER */
|