Added an "off-grid geometry" check, in two versions. The simple

one is an "off_grid" DRC type, which can be used to check geometry
that is below the manufacturing grid.  Normally magic prevents the
grid from being subdivided below the manufacturing grid, but this
limit can be removed and replaced by DRC checks to check for such
errors in a GDS file of unknown origin.  The second version looks
for interactions between subcells that end up with intersections
of non-manhattan geometry landing on points that are not on the
database internal grid.  Such errors cannot be seen by magic's DRC
engine by definition, and so must be detected while flattening
geometry for the DRC checks.
This commit is contained in:
Tim Edwards 2021-02-04 17:35:43 -05:00
parent 2a1494e4d1
commit e53a23de59
9 changed files with 329 additions and 67 deletions

View File

@ -48,7 +48,7 @@ static PaintResultType (*dbCurPaintTbl)[NT][NT] = DBPaintResultTbl;
* such as the design-rule checker that need to use, for example,
* DBPaintPlaneMark instead of the standard version.
*/
static void (*dbCurPaintPlane)() = DBPaintPlaneWrapper;
static int (*dbCurPaintPlane)() = DBPaintPlaneWrapper;
/* Structure passed to DBTreeSrTiles() */
struct copyAllArg
@ -56,6 +56,7 @@ struct copyAllArg
TileTypeBitMask *caa_mask; /* Mask of tile types to be copied */
Rect caa_rect; /* Clipping rect in target coords */
CellUse *caa_targetUse; /* Use to which tiles are copied */
void (*caa_func)(); /* Callback function for off-grid points */
Rect *caa_bbox; /* Bbox of material copied (in
* targetUse coords). Used only when
* copying cells.
@ -96,7 +97,7 @@ struct copyLabelArg
* ----------------------------------------------------------------------------
*/
void
int
DBPaintPlaneWrapper(def, pNum, type, area, undo)
CellDef *def;
int pNum;
@ -106,12 +107,14 @@ DBPaintPlaneWrapper(def, pNum, type, area, undo)
{
TileType loctype = type & TT_LEFTMASK;
Rect expand;
int result;
undo->pu_pNum = pNum;
DBNMPaintPlane(def->cd_planes[pNum], type, area,
result = DBNMPaintPlane(def->cd_planes[pNum], type, area,
dbCurPaintTbl[pNum][loctype], undo);
GEO_EXPAND(area, 1, &expand);
DBMergeNMTiles(def->cd_planes[pNum], &expand, undo);
return result;
}
/*
@ -126,7 +129,7 @@ DBPaintPlaneWrapper(def, pNum, type, area, undo)
* ----------------------------------------------------------------------------
*/
void
int
DBPaintPlaneMark(def, pNum, type, area, undo)
CellDef *def;
int pNum;
@ -137,7 +140,7 @@ DBPaintPlaneMark(def, pNum, type, area, undo)
TileType loctype = type & TT_LEFTMASK;
undo->pu_pNum = pNum;
DBNMPaintPlane0(def->cd_planes[pNum], type, area,
return DBNMPaintPlane0(def->cd_planes[pNum], type, area,
dbCurPaintTbl[pNum][loctype], undo, (unsigned char)PAINT_MARK);
}
@ -147,7 +150,7 @@ DBPaintPlaneMark(def, pNum, type, area, undo)
* ----------------------------------------------------------------------------
*/
void
int
DBPaintPlaneXor(def, pNum, type, area, undo)
CellDef *def;
int pNum;
@ -158,7 +161,7 @@ DBPaintPlaneXor(def, pNum, type, area, undo)
TileType loctype = type & TT_LEFTMASK;
undo->pu_pNum = pNum;
DBNMPaintPlane0(def->cd_planes[pNum], type, area,
return DBNMPaintPlane0(def->cd_planes[pNum], type, area,
dbCurPaintTbl[pNum][loctype], undo, (unsigned char)PAINT_XOR);
}
@ -175,7 +178,7 @@ DBPaintPlaneXor(def, pNum, type, area, undo)
* ----------------------------------------------------------------------------
*/
void
int
DBPaintPlaneActive(def, pNum, type, area, undo)
CellDef *def;
int pNum;
@ -200,11 +203,13 @@ DBPaintPlaneActive(def, pNum, type, area, undo)
DBPaintPlaneWrapper(def, pNum, t | (type &
(TT_SIDE | TT_DIRECTION | TT_DIAGONAL)),
area, undo);
return;
return 0;
}
}
if (TTMaskHasType(&DBActiveLayerBits, loctype))
DBPaintPlaneWrapper(def, pNum, type, area, undo);
return DBPaintPlaneWrapper(def, pNum, type, area, undo);
else
return 0;
}
/*
@ -241,6 +246,7 @@ DBCellCopyManhattanPaint(scx, mask, xMask, targetUse)
arg.caa_mask = mask;
arg.caa_targetUse = targetUse;
arg.caa_func = NULL;
GEOTRANSRECT(&scx->scx_trans, &scx->scx_area, &arg.caa_rect);
(void) DBTreeSrTiles(scx, mask, xMask, dbCopyManhattanPaint, (ClientData) &arg);
@ -281,6 +287,52 @@ DBCellCopyAllPaint(scx, mask, xMask, targetUse)
arg.caa_mask = mask;
arg.caa_targetUse = targetUse;
arg.caa_func = NULL;
GEOTRANSRECT(&scx->scx_trans, &scx->scx_area, &arg.caa_rect);
/* Add any stacking types for the search (but not to mask passed as arg!) */
locMask = *mask;
DBMaskAddStacking(&locMask);
DBTreeSrTiles(scx, &locMask, xMask, dbCopyAllPaint, (ClientData) &arg);
}
/*
*-----------------------------------------------------------------------------
*
* DBCellCheckCopyAllPaint --
*
* Copy paint from the tree rooted at scx->scx_use to the paint planes
* of targetUse, transforming according to the transform in scx.
* Only the types specified by typeMask are copied.
*
* Results:
* None.
*
* Side effects:
* Updates the paint planes in targetUse.
*
*-----------------------------------------------------------------------------
*/
void
DBCellCheckCopyAllPaint(scx, mask, xMask, targetUse, func)
SearchContext *scx; /* Describes root cell to search, area to
* copy, transform from root cell to coords
* of targetUse.
*/
TileTypeBitMask *mask; /* Types of tiles to be yanked/stuffed */
int xMask; /* Expansion state mask to be used in search */
CellUse *targetUse; /* Cell into which material is to be stuffed */
void (*func)(); /* Function to call on tile split error */
{
TileTypeBitMask locMask;
struct copyAllArg arg;
int dbCopyAllPaint();
arg.caa_mask = mask;
arg.caa_targetUse = targetUse;
arg.caa_func = func;
GEOTRANSRECT(&scx->scx_trans, &scx->scx_area, &arg.caa_rect);
/* Add any stacking types for the search (but not to mask passed as arg!) */
@ -441,7 +493,7 @@ DBCellCopyPaint(scx, mask, xMask, targetUse)
for (pNum = PL_PAINTBASE; pNum < DBNumPlanes; pNum++)
if (PlaneMaskHasPlane(planeMask, pNum))
{
cxp.tc_plane = pNum; /* not used? */
cxp.tc_plane = pNum;
(void) DBSrPaintArea((Tile *) NULL,
scx->scx_use->cu_def->cd_planes[pNum], &scx->scx_area,
mask, dbCopyAllPaint, (ClientData) &cxp);
@ -590,6 +642,7 @@ dbCopyAllPaint(tile, cxp)
CellDef *def;
TileType type = TiGetTypeExact(tile);
int pNum = cxp->tc_plane;
int result;
TileTypeBitMask *typeMask;
/*
@ -752,7 +805,12 @@ topbottom:
splitdone:
(*dbCurPaintPlane)(def, pNum, dinfo | type, &targetRect, &ui);
result = (*dbCurPaintPlane)(def, pNum, dinfo | type, &targetRect, &ui);
if ((result != 0) && (arg->caa_func != NULL))
{
/* result == 1 used exclusively for DRC off-grid error flagging */
DRCOffGridError(&targetRect);
}
return (0);
}
@ -1013,11 +1071,11 @@ DBNewPaintTable(newTable))[NT][NT]
* ----------------------------------------------------------------------------
*/
VoidProc
IntProc
DBNewPaintPlane(newProc)
void (*newProc)(); /* Address of new procedure */
int (*newProc)(); /* Address of new procedure */
{
void (*oldProc)() = dbCurPaintPlane;
int (*oldProc)() = dbCurPaintPlane;
dbCurPaintPlane = newProc;
return (oldProc);
}

