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
122
resis/ResBasic.c
122
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/
|
||||
* 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
|
||||
* 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 */
|
||||
ce = tstructs->contactList;
|
||||
while (ce != (cElement *) NULL)
|
||||
|
|
@ -252,7 +254,7 @@ ResEachTile(tile, startpoint)
|
|||
{
|
||||
t2 = TiGetRightType(tp);
|
||||
devptr = ExtCurStyle->exts_device[t2];
|
||||
if(TTMaskHasType(&(ExtCurStyle->exts_deviceMask), t2) &&
|
||||
if (TTMaskHasType(&(ExtCurStyle->exts_deviceMask), t2) &&
|
||||
TTMaskHasType(&(devptr->exts_deviceSDTypes[0]), t1))
|
||||
/* found device */
|
||||
{
|
||||
|
|
@ -275,7 +277,7 @@ ResEachTile(tile, startpoint)
|
|||
{
|
||||
t2 = TiGetLeftType(tp);
|
||||
devptr = ExtCurStyle->exts_device[t2];
|
||||
if(TTMaskHasType(&(ExtCurStyle->exts_deviceMask), t2) &&
|
||||
if (TTMaskHasType(&(ExtCurStyle->exts_deviceMask), t2) &&
|
||||
TTMaskHasType(&(devptr->exts_deviceSDTypes[0]), t1))
|
||||
/* found device */
|
||||
{
|
||||
|
|
@ -298,13 +300,13 @@ ResEachTile(tile, startpoint)
|
|||
{
|
||||
t2 = TiGetBottomType(tp);
|
||||
devptr = ExtCurStyle->exts_device[t2];
|
||||
if(TTMaskHasType(&(ExtCurStyle->exts_deviceMask),t2) &&
|
||||
TTMaskHasType(&(devptr->exts_deviceSDTypes[0]),t1))
|
||||
if (TTMaskHasType(&(ExtCurStyle->exts_deviceMask), t2) &&
|
||||
TTMaskHasType(&(devptr->exts_deviceSDTypes[0]), t1))
|
||||
/* found device */
|
||||
{
|
||||
yj = TOP(tile);
|
||||
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)
|
||||
/* tile is junction */
|
||||
|
|
@ -320,7 +322,7 @@ ResEachTile(tile, startpoint)
|
|||
{
|
||||
t2 = TiGetTopType(tp);
|
||||
devptr = ExtCurStyle->exts_device[t2];
|
||||
if(TTMaskHasType(&(ExtCurStyle->exts_deviceMask), t2) &&
|
||||
if (TTMaskHasType(&(ExtCurStyle->exts_deviceMask), t2) &&
|
||||
TTMaskHasType(&(devptr->exts_deviceSDTypes[0]), t1))
|
||||
/* found device */
|
||||
{
|
||||
|
|
@ -336,6 +338,38 @@ ResEachTile(tile, startpoint)
|
|||
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;
|
||||
|
||||
resAllPortNodes(tile, &ResNodeQueue);
|
||||
|
|
@ -361,14 +395,12 @@ ResEachTile(tile, startpoint)
|
|||
|
||||
int
|
||||
resSubDevFunc(tile,tp)
|
||||
Tile *tile,*tp;
|
||||
|
||||
|
||||
Tile *tile, *tp;
|
||||
{
|
||||
tileJunk *junk = (tileJunk *)(tile->ti_client);
|
||||
resNode *resptr;
|
||||
tElement *tcell;
|
||||
int x,y;
|
||||
int x, y;
|
||||
|
||||
if (junk->deviceList->rd_fet_subs == NULL)
|
||||
{
|
||||
|
|
@ -378,14 +410,14 @@ resSubDevFunc(tile,tp)
|
|||
tcell = (tElement *) mallocMagic((unsigned)(sizeof(tElement)));
|
||||
tcell->te_thist = junk->deviceList;
|
||||
tcell->te_nextt = NULL;
|
||||
x = (LEFT(tile)+RIGHT(tile))>>1;
|
||||
y = (TOP(tile)+BOTTOM(tile))>>1;
|
||||
x = (LEFT(tile) + RIGHT(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;
|
||||
ResAddToQueue(resptr,&ResNodeQueue);
|
||||
ResAddToQueue(resptr, &ResNodeQueue);
|
||||
|
||||
NEWBREAK(resptr,tp,x,y,NULL);
|
||||
NEWBREAK(resptr, tp, x, y, NULL);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
|
|
|||
176
resis/ResMain.c
176
resis/ResMain.c
|
|
@ -43,6 +43,7 @@ extern Tile *FindStartTile();
|
|||
extern int ResEachTile();
|
||||
extern int ResLaplaceTile();
|
||||
extern ResSimNode *ResInitializeNode();
|
||||
TileTypeBitMask ResSDTypesBitMask;
|
||||
|
||||
extern HashTable ResNodeTable;
|
||||
|
||||
|
|
@ -146,36 +147,26 @@ ResDissolveContacts(contacts)
|
|||
TileTypeBitMask residues;
|
||||
|
||||
for (; contacts != (ResContactPoint *) NULL; contacts = contacts->cp_nextcontact)
|
||||
|
||||
{
|
||||
oldtype=contacts->cp_type;
|
||||
|
||||
#ifdef PARANOID
|
||||
if (oldtype == TT_SPACE)
|
||||
{
|
||||
TxError("Error in Contact Dissolving for %s \n",ResCurrentNode);
|
||||
}
|
||||
#endif
|
||||
|
||||
DBFullResidueMask(oldtype, &residues);
|
||||
|
||||
DBErase(ResUse->cu_def, &(contacts->cp_rect), oldtype);
|
||||
for (t = TT_TECHDEPBASE; t < DBNumTypes; t++)
|
||||
{
|
||||
if (TTMaskHasType(&residues, t))
|
||||
{
|
||||
if (TTMaskHasType(&ExtCurStyle->exts_deviceMask, t))
|
||||
continue;
|
||||
DBPaint(ResUse->cu_def, &(contacts->cp_rect), t);
|
||||
}
|
||||
}
|
||||
|
||||
tp = ResDef->cd_planes[DBPlane(contacts->cp_type)]->pl_hint;
|
||||
GOTOPOINT(tp, &(contacts->cp_rect.r_ll));
|
||||
|
||||
#ifdef PARANOID
|
||||
if (TiGetTypeExact(tp) == contacts->cp_type)
|
||||
{
|
||||
TxError("Error in Contact Preprocess Routines\n");
|
||||
}
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
|
@ -494,7 +485,7 @@ ResProcessTiles(goodies, origin)
|
|||
if ((j->tj_status & RES_TILE_DONE) == 0)
|
||||
{
|
||||
resCurrentNode = resptr2;
|
||||
merged |= (*tilefunc)(tile,(Point *)NULL);
|
||||
merged |= (*tilefunc)(tile, (Point *)NULL);
|
||||
}
|
||||
if (merged & ORIGIN) break;
|
||||
}
|
||||
|
|
@ -505,7 +496,7 @@ ResProcessTiles(goodies, origin)
|
|||
|
||||
/* 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;
|
||||
|
||||
|
|
@ -627,7 +618,7 @@ ResCalcPerimOverlap(tile, dev)
|
|||
if TTMaskHasType(omask, TiGetType(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 --
|
||||
*
|
||||
* 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
|
||||
* record (namely the full device area).
|
||||
*
|
||||
|
|
@ -656,7 +647,6 @@ resMakeDevFunc(tile, cx)
|
|||
|
||||
TiToRect(tile, &devArea);
|
||||
GeoTransRect(&cx->tc_scx->scx_trans, &devArea, &thisDev->area);
|
||||
ResCalcPerimOverlap(tile, thisDev);
|
||||
|
||||
if (IsSplit(tile))
|
||||
ttype = (SplitSide(tile)) ? SplitRightType(tile) : SplitLeftType(tile);
|
||||
|
|
@ -675,9 +665,136 @@ resMakeDevFunc(tile, cx)
|
|||
return 0; /* Completely different device? */
|
||||
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;
|
||||
}
|
||||
|
||||
/*
|
||||
*-------------------------------------------------------------------------
|
||||
|
|
@ -700,14 +817,16 @@ ResExtractNet(node, goodies, cellname)
|
|||
char *cellname;
|
||||
{
|
||||
SearchContext scx;
|
||||
int pNum;
|
||||
TileTypeBitMask FirstTileMask;
|
||||
TileTypeBitMask tMask;
|
||||
Point startpoint;
|
||||
static int first = 1;
|
||||
ResDevTile *DevTiles, *thisDev;
|
||||
ResFixPoint *fix;
|
||||
devPtr *tptr;
|
||||
int pNum;
|
||||
int resMakeDevFunc();
|
||||
int resExpandDevFunc();
|
||||
|
||||
/* Make sure all global network variables are reset */
|
||||
|
||||
|
|
@ -783,15 +902,20 @@ ResExtractNet(node, goodies, cellname)
|
|||
DBTreeCopyConnect(&scx, &FirstTileMask, 0, ResCopyMask, &TiPlaneRect,
|
||||
SEL_DO_LABELS, ResUse);
|
||||
|
||||
TTMaskZero(&ResSDTypesBitMask);
|
||||
|
||||
/* Add devices to ResUse from list in node */
|
||||
DevTiles = NULL;
|
||||
for (tptr = node->firstDev; tptr; tptr = tptr->nextDev)
|
||||
{
|
||||
int result;
|
||||
int i;
|
||||
ExtDevice *devptr;
|
||||
|
||||
thisDev = (ResDevTile *)mallocMagic(sizeof(ResDevTile));
|
||||
thisDev->devptr = tptr->thisDev->rs_devptr;
|
||||
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_y = tptr->thisDev->location.p_y;
|
||||
scx.scx_area.r_xtop = scx.scx_area.r_xbot + 1;
|
||||
|
|
@ -810,10 +934,18 @@ ResExtractNet(node, goodies, cellname)
|
|||
thisDev->nextDev = DevTiles;
|
||||
DevTiles = thisDev;
|
||||
|
||||
/* Paint the type into ResUse */
|
||||
pNum = DBPlane(thisDev->type);
|
||||
DBPaintPlane(ResUse->cu_def->cd_planes[pNum], &thisDev->area,
|
||||
DBStdPaintTbl(thisDev->type, pNum), (PaintUndoInfo *)NULL);
|
||||
/* Paint the entire device into ResUse */
|
||||
TTMaskSetOnlyType(&tMask, thisDev->type);
|
||||
DBTreeSrTiles(&scx, &tMask, 0, resExpandDevFunc, (ClientData)thisDev);
|
||||
|
||||
/* 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);
|
||||
|
||||
|
|
|
|||
|
|
@ -46,7 +46,6 @@ bool ResCalcEastWest();
|
|||
* Side Effects: Resistor structures are produced. Some nodes may be
|
||||
* eliminated.
|
||||
*--------------------------------------------------------------------------
|
||||
*
|
||||
*/
|
||||
|
||||
bool
|
||||
|
|
@ -149,7 +148,7 @@ ResCalcEastWest(tile, pendingList, doneList, resList)
|
|||
return(merged);
|
||||
}
|
||||
|
||||
/* re-sort nodes left to right. */
|
||||
/* Re-sort nodes left to right. */
|
||||
|
||||
ResSortBreaks(&junk->breakList, TRUE);
|
||||
|
||||
|
|
@ -160,9 +159,9 @@ ResCalcEastWest(tile, pendingList, doneList, resList)
|
|||
|
||||
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)
|
||||
{
|
||||
p1 = p2;
|
||||
|
|
@ -179,7 +178,7 @@ ResCalcEastWest(tile, pendingList, doneList, resList)
|
|||
else if (p2->br_this == resCurrentNode)
|
||||
{
|
||||
currNode = p1->br_this;
|
||||
ResMergeNodes(p2->br_this,p1->br_this,pendingList,doneList);
|
||||
ResMergeNodes(p2->br_this, p1->br_this, pendingList, doneList);
|
||||
merged = TRUE;
|
||||
freeMagic((char *)p1);
|
||||
}
|
||||
|
|
@ -187,7 +186,7 @@ ResCalcEastWest(tile, pendingList, doneList, resList)
|
|||
{
|
||||
currNode = p2->br_this;
|
||||
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;
|
||||
freeMagic((char *)p2);
|
||||
p2 = p1;
|
||||
|
|
@ -195,7 +194,7 @@ ResCalcEastWest(tile, pendingList, doneList, resList)
|
|||
else
|
||||
{
|
||||
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);
|
||||
}
|
||||
|
||||
|
|
@ -203,13 +202,13 @@ ResCalcEastWest(tile, pendingList, doneList, resList)
|
|||
* Was the node used in another junk or breakpoint?
|
||||
* If so, replace the old node with the new one.
|
||||
*/
|
||||
|
||||
p3 = p2->br_next;
|
||||
while (p3 != NULL)
|
||||
{
|
||||
if (p3->br_this == currNode)
|
||||
{
|
||||
p3->br_this = p2->br_this;
|
||||
}
|
||||
|
||||
p3 = p3->br_next;
|
||||
}
|
||||
}
|
||||
|
|
@ -221,18 +220,18 @@ ResCalcEastWest(tile, pendingList, doneList, resList)
|
|||
|
||||
else
|
||||
{
|
||||
resistor = (resResistor *) mallocMagic((unsigned) (sizeof(resResistor)));
|
||||
resistor = (resResistor *)mallocMagic((unsigned)sizeof(resResistor));
|
||||
resistor->rr_nextResistor = (*resList);
|
||||
resistor->rr_lastResistor = NULL;
|
||||
if ((*resList) != NULL) (*resList)->rr_lastResistor = resistor;
|
||||
(*resList) = resistor;
|
||||
resistor->rr_connection1 = p1->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_thisEl = resistor;
|
||||
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_thisEl = resistor;
|
||||
p2->br_this->rn_re = element;
|
||||
|
|
@ -246,7 +245,6 @@ ResCalcEastWest(tile, pendingList, doneList, resList)
|
|||
resistor->rr_status = RES_DIAGONAL;
|
||||
resistor->rr_status |= (SplitDirection(tile)) ? RES_NS
|
||||
: RES_EW;
|
||||
|
||||
}
|
||||
else
|
||||
{
|
||||
|
|
@ -268,10 +266,11 @@ ResCalcEastWest(tile, pendingList, doneList, resList)
|
|||
freeMagic((char *)p1);
|
||||
}
|
||||
}
|
||||
|
||||
p2->br_this->rn_float.rn_area += height * (RIGHT(tile) - p2->br_loc.p_x);
|
||||
freeMagic((char *)p2);
|
||||
junk->breakList = NULL;
|
||||
return(merged);
|
||||
return merged;
|
||||
}
|
||||
|
||||
|
||||
|
|
@ -303,7 +302,7 @@ ResCalcNorthSouth(tile, pendingList, doneList, resList)
|
|||
tileJunk *junk = (tileJunk *)tile->ti_client;
|
||||
|
||||
merged = FALSE;
|
||||
width = RIGHT(tile)-LEFT(tile);
|
||||
width = RIGHT(tile) - LEFT(tile);
|
||||
|
||||
/*
|
||||
* One Breakpoint? No resistors need to be made. Free up the first
|
||||
|
|
@ -319,7 +318,7 @@ ResCalcNorthSouth(tile, pendingList, doneList, resList)
|
|||
return(merged);
|
||||
}
|
||||
|
||||
/* re-sort nodes south to north. */
|
||||
/* Re-sort nodes south to north. */
|
||||
ResSortBreaks(&junk->breakList, FALSE);
|
||||
|
||||
/*
|
||||
|
|
@ -329,7 +328,7 @@ ResCalcNorthSouth(tile, pendingList, doneList, resList)
|
|||
|
||||
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));
|
||||
while (p2->br_next != NULL)
|
||||
|
|
@ -348,7 +347,7 @@ ResCalcNorthSouth(tile, pendingList, doneList, resList)
|
|||
else if (p2->br_this == resCurrentNode)
|
||||
{
|
||||
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);
|
||||
merged = TRUE;
|
||||
}
|
||||
|
|
@ -356,7 +355,7 @@ ResCalcNorthSouth(tile, pendingList, doneList, resList)
|
|||
{
|
||||
currNode = p2->br_this;
|
||||
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;
|
||||
freeMagic((char *)p2);
|
||||
p2 = p1;
|
||||
|
|
@ -364,7 +363,7 @@ ResCalcNorthSouth(tile, pendingList, doneList, resList)
|
|||
else
|
||||
{
|
||||
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);
|
||||
}
|
||||
|
||||
|
|
@ -376,9 +375,8 @@ ResCalcNorthSouth(tile, pendingList, doneList, resList)
|
|||
while (p3 != NULL)
|
||||
{
|
||||
if (p3->br_this == currNode)
|
||||
{
|
||||
p3->br_this = p2->br_this;
|
||||
}
|
||||
|
||||
p3 = p3->br_next;
|
||||
}
|
||||
}
|
||||
|
|
@ -426,7 +424,7 @@ ResCalcNorthSouth(tile, pendingList, doneList, resList)
|
|||
#endif
|
||||
resistor->rr_value =
|
||||
(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;
|
||||
resistor->rr_connection1->rn_float.rn_area += rArea;
|
||||
resistor->rr_connection2->rn_float.rn_area += rArea;
|
||||
|
|
@ -467,16 +465,15 @@ ResCalcNearDevice(tile, pendingList, doneList, resList)
|
|||
|
||||
{
|
||||
bool merged;
|
||||
int devcount,devedge,deltax,deltay;
|
||||
Breakpoint *p1,*p2,*p3;
|
||||
int devcount, devedge, deltax, deltay;
|
||||
Breakpoint *p1, *p2, *p3;
|
||||
tileJunk *junk = (tileJunk *)tile->ti_client;
|
||||
|
||||
|
||||
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)
|
||||
|
|
@ -485,11 +482,13 @@ ResCalcNearDevice(tile, pendingList, doneList, resList)
|
|||
junk->breakList = NULL;
|
||||
return(merged);
|
||||
}
|
||||
/* count the number of device breakpoints */
|
||||
/* mark which edge they connect to */
|
||||
|
||||
/* Count the number of device breakpoints */
|
||||
/* Mark which edge they connect to */
|
||||
|
||||
devcount = 0;
|
||||
devedge = 0;
|
||||
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)
|
||||
{
|
||||
|
|
@ -500,9 +499,11 @@ ResCalcNearDevice(tile, pendingList, doneList, resList)
|
|||
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 */
|
||||
|
||||
/* 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 & RIGHTEDGE) == devedge ||
|
||||
|
|
@ -511,23 +512,18 @@ ResCalcNearDevice(tile, pendingList, doneList, resList)
|
|||
{
|
||||
ResSortBreaks(&junk->breakList,TRUE);
|
||||
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)
|
||||
{
|
||||
break;
|
||||
}
|
||||
|
||||
if (p1->br_next != NULL &&
|
||||
(p1->br_loc.p_x != p1->br_next->br_loc.p_x ||
|
||||
p1->br_loc.p_y != p1->br_next->br_loc.p_y))
|
||||
|
||||
{
|
||||
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_y == p1->br_loc.p_y; p3 = p3->br_next);
|
||||
if (p3 != NULL)
|
||||
|
|
@ -536,20 +532,20 @@ ResCalcNearDevice(tile, pendingList, doneList, resList)
|
|||
{
|
||||
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)
|
||||
{
|
||||
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
|
||||
{
|
||||
deltax=0;
|
||||
deltax = 0;
|
||||
}
|
||||
}
|
||||
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)
|
||||
|
|
@ -558,27 +554,27 @@ ResCalcNearDevice(tile, pendingList, doneList, resList)
|
|||
{
|
||||
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)
|
||||
{
|
||||
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
|
||||
{
|
||||
deltax=0;
|
||||
deltax = 0;
|
||||
}
|
||||
}
|
||||
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. */
|
||||
ResSortBreaks(&junk->breakList,FALSE);
|
||||
/* Re-sort nodes south to north. */
|
||||
ResSortBreaks(&junk->breakList, FALSE);
|
||||
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)
|
||||
{
|
||||
|
|
@ -587,14 +583,12 @@ ResCalcNearDevice(tile, pendingList, doneList, resList)
|
|||
if (p1->br_next != NULL &&
|
||||
(p1->br_loc.p_x != p1->br_next->br_loc.p_x ||
|
||||
p1->br_loc.p_y != p1->br_next->br_loc.p_y))
|
||||
|
||||
{
|
||||
p2 = p1;
|
||||
}
|
||||
}
|
||||
deltay=INFINITY;
|
||||
for (p3 = p1->br_next;
|
||||
p3 != NULL &&
|
||||
deltay = INFINITY;
|
||||
for (p3 = p1->br_next; p3 != NULL &&
|
||||
p3->br_loc.p_x == p1->br_loc.p_x &&
|
||||
p3->br_loc.p_y == p1->br_loc.p_y; p3 = p3->br_next);
|
||||
if (p3 != NULL)
|
||||
|
|
@ -603,11 +597,11 @@ ResCalcNearDevice(tile, pendingList, doneList, resList)
|
|||
{
|
||||
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)
|
||||
{
|
||||
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
|
||||
{
|
||||
|
|
@ -616,20 +610,20 @@ ResCalcNearDevice(tile, pendingList, doneList, resList)
|
|||
}
|
||||
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->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)
|
||||
{
|
||||
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
|
||||
{
|
||||
|
|
@ -638,20 +632,21 @@ ResCalcNearDevice(tile, pendingList, doneList, resList)
|
|||
}
|
||||
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)
|
||||
{
|
||||
return(ResCalcNorthSouth(tile,pendingList,doneList,resList));
|
||||
return ResCalcNorthSouth(tile, pendingList, doneList, resList);
|
||||
}
|
||||
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)
|
||||
|
|
@ -659,23 +654,22 @@ ResCalcNearDevice(tile, pendingList, doneList, resList)
|
|||
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 */
|
||||
|
||||
/* 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, */
|
||||
/* 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) ||
|
||||
if ((devedge & TOPEDGE) && (devedge & BOTTOMEDGE) &&
|
||||
!(devedge & LEFTEDGE) && !(devedge & RIGHTEDGE) ||
|
||||
(devedge & TOPEDGE || devedge & BOTTOMEDGE) &&
|
||||
(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. */
|
||||
ResSortBreaks(&junk->breakList,FALSE);
|
||||
ResSortBreaks(&junk->breakList, FALSE);
|
||||
|
||||
/* eliminate duplicate S/D pointers */
|
||||
for (p1 = junk->breakList; p1 != NULL; p1 = p1->br_next)
|
||||
|
|
@ -686,10 +680,9 @@ ResCalcNearDevice(tile, pendingList, doneList, resList)
|
|||
{
|
||||
p3 = NULL;
|
||||
p2 = junk->breakList;
|
||||
while ( p2 != NULL)
|
||||
while (p2 != NULL)
|
||||
{
|
||||
if (p2->br_this == p1->br_this &&
|
||||
p2 != p1 &&
|
||||
if (p2->br_this == p1->br_this && p2 != p1 &&
|
||||
p2->br_loc.p_y != BOTTOM(tile) &&
|
||||
p2->br_loc.p_y != TOP(tile))
|
||||
{
|
||||
|
|
@ -714,11 +707,11 @@ ResCalcNearDevice(tile, pendingList, doneList, resList)
|
|||
}
|
||||
}
|
||||
}
|
||||
return(ResCalcNorthSouth(tile,pendingList,doneList,resList));
|
||||
return ResCalcNorthSouth(tile, pendingList, doneList, resList);
|
||||
}
|
||||
else
|
||||
{
|
||||
/* eliminate duplicate S/D pointers */
|
||||
/* Eliminate duplicate S/D pointers */
|
||||
for (p1 = junk->breakList; p1 != NULL; p1 = p1->br_next)
|
||||
{
|
||||
if (p1->br_this->rn_why == RES_NODE_DEVICE &&
|
||||
|
|
@ -727,10 +720,9 @@ ResCalcNearDevice(tile, pendingList, doneList, resList)
|
|||
{
|
||||
p3 = NULL;
|
||||
p2 = junk->breakList;
|
||||
while ( p2 != NULL)
|
||||
while (p2 != NULL)
|
||||
{
|
||||
if (p2->br_this == p1->br_this &&
|
||||
p2 != p1 &&
|
||||
if (p2->br_this == p1->br_this && p2 != p1 &&
|
||||
p2->br_loc.p_x != LEFT(tile) &&
|
||||
p2->br_loc.p_x != RIGHT(tile))
|
||||
{
|
||||
|
|
@ -755,12 +747,11 @@ ResCalcNearDevice(tile, pendingList, doneList, resList)
|
|||
}
|
||||
}
|
||||
}
|
||||
return(ResCalcEastWest(tile,pendingList,doneList,resList));
|
||||
return ResCalcEastWest(tile, pendingList, doneList, resList);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
*-------------------------------------------------------------------------
|
||||
*
|
||||
|
|
@ -799,17 +790,17 @@ ResDoContacts(contact, nodes, resList)
|
|||
int y = contact->cp_center.p_y;
|
||||
|
||||
resptr = (resNode *) mallocMagic((unsigned) (sizeof(resNode)));
|
||||
InitializeNode(resptr,x,y,RES_NODE_CONTACT);
|
||||
ResAddToQueue(resptr,nodes);
|
||||
InitializeNode(resptr, x, y, RES_NODE_CONTACT);
|
||||
ResAddToQueue(resptr, nodes);
|
||||
|
||||
ccell = (cElement *) mallocMagic((unsigned) (sizeof(cElement)));
|
||||
ccell->ce_nextc = resptr->rn_ce;
|
||||
resptr->rn_ce = ccell;
|
||||
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];
|
||||
|
||||
|
|
@ -847,17 +838,17 @@ ResDoContacts(contact, nodes, resList)
|
|||
squaresy = (int)squaresf;
|
||||
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 y = contact->cp_center.p_y;
|
||||
Tile *tile = contact->cp_tile[tilenum];
|
||||
|
||||
resptr = (resNode *) mallocMagic((unsigned) (sizeof(resNode)));
|
||||
InitializeNode(resptr,x,y,RES_NODE_CONTACT);
|
||||
ResAddToQueue(resptr,nodes);
|
||||
InitializeNode(resptr, x, y, RES_NODE_CONTACT);
|
||||
ResAddToQueue(resptr, nodes);
|
||||
|
||||
/* add contact pointer to node */
|
||||
/* Add contact pointer to node */
|
||||
|
||||
ccell = (cElement *) mallocMagic((unsigned) (sizeof(cElement)));
|
||||
ccell->ce_nextc = resptr->rn_ce;
|
||||
|
|
@ -868,7 +859,7 @@ ResDoContacts(contact, nodes, resList)
|
|||
NEWBREAK(resptr, tile, contact->cp_center.p_x,
|
||||
contact->cp_center.p_y, &contact->cp_rect);
|
||||
|
||||
/* add resistors here */
|
||||
/* Add resistors here */
|
||||
|
||||
if (tilenum > 0)
|
||||
{
|
||||
|
|
@ -877,13 +868,13 @@ ResDoContacts(contact, nodes, resList)
|
|||
resistor->rr_lastResistor = NULL;
|
||||
if ((*resList) != NULL) (*resList)->rr_lastResistor = 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];
|
||||
|
||||
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;
|
||||
contact->cp_cnode[tilenum-1]->rn_re = element;
|
||||
contact->cp_cnode[tilenum - 1]->rn_re = element;
|
||||
element = (resElement *) mallocMagic((unsigned)(sizeof(resElement)));
|
||||
element->re_nextEl = contact->cp_cnode[tilenum]->rn_re;
|
||||
element->re_thisEl = resistor;
|
||||
|
|
@ -909,7 +900,7 @@ ResDoContacts(contact, nodes, resList)
|
|||
(squaresx * squaresy);
|
||||
#endif
|
||||
resistor->rr_tt = contact->cp_type;
|
||||
resistor->rr_float.rr_area= 0;
|
||||
resistor->rr_float.rr_area = 0;
|
||||
resistor->rr_status = 0;
|
||||
}
|
||||
}
|
||||
|
|
@ -919,6 +910,11 @@ ResDoContacts(contact, nodes, resList)
|
|||
/*
|
||||
*-------------------------------------------------------------------------
|
||||
*
|
||||
* ResSortBreaks --
|
||||
*
|
||||
* Results:
|
||||
* None
|
||||
*
|
||||
*-------------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
|
|
|
|||
|
|
@ -168,8 +168,10 @@ ResPrintExtDev(outextfile, devices)
|
|||
|
||||
if (devices->subs != NULL)
|
||||
fprintf(outextfile, " \"%s\"", devices->subs->name);
|
||||
else
|
||||
else if (subsName != NULL)
|
||||
fprintf(outextfile, " \"%s\"", subsName);
|
||||
else
|
||||
fprintf(outextfile, " \"None\"");
|
||||
|
||||
if (devices->gate != NULL)
|
||||
fprintf(outextfile, " \"%s\" %d %s",
|
||||
|
|
|
|||
|
|
@ -511,6 +511,8 @@ ResSimDevice(line, rpersquare, devptr)
|
|||
|
||||
device->gate = device->source = device->drain = device->subs = NULL;
|
||||
|
||||
device->rs_ttype = extGetDevType(devptr->exts_deviceName);
|
||||
|
||||
/* sim attributes look like g=a1,a2 */
|
||||
/* ext attributes are "a1","a2" */
|
||||
/* do conversion from one to the other here */
|
||||
|
|
|
|||
|
|
@ -1288,7 +1288,7 @@ ResFixUpConnections(simDev, layoutDev, simNode, nodename)
|
|||
|
||||
}
|
||||
else
|
||||
TxError("missing SD connection\n");
|
||||
TxError("Missing SD connection\n");
|
||||
}
|
||||
}
|
||||
else if (simDev->drain == simNode)
|
||||
|
|
@ -1335,7 +1335,7 @@ ResFixUpConnections(simDev, layoutDev, simNode, nodename)
|
|||
}
|
||||
}
|
||||
else
|
||||
TxError("missing SD connection\n");
|
||||
TxError("Missing SD connection\n");
|
||||
}
|
||||
else
|
||||
resNodeNum--;
|
||||
|
|
|
|||
|
|
@ -87,6 +87,27 @@ ResFirst(tile, arg)
|
|||
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;
|
||||
}
|
||||
}
|
||||
|
||||
/* other plane (in ResUse) */
|
||||
if (source == NULL)
|
||||
{
|
||||
int pNum;
|
||||
Rect r;
|
||||
|
||||
TiToRect(tile, &r);
|
||||
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)
|
||||
{
|
||||
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;
|
||||
STACKPUSH((ClientData)tp2, resDevStack);
|
||||
|
|
|
|||
|
|
@ -603,7 +603,7 @@ extern ResFixPoint *ResFixList;
|
|||
extern int ResTileCount;
|
||||
extern ResSimNode **ResNodeArray;
|
||||
extern CellDef *mainDef;
|
||||
extern TileTypeBitMask ResSubsTypeBitMask;
|
||||
extern TileTypeBitMask ResSDTypesBitMask;
|
||||
extern HashTable ResDevTable;
|
||||
extern TileTypeBitMask ResNoMergeMask[NT];
|
||||
extern ResGlobalParams gparams;
|
||||
|
|
|
|||
Loading…
Reference in New Issue