From 904a60423e11e78b8a8d1244abbaaa6751d8ec5f Mon Sep 17 00:00:00 2001 From: Tim Edwards Date: Tue, 10 Nov 2020 10:26:01 -0500 Subject: [PATCH 01/12] Corrected the CIF "close" function to accommodate non-manhattan geometry. --- VERSION | 2 +- cif/CIFgen.c | 12 +++++++----- 2 files changed, 8 insertions(+), 6 deletions(-) diff --git a/VERSION b/VERSION index e8198f1f..e181c9a0 100644 --- a/VERSION +++ b/VERSION @@ -1 +1 @@ -8.3.78 +8.3.79 diff --git a/cif/CIFgen.c b/cif/CIFgen.c index cde2142d..bf14faf5 100644 --- a/cif/CIFgen.c +++ b/cif/CIFgen.c @@ -2004,6 +2004,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 +2012,8 @@ cifGatherFunc(tile, atotal, mode) } else if (mode == CLOSE_FILL) { - DBPaintPlane(cifPlane, &area, CIFPaintTable, (PaintUndoInfo *)NULL); + DBNMPaintPlane(cifPlane, TiGetTypeExact(tile), &area, CIFPaintTable, + (PaintUndoInfo *)NULL); CIFTileOps++; } @@ -2024,25 +2026,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; From d2fc99c433168857df14ec4ffccda59bee3cd724 Mon Sep 17 00:00:00 2001 From: Tim Edwards Date: Tue, 10 Nov 2020 10:52:32 -0500 Subject: [PATCH 02/12] Corrected an error that makes the "drc listall why" command segfault. --- drc/DRCmain.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drc/DRCmain.c b/drc/DRCmain.c index 6a2e9ade..d6132940 100644 --- a/drc/DRCmain.c +++ b/drc/DRCmain.c @@ -637,9 +637,9 @@ drcWhyAllFunc(scx, cdarg) /* Check paint and interactions in this subcell. */ (void) DRCInteractionCheck(def, &scx->scx_area, &scx->scx_area, - drcListallError, (Plane *)NULL, (ClientData)scx); + drcListallError, (ClientData)scx); (void) DRCArrayCheck(def, &scx->scx_area, - drcListallError, (Plane *)NULL, (ClientData)scx); + drcListallError, (ClientData)scx); /* New behavior: Don't search children, instead propagate errors up. */ /* (void) DBCellSrArea(scx, drcWhyAllFunc, (ClientData)cdarg); */ From 4f7567b8648a6d97f37fc0e67369b8c92f4d477c Mon Sep 17 00:00:00 2001 From: Tim Edwards Date: Tue, 10 Nov 2020 11:11:41 -0500 Subject: [PATCH 03/12] Problem apparently stems from the routine not being in the header file, so corrected that, too. --- drc/drc.h | 3 +++ 1 file changed, 3 insertions(+) diff --git a/drc/drc.h b/drc/drc.h index 061a1ce2..7f3088f5 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 DRCArrayCheck(); + extern void DRCTechInit(); extern bool DRCTechLine(); extern bool DRCTechAddRule(); From 6b84efa86ef5df82da8adac1debda459b59e9ba8 Mon Sep 17 00:00:00 2001 From: Tim Edwards Date: Tue, 10 Nov 2020 13:28:40 -0500 Subject: [PATCH 04/12] Additional correction for the CIF "close" operator. --- cif/CIFgen.c | 18 ++++++++++++++++-- 1 file changed, 16 insertions(+), 2 deletions(-) diff --git a/cif/CIFgen.c b/cif/CIFgen.c index bf14faf5..90f92c87 100644 --- a/cif/CIFgen.c +++ b/cif/CIFgen.c @@ -2012,8 +2012,22 @@ cifGatherFunc(tile, atotal, mode) } else if (mode == CLOSE_FILL) { - DBNMPaintPlane(cifPlane, TiGetTypeExact(tile), &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++; } From 114982fc72ce95a1e931df08427f089e9ab8b9c9 Mon Sep 17 00:00:00 2001 From: Tim Edwards Date: Wed, 11 Nov 2020 11:50:16 -0500 Subject: [PATCH 05/12] Corrected the handling of DRC in cell instance arrays so that it matches the handling of subcell instances generally. Previously it would check the interaction between neighboring cells in an array without regard to any material in the parent cell which might remove those errors; consequently, the array would have to be DRC clean by itself in order for the parent cell to show as DRC clean. The array check has been moved inside the DRCInteractionCheck() routine, so that it runs only where arrayed instances do not interact with anything else. Within interaction areas, the area is flattened and checked, so the array check is not needed. --- VERSION | 2 +- drc/DRCarray.c | 120 +++++++++++++---------------------------------- drc/DRCcontin.c | 13 +---- drc/DRCmain.c | 12 ----- drc/DRCsubcell.c | 10 ++++ drc/drc.h | 2 +- 6 files changed, 46 insertions(+), 113 deletions(-) diff --git a/VERSION b/VERSION index e181c9a0..3d73f92b 100644 --- a/VERSION +++ b/VERSION @@ -1 +1 @@ -8.3.79 +8.3.80 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/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 d6132940..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; } @@ -638,12 +632,6 @@ drcWhyAllFunc(scx, cdarg) (void) DRCInteractionCheck(def, &scx->scx_area, &scx->scx_area, drcListallError, (ClientData)scx); - (void) DRCArrayCheck(def, &scx->scx_area, - drcListallError, (ClientData)scx); - - /* New behavior: Don't search children, instead propagate errors up. */ - /* (void) DBCellSrArea(scx, drcWhyAllFunc, (ClientData)cdarg); */ - 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 7f3088f5..d1638931 100644 --- a/drc/drc.h +++ b/drc/drc.h @@ -247,7 +247,7 @@ extern int DRCGetDefaultWideLayerSpacing(); extern int DRCGetDefaultLayerSurround(); extern int DRCInteractionCheck(); -extern int DRCArrayCheck(); +extern int drcArrayFunc(); extern void DRCTechInit(); extern bool DRCTechLine(); From ad2857dfabc3e33f0ff94519f04fdfa39280c2a9 Mon Sep 17 00:00:00 2001 From: Tim Edwards Date: Wed, 11 Nov 2020 14:06:12 -0500 Subject: [PATCH 06/12] Corrected the "grow-min" CIF operator to grow more than the minimum amount as needed to land on the specified minimum manufacturing grid. --- cif/CIFgen.c | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/cif/CIFgen.c b/cif/CIFgen.c index 90f92c87..8c4e234e 100644 --- a/cif/CIFgen.c +++ b/cif/CIFgen.c @@ -218,6 +218,10 @@ cifGrowMinFunc(tile, table) } } } + + /* Ensure grid limit is not violated */ + SetMinBoxGrid(&area, growDistance); + DBPaintPlane(cifPlane, &area, table, (PaintUndoInfo *) NULL); area = parea; @@ -274,6 +278,8 @@ 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); } } From 73629467edf2883af465128bb081f194fe030759 Mon Sep 17 00:00:00 2001 From: Tim Edwards Date: Wed, 11 Nov 2020 14:12:51 -0500 Subject: [PATCH 07/12] Added a forward reference to prevent a compiler warning. --- cif/CIFgen.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/cif/CIFgen.c b/cif/CIFgen.c index 8c4e234e..938729be 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; + void SetMinBoxGrid(); /* Forward reference */ + TiToRect(tile, &area); From 75a18053f87e213294e7ec4334ff3f1ed322d5af Mon Sep 17 00:00:00 2001 From: Tim Edwards Date: Thu, 12 Nov 2020 10:34:27 -0500 Subject: [PATCH 08/12] Modified the CIFGenLayer() routine to be aware of when it is called during hierarchical processing from CIFGenSubcells() and CIFGenArrays(), and to avoid certain operators that are useless and harmful when applied hierarchically; namely squares, slots, bbox, boundary, and net. --- VERSION | 2 +- calma/CalmaWrite.c | 6 +++- cif/CIFgen.c | 44 ++++++++++++++++++++++++++++-- cif/CIFhier.c | 68 ++++++++++++++++++++++++++++++++++++++++------ cif/CIFrdcl.c | 3 +- cif/CIFsee.c | 9 ++++-- cif/CIFtech.c | 7 +++++ cif/CIFwrite.c | 3 +- drc/DRCcif.c | 2 +- graphics/W3Dmain.c | 3 +- 10 files changed, 127 insertions(+), 20 deletions(-) diff --git a/VERSION b/VERSION index 3d73f92b..896df0cf 100644 --- a/VERSION +++ b/VERSION @@ -1 +1 @@ -8.3.80 +8.3.81 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 938729be..8321da85 100644 --- a/cif/CIFgen.c +++ b/cif/CIFgen.c @@ -4656,7 +4656,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 @@ -4672,6 +4672,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 CIFGenSubcell or CIFGenArray */ ClientData clientdata; /* * Data that may be passed to the CIF operation * function. @@ -4689,6 +4690,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; @@ -4703,6 +4705,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) @@ -4961,6 +4967,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); @@ -4973,6 +4984,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); @@ -4982,6 +4998,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); @@ -5002,6 +5023,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); @@ -5022,6 +5048,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. */ @@ -5047,6 +5078,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 */ @@ -5084,6 +5120,7 @@ CIFGenLayer(op, area, cellDef, origDef, temps, clientdata) default: continue; } + if (hstop) break; /* Don't process any further rules */ } return curPlane; @@ -5112,7 +5149,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 @@ -5135,6 +5172,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 CIFGenSubcell or CIFGenArray */ ClientData clientdata; /* Data that may be passed along to the * CIF operation functions. */ @@ -5160,7 +5198,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/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/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(); From b0616e9f0e417ffef41d5682427d2d5b295086a4 Mon Sep 17 00:00:00 2001 From: Tim Edwards Date: Thu, 12 Nov 2020 10:55:20 -0500 Subject: [PATCH 09/12] Fixed two misspellings in comments. --- cif/CIFgen.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/cif/CIFgen.c b/cif/CIFgen.c index 8321da85..d98313c4 100644 --- a/cif/CIFgen.c +++ b/cif/CIFgen.c @@ -4672,7 +4672,7 @@ CIFGenLayer(op, area, cellDef, origDef, temps, hier, clientdata) Plane *temps[]; /* Temporary layers to be used when needed * for operation. */ - bool hier; /* TRUE if called from CIFGenSubcell or CIFGenArray */ + bool hier; /* TRUE if called from CIFGenSubcells or CIFGenArrays */ ClientData clientdata; /* * Data that may be passed to the CIF operation * function. @@ -5172,7 +5172,7 @@ CIFGen(cellDef, origDef, area, planes, layers, replace, genAllPlanes, hier, clie * those layers not specified as being * generated in the 'layers' mask above. */ - bool hier; /* TRUE if called from CIFGenSubcell or CIFGenArray */ + bool hier; /* TRUE if called from CIFGenSubcells or CIFGenArrays */ ClientData clientdata; /* Data that may be passed along to the * CIF operation functions. */ From cd3d765f9dd7a255a25dba1588cab110266d3cb7 Mon Sep 17 00:00:00 2001 From: Tim Edwards Date: Thu, 12 Nov 2020 13:59:22 -0500 Subject: [PATCH 10/12] Changed the readspice (annotation) script so that it uses the exact label name with "port make", resolving any issues that might arise if the label overlaps another. --- tcltk/readspice.tcl | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tcltk/readspice.tcl b/tcltk/readspice.tcl index 333534f4..45f1a359 100644 --- a/tcltk/readspice.tcl +++ b/tcltk/readspice.tcl @@ -182,7 +182,7 @@ proc readspice {netfile} { if {[string tolower $testpin] == [string tolower $pin]} { goto $testpin set pinidx -1 - port make $n + port $testpin make $n break } } @@ -199,7 +199,7 @@ proc readspice {netfile} { } else { set layer [goto $pin] if {$layer != ""} { - port make $n + port $pin make $n incr n set changed true } From 6d009682bcac4adcd6115633456be3164f808489 Mon Sep 17 00:00:00 2001 From: Tim Edwards Date: Thu, 12 Nov 2020 16:46:51 -0500 Subject: [PATCH 11/12] Applied a patch by Matt Guthaus to a routine in the readspice annotation script, that moves a block of code making a list of all labels outside of an inner loop where it causes a huge slowdown. --- tcltk/readspice.tcl | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/tcltk/readspice.tcl b/tcltk/readspice.tcl index 45f1a359..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,10 +179,6 @@ 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]} { From 750d6c0ecf2704d3f666a34baaf3988e8535c917 Mon Sep 17 00:00:00 2001 From: Tim Edwards Date: Fri, 13 Nov 2020 10:24:31 -0500 Subject: [PATCH 12/12] Corrected a bad error (missing braces around a code block of more than one line) in the "grow-min" function that was affecting GDS output for any layers using the grow-min operator. --- VERSION | 2 +- cif/CIFgen.c | 10 ++++++++-- 2 files changed, 9 insertions(+), 3 deletions(-) diff --git a/VERSION b/VERSION index 896df0cf..0eea60da 100644 --- a/VERSION +++ b/VERSION @@ -1 +1 @@ -8.3.81 +8.3.82 diff --git a/cif/CIFgen.c b/cif/CIFgen.c index d98313c4..6eda31ee 100644 --- a/cif/CIFgen.c +++ b/cif/CIFgen.c @@ -148,9 +148,9 @@ cifGrowMinFunc(tile, table) int locDist, width, height, h; TileType type, tptype; Tile *tp, *tp2; + bool changed; void SetMinBoxGrid(); /* Forward reference */ - TiToRect(tile, &area); area.r_xbot *= cifScale; @@ -159,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; @@ -205,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) { @@ -212,17 +214,19 @@ 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 */ - SetMinBoxGrid(&area, growDistance); + if (changed) SetMinBoxGrid(&area, growDistance); DBPaintPlane(cifPlane, &area, table, (PaintUndoInfo *) NULL); @@ -280,9 +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); + } } }