Made various updates and corrections to the "extresist" code in

support of devices with terminals on different plances, such as
capacitors, diodes, and bipolar transistors.  Output now appears
to give meaningful results for flattened layouts, although
numerous issues remain for hierarchical layouts.
This commit is contained in:
Tim Edwards 2021-09-08 16:41:36 -04:00
parent 0ebdf3e513
commit d63a102515
9 changed files with 586 additions and 392 deletions

View File

@ -1 +1 @@
8.3.203 8.3.204

View File

@ -109,12 +109,43 @@ resAllPortNodes(tile, list)
} }
} }
/*
*--------------------------------------------------------------------------
*
* ResMultiPlaneFunc---
*
* If device is found overlapping one of its source/drain types, then
* generate a new device at the center of the tile and add to ResNodeQueue.
*
* Results:
* Always 0 to keep the search going.
*
* Side effects:
* Adds to ResNodeQueue
*
*--------------------------------------------------------------------------
*/
int
ResMultiPlaneFunc(tile, tpptr)
Tile *tile, **tpptr;
{
Tile *tp = *tpptr;
int xj, yj;
xj = (LEFT(tile) + RIGHT(tile)) / 2;
yj = (TOP(tile) + BOTTOM(tile)) / 2;
ResNewSDDevice(tp, tile, xj, yj, OTHERPLANE, &ResNodeQueue);
return 0;
}
/* /*
*-------------------------------------------------------------------------- *--------------------------------------------------------------------------
* *
* ResEachTile--for each tile, make a list of all possible current sources/ * ResEachTile--for each tile, make a list of all possible current sources/
* sinks including contacts, devices, and junctions. Once this * sinks including contacts, devices, and junctions. Once this
* list is made, calculate the resistor nextwork for the tile. * list is made, calculate the resistor network for the tile.
* *
* Results: returns TRUE or FALSE depending on whether a node was * Results: returns TRUE or FALSE depending on whether a node was
* involved in a merge. * involved in a merge.
@ -197,35 +228,6 @@ ResEachTile(tile, startpoint)
} }
} }
#ifdef ARIEL
if (i = ExtCurStyle->exts_plugSignalNum[t1])
{
tcell = (tElement *) mallocMagic((unsigned)(sizeof(tElement)));
tcell->te_thist= ResImageAddPlug(tile, i, resCurrentNode);
tcell->te_nextt = resCurrentNode->rn_te;
resCurrentNode->rn_te = tcell;
}
if (TTMaskHasType(&ResSubsTypeBitMask,t1) &&
(ResOptionsFlags & ResOpt_DoSubstrate))
{
int pNum;
Rect tileArea;
TileTypeBitMask *mask = &ExtCurStyle->exts_subsTransistorTypes[t1];
TiToRect(tile,&tileArea);
for (pNum = PL_TECHDEPBASE; pNum < DBNumPlanes; pNum++)
{
if (TTMaskIntersect(&DBPlaneTypes[pNum], mask))
{
(void)DBSrPaintArea((Tile *) NULL,
ResUse->cu_def->cd_planes[pNum],
&tileArea, mask, resSubDevFunc, (ClientData) tile);
}
}
}
#endif
/* Process all the contact points */ /* Process all the contact points */
ce = tstructs->contactList; ce = tstructs->contactList;
while (ce != (cElement *) NULL) while (ce != (cElement *) NULL)
@ -252,7 +254,7 @@ ResEachTile(tile, startpoint)
{ {
t2 = TiGetRightType(tp); t2 = TiGetRightType(tp);
devptr = ExtCurStyle->exts_device[t2]; devptr = ExtCurStyle->exts_device[t2];
if(TTMaskHasType(&(ExtCurStyle->exts_deviceMask), t2) && if (TTMaskHasType(&(ExtCurStyle->exts_deviceMask), t2) &&
TTMaskHasType(&(devptr->exts_deviceSDTypes[0]), t1)) TTMaskHasType(&(devptr->exts_deviceSDTypes[0]), t1))
/* found device */ /* found device */
{ {
@ -275,7 +277,7 @@ ResEachTile(tile, startpoint)
{ {
t2 = TiGetLeftType(tp); t2 = TiGetLeftType(tp);
devptr = ExtCurStyle->exts_device[t2]; devptr = ExtCurStyle->exts_device[t2];
if(TTMaskHasType(&(ExtCurStyle->exts_deviceMask), t2) && if (TTMaskHasType(&(ExtCurStyle->exts_deviceMask), t2) &&
TTMaskHasType(&(devptr->exts_deviceSDTypes[0]), t1)) TTMaskHasType(&(devptr->exts_deviceSDTypes[0]), t1))
/* found device */ /* found device */
{ {
@ -298,13 +300,13 @@ ResEachTile(tile, startpoint)
{ {
t2 = TiGetBottomType(tp); t2 = TiGetBottomType(tp);
devptr = ExtCurStyle->exts_device[t2]; devptr = ExtCurStyle->exts_device[t2];
if(TTMaskHasType(&(ExtCurStyle->exts_deviceMask),t2) && if (TTMaskHasType(&(ExtCurStyle->exts_deviceMask), t2) &&
TTMaskHasType(&(devptr->exts_deviceSDTypes[0]),t1)) TTMaskHasType(&(devptr->exts_deviceSDTypes[0]), t1))
/* found device */ /* found device */
{ {
yj = TOP(tile); yj = TOP(tile);
xj = (LEFT(tp)+RIGHT(tp))>>1; xj = (LEFT(tp)+RIGHT(tp))>>1;
ResNewSDDevice(tile,tp,xj,yj,BOTTOMEDGE, &ResNodeQueue); ResNewSDDevice(tile, tp, xj, yj, BOTTOMEDGE, &ResNodeQueue);
} }
if TTMaskHasType(&ExtCurStyle->exts_nodeConn[t1],t2) if TTMaskHasType(&ExtCurStyle->exts_nodeConn[t1],t2)
/* tile is junction */ /* tile is junction */
@ -320,7 +322,7 @@ ResEachTile(tile, startpoint)
{ {
t2 = TiGetTopType(tp); t2 = TiGetTopType(tp);
devptr = ExtCurStyle->exts_device[t2]; devptr = ExtCurStyle->exts_device[t2];
if(TTMaskHasType(&(ExtCurStyle->exts_deviceMask), t2) && if (TTMaskHasType(&(ExtCurStyle->exts_deviceMask), t2) &&
TTMaskHasType(&(devptr->exts_deviceSDTypes[0]), t1)) TTMaskHasType(&(devptr->exts_deviceSDTypes[0]), t1))
/* found device */ /* found device */
{ {
@ -336,6 +338,38 @@ ResEachTile(tile, startpoint)
ResProcessJunction(tile, tp, xj, yj, &ResNodeQueue); ResProcessJunction(tile, tp, xj, yj, &ResNodeQueue);
} }
} }
/* Check for source/drain on other planes (e.g., capacitors, bipolars, ...) */
if (TTMaskHasType(&ResSDTypesBitMask, t1))
{
Rect r;
int pNum;
TileTypeBitMask devMask;
TiToRect(tile, &r);
for (pNum = 0; pNum < DBNumPlanes; pNum++)
{
if (DBTypeOnPlane(t1, pNum)) continue;
/* NOTE: This is ridiculously inefficient and should be done
* in a different way.
*/
TTMaskZero(&devMask);
for (t2 = TT_TECHDEPBASE; t2 < DBNumUserLayers; t2++)
for (devptr = ExtCurStyle->exts_device[t2]; devptr;
devptr = devptr->exts_next)
for (i = 0; !TTMaskIsZero(&devptr->exts_deviceSDTypes[i]); i++)
if (TTMaskHasType(&devptr->exts_deviceSDTypes[i], t1))
TTMaskSetType(&devMask, t2);
DBSrPaintArea((Tile *)NULL, ResUse->cu_def->cd_planes[pNum],
&r, &devMask, ResMultiPlaneFunc, (ClientData)&tile);
}
}
tstructs->tj_status |= RES_TILE_DONE; tstructs->tj_status |= RES_TILE_DONE;
resAllPortNodes(tile, &ResNodeQueue); resAllPortNodes(tile, &ResNodeQueue);
@ -361,31 +395,29 @@ ResEachTile(tile, startpoint)
int int
resSubDevFunc(tile,tp) resSubDevFunc(tile,tp)
Tile *tile,*tp; Tile *tile, *tp;
{ {
tileJunk *junk = (tileJunk *)(tile->ti_client); tileJunk *junk = (tileJunk *)(tile->ti_client);
resNode *resptr; resNode *resptr;
tElement *tcell; tElement *tcell;
int x,y; int x, y;
if (junk->deviceList->rd_fet_subs == NULL) if (junk->deviceList->rd_fet_subs == NULL)
{ {
resptr = (resNode *) mallocMagic((unsigned)(sizeof(resNode))); resptr = (resNode *) mallocMagic((unsigned)(sizeof(resNode)));
junk->deviceList->rd_fet_subs = resptr; junk->deviceList->rd_fet_subs = resptr;
junk->tj_status |= RES_TILE_DEV; junk->tj_status |= RES_TILE_DEV;
tcell = (tElement *) mallocMagic((unsigned)(sizeof(tElement))); tcell = (tElement *) mallocMagic((unsigned)(sizeof(tElement)));
tcell->te_thist = junk->deviceList; tcell->te_thist = junk->deviceList;
tcell->te_nextt = NULL; tcell->te_nextt = NULL;
x = (LEFT(tile)+RIGHT(tile))>>1; x = (LEFT(tile) + RIGHT(tile)) >> 1;
y = (TOP(tile)+BOTTOM(tile))>>1; y = (TOP(tile) + BOTTOM(tile)) >> 1;
InitializeNode(resptr,x,y,RES_NODE_JUNCTION); InitializeNode(resptr, x, y, RES_NODE_JUNCTION);
resptr->rn_te = tcell; resptr->rn_te = tcell;
ResAddToQueue(resptr,&ResNodeQueue); ResAddToQueue(resptr, &ResNodeQueue);
NEWBREAK(resptr,tp,x,y,NULL); NEWBREAK(resptr, tp, x, y, NULL);
} }
return 0; return 0;
} }

View File

@ -43,6 +43,7 @@ extern Tile *FindStartTile();
extern int ResEachTile(); extern int ResEachTile();
extern int ResLaplaceTile(); extern int ResLaplaceTile();
extern ResSimNode *ResInitializeNode(); extern ResSimNode *ResInitializeNode();
TileTypeBitMask ResSDTypesBitMask;
extern HashTable ResNodeTable; extern HashTable ResNodeTable;
@ -139,43 +140,33 @@ ResGetReCell()
*/ */
void void
ResDissolveContacts(contacts) ResDissolveContacts(contacts)
ResContactPoint *contacts; ResContactPoint *contacts;
{ {
TileType t, oldtype; TileType t, oldtype;
Tile *tp; Tile *tp;
TileTypeBitMask residues; TileTypeBitMask residues;
for (; contacts != (ResContactPoint *) NULL; contacts = contacts->cp_nextcontact) for (; contacts != (ResContactPoint *) NULL; contacts = contacts->cp_nextcontact)
{ {
oldtype=contacts->cp_type; oldtype=contacts->cp_type;
#ifdef PARANOID #ifdef PARANOID
if (oldtype == TT_SPACE) if (oldtype == TT_SPACE)
{
TxError("Error in Contact Dissolving for %s \n",ResCurrentNode); TxError("Error in Contact Dissolving for %s \n",ResCurrentNode);
}
#endif #endif
DBFullResidueMask(oldtype, &residues); DBFullResidueMask(oldtype, &residues);
DBErase(ResUse->cu_def, &(contacts->cp_rect), oldtype); DBErase(ResUse->cu_def, &(contacts->cp_rect), oldtype);
for (t = TT_TECHDEPBASE; t < DBNumTypes; t++) for (t = TT_TECHDEPBASE; t < DBNumTypes; t++)
{
if (TTMaskHasType(&residues, t)) if (TTMaskHasType(&residues, t))
{
if (TTMaskHasType(&ExtCurStyle->exts_deviceMask, t))
continue;
DBPaint(ResUse->cu_def, &(contacts->cp_rect), t); DBPaint(ResUse->cu_def, &(contacts->cp_rect), t);
}
}
tp = ResDef->cd_planes[DBPlane(contacts->cp_type)]->pl_hint; tp = ResDef->cd_planes[DBPlane(contacts->cp_type)]->pl_hint;
GOTOPOINT(tp, &(contacts->cp_rect.r_ll)); GOTOPOINT(tp, &(contacts->cp_rect.r_ll));
#ifdef PARANOID #ifdef PARANOID
if (TiGetTypeExact(tp) == contacts->cp_type) if (TiGetTypeExact(tp) == contacts->cp_type)
{
TxError("Error in Contact Preprocess Routines\n"); TxError("Error in Contact Preprocess Routines\n");
}
#endif #endif
} }
} }
@ -494,7 +485,7 @@ ResProcessTiles(goodies, origin)
if ((j->tj_status & RES_TILE_DONE) == 0) if ((j->tj_status & RES_TILE_DONE) == 0)
{ {
resCurrentNode = resptr2; resCurrentNode = resptr2;
merged |= (*tilefunc)(tile,(Point *)NULL); merged |= (*tilefunc)(tile, (Point *)NULL);
} }
if (merged & ORIGIN) break; if (merged & ORIGIN) break;
} }
@ -505,9 +496,9 @@ ResProcessTiles(goodies, origin)
/* Next, Process all contacts. */ /* Next, Process all contacts. */
for (workingc = resptr2->rn_ce;workingc != NULL;workingc = workingc->ce_nextc) for (workingc = resptr2->rn_ce; workingc != NULL; workingc = workingc->ce_nextc)
{ {
ResContactPoint *cp = workingc->ce_thisc; ResContactPoint *cp = workingc->ce_thisc;
if (merged & ORIGIN) break; if (merged & ORIGIN) break;
if (cp->cp_status == FALSE) if (cp->cp_status == FALSE)
@ -627,7 +618,7 @@ ResCalcPerimOverlap(tile, dev)
if TTMaskHasType(omask, TiGetType(tp)) if TTMaskHasType(omask, TiGetType(tp))
overlap += MIN(RIGHT(tile), RIGHT(tp)) - MAX(LEFT(tile), LEFT(tp)); overlap += MIN(RIGHT(tile), RIGHT(tp)) - MAX(LEFT(tile), LEFT(tp));
} }
dev->overlap = overlap; dev->overlap += overlap;
} }
/* /*
*------------------------------------------------------------------------- *-------------------------------------------------------------------------
@ -635,7 +626,7 @@ ResCalcPerimOverlap(tile, dev)
* resMakeDevFunc -- * resMakeDevFunc --
* *
* Callback function from ResExtractNet. For each device in a node's * Callback function from ResExtractNet. For each device in a node's
* device list pulled from the .sim file, find the tile corresponding * device list pulled from the .sim file, find the tile(s) corresponding
* to the device in the source tree, and fill out the complete device * to the device in the source tree, and fill out the complete device
* record (namely the full device area). * record (namely the full device area).
* *
@ -656,7 +647,6 @@ resMakeDevFunc(tile, cx)
TiToRect(tile, &devArea); TiToRect(tile, &devArea);
GeoTransRect(&cx->tc_scx->scx_trans, &devArea, &thisDev->area); GeoTransRect(&cx->tc_scx->scx_trans, &devArea, &thisDev->area);
ResCalcPerimOverlap(tile, thisDev);
if (IsSplit(tile)) if (IsSplit(tile))
ttype = (SplitSide(tile)) ? SplitRightType(tile) : SplitLeftType(tile); ttype = (SplitSide(tile)) ? SplitRightType(tile) : SplitLeftType(tile);
@ -675,10 +665,137 @@ resMakeDevFunc(tile, cx)
return 0; /* Completely different device? */ return 0; /* Completely different device? */
thisDev->type = ttype; thisDev->type = ttype;
} }
return 1;
}
/*
*-------------------------------------------------------------------------
*
* resExpandDevFunc --
*
* Do a boundary search on the first tile found in the search context
* path belonging to a device, including all tiles that belong to the
* device. For each compatible tile found, paint the device tile
* type into ResUse and calculate the overlap.
*
* Returns:
* 1 to stop the search (only the first tile of a device needs to be
* found).
*
* Side effects:
* Paints into ResUse and recalculates values of thisDev.
*-------------------------------------------------------------------------
*/
#define DEV_PROCESSED 1
int
resExpandDevFunc(tile, cx)
Tile *tile;
TreeContext *cx;
{
ResDevTile *thisDev = (ResDevTile *)cx->tc_filter->tf_arg;
static Stack *devExtentsStack = NULL;
static Stack *devResetStack = NULL;
TileTypeBitMask *rMask;
Tile *tp, *tp2;
TileType ttype;
int pNum;
Rect area;
pNum = DBPlane(thisDev->type);
if (devExtentsStack == NULL)
devExtentsStack = StackNew(8);
if (devResetStack == NULL)
devResetStack = StackNew(8);
tile->ti_client = (ClientData)DEV_PROCESSED;
STACKPUSH((ClientData)tile, devExtentsStack);
while (!StackEmpty(devExtentsStack))
{
tp = (Tile *) STACKPOP(devExtentsStack);
STACKPUSH((ClientData)tp, devResetStack);
TiToRect(tp, &area);
/* Paint type thisDev->type into ResUse over area of tile "tp" */
DBNMPaintPlane(ResUse->cu_def->cd_planes[pNum], TiGetTypeExact(tp),
&area, DBStdPaintTbl(thisDev->type, pNum), (PaintUndoInfo *)NULL);
/* Add source/drain perimeter overlap to the device for this tile */
ResCalcPerimOverlap(tp, thisDev);
/* Search boundary of the device tile for more tiles belonging */
/* to the device. If contacts are found, replace them with the */
/* device type. */
/* top */
for (tp2 = RT(tp); RIGHT(tp2) > LEFT(tp); tp2 = BL(tp2))
{
if (tp2->ti_client == (ClientData)DEV_PROCESSED) continue;
ttype = TiGetBottomType(tp2);
if ((ttype == thisDev->type) || (DBIsContact(ttype)
&& TTMaskHasType(DBResidueMask(ttype), thisDev->type)))
{
tp2->ti_client = (ClientData)DEV_PROCESSED;
STACKPUSH((ClientData)tp2, devExtentsStack);
}
}
/* bottom */
for (tp2 = LB(tp); LEFT(tp2) < RIGHT(tp); tp2 = TR(tp2))
{
if (tp2->ti_client == (ClientData)DEV_PROCESSED) continue;
ttype = TiGetTopType(tp2);
if ((ttype == thisDev->type) || (DBIsContact(ttype)
&& TTMaskHasType(DBResidueMask(ttype), thisDev->type)))
{
tp2->ti_client = (ClientData)DEV_PROCESSED;
STACKPUSH((ClientData)tp2, devExtentsStack);
}
}
/* right */
for (tp2 = TR(tp); TOP(tp2) > BOTTOM(tp); tp2 = LB(tp2))
{
if (tp2->ti_client == (ClientData)DEV_PROCESSED) continue;
ttype = TiGetLeftType(tp2);
if ((ttype == thisDev->type) || (DBIsContact(ttype)
&& TTMaskHasType(DBResidueMask(ttype), thisDev->type)))
{
tp2->ti_client = (ClientData)DEV_PROCESSED;
STACKPUSH((ClientData)tp2, devExtentsStack);
}
}
/* left */
for (tp2 = BL(tp); BOTTOM(tp2) < TOP(tp); tp2 = RT(tp2))
{
if (tp2->ti_client == (ClientData)DEV_PROCESSED) continue;
ttype = TiGetRightType(tp2);
if ((ttype == thisDev->type) || (DBIsContact(ttype)
&& TTMaskHasType(DBResidueMask(ttype), thisDev->type)))
{
tp2->ti_client = (ClientData)DEV_PROCESSED;
STACKPUSH((ClientData)tp2, devExtentsStack);
}
}
}
/* Reset the device tile client records */
while (!StackEmpty(devResetStack))
{
tp = (Tile *) STACKPOP(devResetStack);
tp->ti_client = (ClientData)CLIENTDEFAULT;
}
/* Return 1 to stop the search; we only need to run this from */
/* the first device tile. */
return 1; return 1;
} }
/* /*
*------------------------------------------------------------------------- *-------------------------------------------------------------------------
* *
@ -700,14 +817,16 @@ ResExtractNet(node, goodies, cellname)
char *cellname; char *cellname;
{ {
SearchContext scx; SearchContext scx;
int pNum;
TileTypeBitMask FirstTileMask; TileTypeBitMask FirstTileMask;
TileTypeBitMask tMask;
Point startpoint; Point startpoint;
static int first = 1; static int first = 1;
ResDevTile *DevTiles, *thisDev; ResDevTile *DevTiles, *thisDev;
ResFixPoint *fix; ResFixPoint *fix;
devPtr *tptr; devPtr *tptr;
int pNum;
int resMakeDevFunc(); int resMakeDevFunc();
int resExpandDevFunc();
/* Make sure all global network variables are reset */ /* Make sure all global network variables are reset */
@ -783,15 +902,20 @@ ResExtractNet(node, goodies, cellname)
DBTreeCopyConnect(&scx, &FirstTileMask, 0, ResCopyMask, &TiPlaneRect, DBTreeCopyConnect(&scx, &FirstTileMask, 0, ResCopyMask, &TiPlaneRect,
SEL_DO_LABELS, ResUse); SEL_DO_LABELS, ResUse);
TTMaskZero(&ResSDTypesBitMask);
/* Add devices to ResUse from list in node */ /* Add devices to ResUse from list in node */
DevTiles = NULL; DevTiles = NULL;
for (tptr = node->firstDev; tptr; tptr = tptr->nextDev) for (tptr = node->firstDev; tptr; tptr = tptr->nextDev)
{ {
int result; int result;
int i;
ExtDevice *devptr;
thisDev = (ResDevTile *)mallocMagic(sizeof(ResDevTile)); thisDev = (ResDevTile *)mallocMagic(sizeof(ResDevTile));
thisDev->devptr = tptr->thisDev->rs_devptr; thisDev->devptr = tptr->thisDev->rs_devptr;
thisDev->type = tptr->thisDev->rs_ttype; thisDev->type = tptr->thisDev->rs_ttype;
thisDev->overlap = 0;
scx.scx_area.r_ll.p_x = tptr->thisDev->location.p_x; scx.scx_area.r_ll.p_x = tptr->thisDev->location.p_x;
scx.scx_area.r_ll.p_y = tptr->thisDev->location.p_y; scx.scx_area.r_ll.p_y = tptr->thisDev->location.p_y;
scx.scx_area.r_xtop = scx.scx_area.r_xbot + 1; scx.scx_area.r_xtop = scx.scx_area.r_xbot + 1;
@ -810,10 +934,18 @@ ResExtractNet(node, goodies, cellname)
thisDev->nextDev = DevTiles; thisDev->nextDev = DevTiles;
DevTiles = thisDev; DevTiles = thisDev;
/* Paint the type into ResUse */ /* Paint the entire device into ResUse */
pNum = DBPlane(thisDev->type); TTMaskSetOnlyType(&tMask, thisDev->type);
DBPaintPlane(ResUse->cu_def->cd_planes[pNum], &thisDev->area, DBTreeSrTiles(&scx, &tMask, 0, resExpandDevFunc, (ClientData)thisDev);
DBStdPaintTbl(thisDev->type, pNum), (PaintUndoInfo *)NULL);
/* If the device has source/drain types in a different plane than */
/* the device identifier type, then add the source/drain types to */
/* the mask ResSDTypesBitMask. */
for (devptr = ExtCurStyle->exts_device[thisDev->type]; devptr;
devptr = devptr->exts_next)
for (i = 0; !TTMaskIsZero(&devptr->exts_deviceSDTypes[i]); i++)
TTMaskSetMask(&ResSDTypesBitMask, &devptr->exts_deviceSDTypes[i]);
} }
DBReComputeBbox(ResUse->cu_def); DBReComputeBbox(ResUse->cu_def);

View File

@ -46,7 +46,6 @@ bool ResCalcEastWest();
* Side Effects: Resistor structures are produced. Some nodes may be * Side Effects: Resistor structures are produced. Some nodes may be
* eliminated. * eliminated.
*-------------------------------------------------------------------------- *--------------------------------------------------------------------------
*
*/ */
bool bool
@ -136,7 +135,7 @@ ResCalcEastWest(tile, pendingList, doneList, resList)
height = TOP(tile) - BOTTOM(tile); height = TOP(tile) - BOTTOM(tile);
/* /*
* One Breakpoint? No resistors need to be made. Free up the first * One Breakpoint? No resistors need to be made. Free up the first
* breakpoint, then return. * breakpoint, then return.
*/ */
@ -149,7 +148,7 @@ ResCalcEastWest(tile, pendingList, doneList, resList)
return(merged); return(merged);
} }
/* re-sort nodes left to right. */ /* Re-sort nodes left to right. */
ResSortBreaks(&junk->breakList, TRUE); ResSortBreaks(&junk->breakList, TRUE);
@ -160,9 +159,9 @@ ResCalcEastWest(tile, pendingList, doneList, resList)
p2= junk->breakList; p2= junk->breakList;
/* add extra left area to leftmost node */ /* Add extra left area to leftmost node */
p2->br_this->rn_float.rn_area += height*(p2->br_loc.p_x-LEFT(tile)); p2->br_this->rn_float.rn_area += height * (p2->br_loc.p_x - LEFT(tile));
while (p2->br_next != NULL) while (p2->br_next != NULL)
{ {
p1 = p2; p1 = p2;
@ -179,7 +178,7 @@ ResCalcEastWest(tile, pendingList, doneList, resList)
else if (p2->br_this == resCurrentNode) else if (p2->br_this == resCurrentNode)
{ {
currNode = p1->br_this; currNode = p1->br_this;
ResMergeNodes(p2->br_this,p1->br_this,pendingList,doneList); ResMergeNodes(p2->br_this, p1->br_this, pendingList, doneList);
merged = TRUE; merged = TRUE;
freeMagic((char *)p1); freeMagic((char *)p1);
} }
@ -187,7 +186,7 @@ ResCalcEastWest(tile, pendingList, doneList, resList)
{ {
currNode = p2->br_this; currNode = p2->br_this;
p1->br_next = p2->br_next; p1->br_next = p2->br_next;
ResMergeNodes(p1->br_this,p2->br_this,pendingList,doneList); ResMergeNodes(p1->br_this, p2->br_this, pendingList, doneList);
merged = TRUE; merged = TRUE;
freeMagic((char *)p2); freeMagic((char *)p2);
p2 = p1; p2 = p1;
@ -195,7 +194,7 @@ ResCalcEastWest(tile, pendingList, doneList, resList)
else else
{ {
currNode = p1->br_this; currNode = p1->br_this;
ResMergeNodes(p2->br_this,p1->br_this,pendingList,doneList); ResMergeNodes(p2->br_this, p1->br_this, pendingList, doneList);
freeMagic((char *)p1); freeMagic((char *)p1);
} }
@ -203,13 +202,13 @@ ResCalcEastWest(tile, pendingList, doneList, resList)
* Was the node used in another junk or breakpoint? * Was the node used in another junk or breakpoint?
* If so, replace the old node with the new one. * If so, replace the old node with the new one.
*/ */
p3 = p2->br_next; p3 = p2->br_next;
while (p3 != NULL) while (p3 != NULL)
{ {
if (p3->br_this == currNode) if (p3->br_this == currNode)
{
p3->br_this = p2->br_this; p3->br_this = p2->br_this;
}
p3 = p3->br_next; p3 = p3->br_next;
} }
} }
@ -221,18 +220,18 @@ ResCalcEastWest(tile, pendingList, doneList, resList)
else else
{ {
resistor = (resResistor *) mallocMagic((unsigned) (sizeof(resResistor))); resistor = (resResistor *)mallocMagic((unsigned)sizeof(resResistor));
resistor->rr_nextResistor = (*resList); resistor->rr_nextResistor = (*resList);
resistor->rr_lastResistor = NULL; resistor->rr_lastResistor = NULL;
if ((*resList) != NULL) (*resList)->rr_lastResistor = resistor; if ((*resList) != NULL) (*resList)->rr_lastResistor = resistor;
(*resList) = resistor; (*resList) = resistor;
resistor->rr_connection1 = p1->br_this; resistor->rr_connection1 = p1->br_this;
resistor->rr_connection2 = p2->br_this; resistor->rr_connection2 = p2->br_this;
element = (resElement *) mallocMagic((unsigned) (sizeof(resElement))); element = (resElement *)mallocMagic((unsigned)sizeof(resElement));
element->re_nextEl = p1->br_this->rn_re; element->re_nextEl = p1->br_this->rn_re;
element->re_thisEl = resistor; element->re_thisEl = resistor;
p1->br_this->rn_re = element; p1->br_this->rn_re = element;
element = (resElement *) mallocMagic((unsigned) (sizeof(resElement))); element = (resElement *)mallocMagic((unsigned)sizeof(resElement));
element->re_nextEl = p2->br_this->rn_re; element->re_nextEl = p2->br_this->rn_re;
element->re_thisEl = resistor; element->re_thisEl = resistor;
p2->br_this->rn_re = element; p2->br_this->rn_re = element;
@ -246,7 +245,6 @@ ResCalcEastWest(tile, pendingList, doneList, resList)
resistor->rr_status = RES_DIAGONAL; resistor->rr_status = RES_DIAGONAL;
resistor->rr_status |= (SplitDirection(tile)) ? RES_NS resistor->rr_status |= (SplitDirection(tile)) ? RES_NS
: RES_EW; : RES_EW;
} }
else else
{ {
@ -268,10 +266,11 @@ ResCalcEastWest(tile, pendingList, doneList, resList)
freeMagic((char *)p1); freeMagic((char *)p1);
} }
} }
p2->br_this->rn_float.rn_area += height * (RIGHT(tile) - p2->br_loc.p_x); p2->br_this->rn_float.rn_area += height * (RIGHT(tile) - p2->br_loc.p_x);
freeMagic((char *)p2); freeMagic((char *)p2);
junk->breakList = NULL; junk->breakList = NULL;
return(merged); return merged;
} }
@ -303,7 +302,7 @@ ResCalcNorthSouth(tile, pendingList, doneList, resList)
tileJunk *junk = (tileJunk *)tile->ti_client; tileJunk *junk = (tileJunk *)tile->ti_client;
merged = FALSE; merged = FALSE;
width = RIGHT(tile)-LEFT(tile); width = RIGHT(tile) - LEFT(tile);
/* /*
* One Breakpoint? No resistors need to be made. Free up the first * One Breakpoint? No resistors need to be made. Free up the first
@ -319,7 +318,7 @@ ResCalcNorthSouth(tile, pendingList, doneList, resList)
return(merged); return(merged);
} }
/* re-sort nodes south to north. */ /* Re-sort nodes south to north. */
ResSortBreaks(&junk->breakList, FALSE); ResSortBreaks(&junk->breakList, FALSE);
/* /*
@ -329,7 +328,7 @@ ResCalcNorthSouth(tile, pendingList, doneList, resList)
p2 = junk->breakList; p2 = junk->breakList;
/* add extra left area to leftmost node */ /* Add extra left area to leftmost node */
p2->br_this->rn_float.rn_area += width * (p2->br_loc.p_y - BOTTOM(tile)); p2->br_this->rn_float.rn_area += width * (p2->br_loc.p_y - BOTTOM(tile));
while (p2->br_next != NULL) while (p2->br_next != NULL)
@ -348,7 +347,7 @@ ResCalcNorthSouth(tile, pendingList, doneList, resList)
else if (p2->br_this == resCurrentNode) else if (p2->br_this == resCurrentNode)
{ {
currNode = p1->br_this; currNode = p1->br_this;
ResMergeNodes(p2->br_this,p1->br_this,pendingList,doneList); ResMergeNodes(p2->br_this, p1->br_this, pendingList, doneList);
freeMagic((char *)p1); freeMagic((char *)p1);
merged = TRUE; merged = TRUE;
} }
@ -356,7 +355,7 @@ ResCalcNorthSouth(tile, pendingList, doneList, resList)
{ {
currNode = p2->br_this; currNode = p2->br_this;
p1->br_next = p2->br_next; p1->br_next = p2->br_next;
ResMergeNodes(p1->br_this,p2->br_this,pendingList,doneList); ResMergeNodes(p1->br_this, p2->br_this, pendingList, doneList);
merged = TRUE; merged = TRUE;
freeMagic((char *)p2); freeMagic((char *)p2);
p2 = p1; p2 = p1;
@ -364,7 +363,7 @@ ResCalcNorthSouth(tile, pendingList, doneList, resList)
else else
{ {
currNode = p1->br_this; currNode = p1->br_this;
ResMergeNodes(p2->br_this,p1->br_this,pendingList,doneList); ResMergeNodes(p2->br_this, p1->br_this, pendingList, doneList);
freeMagic((char *)p1); freeMagic((char *)p1);
} }
@ -372,13 +371,12 @@ ResCalcNorthSouth(tile, pendingList, doneList, resList)
* Was the node used in another junk or breakpoint? * Was the node used in another junk or breakpoint?
* If so, replace the old node with the new one. * If so, replace the old node with the new one.
*/ */
p3 = p2->br_next; p3 = p2->br_next;
while (p3 != NULL) while (p3 != NULL)
{ {
if (p3->br_this == currNode) if (p3->br_this == currNode)
{
p3->br_this = p2->br_this; p3->br_this = p2->br_this;
}
p3 = p3->br_next; p3 = p3->br_next;
} }
} }
@ -426,7 +424,7 @@ ResCalcNorthSouth(tile, pendingList, doneList, resList)
#endif #endif
resistor->rr_value = resistor->rr_value =
(ExtCurStyle->exts_sheetResist[resistor->rr_tt] (ExtCurStyle->exts_sheetResist[resistor->rr_tt]
* (p2->br_loc.p_y-p1->br_loc.p_y)) / width; * (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_connection1->rn_float.rn_area += rArea;
resistor->rr_connection2->rn_float.rn_area += rArea; resistor->rr_connection2->rn_float.rn_area += rArea;
@ -466,301 +464,294 @@ ResCalcNearDevice(tile, pendingList, doneList, resList)
resResistor **resList; resResistor **resList;
{ {
bool merged; bool merged;
int devcount,devedge,deltax,deltay; int devcount, devedge, deltax, deltay;
Breakpoint *p1,*p2,*p3; Breakpoint *p1, *p2, *p3;
tileJunk *junk = (tileJunk *)tile->ti_client; tileJunk *junk = (tileJunk *)tile->ti_client;
merged = FALSE;
merged = FALSE; /*
* One Breakpoint? No resistors need to be made. Free up the first
/* * breakpoint, then return.
One Breakpoint? No resistors need to be made. Free up the first
breakpoint, then return.
*/ */
if (junk->breakList->br_next == NULL) if (junk->breakList->br_next == NULL)
{ {
freeMagic((char *)junk->breakList); freeMagic((char *)junk->breakList);
junk->breakList = NULL; junk->breakList = NULL;
return(merged); return(merged);
} }
/* count the number of device breakpoints */
/* mark which edge they connect to */ /* Count the number of device breakpoints */
devcount = 0; /* Mark which edge they connect to */
devedge = 0;
for (p1=junk->breakList; p1 != NULL;p1 = p1->br_next) devcount = 0;
{ devedge = 0;
if (p1->br_this->rn_why == RES_NODE_DEVICE) for (p1 = junk->breakList; p1 != NULL; p1 = p1->br_next)
{ {
devcount++; if (p1->br_this->rn_why == RES_NODE_DEVICE)
if (p1->br_loc.p_x == LEFT(tile)) devedge |= LEFTEDGE; {
else if (p1->br_loc.p_x == RIGHT(tile)) devedge |= RIGHTEDGE; devcount++;
else if (p1->br_loc.p_y == TOP(tile)) devedge |= TOPEDGE; if (p1->br_loc.p_x == LEFT(tile)) devedge |= LEFTEDGE;
else if (p1->br_loc.p_y == BOTTOM(tile)) devedge |= BOTTOMEDGE; else if (p1->br_loc.p_x == RIGHT(tile)) devedge |= RIGHTEDGE;
} else if (p1->br_loc.p_y == TOP(tile)) devedge |= TOPEDGE;
} else if (p1->br_loc.p_y == BOTTOM(tile)) devedge |= BOTTOMEDGE;
/* use distance from device to next breakpoint as determinant */ }
/* if there is only one device or if all the devices are along */ }
/* the same edge. */
if (devcount == 1 || /* Use distance from device to next breakpoint as determinant */
/* If there is only one device or if all the devices are along */
/* the same edge. */
if (devcount == 1 ||
(devedge & LEFTEDGE) == devedge || (devedge & LEFTEDGE) == devedge ||
(devedge & RIGHTEDGE) == devedge || (devedge & RIGHTEDGE) == devedge ||
(devedge & TOPEDGE) == devedge || (devedge & TOPEDGE) == devedge ||
(devedge & BOTTOMEDGE) == devedge) (devedge & BOTTOMEDGE) == devedge)
{ {
ResSortBreaks(&junk->breakList,TRUE); ResSortBreaks(&junk->breakList,TRUE);
p2 = NULL; p2 = NULL;
for (p1=junk->breakList; p1 != NULL;p1 = p1->br_next) for (p1 = junk->breakList; p1 != NULL; p1 = p1->br_next)
{ {
if (p1->br_this->rn_why == RES_NODE_DEVICE) if (p1->br_this->rn_why == RES_NODE_DEVICE)
{ break;
break;
} if (p1->br_next != NULL &&
if (p1->br_next != NULL &&
(p1->br_loc.p_x != p1->br_next->br_loc.p_x || (p1->br_loc.p_x != p1->br_next->br_loc.p_x ||
p1->br_loc.p_y != p1->br_next->br_loc.p_y)) p1->br_loc.p_y != p1->br_next->br_loc.p_y))
p2 = p1;
{ }
p2 = p1; deltax = INFINITY;
} for (p3 = p1->br_next; p3 != NULL &&
}
deltax=INFINITY;
for (p3 = p1->br_next;
p3 != NULL &&
p3->br_loc.p_x == p1->br_loc.p_x && p3->br_loc.p_x == p1->br_loc.p_x &&
p3->br_loc.p_y == p1->br_loc.p_y; p3 = p3->br_next); p3->br_loc.p_y == p1->br_loc.p_y; p3 = p3->br_next);
if (p3 != NULL) if (p3 != NULL)
{ {
if (p3->br_crect) if (p3->br_crect)
{ {
if (p3->br_crect->r_ll.p_x > p1->br_loc.p_x) if (p3->br_crect->r_ll.p_x > p1->br_loc.p_x)
{ {
deltax = p3->br_crect->r_ll.p_x-p1->br_loc.p_x; deltax = p3->br_crect->r_ll.p_x - p1->br_loc.p_x;
} }
else if (p3->br_crect->r_ur.p_x < p1->br_loc.p_x) else if (p3->br_crect->r_ur.p_x < p1->br_loc.p_x)
{ {
deltax = p1->br_loc.p_x-p3->br_crect->r_ur.p_x; deltax = p1->br_loc.p_x - p3->br_crect->r_ur.p_x;
} }
else else
{ {
deltax=0; deltax = 0;
} }
} }
else else
{ {
deltax = abs(p1->br_loc.p_x-p3->br_loc.p_x); deltax = abs(p1->br_loc.p_x - p3->br_loc.p_x);
} }
} }
if (p2 != NULL) if (p2 != NULL)
{ {
if (p2->br_crect) if (p2->br_crect)
{ {
if (p2->br_crect->r_ll.p_x > p1->br_loc.p_x) if (p2->br_crect->r_ll.p_x > p1->br_loc.p_x)
{ {
deltax = MIN(deltax,p2->br_crect->r_ll.p_x-p1->br_loc.p_x); deltax = MIN(deltax, p2->br_crect->r_ll.p_x - p1->br_loc.p_x);
} }
else if (p2->br_crect->r_ur.p_x < p1->br_loc.p_x) else if (p2->br_crect->r_ur.p_x < p1->br_loc.p_x)
{ {
deltax = MIN(deltax,p1->br_loc.p_x-p2->br_crect->r_ur.p_x); deltax = MIN(deltax, p1->br_loc.p_x - p2->br_crect->r_ur.p_x);
} }
else else
{ {
deltax=0; deltax = 0;
} }
} }
else else
{ {
deltax = MIN(deltax,abs(p1->br_loc.p_x-p2->br_loc.p_x)); deltax = MIN(deltax, abs(p1->br_loc.p_x - p2->br_loc.p_x));
} }
} }
/* re-sort nodes south to north. */ /* Re-sort nodes south to north. */
ResSortBreaks(&junk->breakList,FALSE); ResSortBreaks(&junk->breakList, FALSE);
p2 = NULL; p2 = NULL;
for (p1=junk->breakList; p1 != NULL;p1 = p1->br_next) for (p1 = junk->breakList; p1 != NULL; p1 = p1->br_next)
{ {
if (p1->br_this->rn_why == RES_NODE_DEVICE) if (p1->br_this->rn_why == RES_NODE_DEVICE)
{ {
break; break;
} }
if (p1->br_next != NULL && if (p1->br_next != NULL &&
(p1->br_loc.p_x != p1->br_next->br_loc.p_x || (p1->br_loc.p_x != p1->br_next->br_loc.p_x ||
p1->br_loc.p_y != p1->br_next->br_loc.p_y)) p1->br_loc.p_y != p1->br_next->br_loc.p_y))
{
{ p2 = p1;
p2 = p1; }
} }
} deltay = INFINITY;
deltay=INFINITY; for (p3 = p1->br_next; p3 != NULL &&
for (p3 = p1->br_next;
p3 != NULL &&
p3->br_loc.p_x == p1->br_loc.p_x && p3->br_loc.p_x == p1->br_loc.p_x &&
p3->br_loc.p_y == p1->br_loc.p_y; p3 = p3->br_next); p3->br_loc.p_y == p1->br_loc.p_y; p3 = p3->br_next);
if (p3 != NULL) if (p3 != NULL)
{ {
if (p3->br_crect) if (p3->br_crect)
{ {
if (p3->br_crect->r_ll.p_y > p1->br_loc.p_y) if (p3->br_crect->r_ll.p_y > p1->br_loc.p_y)
{ {
deltay = p3->br_crect->r_ll.p_y-p1->br_loc.p_y; deltay = p3->br_crect->r_ll.p_y - p1->br_loc.p_y;
} }
else if (p3->br_crect->r_ur.p_y < p1->br_loc.p_y) else if (p3->br_crect->r_ur.p_y < p1->br_loc.p_y)
{ {
deltay = p1->br_loc.p_y-p3->br_crect->r_ur.p_y; deltay = p1->br_loc.p_y - p3->br_crect->r_ur.p_y;
} }
else else
{ {
deltay=0; deltay=0;
} }
} }
else else
{ {
deltay = abs(p1->br_loc.p_y-p3->br_loc.p_y); deltay = abs(p1->br_loc.p_y - p3->br_loc.p_y);
} }
} }
if (p2!= NULL) if (p2 != NULL)
{ {
if (p2->br_crect) if (p2->br_crect)
{ {
if (p2->br_crect->r_ll.p_y > p1->br_loc.p_y) if (p2->br_crect->r_ll.p_y > p1->br_loc.p_y)
{ {
deltay = MIN(deltay,p2->br_crect->r_ll.p_y-p1->br_loc.p_y); deltay = MIN(deltay,p2->br_crect->r_ll.p_y - p1->br_loc.p_y);
} }
else if (p2->br_crect->r_ur.p_y < p1->br_loc.p_y) else if (p2->br_crect->r_ur.p_y < p1->br_loc.p_y)
{ {
deltay = MIN(deltay,p1->br_loc.p_y-p2->br_crect->r_ur.p_y); deltay = MIN(deltay,p1->br_loc.p_y - p2->br_crect->r_ur.p_y);
} }
else else
{ {
deltay=0; deltay=0;
} }
} }
else else
{ {
deltay = MIN(deltay,abs(p1->br_loc.p_y-p2->br_loc.p_y)); deltay = MIN(deltay, abs(p1->br_loc.p_y - p2->br_loc.p_y));
} }
} }
if (deltay > deltax) if (deltay > deltax)
{ {
return(ResCalcNorthSouth(tile,pendingList,doneList,resList)); return ResCalcNorthSouth(tile, pendingList, doneList, resList);
} }
else else
{ {
return(ResCalcEastWest(tile,pendingList,doneList,resList)); return ResCalcEastWest(tile, pendingList, doneList, resList);
} }
}
} /* Multiple devices connected to the partition */
/* multiple devices connected to the partition */
else
{
if (devedge == 0)
{
TxError("Error in device current direction routine\n");
return(merged);
}
/* check to see if the current flow is north-south */
/* possible north-south conditions: */
/* 1. there are devices along the top and bottom edges */
/* but not along the left or right */
/* 2. there are devices along two sides at right angles, */
/* and the tile is wider than it is tall. */
if ((devedge & TOPEDGE) && else
(devedge & BOTTOMEDGE) && {
!(devedge & LEFTEDGE) && if (devedge == 0)
!(devedge & RIGHTEDGE) || {
TxError("Error in device current direction routine\n");
return(merged);
}
/* Check to see if the current flow is north-south */
/* Possible north-south conditions: */
/* 1. There are devices along the top and bottom edges */
/* but not along the left or right */
/* 2. There are devices along two sides at right angles, */
/* and the tile is wider than it is tall. */
if ((devedge & TOPEDGE) && (devedge & BOTTOMEDGE) &&
!(devedge & LEFTEDGE) && !(devedge & RIGHTEDGE) ||
(devedge & TOPEDGE || devedge & BOTTOMEDGE) && (devedge & TOPEDGE || devedge & BOTTOMEDGE) &&
(devedge & LEFTEDGE || devedge & RIGHTEDGE) && (devedge & LEFTEDGE || devedge & RIGHTEDGE) &&
RIGHT(tile)-LEFT(tile) > TOP(tile)-BOTTOM(tile)) (RIGHT(tile) - LEFT(tile)) > (TOP(tile) - BOTTOM(tile)))
{ {
/* re-sort nodes south to north. */ /* re-sort nodes south to north. */
ResSortBreaks(&junk->breakList,FALSE); ResSortBreaks(&junk->breakList, FALSE);
/* eliminate duplicate S/D pointers */ /* eliminate duplicate S/D pointers */
for (p1 = junk->breakList; p1 != NULL; p1 = p1->br_next) for (p1 = junk->breakList; p1 != NULL; p1 = p1->br_next)
{ {
if (p1->br_this->rn_why == RES_NODE_DEVICE && if (p1->br_this->rn_why == RES_NODE_DEVICE &&
(p1->br_loc.p_y == BOTTOM(tile) || (p1->br_loc.p_y == BOTTOM(tile) ||
p1->br_loc.p_y == TOP(tile))) p1->br_loc.p_y == TOP(tile)))
{ {
p3 = NULL; p3 = NULL;
p2 = junk->breakList; p2 = junk->breakList;
while ( p2 != NULL) while (p2 != NULL)
{ {
if (p2->br_this == p1->br_this && if (p2->br_this == p1->br_this && p2 != p1 &&
p2 != p1 &&
p2->br_loc.p_y != BOTTOM(tile) && p2->br_loc.p_y != BOTTOM(tile) &&
p2->br_loc.p_y != TOP(tile)) p2->br_loc.p_y != TOP(tile))
{ {
if (p3 == NULL) if (p3 == NULL)
{ {
junk->breakList = p2->br_next; junk->breakList = p2->br_next;
freeMagic((char *) p2); freeMagic((char *) p2);
p2 = junk->breakList; p2 = junk->breakList;
} }
else else
{ {
p3->br_next = p2->br_next; p3->br_next = p2->br_next;
freeMagic((char *) p2); freeMagic((char *) p2);
p2 = p3->br_next; p2 = p3->br_next;
} }
}
else
{
p3 = p2;
p2 = p2->br_next;
}
} }
} else
} {
return(ResCalcNorthSouth(tile,pendingList,doneList,resList)); p3 = p2;
} p2 = p2->br_next;
else }
{ }
/* eliminate duplicate S/D pointers */ }
for (p1 = junk->breakList; p1 != NULL; p1 = p1->br_next) }
{ return ResCalcNorthSouth(tile, pendingList, doneList, resList);
if (p1->br_this->rn_why == RES_NODE_DEVICE && }
else
{
/* Eliminate duplicate S/D pointers */
for (p1 = junk->breakList; p1 != NULL; p1 = p1->br_next)
{
if (p1->br_this->rn_why == RES_NODE_DEVICE &&
(p1->br_loc.p_x == LEFT(tile) || (p1->br_loc.p_x == LEFT(tile) ||
p1->br_loc.p_x == RIGHT(tile))) p1->br_loc.p_x == RIGHT(tile)))
{ {
p3 = NULL; p3 = NULL;
p2 = junk->breakList; p2 = junk->breakList;
while ( p2 != NULL) while (p2 != NULL)
{ {
if (p2->br_this == p1->br_this && if (p2->br_this == p1->br_this && p2 != p1 &&
p2 != p1 &&
p2->br_loc.p_x != LEFT(tile) && p2->br_loc.p_x != LEFT(tile) &&
p2->br_loc.p_x != RIGHT(tile)) p2->br_loc.p_x != RIGHT(tile))
{ {
if (p3 == NULL) if (p3 == NULL)
{ {
junk->breakList = p2->br_next; junk->breakList = p2->br_next;
freeMagic((char *) p2); freeMagic((char *) p2);
p2 = junk->breakList; p2 = junk->breakList;
} }
else else
{ {
p3->br_next = p2->br_next; p3->br_next = p2->br_next;
freeMagic((char *) p2); freeMagic((char *) p2);
p2 = p3->br_next; p2 = p3->br_next;
} }
}
else
{
p3 = p2;
p2 = p2->br_next;
}
} }
} else
} {
return(ResCalcEastWest(tile,pendingList,doneList,resList)); p3 = p2;
} p2 = p2->br_next;
} }
}
}
}
return ResCalcEastWest(tile, pendingList, doneList, resList);
}
}
} }
/* /*
*------------------------------------------------------------------------- *-------------------------------------------------------------------------
* *
@ -779,7 +770,7 @@ void
ResDoContacts(contact, nodes, resList) ResDoContacts(contact, nodes, resList)
ResContactPoint *contact; ResContactPoint *contact;
resNode **nodes; resNode **nodes;
resResistor **resList; resResistor **resList;
{ {
resNode *resptr; resNode *resptr;
cElement *ccell; cElement *ccell;
@ -799,19 +790,19 @@ ResDoContacts(contact, nodes, resList)
int y = contact->cp_center.p_y; int y = contact->cp_center.p_y;
resptr = (resNode *) mallocMagic((unsigned) (sizeof(resNode))); resptr = (resNode *) mallocMagic((unsigned) (sizeof(resNode)));
InitializeNode(resptr,x,y,RES_NODE_CONTACT); InitializeNode(resptr, x, y, RES_NODE_CONTACT);
ResAddToQueue(resptr,nodes); ResAddToQueue(resptr, nodes);
ccell = (cElement *) mallocMagic((unsigned) (sizeof(cElement))); ccell = (cElement *) mallocMagic((unsigned) (sizeof(cElement)));
ccell->ce_nextc = resptr->rn_ce; ccell->ce_nextc = resptr->rn_ce;
resptr->rn_ce = ccell; resptr->rn_ce = ccell;
ccell->ce_thisc = contact; ccell->ce_thisc = contact;
/* add 1 celement for each layer of contact */ /* Add 1 celement for each layer of contact */
for (tilenum=0; tilenum < contact->cp_currentcontact; tilenum++) for (tilenum = 0; tilenum < contact->cp_currentcontact; tilenum++)
{ {
Tile *tile = contact->cp_tile[tilenum]; Tile *tile = contact->cp_tile[tilenum];
contact->cp_cnode[tilenum] = resptr; contact->cp_cnode[tilenum] = resptr;
NEWBREAK(resptr, tile, contact->cp_center.p_x, NEWBREAK(resptr, tile, contact->cp_center.p_x,
@ -847,17 +838,17 @@ ResDoContacts(contact, nodes, resList)
squaresy = (int)squaresf; squaresy = (int)squaresf;
squaresy++; squaresy++;
} }
for (tilenum=0; tilenum < contact->cp_currentcontact; tilenum++) for (tilenum = 0; tilenum < contact->cp_currentcontact; tilenum++)
{ {
int x = contact->cp_center.p_x; int x = contact->cp_center.p_x;
int y = contact->cp_center.p_y; int y = contact->cp_center.p_y;
Tile *tile = contact->cp_tile[tilenum]; Tile *tile = contact->cp_tile[tilenum];
resptr = (resNode *) mallocMagic((unsigned) (sizeof(resNode))); resptr = (resNode *) mallocMagic((unsigned) (sizeof(resNode)));
InitializeNode(resptr,x,y,RES_NODE_CONTACT); InitializeNode(resptr, x, y, RES_NODE_CONTACT);
ResAddToQueue(resptr,nodes); ResAddToQueue(resptr, nodes);
/* add contact pointer to node */ /* Add contact pointer to node */
ccell = (cElement *) mallocMagic((unsigned) (sizeof(cElement))); ccell = (cElement *) mallocMagic((unsigned) (sizeof(cElement)));
ccell->ce_nextc = resptr->rn_ce; ccell->ce_nextc = resptr->rn_ce;
@ -868,7 +859,7 @@ ResDoContacts(contact, nodes, resList)
NEWBREAK(resptr, tile, contact->cp_center.p_x, NEWBREAK(resptr, tile, contact->cp_center.p_x,
contact->cp_center.p_y, &contact->cp_rect); contact->cp_center.p_y, &contact->cp_rect);
/* add resistors here */ /* Add resistors here */
if (tilenum > 0) if (tilenum > 0)
{ {
@ -877,13 +868,13 @@ ResDoContacts(contact, nodes, resList)
resistor->rr_lastResistor = NULL; resistor->rr_lastResistor = NULL;
if ((*resList) != NULL) (*resList)->rr_lastResistor = resistor; if ((*resList) != NULL) (*resList)->rr_lastResistor = resistor;
(*resList) = resistor; (*resList) = resistor;
resistor->rr_connection1 = contact->cp_cnode[tilenum-1]; resistor->rr_connection1 = contact->cp_cnode[tilenum - 1];
resistor->rr_connection2 = contact->cp_cnode[tilenum]; resistor->rr_connection2 = contact->cp_cnode[tilenum];
element = (resElement *) mallocMagic((unsigned) (sizeof(resElement))); element = (resElement *) mallocMagic((unsigned) (sizeof(resElement)));
element->re_nextEl = contact->cp_cnode[tilenum-1]->rn_re; element->re_nextEl = contact->cp_cnode[tilenum - 1]->rn_re;
element->re_thisEl = resistor; element->re_thisEl = resistor;
contact->cp_cnode[tilenum-1]->rn_re = element; contact->cp_cnode[tilenum - 1]->rn_re = element;
element = (resElement *) mallocMagic((unsigned)(sizeof(resElement))); element = (resElement *) mallocMagic((unsigned)(sizeof(resElement)));
element->re_nextEl = contact->cp_cnode[tilenum]->rn_re; element->re_nextEl = contact->cp_cnode[tilenum]->rn_re;
element->re_thisEl = resistor; element->re_thisEl = resistor;
@ -909,7 +900,7 @@ ResDoContacts(contact, nodes, resList)
(squaresx * squaresy); (squaresx * squaresy);
#endif #endif
resistor->rr_tt = contact->cp_type; resistor->rr_tt = contact->cp_type;
resistor->rr_float.rr_area= 0; resistor->rr_float.rr_area = 0;
resistor->rr_status = 0; resistor->rr_status = 0;
} }
} }
@ -919,6 +910,11 @@ ResDoContacts(contact, nodes, resList)
/* /*
*------------------------------------------------------------------------- *-------------------------------------------------------------------------
* *
* ResSortBreaks --
*
* Results:
* None
*
*------------------------------------------------------------------------- *-------------------------------------------------------------------------
*/ */
@ -928,7 +924,7 @@ ResSortBreaks(masterlist, xsort)
int xsort; int xsort;
{ {
Breakpoint *p1, *p2, *p3, *p4; Breakpoint *p1, *p2, *p3, *p4;
bool changed; bool changed;
changed = TRUE; changed = TRUE;
while (changed == TRUE) while (changed == TRUE)

View File

@ -168,8 +168,10 @@ ResPrintExtDev(outextfile, devices)
if (devices->subs != NULL) if (devices->subs != NULL)
fprintf(outextfile, " \"%s\"", devices->subs->name); fprintf(outextfile, " \"%s\"", devices->subs->name);
else else if (subsName != NULL)
fprintf(outextfile, " \"%s\"", subsName); fprintf(outextfile, " \"%s\"", subsName);
else
fprintf(outextfile, " \"None\"");
if (devices->gate != NULL) if (devices->gate != NULL)
fprintf(outextfile, " \"%s\" %d %s", fprintf(outextfile, " \"%s\" %d %s",

View File

@ -511,6 +511,8 @@ ResSimDevice(line, rpersquare, devptr)
device->gate = device->source = device->drain = device->subs = NULL; device->gate = device->source = device->drain = device->subs = NULL;
device->rs_ttype = extGetDevType(devptr->exts_deviceName);
/* sim attributes look like g=a1,a2 */ /* sim attributes look like g=a1,a2 */
/* ext attributes are "a1","a2" */ /* ext attributes are "a1","a2" */
/* do conversion from one to the other here */ /* do conversion from one to the other here */

View File

@ -1288,7 +1288,7 @@ ResFixUpConnections(simDev, layoutDev, simNode, nodename)
} }
else else
TxError("missing SD connection\n"); TxError("Missing SD connection\n");
} }
} }
else if (simDev->drain == simNode) else if (simDev->drain == simNode)
@ -1335,7 +1335,7 @@ ResFixUpConnections(simDev, layoutDev, simNode, nodename)
} }
} }
else else
TxError("missing SD connection\n"); TxError("Missing SD connection\n");
} }
else else
resNodeNum--; resNodeNum--;