View File

@ -215,7 +215,7 @@ dbJoinUndo(tile, splitx, undo)
* 'undo' can be NULL.
*
* Results:
* None.
* Always return 0.
*
* Side effects:
* Modifies the database plane that contains the given tile.
@ -236,7 +236,7 @@ dbJoinUndo(tile, splitx, undo)
* ----------------------------------------------------------------------------
*/
void
int
DBPaintPlane0(plane, area, resultTbl, undo, method)
Plane *plane; /* Plane whose paint is to be modified */
Rect *area; /* Area to be changed */
@ -262,7 +262,7 @@ DBPaintPlane0(plane, area, resultTbl, undo, method)
bool haschanged;
if (area->r_xtop <= area->r_xbot || area->r_ytop <= area->r_ybot)
return;
return 0;
/*
* The following is a modified version of the area enumeration
@ -697,6 +697,7 @@ enum2:
done2:
plane->pl_hint = tile;
return 0;
}
/*
@ -1442,7 +1443,7 @@ typedef struct
* paint quadrangular (clipped triangle) areas.
*
* Results:
* None.
* 0 on success, 1 on error splitting a non-manhattan tile
*
* Side Effects:
* Plane is painted with a diagonal. The plane may be hacked up
@ -1452,7 +1453,7 @@ typedef struct
* ----------------------------------------------------------------------------
*/
void
int
DBNMPaintPlane0(plane, exacttype, area, resultTbl, undo, method)
Plane *plane; /* Plane whose paint is to be modified */
TileType exacttype; /* diagonal info for tile to be changed */
@ -1478,6 +1479,7 @@ DBNMPaintPlane0(plane, exacttype, area, resultTbl, undo, method)
int xc, yc, width, height;
dlong xref, yref; /* xref, yref can easily exceed 32 bits */
int resstate;
int result = 0;
if (exacttype & TT_DIAGONAL)
{
@ -1532,7 +1534,7 @@ DBNMPaintPlane0(plane, exacttype, area, resultTbl, undo, method)
if (resultTbl[oldType] == oldType)
{
freeMagic((char *) lr);
return;
return 0;
}
}
@ -1544,7 +1546,7 @@ DBNMPaintPlane0(plane, exacttype, area, resultTbl, undo, method)
if (newType == oldType)
{
freeMagic((char *) lr);
return;
return 0;
}
/* Watch for the worst-case scenario of attempting to */
@ -1560,9 +1562,9 @@ DBNMPaintPlane0(plane, exacttype, area, resultTbl, undo, method)
{
if ((width == 1) || (height == 1))
{
DBPaintPlane(plane, &(lr->r_r), resultTbl, undo);
result = DBPaintPlane(plane, &(lr->r_r), resultTbl, undo);
freeMagic((char *) lr);
return;
return 1; /* Flag the error by returning 1 */
}
/* lr->r_r is drawn & quartered */
@ -1605,7 +1607,7 @@ DBNMPaintPlane0(plane, exacttype, area, resultTbl, undo, method)
if (newType & TT_DIAGONAL)
{
DBPaintPlane(plane, &(lr->r_r), DBSpecialPaintTbl,
result = DBPaintPlane(plane, &(lr->r_r), DBSpecialPaintTbl,
(PaintUndoInfo *)NULL);
tile = plane->pl_hint;
GOTOPOINT(tile, &(lr->r_r.r_ll));
@ -1620,14 +1622,14 @@ DBNMPaintPlane0(plane, exacttype, area, resultTbl, undo, method)
{
PaintResultType tempTbl;
tempTbl = newType;
DBPaintPlane0(plane, &(lr->r_r), &tempTbl, undo, method);
result = DBPaintPlane0(plane, &(lr->r_r), &tempTbl,
undo, method);
}
else
DBPaintPlane(plane, &(lr->r_r), resultTbl, undo);
result = DBPaintPlane(plane, &(lr->r_r), resultTbl, undo);
freeMagic((char *) lr);
/* goto nmmerge; */
return;
return result;
}
}
@ -1755,11 +1757,12 @@ paintrect:
if (resstate == RES_DIAG)
{
/* Recursive call to self on sub-area */
DBNMPaintPlane0(plane, exacttype, &(lr->r_r), resultTbl, undo, method);
result |= DBNMPaintPlane0(plane, exacttype, &(lr->r_r), resultTbl,
undo, method);
}
else if ((resstate == RES_LEFT && !dinfo.side) ||
(resstate == RES_RIGHT && dinfo.side)) {
DBPaintPlane(plane, &(lr->r_r), resultTbl, undo);
result |= DBPaintPlane(plane, &(lr->r_r), resultTbl, undo);
}
/* else: Rectangle does not contain type and should be ignored. */
nextrect:
@ -1774,8 +1777,10 @@ nextrect:
}
}
else
DBPaintPlane0(plane, area, resultTbl, undo, (method == PAINT_MARK) ?
result = DBPaintPlane0(plane, area, resultTbl, undo, (method == PAINT_MARK) ?
method : PAINT_NORMAL);
return result;
}
/*
@ -2547,7 +2552,7 @@ dbMergeType(tile, newType, plane, mergeFlags, undo, client)
* ----------------------------------------------------------------------------
*/
void
int
DBPaintPlaneVert(plane, area, resultTbl, undo)
Plane *plane; /* Plane whose paint is to be modified */
Rect *area; /* Area to be changed */

View File

@ -696,13 +696,13 @@ typedef struct
extern void DBPaint();
extern void DBErase();
extern int DBSrPaintArea();
extern void DBPaintPlane0();
extern void DBPaintPlaneActive();
extern void DBPaintPlaneWrapper();
extern void DBPaintPlaneMark();
extern void DBPaintPlaneXor();
extern void DBPaintPlaneByProc();
extern void DBPaintPlaneMergeOnce();
extern int DBPaintPlane0();
extern int DBPaintPlaneActive();
extern int DBPaintPlaneWrapper();
extern int DBPaintPlaneMark();
extern int DBPaintPlaneXor();
extern int DBPaintPlaneByProc();
extern int DBPaintPlaneMergeOnce();
extern void DBPaintMask();
extern void DBEraseMask();
extern void DBClearPaintPlane();
@ -712,7 +712,7 @@ extern void DBUnlockContact();
#define DBPaintPlane(a, b, c, d) DBPaintPlane0(a, b, c, d, PAINT_NORMAL)
#define DBMergeNMTiles(a, b, c) DBMergeNMTiles0(a, b, c, FALSE)
extern void DBNMPaintPlane0();
extern int DBNMPaintPlane0();
#define DBNMPaintPlane(a, b, c, d, e) DBNMPaintPlane0(a, b, c, d, e, PAINT_NORMAL)
/* I/O */
@ -816,6 +816,7 @@ extern char *DBPrintUseId();
/* Massive copying */
extern void DBCellCopyPaint();
extern void DBCellCopyAllPaint();
extern void DBCellCheckCopyAllPaint();
extern void DBCellCopyLabels();
extern void DBCellCopyAllLabels();
extern void DBCellCopyCells();
@ -845,8 +846,8 @@ extern void DBEnumerateTypes();
extern Plane *DBNewPlane();
extern PaintResultType (*DBNewPaintTable())[TT_MAXTYPES][TT_MAXTYPES];
typedef void (*VoidProc)();
VoidProc DBNewPaintPlane();
typedef int (*IntProc)();
IntProc DBNewPaintPlane();
/* Diagnostic */
extern void DBTechPrintTypes();

