Merge branch 'master' of https://github.com/RTimothyEdwards/magic into spice_hier

This commit is contained in:
Dan Moore 2020-11-14 18:04:14 -08:00
commit 60da2963b1
16 changed files with 218 additions and 143 deletions

View File

@ -1 +1 @@
8.3.78 8.3.82

View File

@ -799,6 +799,9 @@ calmaProcessDef(def, outf, do_library)
if (isReadOnly && hasContent && CalmaAddendum) return (0); 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 * Output the definitions for any of our descendants that have
* not already been output. Numbers are assigned to the subcells * 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 */ /* Output all the tiles associated with this cell; skip temporary layers */
GEO_EXPAND(&def->cd_bbox, CIFCurStyle->cs_radius, &bigArea); GEO_EXPAND(&def->cd_bbox, CIFCurStyle->cs_radius, &bigArea);
CIFErrorDef = def; 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) if (!CIFHierWriteDisable)
CIFGenSubcells(def, &bigArea, CIFPlanes); CIFGenSubcells(def, &bigArea, CIFPlanes);
if (!CIFArrayWriteDisable) if (!CIFArrayWriteDisable)

View File

@ -148,6 +148,8 @@ cifGrowMinFunc(tile, table)
int locDist, width, height, h; int locDist, width, height, h;
TileType type, tptype; TileType type, tptype;
Tile *tp, *tp2; Tile *tp, *tp2;
bool changed;
void SetMinBoxGrid(); /* Forward reference */
TiToRect(tile, &area); TiToRect(tile, &area);
@ -157,6 +159,7 @@ cifGrowMinFunc(tile, table)
area.r_ytop *= cifScale; area.r_ytop *= cifScale;
parea = area; parea = area;
changed = FALSE;
/* Check whole tile for minimum width */ /* Check whole tile for minimum width */
width = area.r_xtop - area.r_xbot; width = area.r_xtop - area.r_xbot;
@ -203,6 +206,7 @@ cifGrowMinFunc(tile, table)
0.25 * (double)((growDistance + width) * 0.25 * (double)((growDistance + width) *
(growDistance + width)) + 0.5); (growDistance + width)) + 0.5);
area.r_ybot -= h; area.r_ybot -= h;
changed = TRUE;
} }
else if (freeTop == FALSE && freeBot == TRUE) else if (freeTop == FALSE && freeBot == TRUE)
{ {
@ -210,14 +214,20 @@ cifGrowMinFunc(tile, table)
0.25 * (double)((growDistance + width) * 0.25 * (double)((growDistance + width) *
(growDistance + width)) + 0.5); (growDistance + width)) + 0.5);
area.r_ytop += h; area.r_ytop += h;
changed = TRUE;
} }
else { else {
locDist = (growDistance - height) / 2; locDist = (growDistance - height) / 2;
area.r_ybot -= locDist; area.r_ybot -= locDist;
area.r_ytop += locDist; area.r_ytop += locDist;
changed = TRUE;
} }
} }
} }
/* Ensure grid limit is not violated */
if (changed) SetMinBoxGrid(&area, growDistance);
DBPaintPlane(cifPlane, &area, table, (PaintUndoInfo *) NULL); DBPaintPlane(cifPlane, &area, table, (PaintUndoInfo *) NULL);
area = parea; area = parea;
@ -274,7 +284,11 @@ cifGrowMinFunc(tile, table)
parea.r_ytop = area.r_ytop; parea.r_ytop = area.r_ytop;
} }
if ((width < growDistance) || (height < growDistance)) if ((width < growDistance) || (height < growDistance))
{
/* Ensure grid limit is not violated */
SetMinBoxGrid(&parea, growDistance);
DBPaintPlane(cifPlane, &parea, table, (PaintUndoInfo *) NULL); DBPaintPlane(cifPlane, &parea, table, (PaintUndoInfo *) NULL);
}
} }
} }
@ -2004,6 +2018,7 @@ cifGatherFunc(tile, atotal, mode)
if ((*atotal != INFINITY) && (*atotal < growDistance)) if ((*atotal != INFINITY) && (*atotal < growDistance))
locarea = (dlong)(area.r_xtop - area.r_xbot) locarea = (dlong)(area.r_xtop - area.r_xbot)
* (dlong)(area.r_ytop - area.r_ybot); * (dlong)(area.r_ytop - area.r_ybot);
if (IsSplit(tile)) locarea /= 2;
if (locarea > (dlong)INFINITY) if (locarea > (dlong)INFINITY)
*atotal = INFINITY; *atotal = INFINITY;
else else
@ -2011,7 +2026,22 @@ cifGatherFunc(tile, atotal, mode)
} }
else if (mode == CLOSE_FILL) 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++; CIFTileOps++;
} }
@ -2024,25 +2054,25 @@ cifGatherFunc(tile, atotal, mode)
/* Check top */ /* Check top */
if (area.r_ytop != TiPlaneRect.r_ytop) if (area.r_ytop != TiPlaneRect.r_ytop)
for (tp = RT(tile); RIGHT(tp) > LEFT(tile); tp = BL(tp)) 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); cifGatherFunc(tp, atotal, mode);
/* Check bottom */ /* Check bottom */
if (area.r_ybot != TiPlaneRect.r_ybot) if (area.r_ybot != TiPlaneRect.r_ybot)
for (tp = LB(tile); LEFT(tp) < RIGHT(tile); tp = TR(tp)) 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); cifGatherFunc(tp, atotal, mode);
/* Check left */ /* Check left */
if (area.r_xbot != TiPlaneRect.r_xbot) if (area.r_xbot != TiPlaneRect.r_xbot)
for (tp = BL(tile); BOTTOM(tp) < TOP(tile); tp = RT(tp)) 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); cifGatherFunc(tp, atotal, mode);
/* Check right */ /* Check right */
if (area.r_xtop != TiPlaneRect.r_xtop) if (area.r_xtop != TiPlaneRect.r_xtop)
for (tp = TR(tile); TOP(tp) > BOTTOM(tile); tp = LB(tp)) 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); cifGatherFunc(tp, atotal, mode);
return 0; return 0;
@ -4632,7 +4662,7 @@ cifBridgeLimFunc2(tile, brlims)
*/ */
Plane * 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. */ CIFOp *op; /* List of CIFOps telling how to make layer. */
Rect *area; /* Area to consider when generating CIF. Only Rect *area; /* Area to consider when generating CIF. Only
* material in this area will be considered, so * 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 Plane *temps[]; /* Temporary layers to be used when needed
* for operation. * for operation.
*/ */
bool hier; /* TRUE if called from CIFGenSubcells or CIFGenArrays */
ClientData clientdata; /* ClientData clientdata; /*
* Data that may be passed to the CIF operation * Data that may be passed to the CIF operation
* function. * function.
@ -4665,6 +4696,7 @@ CIFGenLayer(op, area, cellDef, origDef, temps, clientdata)
BridgeStruct brs; BridgeStruct brs;
BridgeLimStruct brlims; BridgeLimStruct brlims;
BridgeData *bridge; BridgeData *bridge;
bool hstop = FALSE;
int (*cifGrowFuncPtr)() = (CIFCurStyle->cs_flags & CWF_GROW_EUCLIDEAN) ? int (*cifGrowFuncPtr)() = (CIFCurStyle->cs_flags & CWF_GROW_EUCLIDEAN) ?
cifGrowEuclideanFunc : cifGrowFunc; cifGrowEuclideanFunc : cifGrowFunc;
@ -4679,6 +4711,10 @@ CIFGenLayer(op, area, cellDef, origDef, temps, clientdata)
/* Go through the geometric operations and process them one /* Go through the geometric operations and process them one
* at a time. * 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) for ( ; op != NULL; op = op->co_next)
@ -4937,6 +4973,11 @@ CIFGenLayer(op, area, cellDef, origDef, temps, clientdata)
break; break;
case CIFOP_SQUARES: case CIFOP_SQUARES:
if (hier)
{
hstop = TRUE; /* Stop hierarchical processing */
break;
}
if (CalmaContactArrays == FALSE) if (CalmaContactArrays == FALSE)
{ {
DBClearPaintPlane(nextPlane); DBClearPaintPlane(nextPlane);
@ -4949,6 +4990,11 @@ CIFGenLayer(op, area, cellDef, origDef, temps, clientdata)
break; break;
case CIFOP_SQUARES_G: case CIFOP_SQUARES_G:
if (hier)
{
hstop = TRUE; /* Stop hierarchical processing */
break;
}
DBClearPaintPlane(nextPlane); DBClearPaintPlane(nextPlane);
cifPlane = nextPlane; cifPlane = nextPlane;
cifSquaresFillArea(op, cellDef, curPlane); cifSquaresFillArea(op, cellDef, curPlane);
@ -4958,6 +5004,11 @@ CIFGenLayer(op, area, cellDef, origDef, temps, clientdata)
break; break;
case CIFOP_SLOTS: case CIFOP_SLOTS:
if (hier)
{
hstop = TRUE; /* Stop hierarchical processing */
break;
}
DBClearPaintPlane(nextPlane); DBClearPaintPlane(nextPlane);
cifPlane = nextPlane; cifPlane = nextPlane;
cifSlotsFillArea(op, cellDef, curPlane); cifSlotsFillArea(op, cellDef, curPlane);
@ -4978,6 +5029,11 @@ CIFGenLayer(op, area, cellDef, origDef, temps, clientdata)
break; break;
case CIFOP_NET: case CIFOP_NET:
if (hier)
{
hstop = TRUE; /* Stop hierarchical processing */
break;
}
netname = (char *)op->co_client; netname = (char *)op->co_client;
cifPlane = curPlane; cifPlane = curPlane;
ttype = CmdFindNetProc(netname, CIFDummyUse, &bbox, FALSE); ttype = CmdFindNetProc(netname, CIFDummyUse, &bbox, FALSE);
@ -4998,6 +5054,11 @@ CIFGenLayer(op, area, cellDef, origDef, temps, clientdata)
break; break;
case CIFOP_BOUNDARY: case CIFOP_BOUNDARY:
if (hier)
{
hstop = TRUE; /* Stop hierarchical processing */
break;
}
cifPlane = curPlane; cifPlane = curPlane;
/* This function for cifoutput only. cifinput handled separately. */ /* This function for cifoutput only. cifinput handled separately. */
@ -5023,6 +5084,11 @@ CIFGenLayer(op, area, cellDef, origDef, temps, clientdata)
break; break;
case CIFOP_BBOX: case CIFOP_BBOX:
if (hier)
{
hstop = TRUE; /* Stop hierarchical processing */
break;
}
if (CIFErrorDef == NULL) break; if (CIFErrorDef == NULL) break;
/* co_client contains the flag (1) for top-level only */ /* co_client contains the flag (1) for top-level only */
@ -5060,6 +5126,7 @@ CIFGenLayer(op, area, cellDef, origDef, temps, clientdata)
default: default:
continue; continue;
} }
if (hstop) break; /* Don't process any further rules */
} }
return curPlane; return curPlane;
@ -5088,7 +5155,7 @@ CIFGenLayer(op, area, cellDef, origDef, temps, clientdata)
*/ */
void 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 *cellDef; /* Cell for which CIF is to be generated. */
CellDef *origDef; /* Original cell, if different from cellDef */ CellDef *origDef; /* Original cell, if different from cellDef */
Rect *area; /* Any CIF overlapping this area (in coords 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 * those layers not specified as being
* generated in the 'layers' mask above. * 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 ClientData clientdata; /* Data that may be passed along to the
* CIF operation functions. * CIF operation functions.
*/ */
@ -5136,7 +5204,7 @@ CIFGen(cellDef, origDef, area, planes, layers, replace, genAllPlanes, clientdata
{ {
CIFErrorLayer = i; CIFErrorLayer = i;
new[i] = CIFGenLayer(CIFCurStyle->cs_layers[i]->cl_ops, 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 */ /* Clean up the non-manhattan geometry in the plane */
if (CIFUnfracture) DBMergeNMTiles(new[i], &expanded, if (CIFUnfracture) DBMergeNMTiles(new[i], &expanded,

View File

@ -27,6 +27,7 @@ static char rcsid[] __attribute__ ((unused)) = "$Header: /usr/cvsroot/magic-8.0/
#include <stdio.h> #include <stdio.h>
#include "tcltk/tclmagic.h"
#include "utils/magic.h" #include "utils/magic.h"
#include "utils/geometry.h" #include "utils/geometry.h"
#include "tiles/tile.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/CIFint.h"
#include "cif/cif.h" #include "cif/cif.h"
#include "drc/drc.h" #include "drc/drc.h"
#include "graphics/graphics.h"
#include "textio/textio.h" #include "textio/textio.h"
#include "utils/undo.h" #include "utils/undo.h"
#include "utils/malloc.h" #include "utils/malloc.h"
@ -326,7 +328,8 @@ cifHierCellFunc(scx)
CIFErrorDef = (CellDef *) NULL; CIFErrorDef = (CellDef *) NULL;
GeoTransRect(&scx->scx_trans, &scx->scx_area, &rootArea); GeoTransRect(&scx->scx_trans, &scx->scx_area, &rootArea);
CIFGen(CIFComponentDef, scx->scx_use->cu_def, &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; return 0;
} }
@ -523,6 +526,8 @@ CIFGenSubcells(def, area, output)
int stepSize, x, y, i, radius, oldTileOps, oldTileOps2; int stepSize, x, y, i, radius, oldTileOps, oldTileOps2;
Rect totalArea, square, interaction; Rect totalArea, square, interaction;
SearchContext scx; SearchContext scx;
int cuts, totcuts;
float pdone, plast;
UndoDisable(); UndoDisable();
CIFInitCells(); CIFInitCells();
@ -537,6 +542,16 @@ CIFGenSubcells(def, area, output)
scx.scx_use = CIFDummyUse; scx.scx_use = CIFDummyUse;
scx.scx_trans = GeoIdentityTransform; 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 /* Any tile operations processed here get billed to hierarchy
* in addition to being added to the total. * in addition to being added to the total.
*/ */
@ -551,6 +566,12 @@ CIFGenSubcells(def, area, output)
totalArea = *area; totalArea = *area;
GeoClip(&totalArea, &def->cd_bbox); 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 (y = totalArea.r_ybot; y < totalArea.r_ytop; y += stepSize)
for (x = totalArea.r_xbot; x < totalArea.r_xtop; x += stepSize) for (x = totalArea.r_xbot; x < totalArea.r_xtop; x += stepSize)
{ {
@ -576,7 +597,8 @@ CIFGenSubcells(def, area, output)
cifHierCopyFunc, (ClientData) CIFTotalDef); cifHierCopyFunc, (ClientData) CIFTotalDef);
CIFErrorDef = def; CIFErrorDef = def;
CIFGen(CIFTotalDef, def, &interaction, CIFTotalPlanes, 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 /* Now go through all the subcells overlapping the area
* and generate CIF for each subcell individually. OR this * and generate CIF for each subcell individually. OR this
@ -593,7 +615,8 @@ CIFGenSubcells(def, area, output)
CIFErrorDef = (CellDef *) NULL; CIFErrorDef = (CellDef *) NULL;
CIFGen(def, def, &interaction, CIFComponentPlanes, 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 /* Make sure everything in the pieces is also in the overall
* CIF, then erase the piece stuff from the overall, and * CIF, then erase the piece stuff from the overall, and
@ -618,9 +641,33 @@ CIFGenSubcells(def, area, output)
CIFHierRects += CIFTileOps - oldTileOps2; CIFHierRects += CIFTileOps - oldTileOps2;
cifHierCleanup(); 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; CIFHierTileOps += CIFTileOps - oldTileOps;
GrDisplayStatus = DISPLAY_IDLE;
SigRemoveTimer();
UndoEnable(); UndoEnable();
} }
@ -680,7 +727,8 @@ cifHierElementFunc(use, transform, x, y, checkArea)
CIFErrorDef = (CellDef *) NULL; CIFErrorDef = (CellDef *) NULL;
CIFGen(CIFComponentDef, use->cu_def, checkArea, CIFComponentPlanes, CIFGen(CIFComponentDef, use->cu_def, checkArea, CIFComponentPlanes,
&CIFCurStyle->cs_hierLayers, FALSE, TRUE); &CIFCurStyle->cs_hierLayers, FALSE, TRUE, TRUE,
(ClientData)NULL);
return 0; return 0;
} }
@ -921,7 +969,8 @@ cifHierArrayFunc(scx, output)
(ClientData) &A); (ClientData) &A);
CIFErrorDef = use->cu_parent; CIFErrorDef = use->cu_parent;
CIFGen(CIFTotalDef, use->cu_def, &A, CIFTotalPlanes, CIFGen(CIFTotalDef, use->cu_def, &A, CIFTotalPlanes,
&CIFCurStyle->cs_hierLayers, FALSE, TRUE); &CIFCurStyle->cs_hierLayers, FALSE, TRUE, TRUE,
(ClientData)NULL);
anyInteractions = TRUE; anyInteractions = TRUE;
} }
@ -938,7 +987,8 @@ cifHierArrayFunc(scx, output)
(ClientData) &C); (ClientData) &C);
CIFErrorDef = use->cu_parent; CIFErrorDef = use->cu_parent;
CIFGen(CIFTotalDef, use->cu_def, &C, CIFTotalPlanes, CIFGen(CIFTotalDef, use->cu_def, &C, CIFTotalPlanes,
&CIFCurStyle->cs_hierLayers, FALSE, TRUE); &CIFCurStyle->cs_hierLayers, FALSE, TRUE, TRUE,
(ClientData)NULL);
anyInteractions = TRUE; anyInteractions = TRUE;
} }
@ -955,7 +1005,8 @@ cifHierArrayFunc(scx, output)
(ClientData) &B); (ClientData) &B);
CIFErrorDef = use->cu_parent; CIFErrorDef = use->cu_parent;
CIFGen(CIFTotalDef, use->cu_def, &B, CIFTotalPlanes, CIFGen(CIFTotalDef, use->cu_def, &B, CIFTotalPlanes,
&CIFCurStyle->cs_hierLayers, FALSE, TRUE); &CIFCurStyle->cs_hierLayers, FALSE, TRUE, TRUE,
(ClientData)NULL);
/* D */ /* D */
@ -968,7 +1019,8 @@ cifHierArrayFunc(scx, output)
(ClientData) &D); (ClientData) &D);
CIFErrorDef = use->cu_parent; CIFErrorDef = use->cu_parent;
CIFGen(CIFTotalDef, use->cu_def, &D, CIFTotalPlanes, CIFGen(CIFTotalDef, use->cu_def, &D, CIFTotalPlanes,
&CIFCurStyle->cs_hierLayers, FALSE, TRUE); &CIFCurStyle->cs_hierLayers, FALSE, TRUE, TRUE,
(ClientData)NULL);
} }
if (anyInteractions) if (anyInteractions)

View File

@ -572,7 +572,8 @@ CIFPaintCurrent(filetype)
CIFOp *op; CIFOp *op;
plane = CIFGenLayer(cifCurReadStyle->crs_layers[i]->crl_ops, 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 /* Generate a paint/erase table, then paint from the CIF
* plane into the current Magic cell. * plane into the current Magic cell.

View File

@ -164,7 +164,8 @@ CIFPaintLayer(rootDef, area, cifLayer, magicLayer, paintDef)
cifHierCopyFunc, (ClientData) CIFComponentDef); cifHierCopyFunc, (ClientData) CIFComponentDef);
oldCount = DBWFeedbackCount; oldCount = DBWFeedbackCount;
CIFGen(CIFComponentDef, rootDef, area, CIFPlanes, &depend, TRUE, TRUE); CIFGen(CIFComponentDef, rootDef, area, CIFPlanes, &depend, TRUE, TRUE, FALSE,
(ClientData)NULL);
DBCellClearDef(CIFComponentDef); DBCellClearDef(CIFComponentDef);
/* Report any errors that occurred. */ /* Report any errors that occurred. */
@ -278,7 +279,8 @@ CIFSeeLayer(rootDef, area, layer)
(void) DBTreeSrTiles(&scx, &DBAllButSpaceAndDRCBits, 0, (void) DBTreeSrTiles(&scx, &DBAllButSpaceAndDRCBits, 0,
cifHierCopyFunc, (ClientData) CIFComponentDef); cifHierCopyFunc, (ClientData) CIFComponentDef);
oldCount = DBWFeedbackCount; oldCount = DBWFeedbackCount;
CIFGen(CIFComponentDef, rootDef, area, CIFPlanes, &depend, TRUE, TRUE); CIFGen(CIFComponentDef, rootDef, area, CIFPlanes, &depend, TRUE, TRUE,
FALSE, (ClientData)NULL);
DBCellClearDef(CIFComponentDef); DBCellClearDef(CIFComponentDef);
/* Report any errors that occurred. */ /* Report any errors that occurred. */
@ -441,7 +443,8 @@ CIFCoverageLayer(rootDef, area, layer)
scx.scx_trans = GeoIdentityTransform; scx.scx_trans = GeoIdentityTransform;
(void) DBTreeSrTiles(&scx, &DBAllButSpaceAndDRCBits, 0, (void) DBTreeSrTiles(&scx, &DBAllButSpaceAndDRCBits, 0,
cifHierCopyFunc, (ClientData) CIFComponentDef); cifHierCopyFunc, (ClientData) CIFComponentDef);
CIFGen(CIFComponentDef, rootDef, area, CIFPlanes, &depend, TRUE, TRUE); CIFGen(CIFComponentDef, rootDef, area, CIFPlanes, &depend, TRUE, TRUE,
FALSE, (ClientData)NULL);
DBCellClearDef(CIFComponentDef); DBCellClearDef(CIFComponentDef);
cstats.coverage = 0; cstats.coverage = 0;

View File

@ -1537,6 +1537,12 @@ cifComputeRadii(layer, des)
for (op = layer->cl_ops; op != NULL; op = op->co_next) 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 /* If CIF layers are used, switch to the max of current
* distances and those of the layers used. * distances and those of the layers used.
*/ */
@ -1597,6 +1603,7 @@ cifComputeRadii(layer, des)
case CIFOP_BRIDGELIM: break; case CIFOP_BRIDGELIM: break;
case CIFOP_SQUARES: break; case CIFOP_SQUARES: break;
case CIFOP_SQUARES_G: break; case CIFOP_SQUARES_G: break;
} }
} }

