From 097f4fb28c74508277afc04bfba1f45a9a887976 Mon Sep 17 00:00:00 2001 From: Tim Edwards Date: Tue, 15 Oct 2019 09:16:07 -0400 Subject: [PATCH 1/4] Corrected node reading from extresist because the ".nodes" file does not have any scaling in the dimensions and so values should not be divided by the factor lambda from the .sim file "units" line. --- resis/ResReadSim.c | 16 ++++++++++------ 1 file changed, 10 insertions(+), 6 deletions(-) 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]); From e969097f847e7ae982c5a0f813a8805ec85ecb71 Mon Sep 17 00:00:00 2001 From: Tim Edwards Date: Tue, 15 Oct 2019 09:51:25 -0400 Subject: [PATCH 2/4] Another correction to fix the tile type for port drivers in extresist, as the tile type was being set to a transistor gate type and not the type of the port. --- resis/ResRex.c | 6 ++++++ 1 file changed, 6 insertions(+) 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) { From 3d7a56ac3a02042a18b0120f322a21658214659d Mon Sep 17 00:00:00 2001 From: Tim Edwards Date: Tue, 15 Oct 2019 16:24:49 -0400 Subject: [PATCH 3/4] Finally got around to undoing an annoyance caused by the wholesale reduction of memory and startup time, which was to maintain only one CIF style in memory. The new method is just to read in and keep the DRC CIF style separately from the output CIF style. Because the CIF sections of the techfile are read before the DRC sections, and the CIF DRC style is declared in the DRC section, the CIF DRC style is read in on the fly during the first DRC checking. --- cif/CIFgen.c | 70 ++++++++++++++++++++++++++++++++++++++++++++++----- cif/CIFint.h | 1 + cif/CIFtech.c | 10 +++++--- drc/DRCcif.c | 40 ++++++++++++++++++++++++----- 4 files changed, 106 insertions(+), 15 deletions(-) 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/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; } /* From 8b0a9275a88c0906641e86b36062efac6d257463 Mon Sep 17 00:00:00 2001 From: Tim Edwards Date: Tue, 15 Oct 2019 20:40:59 -0400 Subject: [PATCH 4/4] Fixed the value of property FIXED_BBOX when saving a file; it needs to be scaled down by "reducer" like all other values in the cell. Suggests a need to have property types other than string, so that a property type "rect" or "box" can be declared that is saved as a Rect and always scales without special hack handling of the specific string FIXED_BBOX. . . --- database/DBio.c | 33 +++++++++++++++++++++++++++++++++ 1 file changed, 33 insertions(+) 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))