View File

@ -620,6 +620,16 @@ drcTile (tile, arg)
drcCheckRectSize(tile, arg, cptr);
continue;
}
/* Off-grid checks apply only to edge */
if (cptr->drcc_flags & DRC_OFFGRID)
{
errRect.r_ytop = edgeTop;
errRect.r_ybot = edgeBot;
errRect.r_xtop = errRect.r_xbot = edgeX;
arg->dCD_cptr = cptr;
drcCheckOffGrid(&errRect, arg, cptr);
continue;
}
result = 0;
arg->dCD_radial = 0;
@ -983,13 +993,22 @@ checkbottom:
}
continue;
}
else if (cptr->drcc_flags & (DRC_AREA | DRC_RECTSIZE
| DRC_MAXWIDTH))
else if (cptr->drcc_flags & (DRC_AREA | DRC_RECTSIZE | DRC_MAXWIDTH))
{
/* only have to do these checks in one direction */
if (trigpending) cptr = cptr->drcc_next;
continue;
}
/* Off-grid checks apply only to edge */
if (cptr->drcc_flags & DRC_OFFGRID)
{
errRect.r_xtop = edgeRight;
errRect.r_xbot = edgeLeft;
errRect.r_ytop = errRect.r_ybot = edgeY;
arg->dCD_cptr = cptr;
drcCheckOffGrid(&errRect, arg, cptr);
continue;
}
result = 0;
arg->dCD_radial = 0;

