Added a new cifinput operator "not-square" that is useful for
differentiating between bar and square contacts on input. Also: added handling of the "mask-hints" operator for GDS input as well as GDS output. This is a bit more realistic now that the mask hint properties are handled as scalable integers and not as character strings.
This commit is contained in:
parent
8f684ad5be
commit
cb7855235a
122
cif/CIFgen.c
122
cif/CIFgen.c
|
|
@ -4458,14 +4458,16 @@ bridgeErase(
|
|||
maskBits = DBPlaneTypes[i];
|
||||
TTMaskAndMask(&maskBits, &brlims->co_paintMask);
|
||||
if (!TTMaskEqual(&maskBits, &DBZeroTypeBits))
|
||||
if (DBSrPaintArea((Tile *) NULL, brlims->def->cd_planes[i], area, &brlims->co_paintMask, cifPaintFunc, CIFEraseTable))
|
||||
if (DBSrPaintArea((Tile *) NULL, brlims->def->cd_planes[i],
|
||||
area, &brlims->co_paintMask, cifPaintFunc, CIFEraseTable))
|
||||
return 0;
|
||||
}
|
||||
|
||||
for (t = 0; t < TT_MAXTYPES; t++, temps++)
|
||||
{
|
||||
if (TTMaskHasType(&brlims->co_cifMask, t))
|
||||
if (DBSrPaintArea((Tile *) NULL, *temps, area, &CIFSolidBits, cifPaintFunc, CIFEraseTable))
|
||||
if (DBSrPaintArea((Tile *) NULL, *temps, area, &CIFSolidBits,
|
||||
cifPaintFunc, CIFEraseTable))
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
@ -4766,6 +4768,106 @@ cifBridgeLimFunc2(
|
|||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* ----------------------------------------------------------------------------
|
||||
*
|
||||
* cifNotSquareFunc --
|
||||
*
|
||||
* Process each tile and remove those which are square and not
|
||||
* connected to any other tile of the same type. This operator aids
|
||||
* in the detection of bar contacts to distinguish them from regular
|
||||
* (square) contact cuts. Because of the special nature of the
|
||||
* operator, only the negative-sense operator "not-square" is
|
||||
* implemented, as the positive-sense operator is not especially
|
||||
* useful (and can be implemented if needed with "not-square" and
|
||||
* "and-not").
|
||||
*
|
||||
* Results:
|
||||
* None.
|
||||
*
|
||||
* Side effects:
|
||||
* Modifies the CIF planes.
|
||||
*
|
||||
* ----------------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
int
|
||||
cifNotSquareFunc(
|
||||
Tile *tile,
|
||||
TileType dinfo,
|
||||
ClientData clientData) /* (unused) */
|
||||
{
|
||||
Tile *tp;
|
||||
TileType ttype;
|
||||
Rect area;
|
||||
int width, height;
|
||||
bool isolated = TRUE;
|
||||
|
||||
if (IsSplit(tile)) return 0; /* Non-Manhattan tiles are never square */
|
||||
ttype = TiGetType(tile);
|
||||
if (ttype == TT_SPACE) return 0; /* Don't handle space tiles */
|
||||
|
||||
/* Search all four sides of the tile. Tiles are only considered square
|
||||
* for the purposes of this operator if they are also unconnected to any
|
||||
* other tile.
|
||||
*/
|
||||
|
||||
/* Top */
|
||||
for (tp = RT(tile); RIGHT(tp) > LEFT(tile); tp = BL(tp))
|
||||
if (TiGetBottomType(tp) == ttype)
|
||||
{
|
||||
isolated = FALSE;
|
||||
break;
|
||||
}
|
||||
|
||||
/* Left */
|
||||
if (isolated)
|
||||
for (tp = BL(tile); BOTTOM(tp) < TOP(tile); tp = RT(tp))
|
||||
if (TiGetBottomType(tp) == ttype)
|
||||
{
|
||||
isolated = FALSE;
|
||||
break;
|
||||
}
|
||||
|
||||
/* Bottom */
|
||||
if (isolated)
|
||||
for (tp = LB(tile); LEFT(tp) < RIGHT(tile); tp = TR(tp))
|
||||
if (TiGetBottomType(tp) == ttype)
|
||||
{
|
||||
isolated = FALSE;
|
||||
break;
|
||||
}
|
||||
|
||||
/* Right */
|
||||
if (isolated)
|
||||
for (tp = TR(tile); TOP(tp) > BOTTOM(tile); tp = LB(tp))
|
||||
if (TiGetBottomType(tp) == ttype)
|
||||
{
|
||||
isolated = FALSE;
|
||||
break;
|
||||
}
|
||||
|
||||
TiToRect(tile, &area);
|
||||
|
||||
if (isolated)
|
||||
{
|
||||
width = area.r_xtop - area.r_xbot;
|
||||
height = area.r_ytop - area.r_ybot;
|
||||
if (width == height) return 0; /* Square and isolated */
|
||||
}
|
||||
|
||||
area.r_xbot *= cifScale;
|
||||
area.r_ybot *= cifScale;
|
||||
area.r_xtop *= cifScale;
|
||||
area.r_ytop *= cifScale;
|
||||
|
||||
DBPaintPlane(cifPlane, &area, CIFPaintTable, (PaintUndoInfo *)NULL);
|
||||
|
||||
CIFTileOps += 1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* ----------------------------------------------------------------------------
|
||||
*
|
||||
|
|
@ -4779,6 +4881,7 @@ cifBridgeLimFunc2(
|
|||
* None.
|
||||
*
|
||||
* Side effects:
|
||||
* Modifies the CIF planes.
|
||||
*
|
||||
* ----------------------------------------------------------------------------
|
||||
*/
|
||||
|
|
@ -5396,7 +5499,6 @@ CIFGenLayer(
|
|||
nextPlane = temp;
|
||||
break;
|
||||
|
||||
|
||||
case CIFOP_MAXRECT:
|
||||
cifPlane = curPlane;
|
||||
|
||||
|
|
@ -5419,6 +5521,19 @@ CIFGenLayer(
|
|||
nextPlane = temp;
|
||||
break;
|
||||
|
||||
case CIFOP_NOTSQUARE:
|
||||
DBClearPaintPlane(nextPlane);
|
||||
cifPlane = nextPlane;
|
||||
cifScale = 1;
|
||||
DBSrPaintArea((Tile *) NULL, curPlane, &TiPlaneRect,
|
||||
&CIFSolidBits, cifNotSquareFunc,
|
||||
(ClientData)NULL);
|
||||
|
||||
temp = curPlane;
|
||||
curPlane = nextPlane;
|
||||
nextPlane = temp;
|
||||
break;
|
||||
|
||||
case CIFOP_NET:
|
||||
if (hier)
|
||||
{
|
||||
|
|
@ -5533,6 +5648,7 @@ CIFGenLayer(
|
|||
|
||||
snprintf(propname, 512, "MASKHINTS_%s", layername);
|
||||
|
||||
if (cellDef == (CellDef *)NULL) break;
|
||||
proprec = DBPropGet(cellDef, propname, &found);
|
||||
if (!found) break; /* No mask hints available */
|
||||
|
||||
|
|
|
|||
|
|
@ -145,6 +145,7 @@ typedef struct cifop
|
|||
* CIFOP_BRIDGE - Added 6/11/20---Bridge across catecorner gaps
|
||||
* CIFOP_BRIDGELIM - Added 27/07/20---Bridge across catecorner gaps, but with limiting layers
|
||||
* CIFOP_MASKHINTS - Added 12/14/20---Add geometry from cell properties, if any.
|
||||
* CIFOP_NOTSQUARE - Added 2/26/26---Keep only geometry which is not square.
|
||||
*/
|
||||
|
||||
#define CIFOP_AND 1
|
||||
|
|
@ -172,6 +173,7 @@ typedef struct cifop
|
|||
#define CIFOP_BRIDGE 23
|
||||
#define CIFOP_BRIDGELIM 24
|
||||
#define CIFOP_MASKHINTS 25
|
||||
#define CIFOP_NOTSQUARE 26
|
||||
|
||||
/* Definitions of bit fields used in the value of co_client for CIFOP_INTERACT */
|
||||
#define CIFOP_INT_NOT 0x1 /* Inverted sense (not interacting) */
|
||||
|
|
|
|||
113
cif/CIFrdcl.c
113
cif/CIFrdcl.c
|
|
@ -688,6 +688,8 @@ CIFPaintCurrent(
|
|||
}
|
||||
else if (op == NULL)
|
||||
{
|
||||
LinkedRect *lrec = NULL, *lsrch;
|
||||
|
||||
/* Handle boundary layer */
|
||||
|
||||
op = cifCurReadStyle->crs_layers[i]->crl_ops;
|
||||
|
|
@ -702,6 +704,115 @@ CIFPaintCurrent(
|
|||
(ClientData)NULL) == 1))
|
||||
DBSrPaintArea((Tile *) NULL, plane, &TiPlaneRect,
|
||||
&CIFSolidBits, cifMakeBoundaryFunc, INT2CD(filetype));
|
||||
|
||||
/* Handle mask-hints input operator */
|
||||
|
||||
op = cifCurReadStyle->crs_layers[i]->crl_ops;
|
||||
while (op)
|
||||
{
|
||||
if (op->co_opcode == CIFOP_MASKHINTS) break;
|
||||
op = op->co_next;
|
||||
}
|
||||
|
||||
if (op && (DBSrPaintArea((Tile *)NULL, plane, &TiPlaneRect,
|
||||
&DBAllButSpaceBits, cifCheckPaintFunc,
|
||||
(ClientData)NULL) == 1))
|
||||
{
|
||||
DBSrPaintArea((Tile *) NULL, plane, &TiPlaneRect,
|
||||
&CIFSolidBits, cifMaskHintFunc,
|
||||
(ClientData)&lrec);
|
||||
|
||||
if (lrec != NULL)
|
||||
{
|
||||
PropertyRecord *proprec, *proporig;
|
||||
char *propname, *layername;
|
||||
int proplen, i, savescale;
|
||||
bool origfound = FALSE;
|
||||
|
||||
layername = (char *)op->co_client;
|
||||
propname = (char *)mallocMagic(11 + strlen(layername));
|
||||
sprintf(propname, "MASKHINTS_%s", layername);
|
||||
|
||||
/* Turn all linked Rects into a mask-hints property in the
|
||||
* target cell.
|
||||
*/
|
||||
proplen = 0;
|
||||
for (lsrch = lrec; lsrch; lsrch = lsrch->r_next)
|
||||
proplen += 4;
|
||||
|
||||
/* If there is already a mask hint for this layer, then
|
||||
* prepend to its data.
|
||||
*/
|
||||
proporig = DBPropGet(cifReadCellDef, layername, &origfound);
|
||||
if (origfound) proplen += proporig->prop_len;
|
||||
|
||||
proprec = (PropertyRecord *)mallocMagic(sizeof(PropertyRecord) *
|
||||
(proplen - 2) * sizeof(int));
|
||||
proprec->prop_type = PROPERTY_TYPE_DIMENSION;
|
||||
proprec->prop_len = proplen;
|
||||
|
||||
proplen = 0;
|
||||
while (lrec != NULL)
|
||||
{
|
||||
lrec->r_r.r_xtop =
|
||||
CIFScaleCoord(lrec->r_r.r_xtop, COORD_EXACT);
|
||||
savescale = cifCurReadStyle->crs_scaleFactor;
|
||||
lrec->r_r.r_ytop =
|
||||
CIFScaleCoord(lrec->r_r.r_ytop, COORD_EXACT);
|
||||
if (savescale != cifCurReadStyle->crs_scaleFactor)
|
||||
{
|
||||
lrec->r_r.r_xtop *=
|
||||
(savescale / cifCurReadStyle->crs_scaleFactor);
|
||||
savescale = cifCurReadStyle->crs_scaleFactor;
|
||||
}
|
||||
lrec->r_r.r_xbot =
|
||||
CIFScaleCoord(lrec->r_r.r_xbot, COORD_EXACT);
|
||||
if (savescale != cifCurReadStyle->crs_scaleFactor)
|
||||
{
|
||||
lrec->r_r.r_xtop *=
|
||||
(savescale / cifCurReadStyle->crs_scaleFactor);
|
||||
lrec->r_r.r_ytop *=
|
||||
(savescale / cifCurReadStyle->crs_scaleFactor);
|
||||
savescale = cifCurReadStyle->crs_scaleFactor;
|
||||
}
|
||||
lrec->r_r.r_ybot =
|
||||
CIFScaleCoord(lrec->r_r.r_ybot, COORD_EXACT);
|
||||
if (savescale != cifCurReadStyle->crs_scaleFactor)
|
||||
{
|
||||
lrec->r_r.r_xtop *=
|
||||
(savescale / cifCurReadStyle->crs_scaleFactor);
|
||||
lrec->r_r.r_ytop *=
|
||||
(savescale / cifCurReadStyle->crs_scaleFactor);
|
||||
lrec->r_r.r_xbot *=
|
||||
(savescale / cifCurReadStyle->crs_scaleFactor);
|
||||
}
|
||||
|
||||
proprec->prop_value.prop_integer[proplen] =
|
||||
lrec->r_r.r_xbot;
|
||||
proprec->prop_value.prop_integer[proplen + 1] =
|
||||
lrec->r_r.r_ybot;
|
||||
proprec->prop_value.prop_integer[proplen + 2] =
|
||||
lrec->r_r.r_xtop;
|
||||
proprec->prop_value.prop_integer[proplen + 3] =
|
||||
lrec->r_r.r_ytop;
|
||||
|
||||
free_magic1_t mm1 = freeMagic1_init();
|
||||
freeMagic1(&mm1, lrec);
|
||||
lrec = lrec->r_next;
|
||||
freeMagic1_end(&mm1);
|
||||
|
||||
proplen += 4;
|
||||
}
|
||||
|
||||
if (origfound)
|
||||
for (i = 0; i < proporig->prop_len; i++)
|
||||
proprec->prop_value.prop_integer[proplen++] =
|
||||
proporig->prop_value.prop_integer[i];
|
||||
|
||||
DBPropPut(cifReadCellDef, propname, proprec);
|
||||
freeMagic(propname);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* Swap planes */
|
||||
|
|
@ -791,8 +902,6 @@ CIFPaintCurrent(
|
|||
for (i = 0; i < cifNReadLayers; i++)
|
||||
{
|
||||
LinkedRect *lrec = NULL, *lsrch;
|
||||
char *propstr = NULL;
|
||||
char locstr[512];
|
||||
Plane *tempp;
|
||||
|
||||
if (!TTMaskHasType(CalmaMaskHints, i)) continue;
|
||||
|
|
|
|||
|
|
@ -324,14 +324,18 @@ cifNewReadStyle(void)
|
|||
{
|
||||
/* Destroy old style and free all memory allocated to it */
|
||||
|
||||
for (i=0; i<MAXCIFRLAYERS; i+=1)
|
||||
for (i = 0; i < MAXCIFRLAYERS; i++)
|
||||
{
|
||||
layer = cifCurReadStyle->crs_layers[i];
|
||||
if (layer != NULL)
|
||||
{
|
||||
free_magic1_t mm1 = freeMagic1_init();
|
||||
for (op = layer->crl_ops; op != NULL; op = op->co_next)
|
||||
{
|
||||
if (op->co_opcode == CIFOP_MASKHINTS)
|
||||
freeMagic((char *)op->co_client);
|
||||
freeMagic1(&mm1, (char *)op);
|
||||
}
|
||||
freeMagic1_end(&mm1);
|
||||
freeMagic((char *)layer);
|
||||
}
|
||||
|
|
@ -990,6 +994,10 @@ CIFReadTechLine(
|
|||
newOp->co_opcode = CIFOP_COPYUP;
|
||||
else if (strcmp(argv[0], "boundary") == 0)
|
||||
newOp->co_opcode = CIFOP_BOUNDARY;
|
||||
else if (strcmp(argv[0], "not-square") == 0)
|
||||
newOp->co_opcode = CIFOP_NOTSQUARE;
|
||||
else if (strcmp(argv[0], "mask-hints") == 0)
|
||||
newOp->co_opcode = CIFOP_MASKHINTS;
|
||||
else
|
||||
{
|
||||
TechError("Unknown statement \"%s\".\n", argv[0]);
|
||||
|
|
@ -1016,6 +1024,10 @@ CIFReadTechLine(
|
|||
goto errorReturn;
|
||||
}
|
||||
break;
|
||||
case CIFOP_MASKHINTS:
|
||||
if (argc != 2) goto wrongNumArgs;
|
||||
newOp->co_client = (ClientData)StrDup((char **)NULL, argv[1]);
|
||||
break;
|
||||
}
|
||||
|
||||
/* Link the new CIFOp onto the list. */
|
||||
|
|
@ -1099,6 +1111,7 @@ CIFReadTechFinal(void)
|
|||
*
|
||||
* ----------------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
void
|
||||
CIFReadLoadStyle(
|
||||
char *stylename)
|
||||
|
|
|
|||
|
|
@ -1117,6 +1117,8 @@ CIFTechLine(
|
|||
newOp->co_opcode = CIFOP_CLOSE;
|
||||
else if (strcmp(argv[0], "orthogonal") == 0)
|
||||
newOp->co_opcode = CIFOP_MANHATTAN;
|
||||
else if (strcmp(argv[0], "not-square") == 0)
|
||||
newOp->co_opcode = CIFOP_NOTSQUARE;
|
||||
else if (strcmp(argv[0], "bridge") == 0)
|
||||
newOp->co_opcode = CIFOP_BRIDGE;
|
||||
else if (strcmp(argv[0], "bridge-lim") == 0)
|
||||
|
|
|
|||
Loading…
Reference in New Issue