diff --git a/VERSION b/VERSION index e8198f1f..0eea60da 100644 --- a/VERSION +++ b/VERSION @@ -1 +1 @@ -8.3.78 +8.3.82 diff --git a/calma/CalmaWrite.c b/calma/CalmaWrite.c index 2118c18a..41732d23 100644 --- a/calma/CalmaWrite.c +++ b/calma/CalmaWrite.c @@ -799,6 +799,9 @@ calmaProcessDef(def, outf, do_library) if (isReadOnly && hasContent && CalmaAddendum) return (0); + /* Give some feedback to the user */ + TxPrintf(" Writing cell %s\n", def->cd_name); + /* * Output the definitions for any of our descendants that have * not already been output. Numbers are assigned to the subcells @@ -1008,7 +1011,8 @@ calmaOutFunc(def, f, cliprect) /* Output all the tiles associated with this cell; skip temporary layers */ GEO_EXPAND(&def->cd_bbox, CIFCurStyle->cs_radius, &bigArea); CIFErrorDef = def; - CIFGen(def, def, &bigArea, CIFPlanes, &DBAllTypeBits, TRUE, TRUE, (ClientData) f); + CIFGen(def, def, &bigArea, CIFPlanes, &DBAllTypeBits, TRUE, TRUE, FALSE, + (ClientData)f); if (!CIFHierWriteDisable) CIFGenSubcells(def, &bigArea, CIFPlanes); if (!CIFArrayWriteDisable) diff --git a/cif/CIFgen.c b/cif/CIFgen.c index cde2142d..6eda31ee 100644 --- a/cif/CIFgen.c +++ b/cif/CIFgen.c @@ -148,6 +148,8 @@ cifGrowMinFunc(tile, table) int locDist, width, height, h; TileType type, tptype; Tile *tp, *tp2; + bool changed; + void SetMinBoxGrid(); /* Forward reference */ TiToRect(tile, &area); @@ -157,6 +159,7 @@ cifGrowMinFunc(tile, table) area.r_ytop *= cifScale; parea = area; + changed = FALSE; /* Check whole tile for minimum width */ width = area.r_xtop - area.r_xbot; @@ -203,6 +206,7 @@ cifGrowMinFunc(tile, table) 0.25 * (double)((growDistance + width) * (growDistance + width)) + 0.5); area.r_ybot -= h; + changed = TRUE; } else if (freeTop == FALSE && freeBot == TRUE) { @@ -210,14 +214,20 @@ cifGrowMinFunc(tile, table) 0.25 * (double)((growDistance + width) * (growDistance + width)) + 0.5); area.r_ytop += h; + changed = TRUE; } else { locDist = (growDistance - height) / 2; area.r_ybot -= locDist; area.r_ytop += locDist; + changed = TRUE; } } } + + /* Ensure grid limit is not violated */ + if (changed) SetMinBoxGrid(&area, growDistance); + DBPaintPlane(cifPlane, &area, table, (PaintUndoInfo *) NULL); area = parea; @@ -274,7 +284,11 @@ cifGrowMinFunc(tile, table) parea.r_ytop = area.r_ytop; } if ((width < growDistance) || (height < growDistance)) + { + /* Ensure grid limit is not violated */ + SetMinBoxGrid(&parea, growDistance); DBPaintPlane(cifPlane, &parea, table, (PaintUndoInfo *) NULL); + } } } @@ -2004,6 +2018,7 @@ cifGatherFunc(tile, atotal, mode) if ((*atotal != INFINITY) && (*atotal < growDistance)) locarea = (dlong)(area.r_xtop - area.r_xbot) * (dlong)(area.r_ytop - area.r_ybot); + if (IsSplit(tile)) locarea /= 2; if (locarea > (dlong)INFINITY) *atotal = INFINITY; else @@ -2011,7 +2026,22 @@ cifGatherFunc(tile, atotal, mode) } else if (mode == CLOSE_FILL) { - DBPaintPlane(cifPlane, &area, CIFPaintTable, (PaintUndoInfo *)NULL); + TileType dinfo = TiGetTypeExact(tile); + + /* The recursive call to cifGatherFunc() below means that the */ + /* tile type cannot be depended on to have the TT_SIDE bit set */ + /* for the side of the tile that is TT_SPACE. So set the */ + /* side bit manually. */ + + if (IsSplit(tile)) + { + if (TiGetLeftType(tile) == TT_SPACE) + dinfo &= ~TT_SIDE; + else + dinfo |= TT_SIDE; + } + + DBNMPaintPlane(cifPlane, dinfo, &area, CIFPaintTable, (PaintUndoInfo *)NULL); CIFTileOps++; } @@ -2024,25 +2054,25 @@ cifGatherFunc(tile, atotal, mode) /* Check top */ if (area.r_ytop != TiPlaneRect.r_ytop) for (tp = RT(tile); RIGHT(tp) > LEFT(tile); tp = BL(tp)) - if (tp->ti_client == cdata && TiGetType(tp) == TT_SPACE) + if (tp->ti_client == cdata && TiGetBottomType(tp) == TT_SPACE) cifGatherFunc(tp, atotal, mode); /* Check bottom */ if (area.r_ybot != TiPlaneRect.r_ybot) for (tp = LB(tile); LEFT(tp) < RIGHT(tile); tp = TR(tp)) - if (tp->ti_client == cdata && TiGetType(tp) == TT_SPACE) + if (tp->ti_client == cdata && TiGetTopType(tp) == TT_SPACE) cifGatherFunc(tp, atotal, mode); /* Check left */ if (area.r_xbot != TiPlaneRect.r_xbot) for (tp = BL(tile); BOTTOM(tp) < TOP(tile); tp = RT(tp)) - if (tp->ti_client == cdata && TiGetType(tp) == TT_SPACE) + if (tp->ti_client == cdata && TiGetRightType(tp) == TT_SPACE) cifGatherFunc(tp, atotal, mode); /* Check right */ if (area.r_xtop != TiPlaneRect.r_xtop) for (tp = TR(tile); TOP(tp) > BOTTOM(tile); tp = LB(tp)) - if (tp->ti_client == cdata && TiGetType(tp) == TT_SPACE) + if (tp->ti_client == cdata && TiGetLeftType(tp) == TT_SPACE) cifGatherFunc(tp, atotal, mode); return 0; @@ -4632,7 +4662,7 @@ cifBridgeLimFunc2(tile, brlims) */ Plane * -CIFGenLayer(op, area, cellDef, origDef, temps, clientdata) +CIFGenLayer(op, area, cellDef, origDef, temps, hier, clientdata) CIFOp *op; /* List of CIFOps telling how to make layer. */ Rect *area; /* Area to consider when generating CIF. Only * material in this area will be considered, so @@ -4648,6 +4678,7 @@ CIFGenLayer(op, area, cellDef, origDef, temps, clientdata) Plane *temps[]; /* Temporary layers to be used when needed * for operation. */ + bool hier; /* TRUE if called from CIFGenSubcells or CIFGenArrays */ ClientData clientdata; /* * Data that may be passed to the CIF operation * function. @@ -4665,6 +4696,7 @@ CIFGenLayer(op, area, cellDef, origDef, temps, clientdata) BridgeStruct brs; BridgeLimStruct brlims; BridgeData *bridge; + bool hstop = FALSE; int (*cifGrowFuncPtr)() = (CIFCurStyle->cs_flags & CWF_GROW_EUCLIDEAN) ? cifGrowEuclideanFunc : cifGrowFunc; @@ -4679,6 +4711,10 @@ CIFGenLayer(op, area, cellDef, origDef, temps, clientdata) /* Go through the geometric operations and process them one * at a time. + * + * NOTE: Some opcodes (and whatever follows them) should never + * be run during hierarchical processing. That includes BOUNDARY, + * SQUARES/SLOTS, BBOX, and NET. */ for ( ; op != NULL; op = op->co_next) @@ -4937,6 +4973,11 @@ CIFGenLayer(op, area, cellDef, origDef, temps, clientdata) break; case CIFOP_SQUARES: + if (hier) + { + hstop = TRUE; /* Stop hierarchical processing */ + break; + } if (CalmaContactArrays == FALSE) { DBClearPaintPlane(nextPlane); @@ -4949,6 +4990,11 @@ CIFGenLayer(op, area, cellDef, origDef, temps, clientdata) break; case CIFOP_SQUARES_G: + if (hier) + { + hstop = TRUE; /* Stop hierarchical processing */ + break; + } DBClearPaintPlane(nextPlane); cifPlane = nextPlane; cifSquaresFillArea(op, cellDef, curPlane); @@ -4958,6 +5004,11 @@ CIFGenLayer(op, area, cellDef, origDef, temps, clientdata) break; case CIFOP_SLOTS: + if (hier) + { + hstop = TRUE; /* Stop hierarchical processing */ + break; + } DBClearPaintPlane(nextPlane); cifPlane = nextPlane; cifSlotsFillArea(op, cellDef, curPlane); @@ -4978,6 +5029,11 @@ CIFGenLayer(op, area, cellDef, origDef, temps, clientdata) break; case CIFOP_NET: + if (hier) + { + hstop = TRUE; /* Stop hierarchical processing */ + break; + } netname = (char *)op->co_client; cifPlane = curPlane; ttype = CmdFindNetProc(netname, CIFDummyUse, &bbox, FALSE); @@ -4998,6 +5054,11 @@ CIFGenLayer(op, area, cellDef, origDef, temps, clientdata) break; case CIFOP_BOUNDARY: + if (hier) + { + hstop = TRUE; /* Stop hierarchical processing */ + break; + } cifPlane = curPlane; /* This function for cifoutput only. cifinput handled separately. */ @@ -5023,6 +5084,11 @@ CIFGenLayer(op, area, cellDef, origDef, temps, clientdata) break; case CIFOP_BBOX: + if (hier) + { + hstop = TRUE; /* Stop hierarchical processing */ + break; + } if (CIFErrorDef == NULL) break; /* co_client contains the flag (1) for top-level only */ @@ -5060,6 +5126,7 @@ CIFGenLayer(op, area, cellDef, origDef, temps, clientdata) default: continue; } + if (hstop) break; /* Don't process any further rules */ } return curPlane; @@ -5088,7 +5155,7 @@ CIFGenLayer(op, area, cellDef, origDef, temps, clientdata) */ void -CIFGen(cellDef, origDef, area, planes, layers, replace, genAllPlanes, clientdata) +CIFGen(cellDef, origDef, area, planes, layers, replace, genAllPlanes, hier, clientdata) CellDef *cellDef; /* Cell for which CIF is to be generated. */ CellDef *origDef; /* Original cell, if different from cellDef */ Rect *area; /* Any CIF overlapping this area (in coords @@ -5111,6 +5178,7 @@ CIFGen(cellDef, origDef, area, planes, layers, replace, genAllPlanes, clientdata * those layers not specified as being * generated in the 'layers' mask above. */ + bool hier; /* TRUE if called from CIFGenSubcells or CIFGenArrays */ ClientData clientdata; /* Data that may be passed along to the * CIF operation functions. */ @@ -5136,7 +5204,7 @@ CIFGen(cellDef, origDef, area, planes, layers, replace, genAllPlanes, clientdata { CIFErrorLayer = i; new[i] = CIFGenLayer(CIFCurStyle->cs_layers[i]->cl_ops, - &expanded, cellDef, origDef, new, clientdata); + &expanded, cellDef, origDef, new, hier, clientdata); /* Clean up the non-manhattan geometry in the plane */ if (CIFUnfracture) DBMergeNMTiles(new[i], &expanded, diff --git a/cif/CIFhier.c b/cif/CIFhier.c index d5afda0e..4759862c 100644 --- a/cif/CIFhier.c +++ b/cif/CIFhier.c @@ -27,6 +27,7 @@ static char rcsid[] __attribute__ ((unused)) = "$Header: /usr/cvsroot/magic-8.0/ #include +#include "tcltk/tclmagic.h" #include "utils/magic.h" #include "utils/geometry.h" #include "tiles/tile.h" @@ -35,6 +36,7 @@ static char rcsid[] __attribute__ ((unused)) = "$Header: /usr/cvsroot/magic-8.0/ #include "cif/CIFint.h" #include "cif/cif.h" #include "drc/drc.h" +#include "graphics/graphics.h" #include "textio/textio.h" #include "utils/undo.h" #include "utils/malloc.h" @@ -326,7 +328,8 @@ cifHierCellFunc(scx) CIFErrorDef = (CellDef *) NULL; GeoTransRect(&scx->scx_trans, &scx->scx_area, &rootArea); CIFGen(CIFComponentDef, scx->scx_use->cu_def, &rootArea, - CIFComponentPlanes, &CIFCurStyle->cs_hierLayers, FALSE, TRUE); + CIFComponentPlanes, &CIFCurStyle->cs_hierLayers, FALSE, + TRUE, TRUE, (ClientData)NULL); return 0; } @@ -523,6 +526,8 @@ CIFGenSubcells(def, area, output) int stepSize, x, y, i, radius, oldTileOps, oldTileOps2; Rect totalArea, square, interaction; SearchContext scx; + int cuts, totcuts; + float pdone, plast; UndoDisable(); CIFInitCells(); @@ -537,6 +542,16 @@ CIFGenSubcells(def, area, output) scx.scx_use = CIFDummyUse; scx.scx_trans = GeoIdentityTransform; + /* This routine can take a long time, so use the display + * timer to force a 5-second progress check (like is done + * with extract) + */ + GrDisplayStatus = DISPLAY_IN_PROGRESS; + SigSetTimer(5); /* Print at 5-second intervals */ + cuts = 0; + pdone = 0.0; + plast = 0.0; + /* Any tile operations processed here get billed to hierarchy * in addition to being added to the total. */ @@ -551,6 +566,12 @@ CIFGenSubcells(def, area, output) totalArea = *area; GeoClip(&totalArea, &def->cd_bbox); + + totcuts = (totalArea.r_ytop - totalArea.r_ybot + stepSize - 1) + / stepSize; + totcuts *= ((totalArea.r_xtop - totalArea.r_xbot + stepSize - 1) + / stepSize); + for (y = totalArea.r_ybot; y < totalArea.r_ytop; y += stepSize) for (x = totalArea.r_xbot; x < totalArea.r_xtop; x += stepSize) { @@ -576,7 +597,8 @@ CIFGenSubcells(def, area, output) cifHierCopyFunc, (ClientData) CIFTotalDef); CIFErrorDef = def; CIFGen(CIFTotalDef, def, &interaction, CIFTotalPlanes, - &CIFCurStyle->cs_hierLayers, TRUE, TRUE); + &CIFCurStyle->cs_hierLayers, TRUE, TRUE, TRUE, + (ClientData)NULL); /* Now go through all the subcells overlapping the area * and generate CIF for each subcell individually. OR this @@ -593,7 +615,8 @@ CIFGenSubcells(def, area, output) CIFErrorDef = (CellDef *) NULL; CIFGen(def, def, &interaction, CIFComponentPlanes, - &CIFCurStyle->cs_hierLayers, FALSE, TRUE); + &CIFCurStyle->cs_hierLayers, FALSE, TRUE, TRUE, + (ClientData)NULL); /* Make sure everything in the pieces is also in the overall * CIF, then erase the piece stuff from the overall, and @@ -618,9 +641,33 @@ CIFGenSubcells(def, area, output) CIFHierRects += CIFTileOps - oldTileOps2; cifHierCleanup(); + + cuts++; + pdone = 100.0 * ((float)cuts / (float)totcuts); + if ((((pdone - plast) > 1.0) || (cuts == totcuts)) && (cuts > 1)) + { + /* Only print something if the 5-second timer has expired */ + if (GrDisplayStatus == DISPLAY_BREAK_PENDING) + { + TxPrintf("Completed %d%%\n", (int)(pdone + 0.5)); + plast = pdone; + TxFlushOut(); + + GrDisplayStatus = DISPLAY_IN_PROGRESS; + SigSetTimer(5); + } +#ifdef MAGIC_WRAPPER + /* We need to let Tk paint the console display */ + while (Tcl_DoOneEvent(TCL_DONT_WAIT) != 0); +#endif + } } CIFHierTileOps += CIFTileOps - oldTileOps; + + GrDisplayStatus = DISPLAY_IDLE; + SigRemoveTimer(); + UndoEnable(); } @@ -680,7 +727,8 @@ cifHierElementFunc(use, transform, x, y, checkArea) CIFErrorDef = (CellDef *) NULL; CIFGen(CIFComponentDef, use->cu_def, checkArea, CIFComponentPlanes, - &CIFCurStyle->cs_hierLayers, FALSE, TRUE); + &CIFCurStyle->cs_hierLayers, FALSE, TRUE, TRUE, + (ClientData)NULL); return 0; } @@ -921,7 +969,8 @@ cifHierArrayFunc(scx, output) (ClientData) &A); CIFErrorDef = use->cu_parent; CIFGen(CIFTotalDef, use->cu_def, &A, CIFTotalPlanes, - &CIFCurStyle->cs_hierLayers, FALSE, TRUE); + &CIFCurStyle->cs_hierLayers, FALSE, TRUE, TRUE, + (ClientData)NULL); anyInteractions = TRUE; } @@ -938,7 +987,8 @@ cifHierArrayFunc(scx, output) (ClientData) &C); CIFErrorDef = use->cu_parent; CIFGen(CIFTotalDef, use->cu_def, &C, CIFTotalPlanes, - &CIFCurStyle->cs_hierLayers, FALSE, TRUE); + &CIFCurStyle->cs_hierLayers, FALSE, TRUE, TRUE, + (ClientData)NULL); anyInteractions = TRUE; } @@ -955,7 +1005,8 @@ cifHierArrayFunc(scx, output) (ClientData) &B); CIFErrorDef = use->cu_parent; CIFGen(CIFTotalDef, use->cu_def, &B, CIFTotalPlanes, - &CIFCurStyle->cs_hierLayers, FALSE, TRUE); + &CIFCurStyle->cs_hierLayers, FALSE, TRUE, TRUE, + (ClientData)NULL); /* D */ @@ -968,7 +1019,8 @@ cifHierArrayFunc(scx, output) (ClientData) &D); CIFErrorDef = use->cu_parent; CIFGen(CIFTotalDef, use->cu_def, &D, CIFTotalPlanes, - &CIFCurStyle->cs_hierLayers, FALSE, TRUE); + &CIFCurStyle->cs_hierLayers, FALSE, TRUE, TRUE, + (ClientData)NULL); } if (anyInteractions) diff --git a/cif/CIFrdcl.c b/cif/CIFrdcl.c index 02114afb..10dd823a 100644 --- a/cif/CIFrdcl.c +++ b/cif/CIFrdcl.c @@ -572,7 +572,8 @@ CIFPaintCurrent(filetype) CIFOp *op; plane = CIFGenLayer(cifCurReadStyle->crs_layers[i]->crl_ops, - &TiPlaneRect, (CellDef *)NULL, (CellDef *)NULL, cifCurReadPlanes); + &TiPlaneRect, (CellDef *)NULL, (CellDef *)NULL, + cifCurReadPlanes, FALSE, (ClientData)NULL); /* Generate a paint/erase table, then paint from the CIF * plane into the current Magic cell. diff --git a/cif/CIFsee.c b/cif/CIFsee.c index 4b880266..e450e003 100644 --- a/cif/CIFsee.c +++ b/cif/CIFsee.c @@ -164,7 +164,8 @@ CIFPaintLayer(rootDef, area, cifLayer, magicLayer, paintDef) cifHierCopyFunc, (ClientData) CIFComponentDef); oldCount = DBWFeedbackCount; - CIFGen(CIFComponentDef, rootDef, area, CIFPlanes, &depend, TRUE, TRUE); + CIFGen(CIFComponentDef, rootDef, area, CIFPlanes, &depend, TRUE, TRUE, FALSE, + (ClientData)NULL); DBCellClearDef(CIFComponentDef); /* Report any errors that occurred. */ @@ -278,7 +279,8 @@ CIFSeeLayer(rootDef, area, layer) (void) DBTreeSrTiles(&scx, &DBAllButSpaceAndDRCBits, 0, cifHierCopyFunc, (ClientData) CIFComponentDef); oldCount = DBWFeedbackCount; - CIFGen(CIFComponentDef, rootDef, area, CIFPlanes, &depend, TRUE, TRUE); + CIFGen(CIFComponentDef, rootDef, area, CIFPlanes, &depend, TRUE, TRUE, + FALSE, (ClientData)NULL); DBCellClearDef(CIFComponentDef); /* Report any errors that occurred. */ @@ -441,7 +443,8 @@ CIFCoverageLayer(rootDef, area, layer) scx.scx_trans = GeoIdentityTransform; (void) DBTreeSrTiles(&scx, &DBAllButSpaceAndDRCBits, 0, cifHierCopyFunc, (ClientData) CIFComponentDef); - CIFGen(CIFComponentDef, rootDef, area, CIFPlanes, &depend, TRUE, TRUE); + CIFGen(CIFComponentDef, rootDef, area, CIFPlanes, &depend, TRUE, TRUE, + FALSE, (ClientData)NULL); DBCellClearDef(CIFComponentDef); cstats.coverage = 0; diff --git a/cif/CIFtech.c b/cif/CIFtech.c index 07343f05..ce939289 100644 --- a/cif/CIFtech.c +++ b/cif/CIFtech.c @@ -1537,6 +1537,12 @@ cifComputeRadii(layer, des) for (op = layer->cl_ops; op != NULL; op = op->co_next) { + /* BBOX and NET operators should never be used hierarchically */ + /* so ignore any grow/shrink operators that come after them. */ + + if (op->co_opcode == CIFOP_BBOX || op->co_opcode == CIFOP_NET) + break; + /* If CIF layers are used, switch to the max of current * distances and those of the layers used. */ @@ -1597,6 +1603,7 @@ cifComputeRadii(layer, des) case CIFOP_BRIDGELIM: break; case CIFOP_SQUARES: break; case CIFOP_SQUARES_G: break; + } } diff --git a/cif/CIFwrite.c b/cif/CIFwrite.c index 558f147c..8f40c2b2 100644 --- a/cif/CIFwrite.c +++ b/cif/CIFwrite.c @@ -378,7 +378,8 @@ cifOutFunc(def, f) GEO_EXPAND(&def->cd_bbox, CIFCurStyle->cs_radius, &bigArea); CIFErrorDef = def; - CIFGen(def, def, &bigArea, CIFPlanes, &DBAllTypeBits, TRUE, TRUE); + CIFGen(def, def, &bigArea, CIFPlanes, &DBAllTypeBits, TRUE, TRUE, FALSE, + (ClientData)NULL); if (!CIFHierWriteDisable) CIFGenSubcells(def, &bigArea, CIFPlanes); if (!CIFArrayWriteDisable) diff --git a/drc/DRCarray.c b/drc/DRCarray.c index f4f8486b..1f44ede6 100644 --- a/drc/DRCarray.c +++ b/drc/DRCarray.c @@ -50,14 +50,6 @@ static DRCCookie drcArrayCookie = { (DRCCookie *) NULL }; -/* Static variables used to pass information between DRCArrayCheck - * and drcArrayFunc: - */ - -static int drcArrayCount; /* Count of number of errors found. */ -static void (*drcArrayErrorFunc)(); /* Function to call on violations. */ -static ClientData drcArrayClientData; /* Extra parameter to pass to func. */ - /* * ---------------------------------------------------------------------------- @@ -106,31 +98,45 @@ static ClientData drcArrayClientData; /* Extra parameter to pass to func. */ */ int -drcArrayFunc(scx, area) +drcArrayFunc(scx, arg) SearchContext *scx; /* Information about the search. */ - Rect *area; /* Area in which errors are to be - * regenerated. - */ + struct drcClientData *arg; /* Information used in overlap */ { int xsep, ysep; int xsize, ysize; + int rval, oldTiles; Rect errorArea, yankArea, tmp, tmp2; + DRCCookie *save_cptr; CellUse *use = scx->scx_use; - struct drcClientData arg; + Rect *area; + int drcArrayCount; /* Count of number of errors found. */ + void (*drcArrayErrorFunc)(); /* Function to call on violations. */ + ClientData drcArrayClientData; /* Extra parameter to pass to func. */ + PaintResultType (*savedPaintTable)[NT][NT]; + PaintResultType (*savedEraseTable)[NT][NT]; + void (*savedPaintPlane)(); if ((use->cu_xlo == use->cu_xhi) && (use->cu_ylo == use->cu_yhi)) return 2; + oldTiles = DRCstatTiles; + + /* During array processing, switch the paint table to catch + * illegal overlaps. + */ + savedPaintTable = DBNewPaintTable(DRCCurStyle->DRCPaintTable); + savedPaintPlane = DBNewPaintPlane(DBPaintPlaneMark); + /* Set up the client data that will be passed down during * checks for exact overlaps. */ - arg.dCD_celldef = DRCdef; - arg.dCD_errors = &drcArrayCount; - arg.dCD_clip = &errorArea; - arg.dCD_cptr = &drcArrayCookie; - arg.dCD_function = drcArrayErrorFunc; - arg.dCD_clientData = drcArrayClientData; + save_cptr = arg->dCD_cptr; + arg->dCD_cptr = &drcArrayCookie; + area = arg->dCD_clip; + drcArrayCount = *arg->dCD_errors; + drcArrayErrorFunc = arg->dCD_function; + drcArrayClientData = arg->dCD_clientData; /* Compute the sizes and separations of elements, in coordinates * of the parend. If the array is 1-dimensional, we set the @@ -178,7 +184,7 @@ drcArrayFunc(scx, area) drcArrayCount += DRCBasicCheck(DRCdef, &yankArea, &errorArea, drcArrayErrorFunc, drcArrayClientData); (void) DBArraySr(use, &errorArea, drcArrayOverlapFunc, - (ClientData) &arg); + (ClientData) arg); } /* C */ @@ -195,7 +201,7 @@ drcArrayFunc(scx, area) drcArrayCount += DRCBasicCheck(DRCdef, &yankArea, &errorArea, drcArrayErrorFunc, drcArrayClientData); (void) DBArraySr(use, &errorArea, drcArrayOverlapFunc, - (ClientData) &arg); + (ClientData) arg); } } @@ -217,7 +223,7 @@ drcArrayFunc(scx, area) drcArrayCount += DRCBasicCheck(DRCdef, &yankArea, &errorArea, drcArrayErrorFunc, drcArrayClientData); (void) DBArraySr(use, &errorArea, drcArrayOverlapFunc, - (ClientData) &arg); + (ClientData) arg); } /* D */ @@ -234,80 +240,20 @@ drcArrayFunc(scx, area) drcArrayCount += DRCBasicCheck(DRCdef, &yankArea, &errorArea, drcArrayErrorFunc, drcArrayClientData); (void) DBArraySr(use, &errorArea, drcArrayOverlapFunc, - (ClientData) &arg); + (ClientData) arg); } } - return 2; -} - -/* - * ---------------------------------------------------------------------------- - * DRCArrayCheck -- - * - * This procedure finds all DRC errors in a given area of - * a given cell that stem from array formation errors in - * children of that cell. Func is called for each violation - * found. Func should have the same form as in DRCBasicCheck. - * Note: the def passed to func is the dummy DRC definition, - * and the errors are all expressed in coordinates of celluse. - * - * Results: - * The number of errors found. - * - * Side effects: - * Whatever is done by func. - * - * ---------------------------------------------------------------------------- - */ - -int -DRCArrayCheck(def, area, func, cdarg) - CellDef *def; /* Parent cell containing the arrays to - * be rechecked. - */ - Rect *area; /* Area, in def's coordinates, where all - * array violations are to be regenerated. - */ - void (*func)(); /* Function to call for each error. */ - ClientData cdarg; /* Client data to be passed to func. */ - -{ - SearchContext scx; - int oldTiles; - PaintResultType (*savedPaintTable)[NT][NT]; - PaintResultType (*savedEraseTable)[NT][NT]; - void (*savedPaintPlane)(); - - /* Use DRCDummyUse to fake up a celluse for searching purposes. */ - - DRCDummyUse->cu_def = def; - - drcArrayErrorFunc = func; - drcArrayClientData = cdarg; - drcArrayCount = 0; - oldTiles = DRCstatTiles; - - scx.scx_area = *area; - scx.scx_use = DRCDummyUse; - scx.scx_trans = GeoIdentityTransform; - - /* During array processing, switch the paint table to catch - * illegal overlaps. - */ - - savedPaintTable = DBNewPaintTable(DRCCurStyle->DRCPaintTable); - savedPaintPlane = DBNewPaintPlane(DBPaintPlaneMark); - (void) DBCellSrArea(&scx, drcArrayFunc, (ClientData) area); (void) DBNewPaintTable(savedPaintTable); (void) DBNewPaintPlane(savedPaintPlane); /* Update count of array tiles processed. */ - DRCstatArrayTiles += DRCstatTiles - oldTiles; - return drcArrayCount; -} + /* Restore original DRC cookie pointer in the argument */ + arg->dCD_cptr = save_cptr; + return 2; +} /* * ---------------------------------------------------------------------------- diff --git a/drc/DRCcif.c b/drc/DRCcif.c index c280c4bd..a06d8d0d 100644 --- a/drc/DRCcif.c +++ b/drc/DRCcif.c @@ -552,7 +552,7 @@ drcCifCheck(arg) oldTiles = DRCstatTiles; CIFGen(arg->dCD_celldef, arg->dCD_celldef, checkRect, CIFPlanes, - &DBAllTypeBits, TRUE, TRUE); + &DBAllTypeBits, TRUE, TRUE, FALSE, (ClientData)NULL); for (i = 0; i < drcCifStyle->cs_nLayers; i++) { diff --git a/drc/DRCcontin.c b/drc/DRCcontin.c index a8131361..5d9a527f 100644 --- a/drc/DRCcontin.c +++ b/drc/DRCcontin.c @@ -696,8 +696,6 @@ drcCheckTile(tile, arg) (void) DBSrPaintArea((Tile *) NULL, celldef->cd_planes[PL_DRC_ERROR], &square, &DBAllButSpaceBits, drcXorFunc, (ClientData) NULL); - /* Check #1: recheck the paint of the cell, ignoring subcells. */ - DRCErrorType = TT_ERROR_P; DBClearPaintPlane(drcTempPlane); @@ -707,10 +705,7 @@ drcCheckTile(tile, arg) * computed within DRCInteractionCheck()). */ - /* DRCBasicCheck (celldef, &checkbox, &erasebox, drcPaintError, - (ClientData) drcTempPlane); */ - - /* Check #2: check interactions between paint and subcells, and + /* Check interactions between paint and subcells, and * also between subcells and other subcells. If any part of a * square is rechecked for interactions, the whole thing has to * be rechecked. We use TT_ERROR_S tiles for this so that we @@ -722,12 +717,6 @@ drcCheckTile(tile, arg) (void) DRCInteractionCheck(celldef, &square, &erasebox, drcPaintError, (ClientData)drcTempPlane); - /* Check #3: check for array formation errors in the area. */ - - DRCErrorType = TT_ERROR_P; - (void) DRCArrayCheck(celldef, &erasebox, drcPaintError, - (ClientData) drcTempPlane); - /* If there was an interrupt, return without modifying the cell * at all. */ diff --git a/drc/DRCmain.c b/drc/DRCmain.c index 6a2e9ade..b57093df 100644 --- a/drc/DRCmain.c +++ b/drc/DRCmain.c @@ -616,12 +616,6 @@ drcWhyFunc(scx, cdarg) (void) DRCInteractionCheck(def, &scx->scx_area, &scx->scx_area, (dolist) ? drcListError : drcPrintError, (ClientData) scx); - (void) DRCArrayCheck(def, &scx->scx_area, - (dolist) ? drcListError : drcPrintError, (ClientData) scx); - - /* New behavior: Don't search children, instead propagate errors up. */ - /* (void) DBCellSrArea(scx, drcWhyFunc, (ClientData)cdarg); */ - return 0; } @@ -637,13 +631,7 @@ drcWhyAllFunc(scx, cdarg) /* Check paint and interactions in this subcell. */ (void) DRCInteractionCheck(def, &scx->scx_area, &scx->scx_area, - drcListallError, (Plane *)NULL, (ClientData)scx); - (void) DRCArrayCheck(def, &scx->scx_area, - drcListallError, (Plane *)NULL, (ClientData)scx); - - /* New behavior: Don't search children, instead propagate errors up. */ - /* (void) DBCellSrArea(scx, drcWhyAllFunc, (ClientData)cdarg); */ - + drcListallError, (ClientData)scx); return 0; } diff --git a/drc/DRCsubcell.c b/drc/DRCsubcell.c index 9ecdb353..fa461378 100644 --- a/drc/DRCsubcell.c +++ b/drc/DRCsubcell.c @@ -157,6 +157,9 @@ drcSubCopyErrors(tile, cxp) * be a real error, and not one that might be resolved by additional * material found in the parent or a sibling cell. * + * Added 11/10/2020: Moved drcArrayFunc() here; this limits the array + * checks to non-interaction areas in the parent cell. + * * Returns: * Whatever DBNoTreeSrTiles() returns. * @@ -708,7 +711,9 @@ DRCInteractionCheck(def, area, erasebox, func, cdarg) /* Copy errors up from all non-interacting children */ scx.scx_area = subArea; + arg.dCD_clip = &subArea; DBCellSrArea(&scx, drcSubCopyFunc, &arg); + DBCellSrArea(&scx, drcArrayFunc, &arg); DRCErrorType = errorSaveType; continue; @@ -735,6 +740,7 @@ DRCInteractionCheck(def, area, erasebox, func, cdarg) eraseClip = *erasebox; GeoClip(&eraseClip, &cliparea); subArea = eraseClip; + arg.dCD_clip = &subArea; /* check above */ if (intArea.r_ytop < eraseClip.r_ytop) @@ -745,6 +751,7 @@ DRCInteractionCheck(def, area, erasebox, func, cdarg) /* Copy errors up from all non-interacting children */ scx.scx_area = subArea; DBCellSrArea(&scx, drcSubCopyFunc, &arg); + DBCellSrArea(&scx, drcArrayFunc, &arg); } /* check below */ if (intArea.r_ybot > eraseClip.r_ybot) @@ -756,6 +763,7 @@ DRCInteractionCheck(def, area, erasebox, func, cdarg) /* Copy errors up from all non-interacting children */ scx.scx_area = subArea; DBCellSrArea(&scx, drcSubCopyFunc, &arg); + DBCellSrArea(&scx, drcArrayFunc, &arg); } subArea.r_ytop = intArea.r_ytop; subArea.r_ybot = intArea.r_ybot; @@ -769,6 +777,7 @@ DRCInteractionCheck(def, area, erasebox, func, cdarg) /* Copy errors up from all non-interacting children */ scx.scx_area = subArea; DBCellSrArea(&scx, drcSubCopyFunc, &arg); + DBCellSrArea(&scx, drcArrayFunc, &arg); } /* check left */ if (intArea.r_xbot > eraseClip.r_xbot) @@ -780,6 +789,7 @@ DRCInteractionCheck(def, area, erasebox, func, cdarg) /* Copy errors up from all non-interacting children */ scx.scx_area = subArea; DBCellSrArea(&scx, drcSubCopyFunc, &arg); + DBCellSrArea(&scx, drcArrayFunc, &arg); } DRCErrorType = errorSaveType; } diff --git a/drc/drc.h b/drc/drc.h index 061a1ce2..d1638931 100644 --- a/drc/drc.h +++ b/drc/drc.h @@ -246,6 +246,9 @@ extern int DRCGetDefaultLayerSpacing(); extern int DRCGetDefaultWideLayerSpacing(); extern int DRCGetDefaultLayerSurround(); +extern int DRCInteractionCheck(); +extern int drcArrayFunc(); + extern void DRCTechInit(); extern bool DRCTechLine(); extern bool DRCTechAddRule(); diff --git a/graphics/W3Dmain.c b/graphics/W3Dmain.c index 656f37b8..ec77baf3 100644 --- a/graphics/W3Dmain.c +++ b/graphics/W3Dmain.c @@ -1739,7 +1739,8 @@ W3DCIFredisplay(w, rootArea, clipArea) scx.scx_trans = GeoIdentityTransform; (void) DBTreeSrTiles(&scx, &DBAllButSpaceAndDRCBits, 0, cifHierCopyFunc, (ClientData) CIFComponentDef); - CIFGen(CIFComponentDef, cellDef, &clipRect, CIFPlanes, &DBAllTypeBits, TRUE, TRUE); + CIFGen(CIFComponentDef, cellDef, &clipRect, CIFPlanes, &DBAllTypeBits, TRUE, + TRUE, FALSE, (ClientData)NULL); DBCellClearDef(CIFComponentDef); w3dClear(); diff --git a/tcltk/readspice.tcl b/tcltk/readspice.tcl index 333534f4..058185e0 100644 --- a/tcltk/readspice.tcl +++ b/tcltk/readspice.tcl @@ -124,6 +124,12 @@ proc readspice {netfile} { set p $p1 } + # Get the complete set of labels in the top cell and make a list + select top cell + select area labels + set all [lindex [what -list] 1] + select clear + foreach pin [lrange $ftokens 2 end] { # If "=" is in the name, then we have finished the pins # and are looking at parameters, and so parsing is done. @@ -173,16 +179,12 @@ proc readspice {netfile} { # port name. If so, convert it into a port if {$pinidx == ""} { - select top cell - select area labels - set all [lindex [what -list] 1] - select clear foreach labrec $all { set testpin [lindex $labrec 0] if {[string tolower $testpin] == [string tolower $pin]} { goto $testpin set pinidx -1 - port make $n + port $testpin make $n break } } @@ -199,7 +201,7 @@ proc readspice {netfile} { } else { set layer [goto $pin] if {$layer != ""} { - port make $n + port $pin make $n incr n set changed true }