From 4b5566af3ea71abc06ceaa6e7e00229d2ca4acda Mon Sep 17 00:00:00 2001 From: Tim Edwards Date: Wed, 18 Sep 2019 20:48:33 -0400 Subject: [PATCH] Corrected an error that causes alias names for layers to become the principle layer name, which should not happen (especially in the case of space, where layers may be aliased to "space" to make them ignored on input). Also: Implemented a "-" option to the "substrate" record in the techfile to declare types which shield layers from the substrate. This allows types like pwell to be used in different contexts, e.g., as part of the substrate, or as a P-well in deep N-well, without requiring a different type. This works in conjunction with the recently-implemented "+" ID types for devices. All of this may seem unnecessary but helps to reduce the number of layers needing to be defined, and the subsequent complexity of the DRC rulesets. --- database/DBtechtype.c | 17 +++++++++-------- extract/ExtBasic.c | 26 ++++++++++++++++++++++++++ extract/ExtTech.c | 18 ++++++++++++++++-- extract/extractInt.h | 7 ++++++- 4 files changed, 57 insertions(+), 11 deletions(-) diff --git a/database/DBtechtype.c b/database/DBtechtype.c index 5851b5a5..5233d077 100644 --- a/database/DBtechtype.c +++ b/database/DBtechtype.c @@ -141,7 +141,7 @@ DBTechInitPlane() for (dpp = dbTechDefaultPlanes; dpp->dp_names; dpp++) { cp = dbTechNameAdd(dpp->dp_names, (ClientData) dpp->dp_plane, - &dbPlaneNameLists); + &dbPlaneNameLists, FALSE); if (cp == NULL) { TxError("DBTechInit: can't add plane names %s\n", dpp->dp_names); @@ -224,7 +224,7 @@ DBTechInitType() for (dtp = dbTechDefaultTypes; dtp->dt_names; dtp++) { cp = dbTechNameAdd(dtp->dt_names, (ClientData) dtp->dt_type, - &dbTypeNameLists); + &dbTypeNameLists, FALSE); if (cp == NULL) { TxError("DBTechInit: can't add type names %s\n", dtp->dt_names); @@ -283,7 +283,7 @@ DBTechAddPlane(sectionName, argc, argv) return FALSE; } - cp = dbTechNameAdd(argv[0], (ClientData) DBNumPlanes, &dbPlaneNameLists); + cp = dbTechNameAdd(argv[0], (ClientData) DBNumPlanes, &dbPlaneNameLists, FALSE); if (cp == NULL) return FALSE; DBPlaneLongNameTbl[DBNumPlanes++] = cp; @@ -315,7 +315,7 @@ DBTechAddNameToType(newname, ttype, canonical) { char *cp; - cp = dbTechNameAdd(newname, (ClientData) ttype, &dbTypeNameLists); + cp = dbTechNameAdd(newname, (ClientData) ttype, &dbTypeNameLists, TRUE); if (canonical) DBTypeLongNameTbl[ttype] = cp; } @@ -455,7 +455,7 @@ DBTechAddType(sectionName, argc, argv) } else { - cp = dbTechNameAdd(argv[1], (ClientData) DBNumTypes, &dbTypeNameLists); + cp = dbTechNameAdd(argv[1], (ClientData) DBNumTypes, &dbTypeNameLists, FALSE); if (cp == NULL) return FALSE; @@ -513,7 +513,7 @@ dbTechNewStackedType(type1, type2) } sprintf(buf, "%s+%s", DBTypeShortName(type1), DBTypeShortName(type2)); - cp = dbTechNameAdd(buf, (ClientData) DBNumTypes, &dbTypeNameLists); + cp = dbTechNameAdd(buf, (ClientData) DBNumTypes, &dbTypeNameLists, FALSE); if (cp == NULL) { TechError("Couldn't generate new stacking type %s\n", buf); @@ -730,10 +730,11 @@ dbTechNameLookup(str, table) */ char * -dbTechNameAdd(name, cdata, ptable) +dbTechNameAdd(name, cdata, ptable, alias) char *name; /* Comma-separated list of names to be added */ ClientData cdata; /* Value to be stored with each name above */ NameList *ptable; /* Table to which we will add names */ + int alias; /* 1 if this is an alias (never make primary) */ { char *cp; char onename[BUFSIZ]; @@ -769,7 +770,7 @@ dbTechNameAdd(name, cdata, ptable) } } - if (primary) + if (primary && (alias == 0)) primary->sn_primary = TRUE; return (first); } diff --git a/extract/ExtBasic.c b/extract/ExtBasic.c index bfd25db0..38d76441 100644 --- a/extract/ExtBasic.c +++ b/extract/ExtBasic.c @@ -3546,7 +3546,11 @@ extSubsFunc(tile, arg) Tile *tile; FindRegion *arg; { + int pNum; + Rect tileArea; TileType type; + TileTypeBitMask *smask; + int extSubsFunc3(); if (IsSplit(tile)) { @@ -3554,6 +3558,17 @@ extSubsFunc(tile, arg) if (type == TT_SPACE) return 0; /* Should not happen */ } + /* Run second search in the area of the tile on the substrate plane */ + /* to make sure that no shield types are covering this tile. */ + + TiToRect(tile, &tileArea); + smask = &ExtCurStyle->exts_globSubstrateShieldTypes; + for (pNum = PL_TECHDEPBASE; pNum < DBNumPlanes; pNum++) + if (TTMaskIntersect(&DBPlaneTypes[pNum], smask)) + if (DBSrPaintArea((Tile *) NULL, arg->fra_def->cd_planes[pNum], + &tileArea, smask, extSubsFunc3, (ClientData)NULL) != 0) + return (1); + /* Mark this tile as pending and push it */ PUSHTILE(tile, arg->fra_pNum); @@ -3568,11 +3583,22 @@ extSubsFunc2(tile, arg) { int pNum; Rect tileArea; + TileTypeBitMask *smask; int extSubsFunc3(); TiToRect(tile, &tileArea); /* Run second search in the area of the tile on the substrate plane */ + /* to make sure that no shield types are covering this tile. */ + + smask = &ExtCurStyle->exts_globSubstrateShieldTypes; + for (pNum = PL_TECHDEPBASE; pNum < DBNumPlanes; pNum++) + if (TTMaskIntersect(&DBPlaneTypes[pNum], smask)) + if (DBSrPaintArea((Tile *) NULL, arg->fra_def->cd_planes[pNum], + &tileArea, smask, extSubsFunc3, (ClientData)NULL) != 0) + return (1); + + /* Run third search in the area of the tile on the substrate plane */ /* to make sure that nothing but space is under these tiles. */ pNum = ExtCurStyle->exts_globSubstratePlane; diff --git a/extract/ExtTech.c b/extract/ExtTech.c index d778749d..314bed99 100644 --- a/extract/ExtTech.c +++ b/extract/ExtTech.c @@ -157,7 +157,7 @@ static keydesc keyTable[] = { "style", STYLE, 2, 4, "stylename", - "substrate", SUBSTRATE, 3, 3, + "substrate", SUBSTRATE, 3, 4, "types plane", "units", UNITS, 2, 2, @@ -675,6 +675,7 @@ extTechStyleInit(style) style->exts_globSubstratePlane = -1; TTMaskZero(&style->exts_globSubstrateTypes); + TTMaskZero(&style->exts_globSubstrateShieldTypes); } @@ -1927,7 +1928,6 @@ ExtTechLine(sectionName, argc, argv) case DEFAULTSIDEWALL: ExtTechSimpleSidewallCap(argv); break; - case DEVICE: /* Parse second argument for device type */ @@ -2587,8 +2587,22 @@ ExtTechLine(sectionName, argc, argv) ExtCurStyle->exts_stepSize = val; break; case SUBSTRATE: + /* If the last entry starts with '-', then use it to set */ + /* the shield types. Otherwise, the shield types mask is */ + /* NULL. */ + + idTypes = DBZeroTypeBits; + if (*argv[argc - 1] == '-') + { + if ((DBTechNameMask(argv[argc - 1] + 1, &idTypes)) == 0) + idTypes = DBZeroTypeBits; + argc--; + } + TTMaskZero(&ExtCurStyle->exts_globSubstrateTypes); + TTMaskZero(&ExtCurStyle->exts_globSubstrateShieldTypes); TTMaskSetMask(&ExtCurStyle->exts_globSubstrateTypes, &types1); + ExtCurStyle->exts_globSubstrateShieldTypes = idTypes; ExtCurStyle->exts_globSubstratePlane = DBTechNoisyNamePlane(argv[2]); break; case NOPLANEORDER: { diff --git a/extract/extractInt.h b/extract/extractInt.h index d5779afa..5e0064e1 100644 --- a/extract/extractInt.h +++ b/extract/extractInt.h @@ -872,11 +872,16 @@ typedef struct extstyle * types that connect to the substrate. Since for non-SOI * processes, this generally is used to specify that space on * the well plane is the substrate, the plane number for the - * well plane is given, too. + * well plane is given, too. The "shield types" mask is a + * mask of types that prevent any types in exts_globSubstrateTypes + * from contacting the substrate (e.g., deep nwell might be a + * shielding type, or it could be a special marker layer like + * "not_substrate"). */ char *exts_globSubstrateName; TileTypeBitMask exts_globSubstrateTypes; int exts_globSubstratePlane; + TileTypeBitMask exts_globSubstrateShieldTypes; /* Scaling */ /*