Made a few corrections to recent code additions. Also added
more points to accept interrupts during DRC checks, and modified the tech file parser to allow the full syntax for magic layers that is allowed elsewhere (e.g., "(*ndiff,poly)/a") (this applies to magic layers, not GDS layers). Fixed a clipping error in the bloat-all function which was causing non-manhattan geometry to produce bad results, which would cause false-positive DRC errors when used in a CIF-DRC rule.
This commit is contained in:
parent
246c0ea7a4
commit
f3adea8c65
51
cif/CIFgen.c
51
cif/CIFgen.c
|
|
@ -28,6 +28,7 @@ static const char rcsid[] __attribute__ ((unused)) = "$Header: /usr/cvsroot/magi
|
||||||
|
|
||||||
#include "utils/magic.h"
|
#include "utils/magic.h"
|
||||||
#include "utils/geometry.h"
|
#include "utils/geometry.h"
|
||||||
|
#include "utils/signals.h"
|
||||||
#include "tiles/tile.h"
|
#include "tiles/tile.h"
|
||||||
#include "utils/hash.h"
|
#include "utils/hash.h"
|
||||||
#include "database/database.h"
|
#include "database/database.h"
|
||||||
|
|
@ -1478,19 +1479,28 @@ cifBloatAllFunc(
|
||||||
|
|
||||||
if (op->co_distance > 0)
|
if (op->co_distance > 0)
|
||||||
{
|
{
|
||||||
|
Rect cifarea;
|
||||||
|
|
||||||
|
cifarea.r_xbot = area.r_xbot;
|
||||||
|
cifarea.r_ybot = area.r_ybot;
|
||||||
|
cifarea.r_xtop = area.r_xtop;
|
||||||
|
cifarea.r_ytop = area.r_ytop;
|
||||||
|
|
||||||
/* Note: This is non-optimal, as it causes all tiles
|
/* Note: This is non-optimal, as it causes all tiles
|
||||||
* in the "bloat" group to be re-processed for each
|
* in the "bloat" group to be re-processed for each
|
||||||
* tile processed in the search group. However, it
|
* tile processed in the search group. However, it
|
||||||
* is difficult to find an optimal method.
|
* is difficult to find an optimal method.
|
||||||
*/
|
*/
|
||||||
STACKPUSH(t, ResetStack);
|
STACKPUSH(t, ResetStack);
|
||||||
GeoClip(&area, &clipArea);
|
GeoClip(&cifarea, &clipArea);
|
||||||
if (GEO_RECTNULL(&area))
|
if (GEO_RECTNULL(&cifarea))
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Diagonal: If expanding across the edge of a diagonal, */
|
/* Diagonal: If expanding across the edge of a diagonal, then */
|
||||||
/* then just fill the whole tile. */
|
/* just fill the whole tile. Note that diagonal tiles are not */
|
||||||
|
/* clipped; the clipping only determines if the tile is */
|
||||||
|
/* outside the clip area. */
|
||||||
|
|
||||||
if (IsSplit(t))
|
if (IsSplit(t))
|
||||||
{
|
{
|
||||||
|
|
@ -1505,8 +1515,11 @@ cifBloatAllFunc(
|
||||||
CIFPaintTable, (PaintUndoInfo *) NULL);
|
CIFPaintTable, (PaintUndoInfo *) NULL);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
{
|
||||||
|
GeoClip(&area, &clipArea);
|
||||||
DBNMPaintPlane(cifPlane, TiGetTypeExact(t), &area,
|
DBNMPaintPlane(cifPlane, TiGetTypeExact(t), &area,
|
||||||
CIFPaintTable, (PaintUndoInfo *) NULL);
|
CIFPaintTable, (PaintUndoInfo *) NULL);
|
||||||
|
}
|
||||||
|
|
||||||
/* Top */
|
/* Top */
|
||||||
for (tp = RT(t); RIGHT(tp) > LEFT(t); tp = BL(tp))
|
for (tp = RT(t); RIGHT(tp) > LEFT(t); tp = BL(tp))
|
||||||
|
|
@ -1547,6 +1560,7 @@ cifBloatAllFunc(
|
||||||
TiSetClient(t, CIF_UNPROCESSED);
|
TiSetClient(t, CIF_UNPROCESSED);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (SigInterruptPending) return 1;
|
||||||
return 0; /* Keep the search alive. . . */
|
return 0; /* Keep the search alive. . . */
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -4695,12 +4709,13 @@ cifBridgeLimFunc2(
|
||||||
void
|
void
|
||||||
cifInteractingRegions(
|
cifInteractingRegions(
|
||||||
CIFOp *op,
|
CIFOp *op,
|
||||||
|
const Rect *area, /* Area of interest to check */
|
||||||
CellDef *cellDef,
|
CellDef *cellDef,
|
||||||
Plane *temps[], /* Planes to use for temporaries. */
|
Plane *temps[], /* Planes to use for temporaries. */
|
||||||
Plane *plane)
|
Plane *plane)
|
||||||
{
|
{
|
||||||
Tile *tile = NULL, *t, *tp;
|
Tile *tile = NULL, *t, *tp;
|
||||||
Rect area;
|
Rect rect;
|
||||||
int i;
|
int i;
|
||||||
TileType type;
|
TileType type;
|
||||||
bool interacts;
|
bool interacts;
|
||||||
|
|
@ -4709,7 +4724,7 @@ cifInteractingRegions(
|
||||||
if (RegStack == (Stack *)NULL)
|
if (RegStack == (Stack *)NULL)
|
||||||
RegStack = StackNew(64);
|
RegStack = StackNew(64);
|
||||||
|
|
||||||
while (DBSrPaintArea((Tile *)tile, plane, &TiPlaneRect, &CIFSolidBits,
|
while (DBSrPaintArea((Tile *)tile, plane, area, &CIFSolidBits,
|
||||||
cifSquaresInitFunc, (ClientData)NULL) != 0)
|
cifSquaresInitFunc, (ClientData)NULL) != 0)
|
||||||
{
|
{
|
||||||
/* Now, search for (nontrivially) connected tiles in all */
|
/* Now, search for (nontrivially) connected tiles in all */
|
||||||
|
|
@ -4729,7 +4744,10 @@ cifInteractingRegions(
|
||||||
TiSetClientINT(t, CIF_PROCESSED);
|
TiSetClientINT(t, CIF_PROCESSED);
|
||||||
|
|
||||||
/* Get tile area for interaction search */
|
/* Get tile area for interaction search */
|
||||||
TiToRect(t, &area);
|
TiToRect(t, &rect);
|
||||||
|
|
||||||
|
/* Ignore tiles outside of the search area */
|
||||||
|
if (!GEO_SURROUND(area, &rect)) continue;
|
||||||
|
|
||||||
/* "interacting" includes touching as well as overlapping, so expand
|
/* "interacting" includes touching as well as overlapping, so expand
|
||||||
* search by one unit in every direction and then check overlap.
|
* search by one unit in every direction and then check overlap.
|
||||||
|
|
@ -4738,10 +4756,10 @@ cifInteractingRegions(
|
||||||
*/
|
*/
|
||||||
if ((pointertype)op->co_client & CIFOP_INT_TOUCHING)
|
if ((pointertype)op->co_client & CIFOP_INT_TOUCHING)
|
||||||
{
|
{
|
||||||
area.r_xbot -= 1;
|
rect.r_xbot -= 1;
|
||||||
area.r_xtop += 1;
|
rect.r_xtop += 1;
|
||||||
area.r_ybot -= 1;
|
rect.r_ybot -= 1;
|
||||||
area.r_ytop += 1;
|
rect.r_ytop += 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Check if this tile interacts with the rule's types, or skip */
|
/* Check if this tile interacts with the rule's types, or skip */
|
||||||
|
|
@ -4749,7 +4767,7 @@ cifInteractingRegions(
|
||||||
|
|
||||||
if (!interacts)
|
if (!interacts)
|
||||||
{
|
{
|
||||||
if (cifSrTiles2(op, &area, cellDef, temps, cifInteractFunc, (ClientData)NULL))
|
if (cifSrTiles2(op, &rect, cellDef, temps, cifInteractFunc, (ClientData)NULL))
|
||||||
interacts = TRUE;
|
interacts = TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -4802,8 +4820,8 @@ cifInteractingRegions(
|
||||||
|
|
||||||
if (interacts)
|
if (interacts)
|
||||||
{
|
{
|
||||||
TiToRect(t, &area);
|
TiToRect(t, &rect);
|
||||||
DBPaintPlane(cifPlane, &area, CIFPaintTable, (PaintUndoInfo *)NULL);
|
DBPaintPlane(cifPlane, &rect, CIFPaintTable, (PaintUndoInfo *)NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Top */
|
/* Top */
|
||||||
|
|
@ -4838,6 +4856,9 @@ cifInteractingRegions(
|
||||||
STACKPUSH(tp, RegStack);
|
STACKPUSH(tp, RegStack);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Allow interrupts here */
|
||||||
|
if (SigInterruptPending) break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -5313,7 +5334,7 @@ CIFGenLayer(
|
||||||
|
|
||||||
DBClearPaintPlane(nextPlane);
|
DBClearPaintPlane(nextPlane);
|
||||||
cifPlane = nextPlane;
|
cifPlane = nextPlane;
|
||||||
cifInteractingRegions(op, cellDef, temps, curPlane);
|
cifInteractingRegions(op, area, cellDef, temps, curPlane);
|
||||||
temp = curPlane;
|
temp = curPlane;
|
||||||
curPlane = nextPlane;
|
curPlane = nextPlane;
|
||||||
nextPlane = temp;
|
nextPlane = temp;
|
||||||
|
|
|
||||||
|
|
@ -234,7 +234,7 @@ cifParseLayers(
|
||||||
*/
|
*/
|
||||||
{
|
{
|
||||||
TileTypeBitMask curCifMask, curPaintMask;
|
TileTypeBitMask curCifMask, curPaintMask;
|
||||||
char curLayer[40], *p, *cp;
|
char curLayer[512], *p, *cp;
|
||||||
TileType paintType;
|
TileType paintType;
|
||||||
int i;
|
int i;
|
||||||
bool allResidues;
|
bool allResidues;
|
||||||
|
|
@ -246,6 +246,10 @@ cifParseLayers(
|
||||||
{
|
{
|
||||||
p = curLayer;
|
p = curLayer;
|
||||||
|
|
||||||
|
if (*string == '(')
|
||||||
|
while ((*string != ')') && (*string != 0))
|
||||||
|
*p++ = *string++;
|
||||||
|
|
||||||
if (*string == '*')
|
if (*string == '*')
|
||||||
{
|
{
|
||||||
allResidues = TRUE;
|
allResidues = TRUE;
|
||||||
|
|
@ -263,7 +267,22 @@ cifParseLayers(
|
||||||
|
|
||||||
if (paintMask != NULL)
|
if (paintMask != NULL)
|
||||||
{
|
{
|
||||||
paintType = DBTechNameTypes(curLayer, &curPaintMask);
|
if (*curLayer == '(')
|
||||||
|
{
|
||||||
|
TileType t;
|
||||||
|
|
||||||
|
/* Layer groups with parentheses can only be paint types,
|
||||||
|
* and will be parsed accordingly. Residues will be
|
||||||
|
* handled within the group. Set paintType to -3, which
|
||||||
|
* is flagged and handled below.
|
||||||
|
*/
|
||||||
|
DBTechNoisyNameMask(curLayer, &curPaintMask);
|
||||||
|
paintType = -3;
|
||||||
|
allResidues = FALSE;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
paintType = DBTechNameTypes(curLayer, &curPaintMask);
|
||||||
|
|
||||||
if (paintType >= 0) goto okpaint;
|
if (paintType >= 0) goto okpaint;
|
||||||
}
|
}
|
||||||
else paintType = -2;
|
else paintType = -2;
|
||||||
|
|
@ -299,7 +318,7 @@ okpaint:
|
||||||
TechError("Ambiguous layer (type) \"%s\".\n", curLayer);
|
TechError("Ambiguous layer (type) \"%s\".\n", curLayer);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
if (paintType >= 0)
|
if ((paintType >= 0) || (paintType == -3))
|
||||||
{
|
{
|
||||||
if (paintType == TT_SPACE && spaceOK ==0)
|
if (paintType == TT_SPACE && spaceOK ==0)
|
||||||
TechError("\"Space\" layer not permitted in CIF rules.\n");
|
TechError("\"Space\" layer not permitted in CIF rules.\n");
|
||||||
|
|
|
||||||
|
|
@ -27,6 +27,7 @@ static char rcsid[] __attribute__ ((unused)) = "$Header: /usr/cvsroot/magic-8.0/
|
||||||
|
|
||||||
#include "utils/magic.h"
|
#include "utils/magic.h"
|
||||||
#include "textio/textio.h"
|
#include "textio/textio.h"
|
||||||
|
#include "utils/signals.h"
|
||||||
#include "utils/geometry.h"
|
#include "utils/geometry.h"
|
||||||
#include "tiles/tile.h"
|
#include "tiles/tile.h"
|
||||||
#include "utils/hash.h"
|
#include "utils/hash.h"
|
||||||
|
|
@ -134,7 +135,7 @@ drcFindOtherCells(use, area)
|
||||||
* different for "drc why" commands than for "drc check".
|
* different for "drc why" commands than for "drc check".
|
||||||
*
|
*
|
||||||
* Returns:
|
* Returns:
|
||||||
* 0 to keep the search going.
|
* 0 to keep the search going. In case of an interrupt, return 1.
|
||||||
*
|
*
|
||||||
* ----------------------------------------------------------------------------
|
* ----------------------------------------------------------------------------
|
||||||
*/
|
*/
|
||||||
|
|
@ -156,6 +157,9 @@ drcSubCopyErrors(tile, cxp)
|
||||||
arg->dCD_clientData);
|
arg->dCD_clientData);
|
||||||
(*(arg->dCD_errors))++;
|
(*(arg->dCD_errors))++;
|
||||||
|
|
||||||
|
/* Allow a break here */
|
||||||
|
if (SigInterruptPending) return 1;
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue