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.
This commit is contained in:
Tim Edwards 2021-09-12 17:20:22 -04:00
parent 96b7c20c17
commit 02f42e7260
7 changed files with 131 additions and 136 deletions

View File

@ -1 +1 @@
8.3.205
8.3.206

View File

@ -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;

View File

@ -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;
}

View File

@ -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;

View File

@ -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. */

View File

@ -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);
}

View File

@ -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;