View File

@ -87,6 +87,27 @@ ResFirst(tile, arg)
return((Region *) NULL); return((Region *) NULL);
} }
/*
*--------------------------------------------------------------------------
*
* resMultiPlaneTerm --
*
* Callback function to set a junk field
*
*--------------------------------------------------------------------------
*/
int
resMultiPlaneTerm(Tile *tile, tileJunk *junk2)
{
tileJunk *Junk;
Junk = resAddField(tile);
Junk->tj_status |= RES_TILE_SD;
junk2->sourceEdge |= OTHERPLANE;
return 0;
}
/* /*
*-------------------------------------------------------------------------- *--------------------------------------------------------------------------
* *
@ -263,13 +284,22 @@ ResAddPlumbing(tile, arg)
break; break;
} }
} }
/* other plane (in ResUse) */ /* other plane (in ResUse) */
if (source == NULL) if (source == NULL)
{ {
int pNum; int pNum;
Rect r;
TiToRect(tile, &r);
for (pNum = PL_TECHDEPBASE; pNum < DBNumPlanes; pNum++) for (pNum = PL_TECHDEPBASE; pNum < DBNumPlanes; pNum++)
{ {
/* XXX */ if (TTMaskIntersect(&DBPlaneTypes[pNum],
&(devptr->exts_deviceSDTypes[i])))
DBSrPaintArea((Tile *)NULL,
ResUse->cu_def->cd_planes[pNum],
&r, &(devptr->exts_deviceSDTypes[i]),
resMultiPlaneTerm, (ClientData)junk2);
} }
} }
@ -303,7 +333,7 @@ ResAddPlumbing(tile, arg)
if (TiGetBottomType(tp2) == t1) if (TiGetBottomType(tp2) == t1)
{ {
tileJunk *j = resAddField(tp2); tileJunk *j = resAddField(tp2);
if ((j->tj_status & RES_TILE_SD) ==0) if ((j->tj_status & RES_TILE_SD) == 0)
{ {
j->tj_status |= RES_TILE_SD; j->tj_status |= RES_TILE_SD;
STACKPUSH((ClientData)tp2, resDevStack); STACKPUSH((ClientData)tp2, resDevStack);

View File

@ -603,7 +603,7 @@ extern ResFixPoint *ResFixList;
extern int ResTileCount; extern int ResTileCount;
extern ResSimNode **ResNodeArray; extern ResSimNode **ResNodeArray;
extern CellDef *mainDef; extern CellDef *mainDef;
extern TileTypeBitMask ResSubsTypeBitMask; extern TileTypeBitMask ResSDTypesBitMask;
extern HashTable ResDevTable; extern HashTable ResDevTable;
extern TileTypeBitMask ResNoMergeMask[NT]; extern TileTypeBitMask ResNoMergeMask[NT];
extern ResGlobalParams gparams; extern ResGlobalParams gparams;