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:
parent
0ebdf3e513
commit
d63a102515
146
resis/ResBasic.c
146
resis/ResBasic.c
|
|
@ -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;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
182
resis/ResMain.c
182
resis/ResMain.c
|
|
@ -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);
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -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)
|
||||||
|
|
|
||||||
|
|
@ -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",
|
||||||
|
|
|
||||||
|
|
@ -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 */
|
||||||
|
|
|
||||||
|
|
@ -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--;
|
||||||
|
|
|
||||||
|
|
@ -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);
|
||||||
|
|
|
||||||
|
|
@ -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;
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue