diff --git a/resis/ResMain.c b/resis/ResMain.c index 8ced8b02..02ef74c4 100644 --- a/resis/ResMain.c +++ b/resis/ResMain.c @@ -867,6 +867,61 @@ resExpandDevFunc(tile, cx) return 1; } +/* + *------------------------------------------------------------------------- + * + * ResShaveContacts --- + * + * Remove the top layer off of every contact in the design, leaving + * only the bottom layer. This also resolves issues with stacked + * contacts by leaving clean contact areas where stacked types + * overlap. Contacts are removed from the plane above the search + * plane, so the removal does not corrupt the current plane search. + * + * Results: + * Return 0 to keep the search going. + * + *------------------------------------------------------------------------- + */ + +int +ResShaveContacts(tile, def) + Tile *tile; + CellDef *def; +{ + TileType ttype; + TileTypeBitMask *rmask; + Rect area; + Plane *plane; + int pNum; + int pMask; + + /* To do: Handle split tiles, although this is unlikely for + * contact types. + */ + ttype = TiGetType(tile); + + if (DBIsContact(ttype)) + { + /* Remove the contact type from the plane above */ + TiToRect(tile, &area); + pMask = DBTypePlaneMaskTbl[ttype]; + for (pNum = PL_TECHDEPBASE; pNum < DBNumPlanes; pNum++) + if (PlaneMaskHasPlane(pMask, pNum)) + break; + + for (++pNum; pNum < DBNumPlanes; pNum++) + if (PlaneMaskHasPlane(pMask, pNum)) + { + plane = def->cd_planes[pNum]; + DBPaintPlane(plane, &area, DBStdEraseTbl(ttype, pNum), + (PaintUndoInfo *)NULL); + } + } + + return 0; +} + /* *------------------------------------------------------------------------- * @@ -1028,6 +1083,21 @@ ResExtractNet(node, goodies, cellname) ExtResetTiles(scx.scx_use->cu_def, extUnInit); + /* To avoid issues with overlapping stacked contact types and */ + /* double-counting contacts on multiple planes, erase the top */ + /* contact layers of all contacts. ExtFindRegions() will still */ + /* find the connectivity above but will only process one tile per */ + /* contact. This temporarily creates an improper database, but */ + /* the contacts are all immediately erased by ResDissolveContacts().*/ + + for (pNum = PL_TECHDEPBASE; pNum < DBNumPlanes; pNum++) + { + Plane *plane = ResUse->cu_def->cd_planes[pNum]; + DBSrPaintArea(plane->pl_hint, plane, &(ResUse->cu_def->cd_bbox), + &DBAllButSpaceAndDRCBits, ResShaveContacts, + (ClientData)ResUse->cu_def); + } + /* Find all contacts in design and note their position */ /* NOTE: ExtFindRegions() will call ResFirst or ResEach for BOTH */ diff --git a/resis/ResMakeRes.c b/resis/ResMakeRes.c index 5c3a2f9f..4feeeb07 100644 --- a/resis/ResMakeRes.c +++ b/resis/ResMakeRes.c @@ -895,14 +895,7 @@ ResDoContacts(contact, nodes, resList) resistor->rr_cl = squaresy; resistor->rr_width = squaresx; - /* NOTE: ExtFindRegions() finds tiles on the top AND */ - /* bottom planes of the contact. So there are two */ - /* tile entries per contact, in parallel. To prevent */ - /* double-counting, double the resistance of each */ - /* entry; this is (probably?) easier than limiting the */ - /* entries to a single plane per contact. */ - - resistor->rr_value = 2.0 * + resistor->rr_value = (float)ExtCurStyle->exts_viaResist[contact->cp_type] / (float)(squaresx * squaresy); #ifdef ARIEL