View File

@ -70,6 +70,50 @@ drcCheckAngles(tile, arg, cptr)
}
}
/*
*-------------------------------------------------------------------------
*
* drcCheckOffGrid- checks to see that an edge is on the specified
* grid pitch.
*
* Results: none
*
* Side Effects: may cause errors to be painted.
*
*-------------------------------------------------------------------------
*/
void
drcCheckOffGrid(edgeRect, arg, cptr)
Rect *edgeRect;
struct drcClientData *arg;
DRCCookie *cptr;
{
Rect rect;
int gtest;
if (cptr->drcc_dist <= 1) return; /* No error by definition */
rect = *edgeRect;
GeoClip(&rect, arg->dCD_clip);
/* Expand rect to nearest pitch */
gtest = (rect.r_xbot / cptr->drcc_dist) * cptr->drcc_dist;
if (gtest < rect.r_xbot) rect.r_xbot = gtest;
gtest = (rect.r_xtop / cptr->drcc_dist) * cptr->drcc_dist;
if (gtest > rect.r_xtop) rect.r_xtop = gtest;
gtest = (rect.r_ybot / cptr->drcc_dist) * cptr->drcc_dist;
if (gtest < rect.r_ybot) rect.r_ybot = gtest;
gtest = (rect.r_ytop / cptr->drcc_dist) * cptr->drcc_dist;
if (gtest > rect.r_ytop) rect.r_ytop = gtest;
if (!GEO_RECTNULL(&rect)) {
(*(arg->dCD_function)) (arg->dCD_celldef, &rect,
arg->dCD_cptr, arg->dCD_clientData);
(*(arg->dCD_errors))++;
}
}
/*
*-------------------------------------------------------------------------
*
@ -144,10 +188,6 @@ drcCheckArea(starttile,arg,cptr)
if (!GEO_RECTNULL(&rect)) {
(*(arg->dCD_function)) (arg->dCD_celldef, &rect,
arg->dCD_cptr, arg->dCD_clientData);
/***
DBWAreaChanged(arg->dCD_celldef,&rect, DBW_ALLWINDOWS,
&DBAllButSpaceBits);
***/
(*(arg->dCD_errors))++;
}
}

View File

