From 02f42e7260c7a4634b3e88d4fe3d3f2d35525197 Mon Sep 17 00:00:00 2001 From: Tim Edwards Date: Sun, 12 Sep 2021 17:20:22 -0400 Subject: [PATCH] Corrections to the extresist code. Some of the changes are just text formatting. Made one critical correction to ResGetDevice() to pass the device type; otherwise, devices on different planes (e.g., MiM caps) with the same coordinate will always return the device on the lowest plane, leading to incorrect results and an eventual crash when the device record is free'd twice. --- VERSION | 2 +- extract/ExtMain.c | 3 +- resis/ResMain.c | 36 ++++---- resis/ResMakeRes.c | 6 +- resis/ResMerge.c | 202 ++++++++++++++++++++++----------------------- resis/ResRex.c | 2 +- resis/ResSimple.c | 16 ++-- 7 files changed, 131 insertions(+), 136 deletions(-) diff --git a/VERSION b/VERSION index b5613efc..a42c3be2 100644 --- a/VERSION +++ b/VERSION @@ -1 +1 @@ -8.3.205 +8.3.206 diff --git a/extract/ExtMain.c b/extract/ExtMain.c index facdb3d8..7a081f85 100644 --- a/extract/ExtMain.c +++ b/extract/ExtMain.c @@ -291,7 +291,8 @@ ExtUnique(rootUse, option) while (def = (CellDef *) StackPop(extDefStack)) { /* EXT_UNIQ_NOTOPPORTS: Use EXT_UNIQ_ALL on all cells other than the top */ - if ((option == EXT_UNIQ_NOTOPPORTS) && (StackLook(extDefStack) != NULL)) + if ((option == EXT_UNIQ_NOTOPPORTS) && + (StackLook(extDefStack) != (ClientData)NULL)) locoption = EXT_UNIQ_ALL; else locoption = option; diff --git a/resis/ResMain.c b/resis/ResMain.c index d1371bea..2d76af70 100644 --- a/resis/ResMain.c +++ b/resis/ResMain.c @@ -1260,7 +1260,8 @@ FindStartTile(goodies, SourcePoint) * * ResGetDevice -- Once the net is extracted, we still have to equate * the sim file devices with the layout devices. ResGetDevice - * looks for a device at the given location. + * looks for a device at the given location. "type" is also + * specified to that the right plane will be searched. * * Results: returns device structure at location DevicePoint, if it * exists. @@ -1271,9 +1272,9 @@ FindStartTile(goodies, SourcePoint) */ resDevice * -ResGetDevice(pt) +ResGetDevice(pt, type) Point *pt; - + TileType type; { Point workingPoint; Tile *tile; @@ -1282,26 +1283,21 @@ ResGetDevice(pt) workingPoint.p_x = (*pt).p_x; workingPoint.p_y = (*pt).p_y; - for (pnum = PL_TECHDEPBASE; pnum < DBNumPlanes; pnum++) + pnum = DBPlane(type); + + /* Start at hint tile for device plane */ + + tile = ResUse->cu_def->cd_planes[pnum]->pl_hint; + GOTOPOINT(tile, &workingPoint); + + if (IsSplit(tile)) { - if (TTMaskIntersect(&ExtCurStyle->exts_deviceMask, &DBPlaneTypes[pnum]) == 0) - continue; - - /* Start at hint tile for device plane */ - - tile = ResUse->cu_def->cd_planes[pnum]->pl_hint; - GOTOPOINT(tile, &workingPoint); - - if (IsSplit(tile)) - { - if (TTMaskHasType(&ExtCurStyle->exts_deviceMask, TiGetLeftType(tile)) + if (TTMaskHasType(&ExtCurStyle->exts_deviceMask, TiGetLeftType(tile)) || TTMaskHasType(&ExtCurStyle->exts_deviceMask, TiGetRightType(tile))) - return (((tileJunk *)tile->ti_client)->deviceList); - } - else if (TTMaskHasType(&ExtCurStyle->exts_deviceMask, TiGetType(tile))) - { return (((tileJunk *)tile->ti_client)->deviceList); - } } + else if (TTMaskHasType(&ExtCurStyle->exts_deviceMask, TiGetType(tile))) + return (((tileJunk *)tile->ti_client)->deviceList); + return NULL; } diff --git a/resis/ResMakeRes.c b/resis/ResMakeRes.c index 29101a81..ddb4fe05 100644 --- a/resis/ResMakeRes.c +++ b/resis/ResMakeRes.c @@ -257,8 +257,8 @@ ResCalcEastWest(tile, pendingList, doneList, resList) #endif resistor->rr_value = (ExtCurStyle->exts_sheetResist[resistor->rr_tt] - * (p2->br_loc.p_x-p1->br_loc.p_x)) / height; - rArea = ((p2->br_loc.p_x-p1->br_loc.p_x) * height) / 2; + * (p2->br_loc.p_x - p1->br_loc.p_x)) / height; + rArea = ((p2->br_loc.p_x - p1->br_loc.p_x) * height) / 2; resistor->rr_connection1->rn_float.rn_area += rArea; resistor->rr_connection2->rn_float.rn_area += rArea; resistor->rr_float.rr_area = 0; @@ -425,7 +425,7 @@ ResCalcNorthSouth(tile, pendingList, doneList, resList) resistor->rr_value = (ExtCurStyle->exts_sheetResist[resistor->rr_tt] * (p2->br_loc.p_y - p1->br_loc.p_y)) / width; - rArea = ((p2->br_loc.p_y-p1->br_loc.p_y) * width) / 2; + rArea = ((p2->br_loc.p_y - p1->br_loc.p_y) * width) / 2; resistor->rr_connection1->rn_float.rn_area += rArea; resistor->rr_connection2->rn_float.rn_area += rArea; resistor->rr_float.rr_area = 0; diff --git a/resis/ResMerge.c b/resis/ResMerge.c index 4650d52e..ec611e6b 100644 --- a/resis/ResMerge.c +++ b/resis/ResMerge.c @@ -44,81 +44,79 @@ extern void ResFixBreakPoint(); void ResDoneWithNode(resptr) - resNode *resptr; + resNode *resptr; { - int status; - resNode *resptr2; - resElement *rcell1; - resResistor *rr1; + int status; + resNode *resptr2; + resElement *rcell1; + resResistor *rr1; - resptr2 = NULL; - resptr->rn_status |= TRUE; - status = UNTOUCHED; + resptr2 = NULL; + resptr->rn_status |= TRUE; + status = UNTOUCHED; - /* are there any resistors? */ + /* are there any resistors? */ - if (resptr->rn_re == NULL) return; + if (resptr->rn_re == NULL) return; - /* Special handling for geometry option */ + /* Special handling for geometry option */ - if (ResOptionsFlags & ResOpt_Geometry) return; + if (ResOptionsFlags & ResOpt_Geometry) return; - /* Eliminate resistors with connections to one terminal and */ - /* resistors with value 0. */ + /* Eliminate resistors with connections to one terminal and */ + /* resistors with value 0. */ - for (rcell1 = resptr->rn_re; rcell1 != NULL; rcell1 = rcell1->re_nextEl) - { - rr1 = rcell1->re_thisEl; - if (rr1->rr_connection1 == rr1->rr_connection2) - { - ResDeleteResPointer(resptr, rr1); - ResDeleteResPointer(resptr, rr1); - resptr->rn_float.rn_area += rr1->rr_float.rr_area; - ResEliminateResistor(rr1, &ResResList); - status = LOOP; - ResDoneWithNode(resptr); - break; + for (rcell1 = resptr->rn_re; rcell1 != NULL; rcell1 = rcell1->re_nextEl) + { + rr1 = rcell1->re_thisEl; + if (rr1->rr_connection1 == rr1->rr_connection2) + { + ResDeleteResPointer(resptr, rr1); + ResDeleteResPointer(resptr, rr1); + resptr->rn_float.rn_area += rr1->rr_float.rr_area; + ResEliminateResistor(rr1, &ResResList); + status = LOOP; + ResDoneWithNode(resptr); + break; - } - else if (rr1->rr_value == 0) - { - ResDeleteResPointer(rr1->rr_connection1, rr1); - ResDeleteResPointer(rr1->rr_connection2, rr1); - if (rr1->rr_connection1 == resptr) - { - resptr2 = rr1->rr_connection2; - }else - { - resptr2 = rr1->rr_connection1; - } - ResMergeNodes(resptr2, resptr, &ResNodeQueue, &ResNodeList); - resptr2->rn_float.rn_area += rr1->rr_float.rr_area; - ResEliminateResistor(rr1, &ResResList); - if ((resptr2->rn_status & TRUE) == TRUE) - { - resptr2->rn_status &= ~TRUE; - ResDoneWithNode(resptr2); - } - resptr2 = NULL; - status = SINGLE; - break; - } - } - if (status != UNTOUCHED) return; /* resptr may be invalid */ + } + else if (rr1->rr_value == 0) + { + ResDeleteResPointer(rr1->rr_connection1, rr1); + ResDeleteResPointer(rr1->rr_connection2, rr1); + if (rr1->rr_connection1 == resptr) + resptr2 = rr1->rr_connection2; + else + resptr2 = rr1->rr_connection1; - /* Eliminations that can be only if there are no devices connected */ - /* to node. Series and dangling connections fall in this group. */ + ResMergeNodes(resptr2, resptr, &ResNodeQueue, &ResNodeList); + resptr2->rn_float.rn_area += rr1->rr_float.rr_area; + ResEliminateResistor(rr1, &ResResList); + if ((resptr2->rn_status & TRUE) == TRUE) + { + resptr2->rn_status &= ~TRUE; + ResDoneWithNode(resptr2); + } + resptr2 = NULL; + status = SINGLE; + break; + } + } + if (status != UNTOUCHED) return; /* resptr may be invalid */ - if ((resptr->rn_te == NULL) && (resptr->rn_why != RES_NODE_ORIGIN) + /* Eliminations that can be only if there are no devices connected */ + /* to node. Series and dangling connections fall in this group. */ + + if ((resptr->rn_te == NULL) && (resptr->rn_why != RES_NODE_ORIGIN) && (status == UNTOUCHED)) - status = ResSeriesCheck(resptr); + status = ResSeriesCheck(resptr); - if ((status == UNTOUCHED) && (resptr->rn_why != RES_NODE_ORIGIN)) - status = ResParallelCheck(resptr); + if ((status == UNTOUCHED) && (resptr->rn_why != RES_NODE_ORIGIN)) + status = ResParallelCheck(resptr); - if ((status == UNTOUCHED) && (resptr->rn_why != RES_NODE_ORIGIN)) - status = ResTriangleCheck(resptr); + if ((status == UNTOUCHED) && (resptr->rn_why != RES_NODE_ORIGIN)) + status = ResTriangleCheck(resptr); } @@ -142,38 +140,38 @@ ResFixRes(resptr, resptr2, resptr3, elimResis, newResis) resResistor *elimResis, *newResis; { - resElement *thisREl; + resElement *thisREl; - resptr3->rn_float.rn_area += newResis->rr_value*resptr->rn_float.rn_area + resptr3->rn_float.rn_area += newResis->rr_value * resptr->rn_float.rn_area / ((float)(newResis->rr_value + elimResis->rr_value)); - resptr2->rn_float.rn_area += elimResis->rr_value*resptr->rn_float.rn_area + resptr2->rn_float.rn_area += elimResis->rr_value * resptr->rn_float.rn_area / ((float)(newResis->rr_value + elimResis->rr_value)); - newResis->rr_value += elimResis->rr_value; - ASSERT(newResis->rr_value > 0, "series"); - newResis->rr_float.rr_area += elimResis->rr_float.rr_area; + newResis->rr_value += elimResis->rr_value; + ASSERT(newResis->rr_value > 0, "series"); + newResis->rr_float.rr_area += elimResis->rr_float.rr_area; #ifdef ARIEL - if (elimResis->rr_csArea && elimResis->rr_csArea < newResis->rr_csArea + if (elimResis->rr_csArea && elimResis->rr_csArea < newResis->rr_csArea || newResis->rr_csArea == 0) - { - newResis->rr_csArea = elimResis->rr_csArea; - newResis->rr_tt = elimResis->rr_tt; - } + { + newResis->rr_csArea = elimResis->rr_csArea; + newResis->rr_tt = elimResis->rr_tt; + } #endif - for (thisREl = resptr3->rn_re; (thisREl != NULL); thisREl = thisREl->re_nextEl) - { - if (thisREl->re_thisEl == elimResis) - { - (thisREl->re_thisEl = newResis); - break; - } + for (thisREl = resptr3->rn_re; (thisREl != NULL); thisREl = thisREl->re_nextEl) + { + if (thisREl->re_thisEl == elimResis) + { + (thisREl->re_thisEl = newResis); + break; + } - } - if (thisREl == NULL) TxError("Resistor not found in duo\n"); - ResDeleteResPointer(resptr, elimResis); - ResDeleteResPointer(resptr, newResis); - ResEliminateResistor(elimResis, &ResResList); - ResCleanNode(resptr, TRUE, &ResNodeList, &ResNodeQueue); + } + if (thisREl == NULL) TxError("Resistor not found in duo\n"); + ResDeleteResPointer(resptr, elimResis); + ResDeleteResPointer(resptr, newResis); + ResEliminateResistor(elimResis, &ResResList); + ResCleanNode(resptr, TRUE, &ResNodeList, &ResNodeQueue); } /* @@ -192,28 +190,28 @@ ResFixRes(resptr, resptr2, resptr3, elimResis, newResis) void ResFixParallel(elimResis, newResis) - resResistor *elimResis, *newResis; + resResistor *elimResis, *newResis; { - if ((newResis->rr_value + elimResis->rr_value) != 0) - { - newResis->rr_value = (((float) newResis->rr_value) * + if ((newResis->rr_value + elimResis->rr_value) != 0) + { + newResis->rr_value = (((float) newResis->rr_value) * ((float)elimResis->rr_value)) / ((float)(newResis->rr_value + - elimResis->rr_value)); - ASSERT(newResis->rr_value >= 0, "parallel"); - } - else - { - newResis->rr_value = 0; - } - newResis->rr_float.rr_area += elimResis->rr_float.rr_area; + elimResis->rr_value)); + ASSERT(newResis->rr_value >= 0, "parallel"); + } + else + { + newResis->rr_value = 0; + } + newResis->rr_float.rr_area += elimResis->rr_float.rr_area; #ifdef ARIEL - newResis->rr_csArea += elimResis->rr_csArea; + newResis->rr_csArea += elimResis->rr_csArea; #endif - ResDeleteResPointer(elimResis->rr_connection1, elimResis); - ResDeleteResPointer(elimResis->rr_connection2, elimResis); - ResEliminateResistor(elimResis, &ResResList); + ResDeleteResPointer(elimResis->rr_connection1, elimResis); + ResDeleteResPointer(elimResis->rr_connection2, elimResis); + ResEliminateResistor(elimResis, &ResResList); } /* @@ -435,7 +433,7 @@ ResParallelCheck(resptr) { r2 = rcell2->re_thisEl; - if (TTMaskHasType(ResNoMergeMask+r1->rr_tt,r2->rr_tt)) continue; + if (TTMaskHasType(ResNoMergeMask+r1->rr_tt, r2->rr_tt)) continue; if (((r1->rr_connection1 == r2->rr_connection1) && (r1->rr_connection2 == r2->rr_connection2))|| ((r1->rr_connection1 == r2->rr_connection2) && @@ -540,7 +538,7 @@ ResTriangleCheck(resptr) } n3 = (resNode *)mallocMagic((unsigned)(sizeof(resNode))); - /* Where should the new node be `put'? It */ + /* Where should the new node be put? It */ /* is arbitrarily assigned to the location */ /* occupied by the first node. */ diff --git a/resis/ResRex.c b/resis/ResRex.c index a40d1d7c..372f0fb2 100644 --- a/resis/ResRex.c +++ b/resis/ResRex.c @@ -1660,7 +1660,7 @@ ResWriteExtFile(celldef, node, tol, rctol, nidx, eidx) } for (ptr = node->firstDev; ptr != NULL; ptr=ptr->nextDev) { - if (layoutDev = ResGetDevice(&ptr->thisDev->location)) + if (layoutDev = ResGetDevice(&ptr->thisDev->location, ptr->thisDev->rs_ttype)) { ResFixUpConnections(ptr->thisDev, layoutDev, node, newname); } diff --git a/resis/ResSimple.c b/resis/ResSimple.c index 698ba573..060c4392 100644 --- a/resis/ResSimple.c +++ b/resis/ResSimple.c @@ -542,7 +542,7 @@ ResScrunchNet(reslist, pendingList, biglist, tolerance) node1 = node2; } else - ResMergeNodes(node1,node2,pendingList,biglist); + ResMergeNodes(node1, node2, pendingList, biglist); /* * Try further simplification on net using ResDoneWithNode and @@ -553,7 +553,7 @@ ResScrunchNet(reslist, pendingList, biglist, tolerance) node1->rn_status &= ~(RES_DONE_ONCE | FINISHED); ResDoneWithNode(node1); while (*pendingList != NULL) - ResSimplifyNet(pendingList,biglist,reslist,tolerance); + ResSimplifyNet(pendingList, biglist, reslist, tolerance); } } @@ -651,7 +651,7 @@ ResDistributeCapacitance(nodelist, totalcap) } capperarea = FEMTOTOATTO * totalcap / totalarea; - for (workingNode = nodelist; workingNode != NULL; workingNode=workingNode->rn_more) + for (workingNode = nodelist; workingNode != NULL; workingNode = workingNode->rn_more) workingNode->rn_float.rn_area *= capperarea; } @@ -719,7 +719,7 @@ ResCalculateChildCapacitance(me) } /* Calculate child Capacitance */ - for (workingRes = me->rn_re; workingRes != NULL; workingRes=workingRes->re_nextEl) + for (workingRes = me->rn_re; workingRes != NULL; workingRes = workingRes->re_nextEl) { if (workingRes->re_thisEl->rr_connection1 == me && (workingRes->re_thisEl->rr_status & RES_TDI_IGNORE) == 0) @@ -864,13 +864,13 @@ ResDoSimplify(tolerance, rctol, goodies) resRemoveLoops = FALSE; ResSetPathRes(); for (node = ResNodeList; node != NULL; node = node->rn_more) - bigres = MAX(bigres,node->rn_noderes); + bigres = MAX(bigres, node->rn_noderes); bigres /= OHMSTOMILLIOHMS; /* convert from milliohms to ohms */ goodies->rg_maxres = bigres; #ifdef PARANOID - ResSanityChecks("ExtractSingleNet",ResResList,ResNodeList,ResDevList); + ResSanityChecks("ExtractSingleNet", ResResList, ResNodeList, ResDevList); #endif /* Is extracted network still greater than the tolerance? */ @@ -986,13 +986,13 @@ ResDoSimplify(tolerance, rctol, goodies) ResOriginNode->rn_less = NULL; ResNodeQueue = ResOriginNode; while (ResNodeQueue != NULL) - ResSimplifyNet(&ResNodeQueue,&ResNodeList,&ResResList,millitolerance); + ResSimplifyNet(&ResNodeQueue, &ResNodeList, &ResResList, millitolerance); /* * Call ResScrunchNet to eliminate any remaining under tolerance * resistors. */ - ResScrunchNet(&ResResList,&ResNodeQueue,&ResNodeList,millitolerance); + ResScrunchNet(&ResResList, &ResNodeQueue, &ResNodeList, millitolerance); } } return 0;