Enhancements to cifinput and cifoutput in the tech file: Added

option "labels ... cellid" to handle some vendor files where
apparently to get around the 30-character cell name limit, the
actual cellname is encoded on a text layer.  Added new cifop
"boundary" (no arguments) for cases where a cell abutment box
is encoded on a GDS layer;  this now translates the bounding
box to the FIXED_BBOX property, as is done with the LEF bounding
box.  Also corrected the property set function to free existing
property value allocated memory when overwriting a property with
a new value.
This commit is contained in:
Tim Edwards 2019-06-05 15:03:51 -04:00
parent 8f7db3942c
commit bbf6008363
11 changed files with 117 additions and 25 deletions

View File

@ -57,8 +57,6 @@ extern HashTable calmaDefInitHash;
extern void calmaLayerError();
bool calmaReadPath();
typedef enum { LABEL_TYPE_NONE, LABEL_TYPE_TEXT, LABEL_TYPE_PORT } labelType;
/*
* ----------------------------------------------------------------------------
*
@ -274,7 +272,6 @@ calmaElementBoundary()
}
}
CIFPropRecordPath(cifReadCellDef, pathheadp, FALSE);
rp = CIFPolyToRects(pathheadp, plane, CIFPaintTable, (PaintUndoInfo *)NULL);
CIFFreePath(pathheadp);
@ -300,7 +297,7 @@ calmaElementBoundary()
rpc.r_ytop /= calmaReadScale1;
if ((ciftype >= 0) &&
((cifCurReadStyle->crs_labelSticky[ciftype] != LABEL_TYPE_NONE)))
(cifCurReadStyle->crs_labelSticky[ciftype] != LABEL_TYPE_NONE))
{
Label *lab;
TileType type;
@ -652,7 +649,7 @@ calmaElementPath()
}
}
CIFPropRecordPath(cifReadCellDef, pathheadp, TRUE);
CIFPropRecordPath(cifReadCellDef, pathheadp, TRUE, "path");
CIFPaintWirePath(pathheadp, width,
(pathtype == CALMAPATH_SQUAREFLUSH || pathtype == CALMAPATH_CUSTOM) ?
FALSE : TRUE, plane, CIFPaintTable, (PaintUndoInfo *)NULL);
@ -889,6 +886,12 @@ calmaElementText()
r.r_ll.p_x * cifCurReadStyle->crs_scaleFactor,
r.r_ll.p_y * cifCurReadStyle->crs_scaleFactor);
}
else if (cifCurReadStyle->crs_labelSticky[cifnum] == LABEL_TYPE_CELLID)
{
/* Special handling of label layers marked "cellid" in the techfile. */
/* The actual cellname is the ID string, not the GDS structure name. */
DBCellRenameDef(cifReadCellDef, textbody);
}
else if (type < 0)
{
calmaReadError("Warning: label \"%s\" at (%d, %d) is on unhandled"

View File

@ -130,6 +130,9 @@ typedef struct
/* Length of record header */
#define CALMAHEADERLENGTH 4
/* Label types */
typedef enum { LABEL_TYPE_NONE, LABEL_TYPE_TEXT, LABEL_TYPE_PORT, LABEL_TYPE_CELLID } labelType;
/* ------------------------- Input macros ----------------------------- */
/* Globals for Calma reading */

View File

@ -3036,6 +3036,29 @@ CIFGenLayer(op, area, cellDef, temps, clientdata)
}
break;
case CIFOP_BOUNDARY:
cifPlane = curPlane;
/* This function for cifoutput only. cifinput handled separately. */
if (cellDef && (cellDef->cd_flags & CDFIXEDBBOX))
{
char *propvalue;
bool found;
propvalue = (char *)DBPropGet(cellDef, "FIXED_BBOX", &found);
if (!found) break;
if (sscanf(propvalue, "%d %d %d %d", &bbox.r_xbot, &bbox.r_ybot,
&bbox.r_xtop, &bbox.r_ytop) != 4) break;
cifScale = (CIFCurStyle) ? CIFCurStyle->cs_scaleFactor : 1;
bbox.r_xbot *= cifScale;
bbox.r_xtop *= cifScale;
bbox.r_ybot *= cifScale;
bbox.r_ytop *= cifScale;
DBNMPaintPlane(cifPlane, CIF_SOLIDTYPE, &bbox,
CIFPaintTable, (PaintUndoInfo *)NULL);
}
break;
case CIFOP_BBOX:
if (CIFErrorDef == NULL) break;
@ -3149,6 +3172,7 @@ CIFGen(cellDef, area, planes, layers, replace, genAllPlanes, clientdata)
CIFErrorLayer = i;
new[i] = CIFGenLayer(CIFCurStyle->cs_layers[i]->cl_ops,
&expanded, cellDef, new, clientdata);
/* Clean up the non-manhattan geometry in the plane */
if (CIFUnfracture) DBMergeNMTiles(new[i], &expanded,
(PaintUndoInfo *)NULL);

View File

@ -121,6 +121,8 @@ typedef struct cifop
* the cell bounding box. This involves no magic type
* layers but may itself be acted upon with grow/shrink
* rules.
* CIFOP_BOUNDARY - Added 6/5/19---map the FIXED_BBOX property bounding
* box coordinates into CIF layer geometry.
* CIFOP_NET - Added 11/3/08---pull an entire electrical net into
* the CIF layer, selectively picking layers.
* CIFOP_MAXRECT - Reduce all areas to the largest internal fitting
@ -144,9 +146,10 @@ typedef struct cifop
#define CIFOP_ANDNOT 12
#define CIFOP_SQUARES_G 13
#define CIFOP_BBOX 14
#define CIFOP_NET 15
#define CIFOP_MAXRECT 16
#define CIFOP_COPYUP 17
#define CIFOP_BOUNDARY 15
#define CIFOP_NET 16
#define CIFOP_MAXRECT 17
#define CIFOP_COPYUP 18
/* Added by Tim 10/21/2004 */
/* The following structure is used to pass information on how to draw

View File

@ -559,13 +559,15 @@ cifCopyPaintFunc(tile, cifCopyRec)
int
CIFPaintCurrent()
{
extern int cifMakeBoundaryFunc(); /* Forward declaration. */
extern int cifPaintCurrentFunc(); /* Forward declaration. */
Plane *plane, *swapplane;
int i;
for (i = 0; i < cifCurReadStyle->crs_nLayers; i++)
{
TileType type;
extern int cifPaintCurrentFunc(); /* Forward declaration. */
CIFOp *op;
plane = CIFGenLayer(cifCurReadStyle->crs_layers[i]->crl_ops,
@ -641,6 +643,23 @@ CIFPaintCurrent()
}
}
}
else if (op == NULL)
{
/* Handle boundary layer */
op = cifCurReadStyle->crs_layers[i]->crl_ops;
while (op)
{
if (op->co_opcode == CIFOP_BOUNDARY) break;
op = op->co_next;
}
if (op && (DBSrPaintArea((Tile *)NULL, plane, &TiPlaneRect,
&DBAllButSpaceBits, cifCheckPaintFunc,
(ClientData)NULL) == 1))
DBSrPaintArea((Tile *) NULL, plane, &TiPlaneRect,
&CIFSolidBits, cifMakeBoundaryFunc, (ClientData)NULL);
}
/* Swap planes */
swapplane = cifCurReadPlanes[type];
@ -668,9 +687,34 @@ CIFPaintCurrent()
return 0;
}
/* Below is the search function invoked for each CIF tile type
* found for the current layer.
*/
/* Use CIF layer geometry to define a fixed bounding box for the current cell */
int
cifMakeBoundaryFunc(tile, clientdata)
Tile *tile; /* Tile of CIF information. */
ClientData clientdata; /* Not used */
{
/* It is assumed that there is one rectangle for the boundary. */
/* If there are multiple rectangles defined with the boundary */
/* layer, then the last one defines the FIXED_BBOX property. */
Rect area;
char propertyvalue[128], *storedvalue;
TiToRect(tile, &area);
if (cifReadCellDef->cd_flags & CDFIXEDBBOX)
CIFReadError("Warning: Cell %s boundary was redefined.\n",
cifReadCellDef->cd_name);
sprintf(propertyvalue, "%d %d %d %d",
area.r_xbot, area.r_ybot, area.r_xtop, area.r_ytop);
storedvalue = StrDup((char **)NULL, propertyvalue);
DBPropPut(cifReadCellDef, "FIXED_BBOX", storedvalue);
cifReadCellDef->cd_flags |= CDFIXEDBBOX;
}
/* Paint CIF layer geometry into the current cell def as magic layer "type" */
int
cifPaintCurrentFunc(tile, type)