@ -74,7 +74,22 @@ static DRCCookie drcInSubCookie = {
(DRCCookie *) NULL
};
/* The following DRC cookie is used when flattening non-Manhattan
* shapes results in a non-integer coordinate. Because the non-
* integer coordinate cannot be represented in magic, the position
* is flagged as a DRC error.
*/
static DRCCookie drcOffGridCookie = {
0, 0, 0, 0,
{ 0 }, { 0 },
0, 0, 0,
DRC_OFFGRID_TAG,
(DRCCookie *) NULL
};
extern int DRCErrorType;
extern CellDef *DRCErrorDef;
/*
* ----------------------------------------------------------------------------
@ -604,6 +619,37 @@ drcExactOverlapTile(tile, cxp)
return 0;
}
/*
* ----------------------------------------------------------------------------
*
* DRCOffGridError ---
*
* Function to call when a call to DBCellCheckCopyAllPaint() flags an error
* indicating that a subcell overlap of non-Manhattan geometry resolves to
* an off-grid intersection point. Note that this is different from the
* DRC off-grid check, which checks for geometry that does not match the
* manufacturing grid pitch. This checks for the case of geometry that
* is finer than the underlying database grid, which can only happen for
* two non-Manhattan shapes interacting between two different cells, and
* can only be caught during the process of flattening the cell contents.
*
* Results:
* None.
*
* Side effects:
* Creates a DRC error or prints the DRC error message, depending on
* the value of drcSubFunc.
*
* ----------------------------------------------------------------------------
*/
void
DRCOffGridError(rect)
Rect *rect; /* Area of error */
{
(*drcSubFunc)(DRCErrorDef, rect, &drcOffGridCookie, drcSubClientData);
}
/*
* ----------------------------------------------------------------------------
*
@ -809,7 +855,8 @@ DRCInteractionCheck(def, area, erasebox, func, cdarg)
savedPaintTable = DBNewPaintTable(DRCCurStyle->DRCPaintTable);
savedPaintPlane = DBNewPaintPlane(DBPaintPlaneMark);
(void) DBCellCopyAllPaint(&scx, &DBAllButSpaceBits, 0, DRCuse);
(void) DBCellCheckCopyAllPaint(&scx, &DBAllButSpaceBits, 0,
DRCuse, func);
(void) DBNewPaintTable(savedPaintTable);
(void) DBNewPaintPlane(savedPaintPlane);

View File

@ -73,7 +73,7 @@ static int DRCtag = 0;
int drcWidth(), drcSpacing(), drcEdge(), drcNoOverlap();
int drcExactOverlap(), drcExtend();
int drcSurround(), drcRectOnly(), drcOverhang();
int drcStepSize(), drcOption();
int drcStepSize(), drcOption(), drcOffGrid();
int drcMaxwidth(), drcArea(), drcRectangle(), drcAngles();
int drcCifSetStyle(), drcCifWidth(), drcCifSpacing();
int drcCifMaxwidth(), drcCifArea();
@ -587,6 +587,11 @@ DRCTechStyleInit()
/* (see DRCsubcell.c). */
drcWhyCreate("See error definition in the subcell");
/* Fifth DRC entry is associated with the statically-allocated */
/* drcOffGridCookie and has a tag of DRC_OFFGRID_TAG = 5 */
/* (see DRCsubcell.c). */
drcWhyCreate("This position does not align with the manufacturing grid");
DRCTechHalo = 0;
/* Put a dummy rule at the beginning of the rules table for each entry */
@ -922,7 +927,8 @@ drcCifAssign(cookie, dist, next, mask, corner, tag, cdist, flags, planeto, plane
int dist, cdist;
TileTypeBitMask *mask, *corner;
int tag;
int flags, planeto, planefrom;
unsigned short flags;
int planeto, planefrom;
{
(cookie)->drcc_dist = dist;
(cookie)->drcc_next = next;
@ -946,7 +952,8 @@ drcAssign(cookie, dist, next, mask, corner, why, cdist, flags, planeto, planefro
int dist, cdist;
TileTypeBitMask *mask, *corner;
int why;
int flags, planeto, planefrom;
unsigned short flags;
int planeto, planefrom;
{
/* Diagnostic */
if (planeto >= DBNumPlanes)
@ -1040,6 +1047,8 @@ DRCTechAddRule(sectionName, argc, argv)
"layers1 width layers2 separation adjacency why",
"area", 5, 5, drcArea,
"layers area horizon why",
"off_grid", 4, 4, drcOffGrid,
"layers pitch why",
"maxwidth", 4, 5, drcMaxwidth,
"layers maxwidth bends why",
"cifstyle", 2, 2, drcCifSetStyle,
@ -1434,6 +1443,85 @@ drcArea(argc, argv)
return (horizon);
}
/*
* ----------------------------------------------------------------------------
*
* drcOffGrid --
*
* Process an off-grid rule.
* This is of the form:
*
* off_grid layers pitch why
*
* e.g,
*
* off_grid m1 5 "metal shapes must be on %d grid"
*
* "pitch" is the grid pitch that shapes must be aligned to.
*
* Results:
* Returns pitch (the halo for detecting off-grid errors).
*
* Side effects:
* Updates the DRC technology variables.
*
* ----------------------------------------------------------------------------
*/
int
drcOffGrid(argc, argv)
int argc;
char *argv[];
{
char *layers = argv[1];
int pitch = atoi(argv[2]);
int why = drcWhyCreate(argv[3]);
TileTypeBitMask set, setC;
DRCCookie *dp, *dpnew;
TileType i, j;
PlaneMask pset;
int plane;
DBTechNoisyNameMask(layers, &set);
TTMaskCom2(&setC, &set);
for (i = 0; i < DBNumTypes; i++)
{
for (j = 0; j < DBNumTypes; j++)
{
if (i == j) continue;
/*
* Must have types in 'set' for at least 'distance'
* to the right of any edge between a type in '~set'
* and a type in 'set'.
*/
if (pset = (DBTypesOnSamePlane(i, j)))
{
if (TTMaskHasType(&setC, i) && TTMaskHasType(&set, j))
{
plane = LowestMaskBit(pset);
/* find bucket preceding the new one we wish to insert */
dp = drcFindBucket(i, j, pitch);
dpnew = (DRCCookie *) mallocMagic(sizeof (DRCCookie));
drcAssign(dpnew, pitch, dp->drcc_next, &set, &set, why,
0, DRC_OFFGRID|DRC_FORWARD, plane, plane);
dp->drcc_next = dpnew;
/* opposite edge also needs to be checked */
dp = drcFindBucket(j, i, pitch);
dpnew = (DRCCookie *) mallocMagic(sizeof (DRCCookie));
drcAssign(dpnew, pitch, dp->drcc_next, &set, &set, why,
0, DRC_OFFGRID|DRC_REVERSE, plane, plane);
dp->drcc_next = dpnew;
}
}
}
}
return (pitch);
}
/*
* ----------------------------------------------------------------------------
*

View File

@ -48,6 +48,7 @@ typedef struct drccookie
#define DRC_OVERLAP_TAG 2
#define DRC_SUBCELL_OVERLAP_TAG 3
#define DRC_IN_SUBCELL_TAG 4
#define DRC_OFFGRID_TAG 5
/* *This is size "int" because it holds an area for DRC_AREA rules, */
/* and therefore may have twice the bit length of a normal rule distance. */
@ -63,20 +64,22 @@ typedef struct drccookie
* edge processing.
*/
#define DRC_FORWARD 0x00
#define DRC_REVERSE 0x01
#define DRC_BOTHCORNERS 0x02
#define DRC_TRIGGER 0x04
#define DRC_BENDS 0x08
#define DRC_OUTSIDE 0x08 // Note: Shared with DRC_BENDS
#define DRC_AREA 0x10
#define DRC_MAXWIDTH 0x20
#define DRC_RECTSIZE 0x40
#define DRC_ANGLES 0x80
#define DRC_NONSTANDARD (DRC_AREA|DRC_MAXWIDTH|DRC_RECTSIZE|DRC_ANGLES)
#define DRC_FORWARD 0x000
#define DRC_REVERSE 0x001
#define DRC_BOTHCORNERS 0x002
#define DRC_TRIGGER 0x004
#define DRC_BENDS 0x008
#define DRC_OUTSIDE 0x010
#define DRC_AREA 0x020
#define DRC_OFFGRID 0x040
#define DRC_MAXWIDTH 0x080
#define DRC_RECTSIZE 0x100
#define DRC_ANGLES 0x200
#define DRC_NONSTANDARD (DRC_AREA|DRC_MAXWIDTH|DRC_RECTSIZE\
|DRC_ANGLES|DRC_OFFGRID)
/* More flags for indicating what the rule type represents */
#define DRC_CIFRULE 0x100
#define DRC_CIFRULE 0x400
#define DRC_PENDING 0
#define DRC_UNPROCESSED CLIENTDEFAULT
@ -165,7 +168,7 @@ typedef struct drcstyle
int DRCScaleFactorD; /* Multiply dist by this to get magic units */
int DRCTechHalo; /* largest action distance of design rules */
int DRCStepSize; /* chunk size for decomposing large areas */
char DRCFlags; /* Option flags */
unsigned short DRCFlags; /* Option flags */
char **DRCWhyList; /* Indexed list of "why" text strings */
int DRCWhySize; /* Length of DRCWhyList */
PaintResultType DRCPaintTable[NP][NT][NT];
@ -271,6 +274,7 @@ extern int DRCFind();
extern void DRCCatchUp();
extern bool DRCFindInteractions();
extern int DRCBasicCheck();
extern void DRCOffGridError();
extern void DRCPrintStyle();
extern void DRCSetStyle();

View File

@ -164,7 +164,7 @@ GAGenChans(chanType, area, f)
Rect *area;
FILE *f;
{
extern void DBPaintPlane0(), DBPaintPlaneVert();
extern int DBPaintPlane0(), DBPaintPlaneVert();
int gaSplitFunc(), gaSplitOut();
static CellDef *genDef = (CellDef *) NULL;
static CellUse *genUse = (CellUse *) NULL;