Merge branch 'master' into magic-8.2
This commit is contained in:
commit
1bcf93616f
70
cif/CIFgen.c
70
cif/CIFgen.c
|
|
@ -842,6 +842,35 @@ endbloat:
|
|||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
*-------------------------------------------------------
|
||||
*
|
||||
* cifFoundFun --
|
||||
*
|
||||
* Find the first tile in the given area.
|
||||
*
|
||||
* Results:
|
||||
* Return 1 to stop the search and process.
|
||||
* Set clientData to the tile found.
|
||||
*
|
||||
*-------------------------------------------------------
|
||||
*/
|
||||
|
||||
int
|
||||
cifFoundFunc(tile, treturn)
|
||||
Tile *tile;
|
||||
Tile **treturn;
|
||||
{
|
||||
*treturn = tile;
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* Data structure for bloat-all function */
|
||||
typedef struct _bloatStruct {
|
||||
CIFOp *op;
|
||||
CellDef *def;
|
||||
} BloatStruct;
|
||||
|
||||
/*
|
||||
* ----------------------------------------------------------------------------
|
||||
*
|
||||
|
|
@ -873,18 +902,26 @@ endbloat:
|
|||
}
|
||||
|
||||
int
|
||||
cifBloatAllFunc(tile, op)
|
||||
cifBloatAllFunc(tile, bls)
|
||||
Tile *tile; /* The tile to be processed. */
|
||||
CIFOp *op; /* Describes the operation to be performed */
|
||||
BloatStruct *bls;
|
||||
{
|
||||
Rect area;
|
||||
TileTypeBitMask connect;
|
||||
Tile *t, *tp;
|
||||
TileType type;
|
||||
BloatData *bloats = (BloatData *)op->co_client;
|
||||
BloatData *bloats;
|
||||
int i;
|
||||
PlaneMask pmask;
|
||||
int pNum;
|
||||
CIFOp *op;
|
||||
CellDef *def;
|
||||
static Stack *BloatStack = (Stack *)NULL;
|
||||
|
||||
op = bls->op;
|
||||
def = bls->def;
|
||||
bloats = (BloatData *)op->co_client;
|
||||
|
||||
/* Create a mask of all connecting types (these must be in a single
|
||||
* plane), then call a search function to find all connecting material
|
||||
* of these types.
|
||||
|
|
@ -900,7 +937,24 @@ cifBloatAllFunc(tile, op)
|
|||
if (BloatStack == (Stack *)NULL)
|
||||
BloatStack = StackNew(64);
|
||||
|
||||
PUSHTILE(tile, BloatStack);
|
||||
/* If the type of the tile to be processed is not in the same plane */
|
||||
/* as the bloat type(s), then find any tile under the tile to be */
|
||||
/* processed that belongs to the connect mask, and use that as the */
|
||||
/* starting tile. */
|
||||
|
||||
t = tile;
|
||||
type = TiGetType(tile);
|
||||
pNum = DBPlane(type);
|
||||
pmask = CoincidentPlanes(&connect, pNum);
|
||||
if (pmask == 0)
|
||||
{
|
||||
TiToRect(tile, &area);
|
||||
if (DBSrPaintArea((Tile *)NULL, def->cd_planes[bloats->bl_plane], &area,
|
||||
&connect, cifFoundFunc, (ClientData)(&t)) == 0)
|
||||
return 0; /* Nothing found here */
|
||||
}
|
||||
|
||||
PUSHTILE(t, BloatStack);
|
||||
while (!StackEmpty(BloatStack))
|
||||
{
|
||||
t = (Tile *) STACKPOP(BloatStack);
|
||||
|
|
@ -2688,6 +2742,7 @@ cifSrTiles(cifOp, area, cellDef, temps, func, cdArg)
|
|||
{
|
||||
TileTypeBitMask maskBits;
|
||||
TileType t;
|
||||
Tile *tp;
|
||||
int i;
|
||||
BloatData *bloats;
|
||||
|
||||
|
|
@ -2699,7 +2754,7 @@ cifSrTiles(cifOp, area, cellDef, temps, func, cdArg)
|
|||
|
||||
cifScale = (CIFCurStyle) ? CIFCurStyle->cs_scaleFactor : 1;
|
||||
|
||||
/* Bloat operations have to be in a single plane */
|
||||
/* Bloat operations (except bloat-all) have to be in a single plane */
|
||||
|
||||
switch (cifOp->co_opcode) {
|
||||
case CIFOP_BLOAT:
|
||||
|
|
@ -2783,6 +2838,7 @@ CIFGenLayer(op, area, cellDef, temps, clientdata)
|
|||
SearchContext scx;
|
||||
TileType ttype;
|
||||
char *netname;
|
||||
BloatStruct bls;
|
||||
int (*cifGrowFuncPtr)() = (CIFCurStyle->cs_flags & CWF_GROW_EUCLIDEAN) ?
|
||||
cifGrowEuclideanFunc : cifGrowFunc;
|
||||
|
||||
|
|
@ -2971,8 +3027,10 @@ CIFGenLayer(op, area, cellDef, temps, clientdata)
|
|||
|
||||
case CIFOP_BLOATALL:
|
||||
cifPlane = curPlane;
|
||||
bls.op = op;
|
||||
bls.def = cellDef;
|
||||
cifSrTiles(op, area, cellDef, temps,
|
||||
cifBloatAllFunc, (ClientData) op);
|
||||
cifBloatAllFunc, (ClientData)&bls);
|
||||
break;
|
||||
|
||||
case CIFOP_SQUARES:
|
||||
|
|
|
|||
|
|
@ -310,6 +310,7 @@ extern void CIFLoadStyle();
|
|||
extern Plane *CIFPlanes[]; /* Normal place to store CIF. */
|
||||
extern CIFKeep *CIFStyleList; /* List of all CIF styles. */
|
||||
extern CIFStyle *CIFCurStyle; /* Current style being used. */
|
||||
extern CIFStyle *CIFDRCStyle; /* CIF style for DRC checking (optional) */
|
||||
extern CellUse *CIFComponentUse; /* Flatten stuff in here if needed. */
|
||||
extern CellDef *CIFComponentDef; /* Corresponds to CIFComponentUse. */
|
||||
extern CellUse *CIFDummyUse; /* Used to dummy up a CellUse for a
|
||||
|
|
|
|||
|
|
@ -1081,13 +1081,17 @@ CIFTechLine(sectionName, argc, argv)
|
|||
if (argc != 3) goto wrongNumArgs;
|
||||
cifParseLayers(argv[1], CIFCurStyle, &newOp->co_paintMask,
|
||||
(TileTypeBitMask *)NULL, FALSE);
|
||||
bloatLayers = newOp->co_paintMask;
|
||||
bloats = (BloatData *)mallocMagic(sizeof(BloatData));
|
||||
for (i = 0; i < TT_MAXTYPES; i++)
|
||||
bloats->bl_distance[i] = 0;
|
||||
newOp->co_client = (ClientData)bloats;
|
||||
|
||||
cifParseLayers(argv[2], CIFCurStyle, &mask, &tempMask, TRUE);
|
||||
|
||||
/* 10/15/2019: Lifting restriction that the types that */
|
||||
/* trigger the bloating must be in the same plane as the */
|
||||
/* types that are bloated into. */
|
||||
|
||||
TTMaskZero(&bloatLayers);
|
||||
TTMaskSetMask(&bloatLayers, &mask);
|
||||
if (!TTMaskEqual(&tempMask, &DBZeroTypeBits))
|
||||
TechError("Can't use templayers in bloat statement.\n");
|
||||
|
|
@ -1945,7 +1949,7 @@ CIFLoadStyle(stylename)
|
|||
{
|
||||
SectionID invcif;
|
||||
|
||||
if (CIFCurStyle->cs_name == stylename) return;
|
||||
if (CIFCurStyle && (CIFCurStyle->cs_name == stylename)) return;
|
||||
|
||||
cifTechNewStyle();
|
||||
CIFCurStyle->cs_name = stylename;
|
||||
|
|
|
|||
|
|
@ -2350,6 +2350,8 @@ DBCellWriteFile(cellDef, f)
|
|||
int reducer;
|
||||
char *estring;
|
||||
char lstring[256];
|
||||
char *propvalue;
|
||||
bool propfound;
|
||||
|
||||
#define FPRINTF(f,s)\
|
||||
{\
|
||||
|
|
@ -2542,12 +2544,43 @@ DBCellWriteFile(cellDef, f)
|
|||
}
|
||||
|
||||
/* And any properties */
|
||||
|
||||
/* NOTE: FIXED_BBOX is treated specially; values are database */
|
||||
/* values and should be divided by reducer. Easiest to do it */
|
||||
/* here and revert values after. */
|
||||
|
||||
propvalue = (char *)DBPropGet(cellDef, "FIXED_BBOX", &propfound);
|
||||
if (propfound)
|
||||
{
|
||||
char *proporig, *propscaled;
|
||||
Rect scalebox, bbox;
|
||||
|
||||
proporig = StrDup((char **)NULL, propvalue);
|
||||
propscaled = mallocMagic(strlen(propvalue) + 5);
|
||||
if (sscanf(propvalue, "%d %d %d %d", &bbox.r_xbot, &bbox.r_ybot,
|
||||
&bbox.r_xtop, &bbox.r_ytop) == 4)
|
||||
{
|
||||
scalebox.r_xbot = bbox.r_xbot / reducer;
|
||||
scalebox.r_xtop = bbox.r_xtop / reducer;
|
||||
scalebox.r_ybot = bbox.r_ybot / reducer;
|
||||
scalebox.r_ytop = bbox.r_ytop / reducer;
|
||||
sprintf(propscaled, "%d %d %d %d",
|
||||
bbox.r_xbot / reducer, bbox.r_ybot / reducer,
|
||||
bbox.r_xtop / reducer, bbox.r_ytop / reducer);
|
||||
|
||||
DBPropPut(cellDef, "FIXED_BBOX", propscaled);
|
||||
propvalue = proporig;
|
||||
}
|
||||
}
|
||||
|
||||
if (cellDef->cd_props != (ClientData)NULL)
|
||||
{
|
||||
FPRINTF(f, "<< properties >>\n");
|
||||
DBPropEnum(cellDef, dbWritePropFunc, (ClientData)f);
|
||||
}
|
||||
|
||||
if (propfound) DBPropPut(cellDef, "FIXED_BBOX", propvalue);
|
||||
|
||||
FPRINTF(f, "<< end >>\n");
|
||||
|
||||
if (fflush(f) == EOF || ferror(f))
|
||||
|
|
|
|||
40
drc/DRCcif.c
40
drc/DRCcif.c
|
|
@ -67,9 +67,10 @@ extern bool DRCForceReload;
|
|||
TileTypeBitMask drcCifGenLayers;
|
||||
|
||||
DRCCookie *drcCifRules[MAXCIFLAYERS][2];
|
||||
DRCCookie *drcCifCur=NULL;
|
||||
DRCCookie *drcCifCur = NULL;
|
||||
int drcCifValid = FALSE;
|
||||
int beenWarned;
|
||||
bool beenWarned = FALSE;
|
||||
char *drcNeedStyle = NULL;
|
||||
|
||||
#define DRC_CIF_SPACE 0
|
||||
#define DRC_CIF_SOLID 1
|
||||
|
|
@ -112,14 +113,12 @@ drcCifSetStyle(argc, argv)
|
|||
{
|
||||
if (!strcmp(new->cs_name, argv[1]))
|
||||
{
|
||||
drcNeedStyle = new->cs_name;
|
||||
DRCForceReload = TRUE;
|
||||
if (!strcmp(new->cs_name, CIFCurStyle->cs_name))
|
||||
drcCifStyle = CIFCurStyle;
|
||||
else
|
||||
{
|
||||
TechError("DRC cif extensions are not enabled.\n\t"
|
||||
"Use \"cif ostyle %s\" to enable them.\n",
|
||||
new->cs_name);
|
||||
drcCifStyle = NULL;
|
||||
beenWarned = TRUE; /* post no more error messages */
|
||||
}
|
||||
|
|
@ -501,9 +500,35 @@ drcCifCheck(arg)
|
|||
int scale;
|
||||
int i,j;
|
||||
int oldTiles;
|
||||
CIFStyle *CIFSaveStyle = NULL;
|
||||
|
||||
if (CIFCurStyle != drcCifStyle)
|
||||
{
|
||||
if (drcNeedStyle == NULL) {
|
||||
TxError("Error: No DRC CIF style declared!\n");
|
||||
return;
|
||||
}
|
||||
|
||||
CIFSaveStyle = CIFCurStyle;
|
||||
|
||||
if (drcCifStyle == NULL)
|
||||
{
|
||||
TxPrintf("Loading DRC CIF style.\n");
|
||||
CIFCurStyle = NULL;
|
||||
CIFLoadStyle(drcNeedStyle);
|
||||
if (drcCifValid == FALSE)
|
||||
CIFCurStyle = CIFSaveStyle;
|
||||
else
|
||||
drcCifStyle = CIFCurStyle;
|
||||
}
|
||||
if (drcCifStyle == NULL)
|
||||
{
|
||||
TxError("Error: Failed to load CIF DRC style.\n");
|
||||
return;
|
||||
}
|
||||
CIFCurStyle = drcCifStyle;
|
||||
}
|
||||
if (drcCifValid == FALSE) return;
|
||||
else if (CIFCurStyle != drcCifStyle) return;
|
||||
|
||||
scale = drcCifStyle->cs_scaleFactor;
|
||||
cifrect = *checkRect;
|
||||
|
|
@ -534,6 +559,9 @@ drcCifCheck(arg)
|
|||
}
|
||||
arg->dCD_rect = checkRect;
|
||||
DRCstatCifTiles += DRCstatTiles - oldTiles;
|
||||
|
||||
/* Put it back the way you found it */
|
||||
if (CIFSaveStyle != NULL) CIFCurStyle = CIFSaveStyle;
|
||||
}
|
||||
|
||||
/*
|
||||
|
|
|
|||
|
|
@ -243,13 +243,17 @@ ResReadNode(nodefile)
|
|||
entry = HashFind(&ResNodeTable,line[NODENODENAME]);
|
||||
node = ResInitializeNode(entry);
|
||||
|
||||
node->location.p_x = (int)((float)atof(line[NODENODEX])/lambda);
|
||||
node->location.p_y = (int)((float)atof(line[NODENODEY])/lambda);
|
||||
/* NOTE: Fixed 10/15/2019. No scalefactor is passed to EFNodeVisit()
|
||||
* so there is no scaling by lambda. Values are in centimicrons always,
|
||||
* and factor of 100 is required to get database units.
|
||||
*/
|
||||
node->location.p_x = (int)((float)atof(line[NODENODEX]) / 100.0);
|
||||
node->location.p_y = (int)((float)atof(line[NODENODEY]) / 100.0);
|
||||
#ifdef ARIEL
|
||||
node->rs_bbox.r_xbot = (int)((float)atof(line[NODE_BBOX_LL_X])/lambda);
|
||||
node->rs_bbox.r_ybot = (int)((float)atof(line[NODE_BBOX_LL_Y])/lambda);
|
||||
node->rs_bbox.r_xtop = (int)((float)atof(line[NODE_BBOX_UR_X])/lambda);
|
||||
node->rs_bbox.r_ytop = (int)((float)atof(line[NODE_BBOX_UR_Y])/lambda);
|
||||
node->rs_bbox.r_xbot = (int)((float)atof(line[NODE_BBOX_LL_X]) / 100.0);
|
||||
node->rs_bbox.r_ybot = (int)((float)atof(line[NODE_BBOX_LL_Y]) / 100.0);
|
||||
node->rs_bbox.r_xtop = (int)((float)atof(line[NODE_BBOX_UR_X]) / 100.0);
|
||||
node->rs_bbox.r_ytop = (int)((float)atof(line[NODE_BBOX_UR_Y]) / 100.0);
|
||||
#endif
|
||||
if (cp = strchr(line[NODETYPE], ';')) *cp = '\0';
|
||||
node->type = DBTechNameType(line[NODETYPE]);
|
||||
|
|
|
|||
|
|
@ -988,6 +988,12 @@ ResCheckSimNodes(celldef, resisdata)
|
|||
gparams.rg_tranloc = &node->drivepoint;
|
||||
gparams.rg_status |= DRIVEONLY;
|
||||
}
|
||||
if (node->status & PORTNODE)
|
||||
{
|
||||
/* The node is a port, not a transistor, so make */
|
||||
/* sure rg_ttype is set accordingly. */
|
||||
gparams.rg_ttype = node->rs_ttype;
|
||||
}
|
||||
}
|
||||
if (gparams.rg_tranloc == NULL && node->status & FORCE)
|
||||
{
|
||||
|
|
|
|||
Loading…
Reference in New Issue