View File

@ -234,9 +234,10 @@ CIFParseFlash()
*/
void
CIFPropRecordPath(def, pathheadp, iswire)
CIFPropRecordPath(def, pathheadp, iswire, propname)
CellDef *def;
CIFPath *pathheadp;
char *propname;
{
extern float CIFGetOutputScale();
CIFPath *pathp;
@ -273,7 +274,7 @@ CIFPropRecordPath(def, pathheadp, iswire)
/* Reallocate pathstr to be no larger than needed to hold the path contents */
StrDup(&pathstr, pathstr);
DBPropPut(def, "path", (ClientData)pathstr);
DBPropPut(def, propname, (ClientData)pathstr);
}
/*

View File

@ -62,9 +62,6 @@ CIFOp *cifCurReadOp; /* Last geometric operation seen. */
void cifReadStyleInit();
void CIFReadLoadStyle();
/* Label types used by the "labels" statement option */
typedef enum { LABEL_TYPE_NONE, LABEL_TYPE_TEXT, LABEL_TYPE_PORT } labelType;
/*
* ----------------------------------------------------------------------------
*
@ -858,6 +855,8 @@ CIFReadTechLine(sectionName, argc, argv)
calmaLabelType = LABEL_TYPE_TEXT;
else if (!strcmp(argv[2], "port"))
calmaLabelType = LABEL_TYPE_PORT;
else if (!strncmp(argv[2], "cell", 4))
calmaLabelType = LABEL_TYPE_CELLID;
else
goto wrongNumArgs;
}
@ -952,6 +951,8 @@ CIFReadTechLine(sectionName, argc, argv)
newOp->co_opcode = CIFOP_SHRINK;
else if (strcmp(argv[0], "copyup") == 0)
newOp->co_opcode = CIFOP_COPYUP;
else if (strcmp(argv[0], "boundary") == 0)
newOp->co_opcode = CIFOP_BOUNDARY;
else
{
TechError("Unknown statement \"%s\".\n", argv[0]);
@ -967,7 +968,6 @@ CIFReadTechLine(sectionName, argc, argv)
if (argc != 2) goto wrongNumArgs;
CIFParseReadLayers(argv[1], &newOp->co_cifMask);
break;
case CIFOP_GROW:
case CIFOP_GROW_G:
case CIFOP_SHRINK:

View File

@ -104,6 +104,7 @@ cifTechFreeStyle()
case CIFOP_OR:
case CIFOP_BBOX:
case CIFOP_MAXRECT:
case CIFOP_BOUNDARY:
/* These options use co_client to hold a single */
/* integer value, so it is not allocated. */
break;
@ -802,8 +803,7 @@ CIFTechLine(sectionName, argc, argv)
if (CIFCurStyle->cs_status != TECH_PENDING) return TRUE;
newLayer = NULL;
if ((strcmp(argv[0], "templayer") == 0)
|| (strcmp(argv[0], "layer") == 0))
if ((strcmp(argv[0], "templayer") == 0) || (strcmp(argv[0], "layer") == 0))
{
if (CIFCurStyle->cs_nLayers == MAXCIFLAYERS)
{
@ -1047,6 +1047,8 @@ CIFTechLine(sectionName, argc, argv)
newOp->co_opcode = CIFOP_NET;
else if (strcmp(argv[0], "maxrect") == 0)
newOp->co_opcode = CIFOP_MAXRECT;
else if (strcmp(argv[0], "boundary") == 0)
newOp->co_opcode = CIFOP_BOUNDARY;
else
{
TechError("Unknown statement \"%s\".\n", argv[0]);
@ -1196,6 +1198,12 @@ bloatCheck:
goto wrongNumArgs;
break;
case CIFOP_BOUNDARY:
/* CIFOP_BOUNDARY has no arguments */
if (argc != 1)
goto wrongNumArgs;
break;
case CIFOP_SQUARES_G:
case CIFOP_SQUARES:
@ -1752,6 +1760,7 @@ CIFTechFinal()
{
case CIFOP_OR:
case CIFOP_BBOX:
case CIFOP_BOUNDARY:
case CIFOP_MAXRECT:
case CIFOP_NET:
break;
@ -2232,6 +2241,7 @@ CIFTechOutputScale(n, d)
{
case CIFOP_OR:
case CIFOP_BBOX:
case CIFOP_BOUNDARY:
case CIFOP_MAXRECT:
case CIFOP_NET:
break;

View File

@ -55,6 +55,7 @@ DBPropPut(cellDef, name, value)
{
HashTable *htab;
HashEntry *entry;
char *oldvalue;
/* Honor the NOEDIT flag */
if (cellDef->cd_flags & CDNOEDIT) return;
@ -67,6 +68,8 @@ DBPropPut(cellDef, name, value)
htab = (HashTable *) cellDef->cd_props;
entry = HashFind(htab, name);
oldvalue = (char *)HashGetValue(entry);
if (oldvalue != NULL) freeMagic(oldvalue);
HashSetValue(entry, value);
}

View File

@ -108,6 +108,7 @@ WireTechLine(sectionName, argc, argv)
return TRUE;
}
WireUnits = atoi(argv[1]);
return TRUE;
}
if (strcmp(argv[0], "contact") != 0)