Merge branch 'master' of https://github.com/RTimothyEdwards/magic into spice_hier
This commit is contained in:
commit
60da2963b1
|
|
@ -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)
|
||||
|
|
|
|||
84
cif/CIFgen.c
84
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,
|
||||
|
|
|
|||
|
|
@ -27,6 +27,7 @@ static char rcsid[] __attribute__ ((unused)) = "$Header: /usr/cvsroot/magic-8.0/
|
|||
|
||||
#include <stdio.h>
|
||||
|
||||
#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)
|
||||
|
|
|
|||
|
|
@ -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.
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
|
|
|
|||
120
drc/DRCarray.c
120
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;
|
||||
}
|
||||
|
||||
/*
|
||||
* ----------------------------------------------------------------------------
|
||||
|
|
|
|||
|
|
@ -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++)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -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.
|
||||
*/
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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();
|
||||
|
|
|
|||
|
|
@ -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();
|
||||
|
|
|
|||
|
|
@ -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
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in New Issue