diff --git a/VERSION b/VERSION index 3580c9fa..aded7447 100644 --- a/VERSION +++ b/VERSION @@ -1 +1 @@ -8.3.663 +8.3.664 diff --git a/extract/ExtHier.c b/extract/ExtHier.c index 09df8ae5..5321d952 100644 --- a/extract/ExtHier.c +++ b/extract/ExtHier.c @@ -115,23 +115,91 @@ bool extTestNMInteract(Tile *t1, TileType di1, Tile *t2, TileType di2) /* *---------------------------------------------------------------------- - * extHierSubShieldFunc -- + * extHierSubInteractFunc -- * - * Simple callback function for extHierSubstrate() that halts the - * search if any substrate shield type is found in the search area + * Simple callback function for extHierSubShielfFunc() that halts + * the search if any type connecting to substrate is found in + * the area. + * + * Results: 1 to stop the search. + * + * Side effects: None. * *---------------------------------------------------------------------- */ int -extHierSubShieldFunc(tile, dinfo, clientdata) - Tile *tile; /* (unused) */ - TileType dinfo; /* (unused) */ - ClientData clientdata; /* (unused) */ +extHierSubInteractFunc(tile, dinfo, clientdata) + Tile *tile; /* unused */ + TileType dinfo; /* unused */ + ClientData clientdata; /* unused */ { return 1; } +/* + *---------------------------------------------------------------------- + * extHierSubShieldFunc -- + * + * Callback function for extHierSubstrate() that halts the search + * if any substrate shield type is found in the search area. To + * avoid flagging substrate shields that overlap the search area + * but do not interact with the cell, check the area of the + * substrate shield for device types that connect to substrate + * (ExtCurStyle->exts_subsDevTypes). If something is found, then + * return 1 immediately to stop the search. + * + * Results: 1 if an interacting substrate shield is found, 0 otherwise. + * + * Side effects: None. + * + *---------------------------------------------------------------------- + */ + +int +extHierSubShieldFunc(tile, dinfo, use) + Tile *tile; + TileType dinfo; + CellUse *use; +{ + Rect r, rsub; + int pNum; + TileType ttype; + CellDef *subdef; + Transform t; + + if (IsSplit(tile)) + { + ttype = TiGetLeftType(tile); + if (!TTMaskHasType(&ExtCurStyle->exts_globSubstrateShieldTypes, ttype)) + ttype = TiGetRightType(tile); + } + else + ttype = TiGetTypeExact(tile); + + TiToRect(tile, &r); + + /* Convert area of tile to the coordinates of the cell "subdef", which is + * a child of the cell containing "tile". + */ + subdef = use->cu_def; + GeoInvertTrans(&use->cu_transform, &t); + GeoTransRect(&t, &r, &rsub); + + for (pNum = PL_TECHDEPBASE; pNum < DBNumPlanes; pNum++) + { + if (TTMaskIntersect(&DBPlaneTypes[pNum], &ExtCurStyle->exts_subsDevTypes)) + { + if (DBSrPaintNMArea((Tile *)NULL, + subdef->cd_planes[pNum], dinfo, &rsub, + &ExtCurStyle->exts_subsDevTypes, + extHierSubInteractFunc, (ClientData)NULL) == 1) + return 1; + } + } + return 0; +} + /* *---------------------------------------------------------------------- * extHierSubstrate -- @@ -229,7 +297,7 @@ extHierSubstrate(ha, use, x, y) if (DBSrPaintArea((Tile *) NULL, def->cd_planes[pNum], &subArea, &ExtCurStyle->exts_globSubstrateShieldTypes, - extHierSubShieldFunc, (ClientData)NULL) != 0) + extHierSubShieldFunc, PTR2CD(use)) != 0) { freeMagic(nodeList); ExtResetTiles(use->cu_def, CLIENTDEFAULT); diff --git a/extract/ExtTech.c b/extract/ExtTech.c index e4884054..b11d0bd9 100644 --- a/extract/ExtTech.c +++ b/extract/ExtTech.c @@ -836,6 +836,7 @@ extTechStyleInit(style) style->exts_sidePlanes = style->exts_overlapPlanes = 0; TTMaskZero(&style->exts_deviceMask); + TTMaskZero(&style->exts_subsDevTypes); style->exts_activeTypes = DBAllButSpaceAndDRCBits; for (r = 0; r < NP; r++) @@ -2355,6 +2356,9 @@ ExtTechLine(sectionName, argc, argv) } TTMaskSetMask(&ExtCurStyle->exts_deviceMask, &types1); + if (!TTMaskIsZero(&subsTypes)) + TTMaskSetMask(&ExtCurStyle->exts_subsDevTypes, &types1); + for (t = TT_TECHDEPBASE; t < DBNumTypes; t++) if (TTMaskHasType(&types1, t)) { @@ -2380,6 +2384,7 @@ ExtTechLine(sectionName, argc, argv) devptr->exts_next = ExtCurStyle->exts_device[t]; ExtCurStyle->exts_device[t] = devptr; + #ifdef ARIEL { int z; @@ -2867,6 +2872,8 @@ ExtTechLine(sectionName, argc, argv) } TTMaskSetMask(&ExtCurStyle->exts_deviceMask, &types1); + if (!TTMaskIsZero(&subsTypes)) + TTMaskSetMask(&ExtCurStyle->exts_subsDevTypes, &types1); for (t = TT_TECHDEPBASE; t < DBNumTypes; t++) { diff --git a/extract/extractInt.h b/extract/extractInt.h index 97cdcf05..7ea28adc 100644 --- a/extract/extractInt.h +++ b/extract/extractInt.h @@ -626,6 +626,13 @@ typedef struct extstyle */ TileTypeBitMask exts_deviceConn[NT]; + /* + * List of device types which connect to a substrate type. This + * distinguishes between devices that make a connection to substrate + * (e.g., FETs) and those that don't (e.g., MiM caps, metal resistors). + */ + TileTypeBitMask exts_subsDevTypes; + /* * Set of types to be considered for extraction. Types not in * this list cannot be nodes (e.g., implant layers) diff --git a/resis/ResMain.c b/resis/ResMain.c index 1e40c73f..5c71b2a2 100644 --- a/resis/ResMain.c +++ b/resis/ResMain.c @@ -1492,7 +1492,7 @@ ResExtractNet(node, resisdata, cellname) resDevTerm *resdevList, *resdevNext; resdevList = (resDevTerm *)HashGetValue(he); - while (resdevList) + if (resdevList) { /* Diagnostic */ Tile *tp; @@ -1501,9 +1501,12 @@ ResExtractNet(node, resisdata, cellname) (resdevList->rdt_term < 0) ? "Substrate" : "Terminal", tp->ti_ll.p_x, tp->ti_ll.p_y); - resdevNext = resdevList->rdt_next; - freeMagic((char *)resdevList); - resdevList = resdevNext; + while (resdevList) + { + resdevNext = resdevList->rdt_next; + freeMagic((char *)resdevList); + resdevList = resdevNext; + } } } HashKill(&DevNodeTable); diff --git a/resis/ResReadExt.c b/resis/ResReadExt.c index 7bd95c09..9ee11ef2 100644 --- a/resis/ResReadExt.c +++ b/resis/ResReadExt.c @@ -737,7 +737,7 @@ ResReadDevice(int argc, char *argv[]) { RDev *device; - int rvalue, i, j, k, w, l; + int rvalue, i, j, k, w, l, n; ExtDevice *devptr; TileType ttype; HashEntry *entry; @@ -791,13 +791,25 @@ ResReadDevice(int argc, * arbitrary number of terminals. */ - if (strcmp(argv[i], "None")) + /* See code in extflat/EFbuild.c: Devices do not necessarily + * declare a substrate terminal. This can be determined by + * noting that all terminals other than the substrate come in + * triplets of arguments, so if the remaining count of arguments + * is divisible by 3, then there is no substrate node, and if + * there is a remainder of 1, then there is. It would probably + * be simpler if all devices just put "None" in this position. + */ + n = argc - i; + if ((n % 3) == 1) /* Device has a substrate argument */ { - entry = HashFind(&ResNodeTable, argv[i]); - device->subs = (ResExtNode *)HashGetValue(entry); - ResNodeAddDevice(device->subs, device, SUBS); + if (strcmp(argv[i], "None")) + { + entry = HashFind(&ResNodeTable, argv[i]); + device->subs = (ResExtNode *)HashGetValue(entry); + ResNodeAddDevice(device->subs, device, SUBS); + } + i++; } - i++; entry = HashFind(&ResNodeTable, argv[i]); device->gate = (ResExtNode *)HashGetValue(entry); device->rs_gattr = StrDup((char **)NULL, argv[i + 2]);