diff --git a/cif/CIFgen.c b/cif/CIFgen.c index d063a087..7233d12f 100644 --- a/cif/CIFgen.c +++ b/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: diff --git a/cif/CIFint.h b/cif/CIFint.h index 6d3ef7ba..c9280e12 100644 --- a/cif/CIFint.h +++ b/cif/CIFint.h @@ -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 diff --git a/cif/CIFtech.c b/cif/CIFtech.c index 54bb05c6..25a920e3 100644 --- a/cif/CIFtech.c +++ b/cif/CIFtech.c @@ -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; diff --git a/database/DBio.c b/database/DBio.c index 6389eb23..9afe30f3 100644 --- a/database/DBio.c +++ b/database/DBio.c @@ -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)) diff --git a/drc/DRCcif.c b/drc/DRCcif.c index b4344620..fa4f00c7 100644 --- a/drc/DRCcif.c +++ b/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; } /* diff --git a/resis/ResReadSim.c b/resis/ResReadSim.c index cc47fb4b..19ae304d 100644 --- a/resis/ResReadSim.c +++ b/resis/ResReadSim.c @@ -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]); diff --git a/resis/ResRex.c b/resis/ResRex.c index a1c98d9e..b31299e8 100644 --- a/resis/ResRex.c +++ b/resis/ResRex.c @@ -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) {