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:
parent
8f7db3942c
commit
bbf6008363
|
|
@ -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);
|
||||
|
|
@ -715,7 +712,7 @@ calmaElementText()
|
|||
cifnum = CIFCalmaLayerToCifLayer(layer, textt, cifCurReadStyle);
|
||||
if (cifnum < 0)
|
||||
{
|
||||
if(cifCurReadStyle->crs_flags & CRF_IGNORE_UNKNOWNLAYER_LABELS)
|
||||
if (cifCurReadStyle->crs_flags & CRF_IGNORE_UNKNOWNLAYER_LABELS)
|
||||
type = -1;
|
||||
else {
|
||||
calmaLayerError("Label on unknown layer/datatype", layer, textt);
|
||||
|
|
@ -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"
|
||||
|
|
|
|||
|
|
@ -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 */
|
||||
|
|
|
|||
24
cif/CIFgen.c
24
cif/CIFgen.c
|
|
@ -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);
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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];
|
||||
|
|
@ -652,8 +671,8 @@ CIFPaintCurrent()
|
|||
DBSrPaintArea((Tile *) NULL, plane, &TiPlaneRect,
|
||||
&CIFSolidBits, cifPaintCurrentFunc,
|
||||
(ClientData)type);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/* Recycle the plane, which was dynamically allocated. */
|
||||
|
||||
DBFreePaintPlane(plane);
|
||||
|
|
@ -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)
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
}
|
||||
|
||||
/*
|
||||
|
|
|
|||
|
|
@ -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:
|
||||
|
|
|
|||
|
|
@ -54,8 +54,8 @@ typedef struct
|
|||
* the "crl_magicType" should be interpreted as a CIF layer.
|
||||
*/
|
||||
|
||||
#define CIFR_SIMPLE 1
|
||||
#define CIFR_TEMPLAYER 2
|
||||
#define CIFR_SIMPLE 1
|
||||
#define CIFR_TEMPLAYER 2
|
||||
|
||||
/* The following structure defines a complete CIF read-in style.
|
||||
* The constant MAXCIFRLAYERS must be less than TT_MAXTYPES, and
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -108,6 +108,7 @@ WireTechLine(sectionName, argc, argv)
|
|||
return TRUE;
|
||||
}
|
||||
WireUnits = atoi(argv[1]);
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
if (strcmp(argv[0], "contact") != 0)
|
||||
|
|
|
|||
Loading…
Reference in New Issue