View File

@ -378,7 +378,8 @@ cifOutFunc(def, f)
GEO_EXPAND(&def->cd_bbox, CIFCurStyle->cs_radius, &bigArea); GEO_EXPAND(&def->cd_bbox, CIFCurStyle->cs_radius, &bigArea);
CIFErrorDef = def; CIFErrorDef = def;
CIFGen(def, def, &bigArea, CIFPlanes, &DBAllTypeBits, TRUE, TRUE); CIFGen(def, def, &bigArea, CIFPlanes, &DBAllTypeBits, TRUE, TRUE, FALSE,
(ClientData)NULL);
if (!CIFHierWriteDisable) if (!CIFHierWriteDisable)
CIFGenSubcells(def, &bigArea, CIFPlanes); CIFGenSubcells(def, &bigArea, CIFPlanes);
if (!CIFArrayWriteDisable) if (!CIFArrayWriteDisable)

View File

@ -50,14 +50,6 @@ static DRCCookie drcArrayCookie = {
(DRCCookie *) NULL (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 int
drcArrayFunc(scx, area) drcArrayFunc(scx, arg)
SearchContext *scx; /* Information about the search. */ SearchContext *scx; /* Information about the search. */
Rect *area; /* Area in which errors are to be struct drcClientData *arg; /* Information used in overlap */
* regenerated.
*/
{ {
int xsep, ysep; int xsep, ysep;
int xsize, ysize; int xsize, ysize;
int rval, oldTiles;
Rect errorArea, yankArea, tmp, tmp2; Rect errorArea, yankArea, tmp, tmp2;
DRCCookie *save_cptr;
CellUse *use = scx->scx_use; 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)) if ((use->cu_xlo == use->cu_xhi) && (use->cu_ylo == use->cu_yhi))
return 2; 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 /* Set up the client data that will be passed down during
* checks for exact overlaps. * checks for exact overlaps.
*/ */
arg.dCD_celldef = DRCdef; save_cptr = arg->dCD_cptr;
arg.dCD_errors = &drcArrayCount; arg->dCD_cptr = &drcArrayCookie;
arg.dCD_clip = &errorArea; area = arg->dCD_clip;
arg.dCD_cptr = &drcArrayCookie; drcArrayCount = *arg->dCD_errors;
arg.dCD_function = drcArrayErrorFunc; drcArrayErrorFunc = arg->dCD_function;
arg.dCD_clientData = drcArrayClientData; drcArrayClientData = arg->dCD_clientData;
/* Compute the sizes and separations of elements, in coordinates /* Compute the sizes and separations of elements, in coordinates
* of the parend. If the array is 1-dimensional, we set the * of the parend. If the array is 1-dimensional, we set the
@ -178,7 +184,7 @@ drcArrayFunc(scx, area)
drcArrayCount += DRCBasicCheck(DRCdef, &yankArea, &errorArea, drcArrayCount += DRCBasicCheck(DRCdef, &yankArea, &errorArea,
drcArrayErrorFunc, drcArrayClientData); drcArrayErrorFunc, drcArrayClientData);
(void) DBArraySr(use, &errorArea, drcArrayOverlapFunc, (void) DBArraySr(use, &errorArea, drcArrayOverlapFunc,
(ClientData) &arg); (ClientData) arg);
} }
/* C */ /* C */
@ -195,7 +201,7 @@ drcArrayFunc(scx, area)
drcArrayCount += DRCBasicCheck(DRCdef, &yankArea, &errorArea, drcArrayCount += DRCBasicCheck(DRCdef, &yankArea, &errorArea,
drcArrayErrorFunc, drcArrayClientData); drcArrayErrorFunc, drcArrayClientData);
(void) DBArraySr(use, &errorArea, drcArrayOverlapFunc, (void) DBArraySr(use, &errorArea, drcArrayOverlapFunc,
(ClientData) &arg); (ClientData) arg);
} }
} }
@ -217,7 +223,7 @@ drcArrayFunc(scx, area)
drcArrayCount += DRCBasicCheck(DRCdef, &yankArea, &errorArea, drcArrayCount += DRCBasicCheck(DRCdef, &yankArea, &errorArea,
drcArrayErrorFunc, drcArrayClientData); drcArrayErrorFunc, drcArrayClientData);
(void) DBArraySr(use, &errorArea, drcArrayOverlapFunc, (void) DBArraySr(use, &errorArea, drcArrayOverlapFunc,
(ClientData) &arg); (ClientData) arg);
} }
/* D */ /* D */
@ -234,80 +240,20 @@ drcArrayFunc(scx, area)
drcArrayCount += DRCBasicCheck(DRCdef, &yankArea, &errorArea, drcArrayCount += DRCBasicCheck(DRCdef, &yankArea, &errorArea,
drcArrayErrorFunc, drcArrayClientData); drcArrayErrorFunc, drcArrayClientData);
(void) DBArraySr(use, &errorArea, drcArrayOverlapFunc, (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) DBNewPaintTable(savedPaintTable);
(void) DBNewPaintPlane(savedPaintPlane); (void) DBNewPaintPlane(savedPaintPlane);
/* Update count of array tiles processed. */ /* Update count of array tiles processed. */
DRCstatArrayTiles += DRCstatTiles - oldTiles; DRCstatArrayTiles += DRCstatTiles - oldTiles;
return drcArrayCount;
}
/* Restore original DRC cookie pointer in the argument */
arg->dCD_cptr = save_cptr;
return 2;
}
/* /*
* ---------------------------------------------------------------------------- * ----------------------------------------------------------------------------

View File

@ -552,7 +552,7 @@ drcCifCheck(arg)
oldTiles = DRCstatTiles; oldTiles = DRCstatTiles;
CIFGen(arg->dCD_celldef, arg->dCD_celldef, checkRect, CIFPlanes, 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++) for (i = 0; i < drcCifStyle->cs_nLayers; i++)
{ {

View File

@ -696,8 +696,6 @@ drcCheckTile(tile, arg)
(void) DBSrPaintArea((Tile *) NULL, celldef->cd_planes[PL_DRC_ERROR], (void) DBSrPaintArea((Tile *) NULL, celldef->cd_planes[PL_DRC_ERROR],
&square, &DBAllButSpaceBits, drcXorFunc, (ClientData) NULL); &square, &DBAllButSpaceBits, drcXorFunc, (ClientData) NULL);
/* Check #1: recheck the paint of the cell, ignoring subcells. */
DRCErrorType = TT_ERROR_P; DRCErrorType = TT_ERROR_P;
DBClearPaintPlane(drcTempPlane); DBClearPaintPlane(drcTempPlane);
@ -707,10 +705,7 @@ drcCheckTile(tile, arg)
* computed within DRCInteractionCheck()). * computed within DRCInteractionCheck()).
*/ */
/* DRCBasicCheck (celldef, &checkbox, &erasebox, drcPaintError, /* Check interactions between paint and subcells, and
(ClientData) drcTempPlane); */
/* Check #2: check interactions between paint and subcells, and
* also between subcells and other subcells. If any part of a * also between subcells and other subcells. If any part of a
* square is rechecked for interactions, the whole thing has to * square is rechecked for interactions, the whole thing has to
* be rechecked. We use TT_ERROR_S tiles for this so that we * 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, (void) DRCInteractionCheck(celldef, &square, &erasebox,
drcPaintError, (ClientData)drcTempPlane); 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 /* If there was an interrupt, return without modifying the cell
* at all. * at all.
*/ */

