From f3adea8c65d62c21c1838db1176f612e11043ed9 Mon Sep 17 00:00:00 2001 From: "R. Timothy Edwards" Date: Fri, 31 Oct 2025 17:37:02 -0400 Subject: [PATCH] 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. --- VERSION | 2 +- cif/CIFgen.c | 51 ++++++++++++++++++++++++++++++++++-------------- cif/CIFtech.c | 25 +++++++++++++++++++++--- drc/DRCsubcell.c | 6 +++++- 4 files changed, 64 insertions(+), 20 deletions(-) diff --git a/VERSION b/VERSION index d671d5db..1825b228 100644 --- a/VERSION +++ b/VERSION @@ -1 +1 @@ -8.3.571 +8.3.572 diff --git a/cif/CIFgen.c b/cif/CIFgen.c index 9d05d554..18a5492d 100644 --- a/cif/CIFgen.c +++ b/cif/CIFgen.c @@ -28,6 +28,7 @@ static const char rcsid[] __attribute__ ((unused)) = "$Header: /usr/cvsroot/magi #include "utils/magic.h" #include "utils/geometry.h" +#include "utils/signals.h" #include "tiles/tile.h" #include "utils/hash.h" #include "database/database.h" @@ -1478,19 +1479,28 @@ cifBloatAllFunc( 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 * in the "bloat" group to be re-processed for each * tile processed in the search group. However, it * is difficult to find an optimal method. */ STACKPUSH(t, ResetStack); - GeoClip(&area, &clipArea); - if (GEO_RECTNULL(&area)) + GeoClip(&cifarea, &clipArea); + if (GEO_RECTNULL(&cifarea)) continue; } - /* Diagonal: If expanding across the edge of a diagonal, */ - /* then just fill the whole tile. */ + /* Diagonal: If expanding across the edge of a diagonal, then */ + /* 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)) { @@ -1505,8 +1515,11 @@ cifBloatAllFunc( CIFPaintTable, (PaintUndoInfo *) NULL); } else + { + GeoClip(&area, &clipArea); DBNMPaintPlane(cifPlane, TiGetTypeExact(t), &area, CIFPaintTable, (PaintUndoInfo *) NULL); + } /* Top */ for (tp = RT(t); RIGHT(tp) > LEFT(t); tp = BL(tp)) @@ -1547,6 +1560,7 @@ cifBloatAllFunc( TiSetClient(t, CIF_UNPROCESSED); } + if (SigInterruptPending) return 1; return 0; /* Keep the search alive. . . */ } @@ -4695,12 +4709,13 @@ cifBridgeLimFunc2( void cifInteractingRegions( CIFOp *op, + const Rect *area, /* Area of interest to check */ CellDef *cellDef, Plane *temps[], /* Planes to use for temporaries. */ Plane *plane) { Tile *tile = NULL, *t, *tp; - Rect area; + Rect rect; int i; TileType type; bool interacts; @@ -4709,7 +4724,7 @@ cifInteractingRegions( if (RegStack == (Stack *)NULL) RegStack = StackNew(64); - while (DBSrPaintArea((Tile *)tile, plane, &TiPlaneRect, &CIFSolidBits, + while (DBSrPaintArea((Tile *)tile, plane, area, &CIFSolidBits, cifSquaresInitFunc, (ClientData)NULL) != 0) { /* Now, search for (nontrivially) connected tiles in all */ @@ -4729,7 +4744,10 @@ cifInteractingRegions( TiSetClientINT(t, CIF_PROCESSED); /* 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 * search by one unit in every direction and then check overlap. @@ -4738,10 +4756,10 @@ cifInteractingRegions( */ if ((pointertype)op->co_client & CIFOP_INT_TOUCHING) { - area.r_xbot -= 1; - area.r_xtop += 1; - area.r_ybot -= 1; - area.r_ytop += 1; + rect.r_xbot -= 1; + rect.r_xtop += 1; + rect.r_ybot -= 1; + rect.r_ytop += 1; } /* Check if this tile interacts with the rule's types, or skip */ @@ -4749,7 +4767,7 @@ cifInteractingRegions( if (!interacts) { - if (cifSrTiles2(op, &area, cellDef, temps, cifInteractFunc, (ClientData)NULL)) + if (cifSrTiles2(op, &rect, cellDef, temps, cifInteractFunc, (ClientData)NULL)) interacts = TRUE; } @@ -4802,8 +4820,8 @@ cifInteractingRegions( if (interacts) { - TiToRect(t, &area); - DBPaintPlane(cifPlane, &area, CIFPaintTable, (PaintUndoInfo *)NULL); + TiToRect(t, &rect); + DBPaintPlane(cifPlane, &rect, CIFPaintTable, (PaintUndoInfo *)NULL); } /* Top */ @@ -4838,6 +4856,9 @@ cifInteractingRegions( STACKPUSH(tp, RegStack); } } + + /* Allow interrupts here */ + if (SigInterruptPending) break; } } @@ -5313,7 +5334,7 @@ CIFGenLayer( DBClearPaintPlane(nextPlane); cifPlane = nextPlane; - cifInteractingRegions(op, cellDef, temps, curPlane); + cifInteractingRegions(op, area, cellDef, temps, curPlane); temp = curPlane; curPlane = nextPlane; nextPlane = temp; diff --git a/cif/CIFtech.c b/cif/CIFtech.c index 2641ca64..c07e48ff 100644 --- a/cif/CIFtech.c +++ b/cif/CIFtech.c @@ -234,7 +234,7 @@ cifParseLayers( */ { TileTypeBitMask curCifMask, curPaintMask; - char curLayer[40], *p, *cp; + char curLayer[512], *p, *cp; TileType paintType; int i; bool allResidues; @@ -246,6 +246,10 @@ cifParseLayers( { p = curLayer; + if (*string == '(') + while ((*string != ')') && (*string != 0)) + *p++ = *string++; + if (*string == '*') { allResidues = TRUE; @@ -263,7 +267,22 @@ cifParseLayers( 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; } else paintType = -2; @@ -299,7 +318,7 @@ okpaint: TechError("Ambiguous layer (type) \"%s\".\n", curLayer); continue; } - if (paintType >= 0) + if ((paintType >= 0) || (paintType == -3)) { if (paintType == TT_SPACE && spaceOK ==0) TechError("\"Space\" layer not permitted in CIF rules.\n"); diff --git a/drc/DRCsubcell.c b/drc/DRCsubcell.c index b51367c6..07100431 100644 --- a/drc/DRCsubcell.c +++ b/drc/DRCsubcell.c @@ -27,6 +27,7 @@ static char rcsid[] __attribute__ ((unused)) = "$Header: /usr/cvsroot/magic-8.0/ #include "utils/magic.h" #include "textio/textio.h" +#include "utils/signals.h" #include "utils/geometry.h" #include "tiles/tile.h" #include "utils/hash.h" @@ -134,7 +135,7 @@ drcFindOtherCells(use, area) * different for "drc why" commands than for "drc check". * * 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_errors))++; + /* Allow a break here */ + if (SigInterruptPending) return 1; + return 0; }