View File

@ -616,12 +616,6 @@ drcWhyFunc(scx, cdarg)
(void) DRCInteractionCheck(def, &scx->scx_area, &scx->scx_area, (void) DRCInteractionCheck(def, &scx->scx_area, &scx->scx_area,
(dolist) ? drcListError : drcPrintError, (ClientData) scx); (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; return 0;
} }
@ -637,13 +631,7 @@ drcWhyAllFunc(scx, cdarg)
/* Check paint and interactions in this subcell. */ /* Check paint and interactions in this subcell. */
(void) DRCInteractionCheck(def, &scx->scx_area, &scx->scx_area, (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);
/* New behavior: Don't search children, instead propagate errors up. */
/* (void) DBCellSrArea(scx, drcWhyAllFunc, (ClientData)cdarg); */
return 0; return 0;
} }

View File

@ -157,6 +157,9 @@ drcSubCopyErrors(tile, cxp)
* be a real error, and not one that might be resolved by additional * be a real error, and not one that might be resolved by additional
* material found in the parent or a sibling cell. * 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: * Returns:
* Whatever DBNoTreeSrTiles() returns. * Whatever DBNoTreeSrTiles() returns.
* *
@ -708,7 +711,9 @@ DRCInteractionCheck(def, area, erasebox, func, cdarg)
/* Copy errors up from all non-interacting children */ /* Copy errors up from all non-interacting children */
scx.scx_area = subArea; scx.scx_area = subArea;
arg.dCD_clip = &subArea;
DBCellSrArea(&scx, drcSubCopyFunc, &arg); DBCellSrArea(&scx, drcSubCopyFunc, &arg);
DBCellSrArea(&scx, drcArrayFunc, &arg);
DRCErrorType = errorSaveType; DRCErrorType = errorSaveType;
continue; continue;
@ -735,6 +740,7 @@ DRCInteractionCheck(def, area, erasebox, func, cdarg)
eraseClip = *erasebox; eraseClip = *erasebox;
GeoClip(&eraseClip, &cliparea); GeoClip(&eraseClip, &cliparea);
subArea = eraseClip; subArea = eraseClip;
arg.dCD_clip = &subArea;
/* check above */ /* check above */
if (intArea.r_ytop < eraseClip.r_ytop) 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 */ /* Copy errors up from all non-interacting children */
scx.scx_area = subArea; scx.scx_area = subArea;
DBCellSrArea(&scx, drcSubCopyFunc, &arg); DBCellSrArea(&scx, drcSubCopyFunc, &arg);
DBCellSrArea(&scx, drcArrayFunc, &arg);
} }
/* check below */ /* check below */
if (intArea.r_ybot > eraseClip.r_ybot) 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 */ /* Copy errors up from all non-interacting children */
scx.scx_area = subArea; scx.scx_area = subArea;
DBCellSrArea(&scx, drcSubCopyFunc, &arg); DBCellSrArea(&scx, drcSubCopyFunc, &arg);
DBCellSrArea(&scx, drcArrayFunc, &arg);
} }
subArea.r_ytop = intArea.r_ytop; subArea.r_ytop = intArea.r_ytop;
subArea.r_ybot = intArea.r_ybot; subArea.r_ybot = intArea.r_ybot;
@ -769,6 +777,7 @@ DRCInteractionCheck(def, area, erasebox, func, cdarg)
/* Copy errors up from all non-interacting children */ /* Copy errors up from all non-interacting children */
scx.scx_area = subArea; scx.scx_area = subArea;
DBCellSrArea(&scx, drcSubCopyFunc, &arg); DBCellSrArea(&scx, drcSubCopyFunc, &arg);
DBCellSrArea(&scx, drcArrayFunc, &arg);
} }
/* check left */ /* check left */
if (intArea.r_xbot > eraseClip.r_xbot) 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 */ /* Copy errors up from all non-interacting children */
scx.scx_area = subArea; scx.scx_area = subArea;
DBCellSrArea(&scx, drcSubCopyFunc, &arg); DBCellSrArea(&scx, drcSubCopyFunc, &arg);
DBCellSrArea(&scx, drcArrayFunc, &arg);
} }
DRCErrorType = errorSaveType; DRCErrorType = errorSaveType;
} }

View File

@ -246,6 +246,9 @@ extern int DRCGetDefaultLayerSpacing();
extern int DRCGetDefaultWideLayerSpacing(); extern int DRCGetDefaultWideLayerSpacing();
extern int DRCGetDefaultLayerSurround(); extern int DRCGetDefaultLayerSurround();
extern int DRCInteractionCheck();
extern int drcArrayFunc();
extern void DRCTechInit(); extern void DRCTechInit();
extern bool DRCTechLine(); extern bool DRCTechLine();
extern bool DRCTechAddRule(); extern bool DRCTechAddRule();

View File

@ -1739,7 +1739,8 @@ W3DCIFredisplay(w, rootArea, clipArea)
scx.scx_trans = GeoIdentityTransform; scx.scx_trans = GeoIdentityTransform;
(void) DBTreeSrTiles(&scx, &DBAllButSpaceAndDRCBits, 0, (void) DBTreeSrTiles(&scx, &DBAllButSpaceAndDRCBits, 0,
cifHierCopyFunc, (ClientData) CIFComponentDef); cifHierCopyFunc, (ClientData) CIFComponentDef);
CIFGen(CIFComponentDef, cellDef, &clipRect, CIFPlanes, &DBAllTypeBits, TRUE, TRUE); CIFGen(CIFComponentDef, cellDef, &clipRect, CIFPlanes, &DBAllTypeBits, TRUE,
TRUE, FALSE, (ClientData)NULL);
DBCellClearDef(CIFComponentDef); DBCellClearDef(CIFComponentDef);
w3dClear(); w3dClear();

View File

@ -124,6 +124,12 @@ proc readspice {netfile} {
set p $p1 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] { foreach pin [lrange $ftokens 2 end] {
# If "=" is in the name, then we have finished the pins # If "=" is in the name, then we have finished the pins
# and are looking at parameters, and so parsing is done. # 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 # port name. If so, convert it into a port
if {$pinidx == ""} { if {$pinidx == ""} {
select top cell
select area labels
set all [lindex [what -list] 1]
select clear
foreach labrec $all { foreach labrec $all {
set testpin [lindex $labrec 0] set testpin [lindex $labrec 0]
if {[string tolower $testpin] == [string tolower $pin]} { if {[string tolower $testpin] == [string tolower $pin]} {
goto $testpin goto $testpin
set pinidx -1 set pinidx -1
port make $n port $testpin make $n
break break
} }
} }
@ -199,7 +201,7 @@ proc readspice {netfile} {
} else { } else {
set layer [goto $pin] set layer [goto $pin]
if {$layer != ""} { if {$layer != ""} {
port make $n port $pin make $n
incr n incr n
set changed true set changed true
} }