A number of fixes to the extresist code (as well as style cleanup).
Still tracking down a problem with non-FET devices (e.g., capacitors). So, work in progress. Nothing should be affected outside of extresist.
This commit is contained in:
parent
c22d584ac3
commit
9aa39f820f
128
resis/ResMain.c
128
resis/ResMain.c
|
|
@ -23,20 +23,20 @@ static char rcsid[] __attribute__ ((unused)) = "$Header: /usr/cvsroot/magic-8.0/
|
||||||
#include "textio/txcommands.h"
|
#include "textio/txcommands.h"
|
||||||
#include "resis/resis.h"
|
#include "resis/resis.h"
|
||||||
|
|
||||||
CellUse *ResUse=NULL; /* Our use and def */
|
CellUse *ResUse = NULL; /* Our use and def */
|
||||||
CellDef *ResDef=NULL;
|
CellDef *ResDef = NULL;
|
||||||
TileTypeBitMask ResConnectWithSD[NT]; /* A mask that goes from */
|
TileTypeBitMask ResConnectWithSD[NT]; /* A mask that goes from */
|
||||||
/* SD's to devices. */
|
/* SD's to devices. */
|
||||||
TileTypeBitMask ResCopyMask[NT]; /* Indicates which tiles */
|
TileTypeBitMask ResCopyMask[NT]; /* Indicates which tiles */
|
||||||
/* are to be copied. */
|
/* are to be copied. */
|
||||||
resResistor *ResResList=NULL; /* Resistor list */
|
resResistor *ResResList = NULL; /* Resistor list */
|
||||||
resNode *ResNodeList=NULL; /* Processed Nodes */
|
resNode *ResNodeList = NULL; /* Processed Nodes */
|
||||||
resDevice *ResDevList=NULL; /* Devices */
|
resDevice *ResDevList = NULL; /* Devices */
|
||||||
ResContactPoint *ResContactList=NULL; /* Contacts */
|
ResContactPoint *ResContactList = NULL; /* Contacts */
|
||||||
resNode *ResNodeQueue=NULL; /* Pending nodes */
|
resNode *ResNodeQueue = NULL; /* Pending nodes */
|
||||||
resNode *ResOriginNode=NULL; /* node where R=0 */
|
resNode *ResOriginNode = NULL; /* node where R=0 */
|
||||||
resNode *resCurrentNode;
|
resNode *resCurrentNode;
|
||||||
int ResTileCount=0; /* Number of tiles rn_status */
|
int ResTileCount = 0; /* Number of tiles rn_status */
|
||||||
extern Region *ResFirst();
|
extern Region *ResFirst();
|
||||||
extern Tile *FindStartTile();
|
extern Tile *FindStartTile();
|
||||||
extern int ResEachTile();
|
extern int ResEachTile();
|
||||||
|
|
@ -46,7 +46,6 @@ extern ResSimNode *ResInitializeNode();
|
||||||
extern HashTable ResNodeTable;
|
extern HashTable ResNodeTable;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
*--------------------------------------------------------------------------
|
*--------------------------------------------------------------------------
|
||||||
*
|
*
|
||||||
|
|
@ -78,13 +77,13 @@ ResInitializeConn()
|
||||||
for (diff = TT_TECHDEPBASE; diff < TT_MAXTYPES; diff++)
|
for (diff = TT_TECHDEPBASE; diff < TT_MAXTYPES; diff++)
|
||||||
{
|
{
|
||||||
if TTMaskHasType(&(devptr->exts_deviceSDTypes[0]), diff)
|
if TTMaskHasType(&(devptr->exts_deviceSDTypes[0]), diff)
|
||||||
TTMaskSetType(&ResConnectWithSD[diff],dev);
|
TTMaskSetType(&ResConnectWithSD[diff], dev);
|
||||||
|
|
||||||
if TTMaskHasType(&(devptr->exts_deviceSubstrateTypes),diff)
|
if TTMaskHasType(&(devptr->exts_deviceSubstrateTypes), diff)
|
||||||
TTMaskSetType(&ResConnectWithSD[diff],dev);
|
TTMaskSetType(&ResConnectWithSD[diff], dev);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
TTMaskSetMask(&ResConnectWithSD[dev],&DBConnectTbl[dev]);
|
TTMaskSetMask(&ResConnectWithSD[dev], &DBConnectTbl[dev]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -121,7 +120,6 @@ ResGetReCell()
|
||||||
ResUse = DBCellNewUse(ResDef, (char *) NULL);
|
ResUse = DBCellNewUse(ResDef, (char *) NULL);
|
||||||
DBSetTrans(ResUse, &GeoIdentityTransform);
|
DBSetTrans(ResUse, &GeoIdentityTransform);
|
||||||
ResUse->cu_expandMask = CU_DESCEND_SPECIAL;
|
ResUse->cu_expandMask = CU_DESCEND_SPECIAL;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|
@ -172,7 +170,7 @@ ResDissolveContacts(contacts)
|
||||||
}
|
}
|
||||||
|
|
||||||
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)
|
||||||
{
|
{
|
||||||
|
|
@ -334,7 +332,7 @@ ResFindNewContactTiles(contacts)
|
||||||
for (; contacts != (ResContactPoint *) NULL; contacts = contacts->cp_nextcontact)
|
for (; contacts != (ResContactPoint *) NULL; contacts = contacts->cp_nextcontact)
|
||||||
{
|
{
|
||||||
DBFullResidueMask(contacts->cp_type, &mask);
|
DBFullResidueMask(contacts->cp_type, &mask);
|
||||||
for (pNum=PL_TECHDEPBASE; pNum<DBNumPlanes; pNum++)
|
for (pNum = PL_TECHDEPBASE; pNum < DBNumPlanes; pNum++)
|
||||||
{
|
{
|
||||||
tile = ResDef->cd_planes[pNum]->pl_hint;
|
tile = ResDef->cd_planes[pNum]->pl_hint;
|
||||||
GOTOPOINT(tile, &(contacts->cp_center));
|
GOTOPOINT(tile, &(contacts->cp_center));
|
||||||
|
|
@ -389,7 +387,7 @@ ResProcessTiles(goodies, origin)
|
||||||
|
|
||||||
{
|
{
|
||||||
Tile *startTile;
|
Tile *startTile;
|
||||||
int tilenum,merged;
|
int tilenum, merged;
|
||||||
resNode *resptr2;
|
resNode *resptr2;
|
||||||
jElement *workingj;
|
jElement *workingj;
|
||||||
cElement *workingc;
|
cElement *workingc;
|
||||||
|
|
@ -398,7 +396,7 @@ ResProcessTiles(goodies, origin)
|
||||||
int (*tilefunc)();
|
int (*tilefunc)();
|
||||||
|
|
||||||
#ifdef LAPLACE
|
#ifdef LAPLACE
|
||||||
tilefunc = (ResOptionsFlags & ResOpt_DoLaplace)?ResLaplaceTile:ResEachTile;
|
tilefunc = (ResOptionsFlags & ResOpt_DoLaplace) ? ResLaplaceTile : ResEachTile;
|
||||||
#else
|
#else
|
||||||
tilefunc = ResEachTile;
|
tilefunc = ResEachTile;
|
||||||
#endif
|
#endif
|
||||||
|
|
@ -413,12 +411,11 @@ ResProcessTiles(goodies, origin)
|
||||||
#ifdef ARIEL
|
#ifdef ARIEL
|
||||||
else if (ResOptionsFlags & ResOpt_Power)
|
else if (ResOptionsFlags & ResOpt_Power)
|
||||||
{
|
{
|
||||||
for (fix = ResFixList; fix != NULL;fix=fix->fp_next)
|
for (fix = ResFixList; fix != NULL; fix = fix->fp_next)
|
||||||
{
|
{
|
||||||
Tile *tile = fix->fp_tile;
|
Tile *tile = fix->fp_tile;
|
||||||
if (tile == NULL)
|
if (tile == NULL)
|
||||||
{
|
{
|
||||||
|
|
||||||
tile = ResDef->cd_planes[DBPlane(fix->fp_ttype)]->pl_hint;
|
tile = ResDef->cd_planes[DBPlane(fix->fp_ttype)]->pl_hint;
|
||||||
GOTOPOINT(tile, &(fix->fp_loc));
|
GOTOPOINT(tile, &(fix->fp_loc));
|
||||||
if (TiGetTypeExact(tile) != TT_SPACE)
|
if (TiGetTypeExact(tile) != TT_SPACE)
|
||||||
|
|
@ -486,7 +483,7 @@ ResProcessTiles(goodies, origin)
|
||||||
for (tilenum = 0; tilenum < TILES_PER_JUNCTION; tilenum++)
|
for (tilenum = 0; tilenum < TILES_PER_JUNCTION; tilenum++)
|
||||||
{
|
{
|
||||||
Tile *tile = rj->rj_Tile[tilenum];
|
Tile *tile = rj->rj_Tile[tilenum];
|
||||||
tileJunk *j = (tileJunk *) tile->ti_client;
|
tileJunk *j = (tileJunk *)tile->ti_client;
|
||||||
|
|
||||||
if ((j->tj_status & RES_TILE_DONE) == 0)
|
if ((j->tj_status & RES_TILE_DONE) == 0)
|
||||||
{
|
{
|
||||||
|
|
@ -542,7 +539,7 @@ ResProcessTiles(goodies, origin)
|
||||||
|
|
||||||
if (merged == FALSE)
|
if (merged == FALSE)
|
||||||
{
|
{
|
||||||
ResRemoveFromQueue(resptr2,&ResNodeQueue);
|
ResRemoveFromQueue(resptr2, &ResNodeQueue);
|
||||||
resptr2->rn_more = ResNodeList;
|
resptr2->rn_more = ResNodeList;
|
||||||
resptr2->rn_less = NULL;
|
resptr2->rn_less = NULL;
|
||||||
resptr2->rn_status &= ~PENDING;
|
resptr2->rn_status &= ~PENDING;
|
||||||
|
|
@ -618,7 +615,7 @@ ResExtractNet(startlist, goodies, cellname)
|
||||||
if (cellname)
|
if (cellname)
|
||||||
{
|
{
|
||||||
CellDef *def = DBCellLookDef(cellname);
|
CellDef *def = DBCellLookDef(cellname);
|
||||||
if (def == (CellDef *) NULL)
|
if (def == (CellDef *)NULL)
|
||||||
{
|
{
|
||||||
TxError("Error: No such cell \"%s\"\n", cellname);
|
TxError("Error: No such cell \"%s\"\n", cellname);
|
||||||
return TRUE;
|
return TRUE;
|
||||||
|
|
@ -629,8 +626,8 @@ ResExtractNet(startlist, goodies, cellname)
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
MagWindow *w = ToolGetBoxWindow(&scx.scx_area, (int *) NULL);
|
MagWindow *w = ToolGetBoxWindow(&scx.scx_area, (int *)NULL);
|
||||||
if (w == (MagWindow *) NULL)
|
if (w == (MagWindow *)NULL)
|
||||||
{
|
{
|
||||||
TxError("Sorry, the box must appear in one of the windows.\n");
|
TxError("Sorry, the box must appear in one of the windows.\n");
|
||||||
return TRUE;
|
return TRUE;
|
||||||
|
|
@ -682,9 +679,9 @@ ResExtractNet(startlist, goodies, cellname)
|
||||||
|
|
||||||
ExtResetTiles(scx.scx_use->cu_def, extUnInit);
|
ExtResetTiles(scx.scx_use->cu_def, extUnInit);
|
||||||
|
|
||||||
/* find all contacts in design and note their position */
|
/* Find all contacts in design and note their position */
|
||||||
|
|
||||||
ResContactList = (ResContactPoint *) ExtFindRegions(ResUse->cu_def,
|
ResContactList = (ResContactPoint *)ExtFindRegions(ResUse->cu_def,
|
||||||
&(ResUse->cu_def->cd_bbox),
|
&(ResUse->cu_def->cd_bbox),
|
||||||
&DBAllButSpaceAndDRCBits,
|
&DBAllButSpaceAndDRCBits,
|
||||||
ResConnectWithSD, extUnInit, ResFirst,
|
ResConnectWithSD, extUnInit, ResFirst,
|
||||||
|
|
@ -705,7 +702,7 @@ ResExtractNet(startlist, goodies, cellname)
|
||||||
Plane *plane = ResUse->cu_def->cd_planes[pNum];
|
Plane *plane = ResUse->cu_def->cd_planes[pNum];
|
||||||
Rect *rect = &ResUse->cu_def->cd_bbox;
|
Rect *rect = &ResUse->cu_def->cd_bbox;
|
||||||
ResFracture(plane, rect);
|
ResFracture(plane, rect);
|
||||||
(void) DBSrPaintClient((Tile *) NULL,plane,rect,
|
(void) DBSrPaintClient((Tile *) NULL, plane, rect,
|
||||||
&DBAllButSpaceAndDRCBits,
|
&DBAllButSpaceAndDRCBits,
|
||||||
(ClientData) CLIENTDEFAULT, ResAddPlumbing,
|
(ClientData) CLIENTDEFAULT, ResAddPlumbing,
|
||||||
(ClientData) &ResDevList);
|
(ClientData) &ResDevList);
|
||||||
|
|
@ -725,7 +722,7 @@ ResExtractNet(startlist, goodies, cellname)
|
||||||
{
|
{
|
||||||
Plane *plane = ResUse->cu_def->cd_planes[pNum];
|
Plane *plane = ResUse->cu_def->cd_planes[pNum];
|
||||||
Rect *rect = &ResUse->cu_def->cd_bbox;
|
Rect *rect = &ResUse->cu_def->cd_bbox;
|
||||||
Res1d(plane,rect);
|
Res1d(plane, rect);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
@ -733,10 +730,10 @@ ResExtractNet(startlist, goodies, cellname)
|
||||||
#ifdef ARIEL
|
#ifdef ARIEL
|
||||||
if (ResOptionsFlags & ResOpt_Power)
|
if (ResOptionsFlags & ResOpt_Power)
|
||||||
{
|
{
|
||||||
for (fix = startlist; fix != NULL;fix=fix->fp_next)
|
for (fix = startlist; fix != NULL; fix = fix->fp_next)
|
||||||
{
|
{
|
||||||
fix->fp_tile = ResUse->cu_def->cd_planes[DBPlane(fix->fp_ttype)]->pl_hint;
|
fix->fp_tile = ResUse->cu_def->cd_planes[DBPlane(fix->fp_ttype)]->pl_hint;
|
||||||
GOTOPOINT(fix->fp_tile,&fix->fp_loc);
|
GOTOPOINT(fix->fp_tile, &fix->fp_loc);
|
||||||
if (TiGetTypeExact(fix->fp_tile) == TT_SPACE) fix->fp_tile = NULL;
|
if (TiGetTypeExact(fix->fp_tile) == TT_SPACE) fix->fp_tile = NULL;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -771,20 +768,19 @@ ResCleanUpEverything()
|
||||||
resDevice *oldDev;
|
resDevice *oldDev;
|
||||||
ResContactPoint *oldCon;
|
ResContactPoint *oldCon;
|
||||||
|
|
||||||
/* check integrity of internal database. Free up lists. */
|
/* Check integrity of internal database. Free up lists. */
|
||||||
|
|
||||||
for (pNum = PL_TECHDEPBASE; pNum < DBNumPlanes; pNum++)
|
for (pNum = PL_TECHDEPBASE; pNum < DBNumPlanes; pNum++)
|
||||||
{
|
{
|
||||||
(void) DBSrPaintClient((Tile *) NULL,ResUse->cu_def->cd_planes[pNum],
|
(void) DBSrPaintClient((Tile *)NULL, ResUse->cu_def->cd_planes[pNum],
|
||||||
&(ResUse->cu_def->cd_bbox),&DBAllButSpaceAndDRCBits,
|
&(ResUse->cu_def->cd_bbox), &DBAllButSpaceAndDRCBits,
|
||||||
(ClientData) CLIENTDEFAULT,ResRemovePlumbing,
|
(ClientData)CLIENTDEFAULT, ResRemovePlumbing,
|
||||||
(ClientData) NULL);
|
(ClientData)NULL);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
while (ResNodeList != NULL)
|
while (ResNodeList != NULL)
|
||||||
{
|
{
|
||||||
ResCleanNode(ResNodeList,TRUE,&ResNodeList,&ResNodeQueue);
|
ResCleanNode(ResNodeList, TRUE, &ResNodeList, &ResNodeQueue);
|
||||||
}
|
}
|
||||||
while (ResContactList != NULL)
|
while (ResContactList != NULL)
|
||||||
{
|
{
|
||||||
|
|
@ -808,12 +804,9 @@ ResCleanUpEverything()
|
||||||
freeMagic((char *)oldDev);
|
freeMagic((char *)oldDev);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
DBCellClearDef(ResUse->cu_def);
|
DBCellClearDef(ResUse->cu_def);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
*-------------------------------------------------------------------------
|
*-------------------------------------------------------------------------
|
||||||
*
|
*
|
||||||
|
|
@ -935,54 +928,55 @@ FindStartTile(goodies, SourcePoint)
|
||||||
t1 = TiGetType(tile);
|
t1 = TiGetType(tile);
|
||||||
|
|
||||||
devptr = ExtCurStyle->exts_device[t1];
|
devptr = ExtCurStyle->exts_device[t1];
|
||||||
|
|
||||||
/* left */
|
/* left */
|
||||||
for (tp = BL(tile); BOTTOM(tp) < TOP(tile); tp=RT(tp))
|
for (tp = BL(tile); BOTTOM(tp) < TOP(tile); tp = RT(tp))
|
||||||
{
|
{
|
||||||
t2 = TiGetRightType(tp);
|
t2 = TiGetRightType(tp);
|
||||||
if (TTMaskHasType(&(devptr->exts_deviceSDTypes[0]),t2))
|
if (TTMaskHasType(&(devptr->exts_deviceSDTypes[0]), t2))
|
||||||
{
|
{
|
||||||
SourcePoint->p_x = LEFT(tile);
|
SourcePoint->p_x = LEFT(tile);
|
||||||
SourcePoint->p_y = (MIN(TOP(tile),TOP(tp))+
|
SourcePoint->p_y = (MIN(TOP(tile),TOP(tp)) +
|
||||||
MAX(BOTTOM(tile),BOTTOM(tp)))>>1;
|
MAX(BOTTOM(tile), BOTTOM(tp))) >> 1;
|
||||||
return(tp);
|
return(tp);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* right */
|
/* right */
|
||||||
for (tp = TR(tile); TOP(tp) > BOTTOM(tile); tp=LB(tp))
|
for (tp = TR(tile); TOP(tp) > BOTTOM(tile); tp = LB(tp))
|
||||||
{
|
{
|
||||||
t2 = TiGetLeftType(tp);
|
t2 = TiGetLeftType(tp);
|
||||||
if (TTMaskHasType(&(devptr->exts_deviceSDTypes[0]),t2))
|
if (TTMaskHasType(&(devptr->exts_deviceSDTypes[0]), t2))
|
||||||
{
|
{
|
||||||
SourcePoint->p_x = RIGHT(tile);
|
SourcePoint->p_x = RIGHT(tile);
|
||||||
SourcePoint->p_y = (MIN(TOP(tile),TOP(tp))+
|
SourcePoint->p_y = (MIN(TOP(tile), TOP(tp))+
|
||||||
MAX(BOTTOM(tile),BOTTOM(tp)))>>1;
|
MAX(BOTTOM(tile), BOTTOM(tp))) >> 1;
|
||||||
return(tp);
|
return(tp);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* top */
|
/* top */
|
||||||
for (tp = RT(tile); RIGHT(tp) > LEFT(tile); tp=BL(tp))
|
for (tp = RT(tile); RIGHT(tp) > LEFT(tile); tp = BL(tp))
|
||||||
{
|
{
|
||||||
t2 = TiGetBottomType(tp);
|
t2 = TiGetBottomType(tp);
|
||||||
if (TTMaskHasType(&(devptr->exts_deviceSDTypes[0]),t2))
|
if (TTMaskHasType(&(devptr->exts_deviceSDTypes[0]), t2))
|
||||||
{
|
{
|
||||||
SourcePoint->p_y = TOP(tile);
|
SourcePoint->p_y = TOP(tile);
|
||||||
SourcePoint->p_x = (MIN(RIGHT(tile),RIGHT(tp))+
|
SourcePoint->p_x = (MIN(RIGHT(tile),RIGHT(tp)) +
|
||||||
MAX(LEFT(tile),LEFT(tp)))>>1;
|
MAX(LEFT(tile), LEFT(tp))) >> 1;
|
||||||
return(tp);
|
return(tp);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* bottom */
|
/* bottom */
|
||||||
for (tp = LB(tile); LEFT(tp) < RIGHT(tile); tp=TR(tp))
|
for (tp = LB(tile); LEFT(tp) < RIGHT(tile); tp = TR(tp))
|
||||||
{
|
{
|
||||||
t2 = TiGetTopType(tp);
|
t2 = TiGetTopType(tp);
|
||||||
if (TTMaskHasType(&(devptr->exts_deviceSDTypes[0]),t2))
|
if (TTMaskHasType(&(devptr->exts_deviceSDTypes[0]), t2))
|
||||||
{
|
{
|
||||||
SourcePoint->p_y = BOTTOM(tile);
|
SourcePoint->p_y = BOTTOM(tile);
|
||||||
SourcePoint->p_x = (MIN(RIGHT(tile),RIGHT(tp))+
|
SourcePoint->p_x = (MIN(RIGHT(tile), RIGHT(tp)) +
|
||||||
MAX(LEFT(tile),LEFT(tp)))>>1;
|
MAX(LEFT(tile), LEFT(tp))) >> 1;
|
||||||
return(tp);
|
return(tp);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -1016,26 +1010,26 @@ ResGetDevice(pt)
|
||||||
workingPoint.p_x = (*pt).p_x;
|
workingPoint.p_x = (*pt).p_x;
|
||||||
workingPoint.p_y = (*pt).p_y;
|
workingPoint.p_y = (*pt).p_y;
|
||||||
|
|
||||||
for (pnum= PL_TECHDEPBASE; pnum < DBNumPlanes; pnum++)
|
for (pnum = PL_TECHDEPBASE; pnum < DBNumPlanes; pnum++)
|
||||||
{
|
|
||||||
if (TTMaskIntersect(&ExtCurStyle->exts_deviceMask,&DBPlaneTypes[pnum]) == 0)
|
|
||||||
{
|
{
|
||||||
|
if (TTMaskIntersect(&ExtCurStyle->exts_deviceMask, &DBPlaneTypes[pnum]) == 0)
|
||||||
continue;
|
continue;
|
||||||
}
|
|
||||||
/*start at hint tile for device plane */
|
/* Start at hint tile for device plane */
|
||||||
|
|
||||||
tile = ResUse->cu_def->cd_planes[pnum]->pl_hint;
|
tile = ResUse->cu_def->cd_planes[pnum]->pl_hint;
|
||||||
GOTOPOINT(tile,&workingPoint);
|
GOTOPOINT(tile, &workingPoint);
|
||||||
|
|
||||||
if (IsSplit(tile))
|
if (IsSplit(tile))
|
||||||
{
|
{
|
||||||
if (TTMaskHasType(&ExtCurStyle->exts_deviceMask, TiGetLeftType(tile))
|
if (TTMaskHasType(&ExtCurStyle->exts_deviceMask, TiGetLeftType(tile))
|
||||||
|| TTMaskHasType(&ExtCurStyle->exts_deviceMask, TiGetRightType(tile)))
|
|| TTMaskHasType(&ExtCurStyle->exts_deviceMask, TiGetRightType(tile)))
|
||||||
return(((tileJunk *)tile->ti_client)->deviceList);
|
return (((tileJunk *)tile->ti_client)->deviceList);
|
||||||
}
|
}
|
||||||
else if (TTMaskHasType(&ExtCurStyle->exts_deviceMask, TiGetType(tile)))
|
else if (TTMaskHasType(&ExtCurStyle->exts_deviceMask, TiGetType(tile)))
|
||||||
{
|
{
|
||||||
return(((tileJunk *)tile->ti_client)->deviceList);
|
return (((tileJunk *)tile->ti_client)->deviceList);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return (NULL);
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
456
resis/ResMerge.c
456
resis/ResMerge.c
|
|
@ -29,9 +29,10 @@ extern void ResFixBreakPoint();
|
||||||
/*
|
/*
|
||||||
*-------------------------------------------------------------------------
|
*-------------------------------------------------------------------------
|
||||||
*
|
*
|
||||||
* ResDoneWithNode--After all connections to node are made, ResDoneWithNode
|
* ResDoneWithNode--
|
||||||
* is called. It checks for parallel, series, loop, triangle,
|
* After all connections to node are made, ResDoneWithNode is
|
||||||
* and single conections, and simplifies the network where possible.
|
* called. It checks for parallel, series, loop, triangle, and
|
||||||
|
* single conections, and simplifies the network where possible.
|
||||||
*
|
*
|
||||||
* Results: none
|
* Results: none
|
||||||
*
|
*
|
||||||
|
|
@ -56,10 +57,7 @@ ResDoneWithNode(resptr)
|
||||||
|
|
||||||
/* are there any resistors? */
|
/* are there any resistors? */
|
||||||
|
|
||||||
if (resptr->rn_re == NULL)
|
if (resptr->rn_re == NULL) return;
|
||||||
{
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Special handling for geometry option */
|
/* Special handling for geometry option */
|
||||||
|
|
||||||
|
|
@ -73,10 +71,10 @@ ResDoneWithNode(resptr)
|
||||||
rr1 = rcell1->re_thisEl;
|
rr1 = rcell1->re_thisEl;
|
||||||
if (rr1->rr_connection1 == rr1->rr_connection2)
|
if (rr1->rr_connection1 == rr1->rr_connection2)
|
||||||
{
|
{
|
||||||
ResDeleteResPointer(resptr,rr1);
|
ResDeleteResPointer(resptr, rr1);
|
||||||
ResDeleteResPointer(resptr,rr1);
|
ResDeleteResPointer(resptr, rr1);
|
||||||
resptr->rn_float.rn_area += rr1->rr_float.rr_area;
|
resptr->rn_float.rn_area += rr1->rr_float.rr_area;
|
||||||
ResEliminateResistor(rr1,&ResResList);
|
ResEliminateResistor(rr1, &ResResList);
|
||||||
status = LOOP;
|
status = LOOP;
|
||||||
ResDoneWithNode(resptr);
|
ResDoneWithNode(resptr);
|
||||||
break;
|
break;
|
||||||
|
|
@ -84,8 +82,8 @@ ResDoneWithNode(resptr)
|
||||||
}
|
}
|
||||||
else if (rr1->rr_value == 0)
|
else if (rr1->rr_value == 0)
|
||||||
{
|
{
|
||||||
ResDeleteResPointer(rr1->rr_connection1,rr1);
|
ResDeleteResPointer(rr1->rr_connection1, rr1);
|
||||||
ResDeleteResPointer(rr1->rr_connection2,rr1);
|
ResDeleteResPointer(rr1->rr_connection2, rr1);
|
||||||
if (rr1->rr_connection1 == resptr)
|
if (rr1->rr_connection1 == resptr)
|
||||||
{
|
{
|
||||||
resptr2 = rr1->rr_connection2;
|
resptr2 = rr1->rr_connection2;
|
||||||
|
|
@ -93,9 +91,9 @@ ResDoneWithNode(resptr)
|
||||||
{
|
{
|
||||||
resptr2 = rr1->rr_connection1;
|
resptr2 = rr1->rr_connection1;
|
||||||
}
|
}
|
||||||
ResMergeNodes(resptr2,resptr,&ResNodeQueue,&ResNodeList);
|
ResMergeNodes(resptr2, resptr, &ResNodeQueue, &ResNodeList);
|
||||||
resptr2->rn_float.rn_area += rr1->rr_float.rr_area;
|
resptr2->rn_float.rn_area += rr1->rr_float.rr_area;
|
||||||
ResEliminateResistor(rr1,&ResResList);
|
ResEliminateResistor(rr1, &ResResList);
|
||||||
if ((resptr2->rn_status & TRUE) == TRUE)
|
if ((resptr2->rn_status & TRUE) == TRUE)
|
||||||
{
|
{
|
||||||
resptr2->rn_status &= ~TRUE;
|
resptr2->rn_status &= ~TRUE;
|
||||||
|
|
@ -106,23 +104,20 @@ ResDoneWithNode(resptr)
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if (status != UNTOUCHED) return; /* resptr may be invalid */
|
||||||
|
|
||||||
/* Eliminations that can be only if there are no devices connected */
|
/* Eliminations that can be only if there are no devices connected */
|
||||||
/* to node. Series and dangling connections fall in this group. */
|
/* to node. Series and dangling connections fall in this group. */
|
||||||
|
|
||||||
if ((resptr->rn_te == NULL) && (resptr->rn_why != RES_NODE_ORIGIN)
|
if ((resptr->rn_te == NULL) && (resptr->rn_why != RES_NODE_ORIGIN)
|
||||||
&& (status == UNTOUCHED))
|
&& (status == UNTOUCHED))
|
||||||
{
|
|
||||||
status = ResSeriesCheck(resptr);
|
status = ResSeriesCheck(resptr);
|
||||||
}
|
|
||||||
if ((status == UNTOUCHED) && (resptr->rn_why != RES_NODE_ORIGIN))
|
if ((status == UNTOUCHED) && (resptr->rn_why != RES_NODE_ORIGIN))
|
||||||
{
|
|
||||||
status = ResParallelCheck(resptr);
|
status = ResParallelCheck(resptr);
|
||||||
}
|
|
||||||
if ((status == UNTOUCHED) && (resptr->rn_why != RES_NODE_ORIGIN))
|
if ((status == UNTOUCHED) && (resptr->rn_why != RES_NODE_ORIGIN))
|
||||||
{
|
|
||||||
status = ResTriangleCheck(resptr);
|
status = ResTriangleCheck(resptr);
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -141,20 +136,24 @@ ResDoneWithNode(resptr)
|
||||||
*/
|
*/
|
||||||
|
|
||||||
void
|
void
|
||||||
ResFixRes(resptr,resptr2,resptr3,elimResis,newResis)
|
ResFixRes(resptr, resptr2, resptr3, elimResis, newResis)
|
||||||
resNode *resptr,*resptr2,*resptr3;
|
resNode *resptr, *resptr2, *resptr3;
|
||||||
resResistor *elimResis, *newResis;
|
resResistor *elimResis, *newResis;
|
||||||
|
|
||||||
{
|
{
|
||||||
resElement *thisREl;
|
resElement *thisREl;
|
||||||
|
|
||||||
resptr3->rn_float.rn_area += newResis->rr_value*resptr->rn_float.rn_area/((float)(newResis->rr_value+elimResis->rr_value));
|
resptr3->rn_float.rn_area += newResis->rr_value*resptr->rn_float.rn_area
|
||||||
resptr2->rn_float.rn_area += elimResis->rr_value*resptr->rn_float.rn_area/((float)(newResis->rr_value+elimResis->rr_value));
|
/ ((float)(newResis->rr_value + elimResis->rr_value));
|
||||||
|
resptr2->rn_float.rn_area += elimResis->rr_value*resptr->rn_float.rn_area
|
||||||
|
/ ((float)(newResis->rr_value + elimResis->rr_value));
|
||||||
newResis->rr_value += elimResis->rr_value;
|
newResis->rr_value += elimResis->rr_value;
|
||||||
ASSERT(newResis->rr_value > 0,"series");
|
ASSERT(newResis->rr_value > 0, "series");
|
||||||
newResis->rr_float.rr_area += elimResis->rr_float.rr_area;
|
newResis->rr_float.rr_area += elimResis->rr_float.rr_area;
|
||||||
|
|
||||||
#ifdef ARIEL
|
#ifdef ARIEL
|
||||||
if (elimResis->rr_csArea && elimResis->rr_csArea < newResis->rr_csArea || newResis->rr_csArea == 0)
|
if (elimResis->rr_csArea && elimResis->rr_csArea < newResis->rr_csArea
|
||||||
|
|| newResis->rr_csArea == 0)
|
||||||
{
|
{
|
||||||
newResis->rr_csArea = elimResis->rr_csArea;
|
newResis->rr_csArea = elimResis->rr_csArea;
|
||||||
newResis->rr_tt = elimResis->rr_tt;
|
newResis->rr_tt = elimResis->rr_tt;
|
||||||
|
|
@ -170,10 +169,10 @@ ResFixRes(resptr,resptr2,resptr3,elimResis,newResis)
|
||||||
|
|
||||||
}
|
}
|
||||||
if (thisREl == NULL) TxError("Resistor not found in duo\n");
|
if (thisREl == NULL) TxError("Resistor not found in duo\n");
|
||||||
ResDeleteResPointer(resptr,elimResis);
|
ResDeleteResPointer(resptr, elimResis);
|
||||||
ResDeleteResPointer(resptr,newResis);
|
ResDeleteResPointer(resptr, newResis);
|
||||||
ResEliminateResistor(elimResis, &ResResList);
|
ResEliminateResistor(elimResis, &ResResList);
|
||||||
ResCleanNode(resptr, TRUE,&ResNodeList,&ResNodeQueue);
|
ResCleanNode(resptr, TRUE, &ResNodeList, &ResNodeQueue);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|
@ -191,36 +190,36 @@ ResFixRes(resptr,resptr2,resptr3,elimResis,newResis)
|
||||||
*/
|
*/
|
||||||
|
|
||||||
void
|
void
|
||||||
ResFixParallel(elimResis,newResis)
|
ResFixParallel(elimResis, newResis)
|
||||||
resResistor *elimResis,*newResis;
|
resResistor *elimResis, *newResis;
|
||||||
|
|
||||||
{
|
{
|
||||||
if ((newResis->rr_value+elimResis->rr_value) != 0)
|
if ((newResis->rr_value + elimResis->rr_value) != 0)
|
||||||
{
|
{
|
||||||
newResis->rr_value = (((float) newResis->rr_value)*
|
newResis->rr_value = (((float) newResis->rr_value) *
|
||||||
((float)elimResis->rr_value))/
|
((float)elimResis->rr_value)) /
|
||||||
((float)(newResis->rr_value+
|
((float)(newResis->rr_value +
|
||||||
elimResis->rr_value));
|
elimResis->rr_value));
|
||||||
ASSERT(newResis->rr_value >= 0,"parallel");
|
ASSERT(newResis->rr_value >= 0, "parallel");
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
newResis->rr_value =0;
|
newResis->rr_value = 0;
|
||||||
}
|
}
|
||||||
newResis->rr_float.rr_area += elimResis->rr_float.rr_area;
|
newResis->rr_float.rr_area += elimResis->rr_float.rr_area;
|
||||||
#ifdef ARIEL
|
#ifdef ARIEL
|
||||||
newResis->rr_csArea += elimResis->rr_csArea;
|
newResis->rr_csArea += elimResis->rr_csArea;
|
||||||
#endif
|
#endif
|
||||||
ResDeleteResPointer(elimResis->rr_connection1,elimResis);
|
ResDeleteResPointer(elimResis->rr_connection1, elimResis);
|
||||||
ResDeleteResPointer(elimResis->rr_connection2,elimResis);
|
ResDeleteResPointer(elimResis->rr_connection2, elimResis);
|
||||||
ResEliminateResistor(elimResis,&ResResList);
|
ResEliminateResistor(elimResis, &ResResList);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
*-------------------------------------------------------------------------
|
*-------------------------------------------------------------------------
|
||||||
*
|
*
|
||||||
* ResSeriesCheck -- for nodes with no devices, sees if a series
|
* ResSeriesCheck -- for nodes with no devices, sees if a series
|
||||||
or loop combination is possible.
|
* or loop combination is possible.
|
||||||
*
|
*
|
||||||
* Results: returns SINGLE,LOOP,or SERIES if succesful.
|
* Results: returns SINGLE,LOOP,or SERIES if succesful.
|
||||||
*
|
*
|
||||||
|
|
@ -235,8 +234,8 @@ ResSeriesCheck(resptr)
|
||||||
|
|
||||||
{
|
{
|
||||||
resResistor *rr1,*rr2;
|
resResistor *rr1,*rr2;
|
||||||
resNode *resptr2,*resptr3;
|
resNode *resptr2, *resptr3;
|
||||||
int status=UNTOUCHED;
|
int status = UNTOUCHED;
|
||||||
resElement *res_next;
|
resElement *res_next;
|
||||||
|
|
||||||
rr1 = resptr->rn_re->re_thisEl;
|
rr1 = resptr->rn_re->re_thisEl;
|
||||||
|
|
@ -245,15 +244,15 @@ ResSeriesCheck(resptr)
|
||||||
if (res_next == NULL)
|
if (res_next == NULL)
|
||||||
/* node with only one connection */
|
/* node with only one connection */
|
||||||
{
|
{
|
||||||
resptr2 = (rr1->rr_connection1 == resptr)?rr1->rr_connection2:
|
resptr2 = (rr1->rr_connection1 == resptr) ? rr1->rr_connection2:
|
||||||
rr1->rr_connection1;
|
rr1->rr_connection1;
|
||||||
|
|
||||||
ResDeleteResPointer(rr1->rr_connection1,rr1);
|
ResDeleteResPointer(rr1->rr_connection1, rr1);
|
||||||
ResDeleteResPointer(rr1->rr_connection2,rr1);
|
ResDeleteResPointer(rr1->rr_connection2, rr1);
|
||||||
resptr2->rn_float.rn_area += rr1->rr_float.rr_area+
|
resptr2->rn_float.rn_area += rr1->rr_float.rr_area +
|
||||||
resptr->rn_float.rn_area;
|
resptr->rn_float.rn_area;
|
||||||
ResEliminateResistor(rr1,&ResResList);
|
ResEliminateResistor(rr1, &ResResList);
|
||||||
ResCleanNode(resptr,TRUE,&ResNodeList,&ResNodeQueue);
|
ResCleanNode(resptr, TRUE, &ResNodeList, &ResNodeQueue);
|
||||||
status = SINGLE;
|
status = SINGLE;
|
||||||
if (resptr2->rn_status & TRUE)
|
if (resptr2->rn_status & TRUE)
|
||||||
{
|
{
|
||||||
|
|
@ -265,34 +264,33 @@ ResSeriesCheck(resptr)
|
||||||
else if (res_next->re_nextEl == NULL)
|
else if (res_next->re_nextEl == NULL)
|
||||||
{
|
{
|
||||||
rr2 = res_next->re_thisEl;
|
rr2 = res_next->re_thisEl;
|
||||||
if (!TTMaskHasType(ResNoMergeMask+rr1->rr_tt,rr2->rr_tt))
|
if (!TTMaskHasType(ResNoMergeMask + rr1->rr_tt, rr2->rr_tt))
|
||||||
{
|
{
|
||||||
if (rr1->rr_connection1 == resptr)
|
if (rr1->rr_connection1 == resptr)
|
||||||
{
|
{
|
||||||
|
|
||||||
if (rr2->rr_connection1 == resptr)
|
if (rr2->rr_connection1 == resptr)
|
||||||
{
|
{
|
||||||
resptr2 = rr1->rr_connection2;
|
resptr2 = rr1->rr_connection2;
|
||||||
if (rr1->rr_connection2 ==
|
if (rr1->rr_connection2 == rr2->rr_connection2)
|
||||||
rr2->rr_connection2)
|
|
||||||
{
|
{
|
||||||
status = LOOP;
|
status = LOOP;
|
||||||
ResDeleteResPointer(rr1->rr_connection1,rr1);
|
ResDeleteResPointer(rr1->rr_connection1, rr1);
|
||||||
ResDeleteResPointer(rr1->rr_connection2,rr1);
|
ResDeleteResPointer(rr1->rr_connection2, rr1);
|
||||||
ResDeleteResPointer(rr2->rr_connection1,rr2);
|
ResDeleteResPointer(rr2->rr_connection1, rr2);
|
||||||
ResDeleteResPointer(rr2->rr_connection2,rr2);
|
ResDeleteResPointer(rr2->rr_connection2, rr2);
|
||||||
resptr2->rn_float.rn_area += rr1->rr_float.rr_area
|
resptr2->rn_float.rn_area += rr1->rr_float.rr_area
|
||||||
+ rr2->rr_float.rr_area
|
+ rr2->rr_float.rr_area
|
||||||
+ resptr->rn_float.rn_area;
|
+ resptr->rn_float.rn_area;
|
||||||
ResEliminateResistor(rr1,&ResResList);
|
ResEliminateResistor(rr1, &ResResList);
|
||||||
ResEliminateResistor(rr2,&ResResList);
|
ResEliminateResistor(rr2, &ResResList);
|
||||||
ResCleanNode(resptr,TRUE,&ResNodeList,&ResNodeQueue);
|
ResCleanNode(resptr, TRUE, &ResNodeList, &ResNodeQueue);
|
||||||
}else
|
}
|
||||||
|
else
|
||||||
{
|
{
|
||||||
status = SERIES;
|
status = SERIES;
|
||||||
resptr3 = rr2->rr_connection2;
|
resptr3 = rr2->rr_connection2;
|
||||||
rr1->rr_connection1 = rr2->rr_connection2;
|
rr1->rr_connection1 = rr2->rr_connection2;
|
||||||
ResFixRes(resptr,resptr2,resptr3,rr2,rr1);
|
ResFixRes(resptr, resptr2, resptr3, rr2, rr1);
|
||||||
}
|
}
|
||||||
if ((resptr2->rn_status & TRUE) == TRUE)
|
if ((resptr2->rn_status & TRUE) == TRUE)
|
||||||
{
|
{
|
||||||
|
|
@ -300,28 +298,30 @@ ResSeriesCheck(resptr)
|
||||||
ResDoneWithNode(resptr2);
|
ResDoneWithNode(resptr2);
|
||||||
}
|
}
|
||||||
resptr2 = NULL;
|
resptr2 = NULL;
|
||||||
}else
|
}
|
||||||
|
else
|
||||||
{
|
{
|
||||||
resptr2 = rr1->rr_connection2;
|
resptr2 = rr1->rr_connection2;
|
||||||
if (rr1->rr_connection2 == rr2->rr_connection1)
|
if (rr1->rr_connection2 == rr2->rr_connection1)
|
||||||
{
|
{
|
||||||
status = LOOP;
|
status = LOOP;
|
||||||
ResDeleteResPointer(rr1->rr_connection1,rr1);
|
ResDeleteResPointer(rr1->rr_connection1, rr1);
|
||||||
ResDeleteResPointer(rr1->rr_connection2,rr1);
|
ResDeleteResPointer(rr1->rr_connection2, rr1);
|
||||||
ResDeleteResPointer(rr2->rr_connection1,rr2);
|
ResDeleteResPointer(rr2->rr_connection1, rr2);
|
||||||
ResDeleteResPointer(rr2->rr_connection2,rr2);
|
ResDeleteResPointer(rr2->rr_connection2, rr2);
|
||||||
resptr2->rn_float.rn_area += rr1->rr_float.rr_area
|
resptr2->rn_float.rn_area += rr1->rr_float.rr_area
|
||||||
+ rr2->rr_float.rr_area
|
+ rr2->rr_float.rr_area
|
||||||
+ resptr->rn_float.rn_area;
|
+ resptr->rn_float.rn_area;
|
||||||
ResEliminateResistor(rr1,&ResResList);
|
ResEliminateResistor(rr1, &ResResList);
|
||||||
ResEliminateResistor(rr2,&ResResList);
|
ResEliminateResistor(rr2, &ResResList);
|
||||||
ResCleanNode(resptr,TRUE,&ResNodeList,&ResNodeQueue);
|
ResCleanNode(resptr, TRUE, &ResNodeList, &ResNodeQueue);
|
||||||
}else
|
}
|
||||||
|
else
|
||||||
{
|
{
|
||||||
status = SERIES;
|
status = SERIES;
|
||||||
resptr3 = rr2->rr_connection1;
|
resptr3 = rr2->rr_connection1;
|
||||||
rr1->rr_connection1 = rr2->rr_connection1;
|
rr1->rr_connection1 = rr2->rr_connection1;
|
||||||
ResFixRes(resptr,resptr2,resptr3,rr2,rr1);
|
ResFixRes(resptr, resptr2, resptr3, rr2, rr1);
|
||||||
}
|
}
|
||||||
if ((resptr2->rn_status & TRUE) == TRUE)
|
if ((resptr2->rn_status & TRUE) == TRUE)
|
||||||
{
|
{
|
||||||
|
|
@ -330,7 +330,8 @@ ResSeriesCheck(resptr)
|
||||||
}
|
}
|
||||||
resptr2 = NULL;
|
resptr2 = NULL;
|
||||||
}
|
}
|
||||||
}else
|
}
|
||||||
|
else
|
||||||
{
|
{
|
||||||
if (rr2->rr_connection1 == resptr)
|
if (rr2->rr_connection1 == resptr)
|
||||||
{
|
{
|
||||||
|
|
@ -338,23 +339,23 @@ ResSeriesCheck(resptr)
|
||||||
if (rr1->rr_connection1 == rr2->rr_connection2)
|
if (rr1->rr_connection1 == rr2->rr_connection2)
|
||||||
{
|
{
|
||||||
status = LOOP;
|
status = LOOP;
|
||||||
ResDeleteResPointer(rr1->rr_connection1,rr1);
|
ResDeleteResPointer(rr1->rr_connection1, rr1);
|
||||||
ResDeleteResPointer(rr1->rr_connection2,rr1);
|
ResDeleteResPointer(rr1->rr_connection2, rr1);
|
||||||
ResDeleteResPointer(rr2->rr_connection1,rr2);
|
ResDeleteResPointer(rr2->rr_connection1, rr2);
|
||||||
ResDeleteResPointer(rr2->rr_connection2,rr2);
|
ResDeleteResPointer(rr2->rr_connection2, rr2);
|
||||||
resptr2->rn_float.rn_area += rr1->rr_float.rr_area
|
resptr2->rn_float.rn_area += rr1->rr_float.rr_area
|
||||||
+ rr2->rr_float.rr_area
|
+ rr2->rr_float.rr_area
|
||||||
+ resptr->rn_float.rn_area;
|
+ resptr->rn_float.rn_area;
|
||||||
ResEliminateResistor(rr1,&ResResList);
|
ResEliminateResistor(rr1, &ResResList);
|
||||||
ResEliminateResistor(rr2,&ResResList);
|
ResEliminateResistor(rr2, &ResResList);
|
||||||
ResCleanNode(resptr,TRUE,&ResNodeList,&ResNodeQueue);
|
ResCleanNode(resptr, TRUE, &ResNodeList, &ResNodeQueue);
|
||||||
}else
|
}
|
||||||
|
else
|
||||||
{
|
{
|
||||||
status = SERIES;
|
status = SERIES;
|
||||||
resptr3 = rr2->rr_connection2;
|
resptr3 = rr2->rr_connection2;
|
||||||
rr1->rr_connection2 =
|
rr1->rr_connection2 = rr2->rr_connection2;
|
||||||
rr2->rr_connection2;
|
ResFixRes(resptr, resptr2, resptr3, rr2, rr1);
|
||||||
ResFixRes(resptr,resptr2,resptr3,rr2,rr1);
|
|
||||||
}
|
}
|
||||||
if ((resptr2->rn_status & TRUE) == TRUE)
|
if ((resptr2->rn_status & TRUE) == TRUE)
|
||||||
{
|
{
|
||||||
|
|
@ -362,29 +363,30 @@ ResSeriesCheck(resptr)
|
||||||
ResDoneWithNode(resptr2);
|
ResDoneWithNode(resptr2);
|
||||||
}
|
}
|
||||||
resptr2 = NULL;
|
resptr2 = NULL;
|
||||||
}else
|
}
|
||||||
|
else
|
||||||
{
|
{
|
||||||
resptr2 = rr1->rr_connection1;
|
resptr2 = rr1->rr_connection1;
|
||||||
if (rr1->rr_connection1 == rr2->rr_connection1)
|
if (rr1->rr_connection1 == rr2->rr_connection1)
|
||||||
{
|
{
|
||||||
status = LOOP;
|
status = LOOP;
|
||||||
ResDeleteResPointer(rr1->rr_connection1,rr1);
|
ResDeleteResPointer(rr1->rr_connection1, rr1);
|
||||||
ResDeleteResPointer(rr1->rr_connection2,rr1);
|
ResDeleteResPointer(rr1->rr_connection2, rr1);
|
||||||
ResDeleteResPointer(rr2->rr_connection1,rr2);
|
ResDeleteResPointer(rr2->rr_connection1, rr2);
|
||||||
ResDeleteResPointer(rr2->rr_connection2,rr2);
|
ResDeleteResPointer(rr2->rr_connection2, rr2);
|
||||||
resptr2->rn_float.rn_area += rr1->rr_float.rr_area
|
resptr2->rn_float.rn_area += rr1->rr_float.rr_area
|
||||||
+ rr2->rr_float.rr_area
|
+ rr2->rr_float.rr_area
|
||||||
+ resptr->rn_float.rn_area;
|
+ resptr->rn_float.rn_area;
|
||||||
ResEliminateResistor(rr1,&ResResList);
|
ResEliminateResistor(rr1, &ResResList);
|
||||||
ResEliminateResistor(rr2,&ResResList);
|
ResEliminateResistor(rr2, &ResResList);
|
||||||
ResCleanNode(resptr,TRUE,&ResNodeList,&ResNodeQueue);
|
ResCleanNode(resptr, TRUE, &ResNodeList, &ResNodeQueue);
|
||||||
}else
|
}
|
||||||
|
else
|
||||||
{
|
{
|
||||||
status = SERIES;
|
status = SERIES;
|
||||||
resptr3 = rr2->rr_connection1;
|
resptr3 = rr2->rr_connection1;
|
||||||
rr1->rr_connection2 =
|
rr1->rr_connection2 = rr2->rr_connection1;
|
||||||
rr2->rr_connection1;
|
ResFixRes(resptr, resptr2, resptr3, rr2, rr1);
|
||||||
ResFixRes(resptr,resptr2,resptr3,rr2,rr1);
|
|
||||||
}
|
}
|
||||||
if ((resptr2->rn_status & TRUE) == TRUE)
|
if ((resptr2->rn_status & TRUE) == TRUE)
|
||||||
{
|
{
|
||||||
|
|
@ -399,7 +401,6 @@ ResSeriesCheck(resptr)
|
||||||
return status;
|
return status;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
*-------------------------------------------------------------------------
|
*-------------------------------------------------------------------------
|
||||||
*
|
*
|
||||||
|
|
@ -419,17 +420,17 @@ ResParallelCheck(resptr)
|
||||||
{
|
{
|
||||||
resResistor *r1,*r2;
|
resResistor *r1,*r2;
|
||||||
resNode *resptr2,*resptr3;
|
resNode *resptr2,*resptr3;
|
||||||
int status=UNTOUCHED;
|
int status = UNTOUCHED;
|
||||||
resElement *rcell1,*rcell2;
|
resElement *rcell1, *rcell2;
|
||||||
|
|
||||||
|
|
||||||
for (rcell1 = resptr->rn_re;
|
for (rcell1 = resptr->rn_re; rcell1->re_nextEl != NULL;
|
||||||
rcell1->re_nextEl != NULL; rcell1 = rcell1->re_nextEl)
|
rcell1 = rcell1->re_nextEl)
|
||||||
{
|
{
|
||||||
r1 = rcell1->re_thisEl;
|
r1 = rcell1->re_thisEl;
|
||||||
|
|
||||||
for (rcell2 = rcell1->re_nextEl;
|
for (rcell2 = rcell1->re_nextEl; rcell2 != NULL;
|
||||||
rcell2 != NULL; rcell2 = rcell2->re_nextEl)
|
rcell2 = rcell2->re_nextEl)
|
||||||
|
|
||||||
{
|
{
|
||||||
r2 = rcell2->re_thisEl;
|
r2 = rcell2->re_thisEl;
|
||||||
|
|
@ -441,7 +442,7 @@ ResParallelCheck(resptr)
|
||||||
{
|
{
|
||||||
resptr3 = (r1->rr_connection1 == resptr) ?
|
resptr3 = (r1->rr_connection1 == resptr) ?
|
||||||
r1->rr_connection2 : r1->rr_connection1;
|
r1->rr_connection2 : r1->rr_connection1;
|
||||||
ResFixParallel(r1,r2);
|
ResFixParallel(r1, r2);
|
||||||
status = PARALLEL;
|
status = PARALLEL;
|
||||||
resptr2 = NULL;
|
resptr2 = NULL;
|
||||||
if (resptr3->rn_status & TRUE)
|
if (resptr3->rn_status & TRUE)
|
||||||
|
|
@ -477,34 +478,34 @@ ResTriangleCheck(resptr)
|
||||||
resNode *resptr;
|
resNode *resptr;
|
||||||
|
|
||||||
{
|
{
|
||||||
resResistor *rr1,*rr2,*rr3;
|
resResistor *rr1, *rr2, *rr3;
|
||||||
int status=UNTOUCHED;
|
int status = UNTOUCHED;
|
||||||
float r1,r2,r3,denom;
|
float r1, r2, r3, denom;
|
||||||
resNode *n1,*n2,*n3;
|
resNode *n1, *n2, *n3;
|
||||||
resElement *rcell1,*rcell2,*rcell3,*element;
|
resElement *rcell1, *rcell2, *rcell3, *element;
|
||||||
|
|
||||||
for (rcell1 = resptr->rn_re;
|
for (rcell1 = resptr->rn_re; rcell1->re_nextEl != NULL;
|
||||||
rcell1->re_nextEl != NULL; rcell1 = rcell1->re_nextEl)
|
rcell1 = rcell1->re_nextEl)
|
||||||
{
|
{
|
||||||
rr1 = rcell1->re_thisEl;
|
rr1 = rcell1->re_thisEl;
|
||||||
n1 = (rr1->rr_connection1 == resptr)?rr1->rr_connection2:
|
n1 = (rr1->rr_connection1 == resptr) ? rr1->rr_connection2:
|
||||||
rr1->rr_connection1;
|
rr1->rr_connection1;
|
||||||
|
|
||||||
for (rcell2 = rcell1->re_nextEl;
|
for (rcell2 = rcell1->re_nextEl; rcell2 != NULL;
|
||||||
rcell2 != NULL; rcell2 = rcell2->re_nextEl)
|
rcell2 = rcell2->re_nextEl)
|
||||||
{
|
{
|
||||||
rr2 = rcell2->re_thisEl;
|
rr2 = rcell2->re_thisEl;
|
||||||
if (TTMaskHasType(ResNoMergeMask + rr1->rr_tt, rr2->rr_tt))
|
if (TTMaskHasType(ResNoMergeMask + rr1->rr_tt, rr2->rr_tt))
|
||||||
continue;
|
continue;
|
||||||
n2 = (rr2->rr_connection1 == resptr) ? rr2->rr_connection2 :
|
n2 = (rr2->rr_connection1 == resptr) ? rr2->rr_connection2 :
|
||||||
rr2->rr_connection1;
|
rr2->rr_connection1;
|
||||||
for (rcell3 = n1->rn_re;
|
for (rcell3 = n1->rn_re; rcell3 != NULL;
|
||||||
rcell3 != NULL; rcell3 = rcell3->re_nextEl)
|
rcell3 = rcell3->re_nextEl)
|
||||||
{
|
{
|
||||||
rr3 = rcell3->re_thisEl;
|
rr3 = rcell3->re_thisEl;
|
||||||
if (TTMaskHasType(ResNoMergeMask+rr1->rr_tt,rr3->rr_tt))
|
if (TTMaskHasType(ResNoMergeMask + rr1->rr_tt, rr3->rr_tt))
|
||||||
continue;
|
continue;
|
||||||
if (TTMaskHasType(ResNoMergeMask+rr2->rr_tt,rr3->rr_tt))
|
if (TTMaskHasType(ResNoMergeMask + rr2->rr_tt, rr3->rr_tt))
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
if (((rr3->rr_connection1 != n1) ||
|
if (((rr3->rr_connection1 != n1) ||
|
||||||
|
|
@ -513,25 +514,22 @@ ResTriangleCheck(resptr)
|
||||||
(rr3->rr_connection1 != n2))) continue;
|
(rr3->rr_connection1 != n2))) continue;
|
||||||
|
|
||||||
status = TRIANGLE;
|
status = TRIANGLE;
|
||||||
if ((denom=rr1->rr_value+rr2->rr_value+rr3->rr_value) != 0.0)
|
if ((denom = rr1->rr_value + rr2->rr_value + rr3->rr_value) != 0.0)
|
||||||
{
|
{
|
||||||
denom = 1.0/denom;
|
denom = 1.0 /denom;
|
||||||
/*calculate new values for resistors */
|
/* calculate new values for resistors */
|
||||||
r1 = (((float) rr1->rr_value)*
|
r1 = (((float)rr1->rr_value) * ((float)rr2->rr_value)) * denom;
|
||||||
((float) rr2->rr_value))*denom;
|
|
||||||
|
|
||||||
r2 = (((float) rr2->rr_value)*
|
r2 = (((float)rr2->rr_value) * ((float)rr3->rr_value)) * denom;
|
||||||
((float) rr3->rr_value))*denom;
|
|
||||||
|
|
||||||
r3 = (((float) rr1->rr_value)*
|
r3 = (((float)rr1->rr_value) * ((float)rr3->rr_value)) * denom;
|
||||||
((float) rr3->rr_value))*denom;
|
|
||||||
|
|
||||||
rr1->rr_value = r1+0.5;
|
rr1->rr_value = r1 + 0.5;
|
||||||
rr2->rr_value = r2+0.5;
|
rr2->rr_value = r2 + 0.5;
|
||||||
rr3->rr_value = r3+0.5;
|
rr3->rr_value = r3 + 0.5;
|
||||||
ASSERT(rr1->rr_value >= 0,"Triangle");
|
ASSERT(rr1->rr_value >= 0, "Triangle");
|
||||||
ASSERT(rr2->rr_value >= 0,"Triangle");
|
ASSERT(rr2->rr_value >= 0, "Triangle");
|
||||||
ASSERT(rr3->rr_value >= 0,"Triangle");
|
ASSERT(rr3->rr_value >= 0, "Triangle");
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
|
@ -539,12 +537,13 @@ ResTriangleCheck(resptr)
|
||||||
rr2->rr_value = 0;
|
rr2->rr_value = 0;
|
||||||
rr3->rr_value = 0;
|
rr3->rr_value = 0;
|
||||||
}
|
}
|
||||||
n3 = (resNode *) mallocMagic((unsigned) (sizeof(resNode)));
|
n3 = (resNode *)mallocMagic((unsigned)(sizeof(resNode)));
|
||||||
|
|
||||||
/* Where should the new node be `put'? It */
|
/* Where should the new node be `put'? It */
|
||||||
/* is arbitrarily assigned to the location */
|
/* is arbitrarily assigned to the location */
|
||||||
/* occupied by the first node. */
|
/* occupied by the first node. */
|
||||||
|
|
||||||
InitializeNode(n3,resptr->rn_loc.p_x,resptr->rn_loc.p_y,TRIANGLE);
|
InitializeNode(n3, resptr->rn_loc.p_x, resptr->rn_loc.p_y, TRIANGLE);
|
||||||
n3->rn_status = FINISHED | TRUE | MARKED;
|
n3->rn_status = FINISHED | TRUE | MARKED;
|
||||||
|
|
||||||
n3->rn_less = NULL;
|
n3->rn_less = NULL;
|
||||||
|
|
@ -553,62 +552,56 @@ ResTriangleCheck(resptr)
|
||||||
ResNodeList = n3;
|
ResNodeList = n3;
|
||||||
if (resptr == rr1->rr_connection1)
|
if (resptr == rr1->rr_connection1)
|
||||||
{
|
{
|
||||||
ResDeleteResPointer(rr1->rr_connection2,rr1);
|
ResDeleteResPointer(rr1->rr_connection2, rr1);
|
||||||
rr1->rr_connection2 = n3;
|
rr1->rr_connection2 = n3;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
ResDeleteResPointer(rr1->rr_connection1,rr1);
|
ResDeleteResPointer(rr1->rr_connection1, rr1);
|
||||||
rr1->rr_connection1 = n3;
|
rr1->rr_connection1 = n3;
|
||||||
}
|
}
|
||||||
if (n2 == rr2->rr_connection1)
|
if (n2 == rr2->rr_connection1)
|
||||||
{
|
{
|
||||||
ResDeleteResPointer(rr2->rr_connection2,rr2);
|
ResDeleteResPointer(rr2->rr_connection2, rr2);
|
||||||
rr2->rr_connection2 = n3;
|
rr2->rr_connection2 = n3;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
ResDeleteResPointer(rr2->rr_connection1,rr2);
|
ResDeleteResPointer(rr2->rr_connection1, rr2);
|
||||||
rr2->rr_connection1 = n3;
|
rr2->rr_connection1 = n3;
|
||||||
}
|
}
|
||||||
if (n1 == rr3->rr_connection1)
|
if (n1 == rr3->rr_connection1)
|
||||||
{
|
{
|
||||||
ResDeleteResPointer(rr3->rr_connection2,rr3);
|
ResDeleteResPointer(rr3->rr_connection2, rr3);
|
||||||
rr3->rr_connection2 = n3;
|
rr3->rr_connection2 = n3;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
ResDeleteResPointer(rr3->rr_connection1,rr3);
|
ResDeleteResPointer(rr3->rr_connection1, rr3);
|
||||||
rr3->rr_connection1 = n3;
|
rr3->rr_connection1 = n3;
|
||||||
}
|
}
|
||||||
element = (resElement *) mallocMagic((unsigned)(sizeof(resElement)));
|
element = (resElement *)mallocMagic((unsigned)(sizeof(resElement)));
|
||||||
element->re_nextEl = NULL;
|
element->re_nextEl = NULL;
|
||||||
element->re_thisEl = rr1;
|
element->re_thisEl = rr1;
|
||||||
n3->rn_re = element;
|
n3->rn_re = element;
|
||||||
element = (resElement *) mallocMagic((unsigned)(sizeof(resElement)));
|
element = (resElement *)mallocMagic((unsigned)(sizeof(resElement)));
|
||||||
element->re_nextEl = n3->rn_re;
|
element->re_nextEl = n3->rn_re;
|
||||||
element->re_thisEl = rr2;
|
element->re_thisEl = rr2;
|
||||||
n3->rn_re = element;
|
n3->rn_re = element;
|
||||||
element = (resElement *) mallocMagic((unsigned)(sizeof(resElement)));
|
element = (resElement *)mallocMagic((unsigned)(sizeof(resElement)));
|
||||||
element->re_nextEl = n3->rn_re;
|
element->re_nextEl = n3->rn_re;
|
||||||
element->re_thisEl = rr3;
|
element->re_thisEl = rr3;
|
||||||
n3->rn_re = element;
|
n3->rn_re = element;
|
||||||
if ((n1->rn_status & TRUE) == TRUE)
|
if ((n1->rn_status & TRUE) == TRUE)
|
||||||
{
|
|
||||||
n1->rn_status &= ~TRUE;
|
n1->rn_status &= ~TRUE;
|
||||||
}
|
|
||||||
else
|
else
|
||||||
{
|
|
||||||
n1 = NULL;
|
n1 = NULL;
|
||||||
}
|
|
||||||
if ((n2->rn_status & TRUE) == TRUE)
|
if ((n2->rn_status & TRUE) == TRUE)
|
||||||
{
|
|
||||||
n2->rn_status &= ~TRUE;
|
n2->rn_status &= ~TRUE;
|
||||||
}
|
|
||||||
else
|
else
|
||||||
{
|
|
||||||
n2 = NULL;
|
n2 = NULL;
|
||||||
}
|
|
||||||
ResDoneWithNode(resptr);
|
ResDoneWithNode(resptr);
|
||||||
if (n1 != NULL) ResDoneWithNode(n1);
|
if (n1 != NULL) ResDoneWithNode(n1);
|
||||||
if (n2 != NULL) ResDoneWithNode(n2);
|
if (n2 != NULL) ResDoneWithNode(n2);
|
||||||
|
|
@ -636,19 +629,20 @@ ResTriangleCheck(resptr)
|
||||||
*/
|
*/
|
||||||
|
|
||||||
void
|
void
|
||||||
ResMergeNodes(node1,node2,pendingList,doneList)
|
ResMergeNodes(node1, node2, pendingList, doneList)
|
||||||
resNode *node1,*node2,**pendingList,**doneList;
|
resNode *node1, *node2;
|
||||||
|
resNode **pendingList, **doneList;
|
||||||
{
|
{
|
||||||
resElement *workingRes,*tRes;
|
resElement *workingRes, *tRes;
|
||||||
tElement *workingDev,*tDev;
|
tElement *workingDev, *tDev;
|
||||||
jElement *workingJunc,*tJunc;
|
jElement *workingJunc, *tJunc;
|
||||||
cElement *workingCon,*tCon;
|
cElement *workingCon, *tCon;
|
||||||
Tile *tile;
|
Tile *tile;
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
/* sanity check */
|
/* sanity check */
|
||||||
if (node1 == node2) return;
|
if (node1 == node2) return;
|
||||||
|
|
||||||
if (node1 == NULL || node2 == NULL)
|
if (node1 == NULL || node2 == NULL)
|
||||||
{
|
{
|
||||||
TxError("Attempt to merge NULL node\n");
|
TxError("Attempt to merge NULL node\n");
|
||||||
|
|
@ -657,27 +651,24 @@ ResMergeNodes(node1,node2,pendingList,doneList)
|
||||||
|
|
||||||
/* don't want to merge away startpoint */
|
/* don't want to merge away startpoint */
|
||||||
if (node2->rn_why & RES_NODE_ORIGIN)
|
if (node2->rn_why & RES_NODE_ORIGIN)
|
||||||
{
|
|
||||||
node1->rn_why = RES_NODE_ORIGIN;
|
node1->rn_why = RES_NODE_ORIGIN;
|
||||||
}
|
|
||||||
|
|
||||||
/* set node resistance */
|
/* set node resistance */
|
||||||
if (node1->rn_noderes >node2->rn_noderes)
|
if (node1->rn_noderes > node2->rn_noderes)
|
||||||
{
|
{
|
||||||
node1->rn_noderes = node2->rn_noderes;
|
node1->rn_noderes = node2->rn_noderes;
|
||||||
if ((node1->rn_status & FINISHED) != FINISHED)
|
if ((node1->rn_status & FINISHED) != FINISHED)
|
||||||
{
|
{
|
||||||
ResRemoveFromQueue(node1,pendingList);
|
ResRemoveFromQueue(node1, pendingList);
|
||||||
ResAddToQueue(node1,pendingList);
|
ResAddToQueue(node1, pendingList);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
node1->rn_float.rn_area += node2->rn_float.rn_area;
|
node1->rn_float.rn_area += node2->rn_float.rn_area;
|
||||||
|
|
||||||
|
|
||||||
/* combine relevant flags */
|
/* combine relevant flags */
|
||||||
node1->rn_status |= (node2->rn_status & RN_MAXTDI);
|
node1->rn_status |= (node2->rn_status & RN_MAXTDI);
|
||||||
|
|
||||||
/*merge device lists */
|
/* merge device lists */
|
||||||
workingDev = node2->rn_te;
|
workingDev = node2->rn_te;
|
||||||
while (workingDev != NULL)
|
while (workingDev != NULL)
|
||||||
{
|
{
|
||||||
|
|
@ -685,13 +676,11 @@ ResMergeNodes(node1,node2,pendingList,doneList)
|
||||||
{
|
{
|
||||||
ResPlug *plug = (ResPlug *) workingDev->te_thist;
|
ResPlug *plug = (ResPlug *) workingDev->te_thist;
|
||||||
if (plug->rpl_node == node2)
|
if (plug->rpl_node == node2)
|
||||||
{
|
|
||||||
plug->rpl_node = node1;
|
plug->rpl_node = node1;
|
||||||
}
|
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
TxError("Bad plug node: is (%d %d), should be (%d %d)\n",
|
TxError("Bad plug node: is (%d %d), should be (%d %d)\n",
|
||||||
plug->rpl_node->rn_loc,node2->rn_loc);
|
plug->rpl_node->rn_loc, node2->rn_loc);
|
||||||
plug->rpl_node = NULL;
|
plug->rpl_node = NULL;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -701,10 +690,8 @@ ResMergeNodes(node1,node2,pendingList,doneList)
|
||||||
|
|
||||||
for (j = 0; j != workingDev->te_thist->rd_nterms; j++)
|
for (j = 0; j != workingDev->te_thist->rd_nterms; j++)
|
||||||
if (workingDev->te_thist->rd_terminals[j] == node2)
|
if (workingDev->te_thist->rd_terminals[j] == node2)
|
||||||
{
|
|
||||||
workingDev->te_thist->rd_terminals[j] = node1;
|
workingDev->te_thist->rd_terminals[j] = node1;
|
||||||
}
|
}
|
||||||
}
|
|
||||||
tDev = workingDev;
|
tDev = workingDev;
|
||||||
workingDev = workingDev->te_nextt;
|
workingDev = workingDev->te_nextt;
|
||||||
tDev->te_nextt = node1->rn_te;
|
tDev->te_nextt = node1->rn_te;
|
||||||
|
|
@ -712,21 +699,20 @@ ResMergeNodes(node1,node2,pendingList,doneList)
|
||||||
}
|
}
|
||||||
|
|
||||||
/* append junction lists */
|
/* append junction lists */
|
||||||
|
|
||||||
workingJunc = node2->rn_je;
|
workingJunc = node2->rn_je;
|
||||||
while (workingJunc != NULL)
|
while (workingJunc != NULL)
|
||||||
{
|
{
|
||||||
tJunc = workingJunc;
|
tJunc = workingJunc;
|
||||||
for (i=0; i<TILES_PER_JUNCTION; i++)
|
for (i = 0; i < TILES_PER_JUNCTION; i++)
|
||||||
{
|
{
|
||||||
tileJunk *junk;
|
tileJunk *junk;
|
||||||
|
|
||||||
tile =tJunc->je_thisj->rj_Tile[i];
|
tile = tJunc->je_thisj->rj_Tile[i];
|
||||||
junk = (tileJunk *) tile->ti_client;
|
junk = (tileJunk *) tile->ti_client;
|
||||||
|
|
||||||
if ((junk->tj_status & RES_TILE_DONE) == FALSE)
|
if ((junk->tj_status & RES_TILE_DONE) == FALSE)
|
||||||
{
|
ResFixBreakPoint(&junk->breakList, node2, node1);
|
||||||
ResFixBreakPoint(&junk->breakList,node2,node1);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
tJunc->je_thisj->rj_jnode = node1;
|
tJunc->je_thisj->rj_jnode = node1;
|
||||||
workingJunc = workingJunc->je_nextj;
|
workingJunc = workingJunc->je_nextj;
|
||||||
|
|
@ -739,7 +725,7 @@ ResMergeNodes(node1,node2,pendingList,doneList)
|
||||||
while (workingCon != NULL)
|
while (workingCon != NULL)
|
||||||
{
|
{
|
||||||
tCon = workingCon;
|
tCon = workingCon;
|
||||||
for (i=0; i <workingCon->ce_thisc->cp_currentcontact;i++)
|
for (i = 0; i < workingCon->ce_thisc->cp_currentcontact; i++)
|
||||||
{
|
{
|
||||||
if (workingCon->ce_thisc->cp_cnode[i] == node2)
|
if (workingCon->ce_thisc->cp_cnode[i] == node2)
|
||||||
{
|
{
|
||||||
|
|
@ -749,9 +735,7 @@ ResMergeNodes(node1,node2,pendingList,doneList)
|
||||||
tile =tCon->ce_thisc->cp_tile[i];
|
tile =tCon->ce_thisc->cp_tile[i];
|
||||||
junk = (tileJunk *) tile->ti_client;
|
junk = (tileJunk *) tile->ti_client;
|
||||||
if ((junk->tj_status & RES_TILE_DONE) == FALSE)
|
if ((junk->tj_status & RES_TILE_DONE) == FALSE)
|
||||||
{
|
ResFixBreakPoint(&junk->breakList, node2, node1);
|
||||||
ResFixBreakPoint(&junk->breakList,node2,node1);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
workingCon = workingCon->ce_nextc;
|
workingCon = workingCon->ce_nextc;
|
||||||
|
|
@ -760,50 +744,41 @@ ResMergeNodes(node1,node2,pendingList,doneList)
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Moves resistors to new node */
|
/* Moves resistors to new node */
|
||||||
|
|
||||||
workingRes = node2->rn_re;
|
workingRes = node2->rn_re;
|
||||||
while (workingRes != NULL)
|
while (workingRes != NULL)
|
||||||
{
|
{
|
||||||
if (workingRes->re_thisEl->rr_connection1 == node2)
|
if (workingRes->re_thisEl->rr_connection1 == node2)
|
||||||
{
|
|
||||||
workingRes->re_thisEl->rr_connection1 = node1;
|
workingRes->re_thisEl->rr_connection1 = node1;
|
||||||
}
|
|
||||||
else if (workingRes->re_thisEl->rr_connection2 == node2)
|
else if (workingRes->re_thisEl->rr_connection2 == node2)
|
||||||
{
|
|
||||||
workingRes->re_thisEl->rr_connection2 = node1;
|
workingRes->re_thisEl->rr_connection2 = node1;
|
||||||
}
|
|
||||||
else
|
else
|
||||||
{
|
|
||||||
TxError("Resistor not found.\n");
|
TxError("Resistor not found.\n");
|
||||||
}
|
|
||||||
tRes = workingRes;
|
tRes = workingRes;
|
||||||
workingRes = workingRes->re_nextEl;
|
workingRes = workingRes->re_nextEl;
|
||||||
tRes->re_nextEl = node1->rn_re;
|
tRes->re_nextEl = node1->rn_re;
|
||||||
node1->rn_re = tRes;
|
node1->rn_re = tRes;
|
||||||
}
|
}
|
||||||
if ((node2->rn_status & FINISHED) == FINISHED)
|
if ((node2->rn_status & FINISHED) == FINISHED)
|
||||||
{
|
ResRemoveFromQueue(node2, doneList);
|
||||||
ResRemoveFromQueue(node2,doneList);
|
|
||||||
}
|
|
||||||
else
|
else
|
||||||
{
|
ResRemoveFromQueue(node2, pendingList);
|
||||||
ResRemoveFromQueue(node2,pendingList);
|
|
||||||
}
|
|
||||||
if (node2->rn_client != (ClientData)NULL)
|
if (node2->rn_client != (ClientData)NULL)
|
||||||
{
|
{
|
||||||
freeMagic((char *)node2->rn_client);
|
freeMagic((char *)node2->rn_client);
|
||||||
node2->rn_client = (ClientData)NULL;
|
node2->rn_client = (ClientData)NULL;
|
||||||
}
|
}
|
||||||
{
|
|
||||||
node2->rn_re = (resElement *) CLIENTDEFAULT;
|
|
||||||
node2->rn_ce = (cElement *) CLIENTDEFAULT;
|
|
||||||
node2->rn_je = (jElement *) CLIENTDEFAULT;
|
|
||||||
node2->rn_te = (tElement *) CLIENTDEFAULT;
|
|
||||||
node2->rn_more = (resNode *) CLIENTDEFAULT;
|
|
||||||
node2->rn_less = (resNode *) CLIENTDEFAULT;
|
|
||||||
}
|
|
||||||
freeMagic((char *)node2);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
node2->rn_re = (resElement *)CLIENTDEFAULT;
|
||||||
|
node2->rn_ce = (cElement *)CLIENTDEFAULT;
|
||||||
|
node2->rn_je = (jElement *)CLIENTDEFAULT;
|
||||||
|
node2->rn_te = (tElement *)CLIENTDEFAULT;
|
||||||
|
node2->rn_more = (resNode *)CLIENTDEFAULT;
|
||||||
|
node2->rn_less = (resNode *)CLIENTDEFAULT;
|
||||||
|
freeMagic((char *)node2);
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
*-------------------------------------------------------------------------
|
*-------------------------------------------------------------------------
|
||||||
|
|
@ -824,8 +799,8 @@ ResDeleteResPointer(node,resistor)
|
||||||
resResistor *resistor;
|
resResistor *resistor;
|
||||||
|
|
||||||
{
|
{
|
||||||
resElement *rcell1,*rcell2;
|
resElement *rcell1, *rcell2;
|
||||||
int notfound=TRUE;
|
int notfound = TRUE;
|
||||||
|
|
||||||
rcell1 = NULL;
|
rcell1 = NULL;
|
||||||
rcell2 = node->rn_re;
|
rcell2 = node->rn_re;
|
||||||
|
|
@ -833,14 +808,12 @@ ResDeleteResPointer(node,resistor)
|
||||||
{
|
{
|
||||||
if (rcell2->re_thisEl == resistor)
|
if (rcell2->re_thisEl == resistor)
|
||||||
{
|
{
|
||||||
notfound=FALSE;
|
notfound = FALSE;
|
||||||
if (rcell1 != NULL)
|
if (rcell1 != NULL)
|
||||||
{
|
|
||||||
rcell1->re_nextEl = rcell2->re_nextEl;
|
rcell1->re_nextEl = rcell2->re_nextEl;
|
||||||
}else
|
else
|
||||||
{
|
|
||||||
node->rn_re = rcell2->re_nextEl;
|
node->rn_re = rcell2->re_nextEl;
|
||||||
}
|
|
||||||
/* Set fields to null just in case there are any stray */
|
/* Set fields to null just in case there are any stray */
|
||||||
/* pointers to structure. */
|
/* pointers to structure. */
|
||||||
rcell2->re_thisEl = NULL;
|
rcell2->re_thisEl = NULL;
|
||||||
|
|
@ -852,10 +825,8 @@ ResDeleteResPointer(node,resistor)
|
||||||
rcell2 = rcell2->re_nextEl;
|
rcell2 = rcell2->re_nextEl;
|
||||||
}
|
}
|
||||||
if (notfound)
|
if (notfound)
|
||||||
{
|
|
||||||
TxError("Missing rptr at (%d %d).\n",
|
TxError("Missing rptr at (%d %d).\n",
|
||||||
node->rn_loc.p_x,node->rn_loc.p_y);
|
node->rn_loc.p_x, node->rn_loc.p_y);
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -873,24 +844,21 @@ ResDeleteResPointer(node,resistor)
|
||||||
*/
|
*/
|
||||||
|
|
||||||
void
|
void
|
||||||
ResEliminateResistor(resistor,homelist)
|
ResEliminateResistor(resistor, homelist)
|
||||||
resResistor *resistor,**homelist;
|
resResistor *resistor, **homelist;
|
||||||
|
|
||||||
{
|
{
|
||||||
if (resistor->rr_lastResistor == NULL)
|
if (resistor->rr_lastResistor == NULL)
|
||||||
{
|
|
||||||
*homelist = resistor->rr_nextResistor;
|
*homelist = resistor->rr_nextResistor;
|
||||||
}else
|
else
|
||||||
{
|
|
||||||
resistor->rr_lastResistor->rr_nextResistor = resistor->rr_nextResistor;
|
resistor->rr_lastResistor->rr_nextResistor = resistor->rr_nextResistor;
|
||||||
}
|
|
||||||
if (resistor->rr_nextResistor != NULL)
|
if (resistor->rr_nextResistor != NULL)
|
||||||
{
|
|
||||||
resistor->rr_nextResistor->rr_lastResistor = resistor->rr_lastResistor;
|
resistor->rr_nextResistor->rr_lastResistor = resistor->rr_lastResistor;
|
||||||
}
|
|
||||||
|
|
||||||
/* set everything to null so that any stray pointers will cause */
|
/* set everything to null so that any stray pointers will cause */
|
||||||
/* immediate death instead of a slow lingering one. */
|
/* immediate death instead of a slow lingering one. */
|
||||||
|
|
||||||
resistor->rr_nextResistor = NULL;
|
resistor->rr_nextResistor = NULL;
|
||||||
resistor->rr_lastResistor = NULL;
|
resistor->rr_lastResistor = NULL;
|
||||||
resistor->rr_connection1 = NULL;
|
resistor->rr_connection1 = NULL;
|
||||||
|
|
@ -898,7 +866,6 @@ ResEliminateResistor(resistor,homelist)
|
||||||
freeMagic((char *)resistor);
|
freeMagic((char *)resistor);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
*-------------------------------------------------------------------------
|
*-------------------------------------------------------------------------
|
||||||
*
|
*
|
||||||
|
|
@ -915,7 +882,7 @@ ResEliminateResistor(resistor,homelist)
|
||||||
*/
|
*/
|
||||||
|
|
||||||
void
|
void
|
||||||
ResCleanNode(resptr,junk,homelist1,homelist2)
|
ResCleanNode(resptr, junk, homelist1, homelist2)
|
||||||
resNode *resptr;
|
resNode *resptr;
|
||||||
int junk;
|
int junk;
|
||||||
resNode **homelist1;
|
resNode **homelist1;
|
||||||
|
|
@ -960,36 +927,26 @@ ResCleanNode(resptr,junk,homelist1,homelist2)
|
||||||
freeMagic((char *)rcell);
|
freeMagic((char *)rcell);
|
||||||
}
|
}
|
||||||
if (resptr->rn_less != NULL)
|
if (resptr->rn_less != NULL)
|
||||||
{
|
|
||||||
resptr->rn_less->rn_more = resptr->rn_more;
|
resptr->rn_less->rn_more = resptr->rn_more;
|
||||||
}else
|
|
||||||
{
|
|
||||||
if (*homelist1 == resptr)
|
|
||||||
{
|
|
||||||
*homelist1 = resptr->rn_more;
|
|
||||||
}
|
|
||||||
else if (*homelist2 == resptr)
|
|
||||||
{
|
|
||||||
*homelist2 = resptr->rn_more;
|
|
||||||
}
|
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
if (*homelist1 == resptr)
|
||||||
|
*homelist1 = resptr->rn_more;
|
||||||
|
else if (*homelist2 == resptr)
|
||||||
|
*homelist2 = resptr->rn_more;
|
||||||
|
else
|
||||||
TxError("Error: Attempted to eliminate node from wrong list.\n");
|
TxError("Error: Attempted to eliminate node from wrong list.\n");
|
||||||
}
|
}
|
||||||
}
|
|
||||||
if (resptr->rn_more != NULL)
|
if (resptr->rn_more != NULL)
|
||||||
{
|
|
||||||
resptr->rn_more->rn_less = resptr->rn_less;
|
resptr->rn_more->rn_less = resptr->rn_less;
|
||||||
}
|
|
||||||
|
|
||||||
{
|
|
||||||
resptr->rn_re = (resElement *) CLIENTDEFAULT;
|
resptr->rn_re = (resElement *) CLIENTDEFAULT;
|
||||||
resptr->rn_ce = (cElement *) CLIENTDEFAULT;
|
resptr->rn_ce = (cElement *) CLIENTDEFAULT;
|
||||||
resptr->rn_je = (jElement *) CLIENTDEFAULT;
|
resptr->rn_je = (jElement *) CLIENTDEFAULT;
|
||||||
resptr->rn_te = (tElement *) CLIENTDEFAULT;
|
resptr->rn_te = (tElement *) CLIENTDEFAULT;
|
||||||
resptr->rn_more = (resNode *) CLIENTDEFAULT;
|
resptr->rn_more = (resNode *) CLIENTDEFAULT;
|
||||||
resptr->rn_less = (resNode *) CLIENTDEFAULT;
|
resptr->rn_less = (resNode *) CLIENTDEFAULT;
|
||||||
}
|
|
||||||
freeMagic((char *)resptr);
|
freeMagic((char *)resptr);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -1010,12 +967,12 @@ ResCleanNode(resptr,junk,homelist1,homelist2)
|
||||||
*/
|
*/
|
||||||
|
|
||||||
void
|
void
|
||||||
ResFixBreakPoint(sourcelist,origNode,newNode)
|
ResFixBreakPoint(sourcelist, origNode, newNode)
|
||||||
Breakpoint **sourcelist;
|
Breakpoint **sourcelist;
|
||||||
resNode *origNode,*newNode;
|
resNode *origNode, *newNode;
|
||||||
|
|
||||||
{
|
{
|
||||||
Breakpoint *bp,*bp2,*bp3,*bp4;
|
Breakpoint *bp, *bp2, *bp3, *bp4;
|
||||||
int alreadypresent;
|
int alreadypresent;
|
||||||
|
|
||||||
alreadypresent = FALSE;
|
alreadypresent = FALSE;
|
||||||
|
|
@ -1036,28 +993,23 @@ ResFixBreakPoint(sourcelist,origNode,newNode)
|
||||||
if (alreadypresent)
|
if (alreadypresent)
|
||||||
{
|
{
|
||||||
if (bp2 == NULL)
|
if (bp2 == NULL)
|
||||||
{
|
|
||||||
*sourcelist = bp->br_next;
|
*sourcelist = bp->br_next;
|
||||||
}else
|
else
|
||||||
{
|
|
||||||
bp2->br_next = bp->br_next;
|
bp2->br_next = bp->br_next;
|
||||||
}
|
|
||||||
bp3 = bp;
|
bp3 = bp;
|
||||||
bp = bp->br_next;
|
bp = bp->br_next;
|
||||||
|
|
||||||
if (bp3->br_crect != NULL && bp4->br_crect == NULL)
|
if (bp3->br_crect != NULL && bp4->br_crect == NULL)
|
||||||
{
|
|
||||||
bp4->br_crect = bp3->br_crect;
|
bp4->br_crect = bp3->br_crect;
|
||||||
}
|
|
||||||
freeMagic((char *)bp3);
|
freeMagic((char *)bp3);
|
||||||
continue;
|
continue;
|
||||||
}else
|
|
||||||
{
|
|
||||||
(bp->br_this = newNode);
|
|
||||||
}
|
}
|
||||||
|
else
|
||||||
|
bp->br_this = newNode;
|
||||||
}
|
}
|
||||||
bp2 = bp;
|
bp2 = bp;
|
||||||
bp = bp->br_next;
|
bp = bp->br_next;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -171,16 +171,25 @@ ResPrintExtDev(outextfile, devices)
|
||||||
else
|
else
|
||||||
fprintf(outextfile, " \"%s\"", subsName);
|
fprintf(outextfile, " \"%s\"", subsName);
|
||||||
|
|
||||||
fprintf(outextfile, " \"%s\" %d %s \"%s\" %d %s \"%s\" %d %s\n",
|
if (devices->gate != NULL)
|
||||||
|
fprintf(outextfile, " \"%s\" %d %s",
|
||||||
devices->gate->name,
|
devices->gate->name,
|
||||||
devices->layout->rd_length * 2,
|
devices->layout->rd_length * 2,
|
||||||
devices->rs_gattr,
|
devices->rs_gattr);
|
||||||
|
|
||||||
|
if (devices->source != NULL)
|
||||||
|
fprintf(outextfile, " \"%s\" %d %s",
|
||||||
devices->source->name,
|
devices->source->name,
|
||||||
devices->layout->rd_width,
|
devices->layout->rd_width,
|
||||||
devices->rs_sattr,
|
devices->rs_sattr);
|
||||||
|
|
||||||
|
if (devices->drain != NULL)
|
||||||
|
fprintf(outextfile, " \"%s\" %d %s",
|
||||||
devices->drain->name,
|
devices->drain->name,
|
||||||
devices->layout->rd_width,
|
devices->layout->rd_width,
|
||||||
devices->rs_dattr);
|
devices->rs_dattr);
|
||||||
|
|
||||||
|
fprintf(outextfile, "\n");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -92,12 +92,12 @@ ResFixPoint *ResFixList;
|
||||||
ResNodeList = n;\
|
ResNodeList = n;\
|
||||||
(n)->rn_te = NULL;\
|
(n)->rn_te = NULL;\
|
||||||
(n)->rn_re = NULL;\
|
(n)->rn_re = NULL;\
|
||||||
(n)->rn_je=NULL;\
|
(n)->rn_je = NULL;\
|
||||||
(n)->rn_ce=NULL;\
|
(n)->rn_ce = NULL;\
|
||||||
(n)->rn_noderes=RES_INFINITY;\
|
(n)->rn_noderes = RES_INFINITY;\
|
||||||
(n)->location.p_x=MINFINITY;\
|
(n)->location.p_x = MINFINITY;\
|
||||||
(n)->location.p_y=MINFINITY;\
|
(n)->location.p_y = MINFINITY;\
|
||||||
(n)->rn_why=0;\
|
(n)->rn_why = 0;\
|
||||||
(n)->rn_status = TRUE;\
|
(n)->rn_status = TRUE;\
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -105,7 +105,6 @@ ResFixPoint *ResFixList;
|
||||||
|
|
||||||
extern void ResSimProcessDrivePoints();
|
extern void ResSimProcessDrivePoints();
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
*-------------------------------------------------------------------------
|
*-------------------------------------------------------------------------
|
||||||
*
|
*
|
||||||
|
|
@ -126,19 +125,19 @@ ResReadSim(simfile, fetproc, capproc, resproc, attrproc, mergeproc, subproc)
|
||||||
|
|
||||||
{
|
{
|
||||||
char line[MAXLINE][MAXTOKEN];
|
char line[MAXLINE][MAXTOKEN];
|
||||||
int result,fettype,extfile;
|
int result, fettype, extfile;
|
||||||
FILE *fp, *fopen();
|
FILE *fp, *fopen();
|
||||||
|
|
||||||
fp = PaOpen(simfile,"r",".sim",".",(char *) NULL, (char **) NULL);
|
fp = PaOpen(simfile, "r", ".sim", ".", (char *)NULL, (char **)NULL);
|
||||||
if (fp == NULL)
|
if (fp == NULL)
|
||||||
{
|
{
|
||||||
TxError("Cannot open file %s%s\n",simfile,".sim");
|
TxError("Cannot open file %s%s\n", simfile, ".sim");
|
||||||
return(1);
|
return 1;
|
||||||
}
|
}
|
||||||
extfile = 0;
|
extfile = 0;
|
||||||
|
|
||||||
/*read in file */
|
/* Read in file */
|
||||||
while (gettokens(line,fp) != 0)
|
while (gettokens(line, fp) != 0)
|
||||||
{
|
{
|
||||||
fettype = MINFINITY;
|
fettype = MINFINITY;
|
||||||
switch(line[0][0])
|
switch(line[0][0])
|
||||||
|
|
@ -151,34 +150,45 @@ ResReadSim(simfile, fetproc, capproc, resproc, attrproc, mergeproc, subproc)
|
||||||
}
|
}
|
||||||
result=0;
|
result=0;
|
||||||
break;
|
break;
|
||||||
case 'e': fettype = DBTechNameType("efet");
|
case 'e':
|
||||||
|
fettype = DBTechNameType("efet");
|
||||||
break;
|
break;
|
||||||
case 'd': fettype = DBTechNameType("dfet");
|
case 'd':
|
||||||
|
fettype = DBTechNameType("dfet");
|
||||||
break;
|
break;
|
||||||
case 'n': fettype = DBTechNameType("nfet");
|
case 'n':
|
||||||
|
fettype = DBTechNameType("nfet");
|
||||||
break;
|
break;
|
||||||
case 'p': fettype = DBTechNameType("pfet");
|
case 'p':
|
||||||
|
fettype = DBTechNameType("pfet");
|
||||||
break;
|
break;
|
||||||
case 'b': fettype = DBTechNameType("bnpn");
|
case 'b':
|
||||||
|
fettype = DBTechNameType("bnpn");
|
||||||
break;
|
break;
|
||||||
case 'C': if (capproc) result = (*capproc)(line);
|
case 'C':
|
||||||
|
if (capproc) result = (*capproc)(line);
|
||||||
break;
|
break;
|
||||||
case 'R': if (resproc)result = (*resproc)(line);
|
case 'R':
|
||||||
|
if (resproc) result = (*resproc)(line);
|
||||||
break;
|
break;
|
||||||
case '=': if (mergeproc)result = (*mergeproc)(line);
|
case '=':
|
||||||
|
if (mergeproc) result = (*mergeproc)(line);
|
||||||
break;
|
break;
|
||||||
case 'A': if (attrproc) result =
|
case 'A':
|
||||||
(*attrproc)(line[ATTRIBUTENODENAME],
|
if (attrproc)
|
||||||
line[ATTRIBUTEVALUE],
|
result = (*attrproc)(line[ATTRIBUTENODENAME],
|
||||||
simfile, &extfile);
|
line[ATTRIBUTEVALUE], simfile, &extfile);
|
||||||
break;
|
break;
|
||||||
case 'x': fettype = DBNumTypes;
|
case 'x':
|
||||||
|
fettype = DBNumTypes;
|
||||||
break;
|
break;
|
||||||
case 'D':
|
case 'D':
|
||||||
case 'c':
|
case 'c':
|
||||||
case 'r': break;
|
case 'r':
|
||||||
default: result = 1;
|
break;
|
||||||
(void)fclose(fp);
|
default:
|
||||||
|
result = 1;
|
||||||
|
fclose(fp);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
if (fettype == -1)
|
if (fettype == -1)
|
||||||
|
|
@ -196,16 +206,16 @@ ResReadSim(simfile, fetproc, capproc, resproc, attrproc, mergeproc, subproc)
|
||||||
ExtDevice *devptr;
|
ExtDevice *devptr;
|
||||||
|
|
||||||
devptr = ExtCurStyle->exts_device[fettype];
|
devptr = ExtCurStyle->exts_device[fettype];
|
||||||
sheetr=(float)devptr->exts_linearResist;
|
sheetr = (float)devptr->exts_linearResist;
|
||||||
result = (*fetproc)(line,sheetr,fettype);
|
result = (*fetproc)(line, sheetr, fettype);
|
||||||
}
|
}
|
||||||
if (result != 0)
|
if (result != 0)
|
||||||
{
|
{
|
||||||
TxError("Error in sim file %s\n",line[0]);
|
TxError("Error in sim file %s\n", line[0]);
|
||||||
return(1);
|
return 1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
(void)fclose(fp);
|
fclose(fp);
|
||||||
return(result);
|
return(result);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -226,7 +236,6 @@ ResReadSim(simfile, fetproc, capproc, resproc, attrproc, mergeproc, subproc)
|
||||||
int
|
int
|
||||||
ResReadNode(nodefile)
|
ResReadNode(nodefile)
|
||||||
char *nodefile;
|
char *nodefile;
|
||||||
|
|
||||||
{
|
{
|
||||||
char line[MAXLINE][MAXTOKEN];
|
char line[MAXLINE][MAXTOKEN];
|
||||||
FILE *fp, *fopen();
|
FILE *fp, *fopen();
|
||||||
|
|
@ -235,15 +244,15 @@ ResReadNode(nodefile)
|
||||||
char *cp;
|
char *cp;
|
||||||
float lambda;
|
float lambda;
|
||||||
|
|
||||||
fp = PaOpen(nodefile,"r",".nodes",".", (char *) NULL, (char **) NULL);
|
fp = PaOpen(nodefile, "r", ".nodes", ".", (char *)NULL, (char **)NULL);
|
||||||
if (fp == NULL)
|
if (fp == NULL)
|
||||||
{
|
{
|
||||||
TxError("Cannot open file %s%s\n",nodefile,".nodes");
|
TxError("Cannot open file %s%s\n", nodefile, ".nodes");
|
||||||
return(1);
|
return 1;
|
||||||
}
|
}
|
||||||
while (gettokens(line,fp) != 0)
|
while (gettokens(line,fp) != 0)
|
||||||
{
|
{
|
||||||
entry = HashFind(&ResNodeTable,line[NODES_NODENAME]);
|
entry = HashFind(&ResNodeTable, line[NODES_NODENAME]);
|
||||||
node = ResInitializeNode(entry);
|
node = ResInitializeNode(entry);
|
||||||
|
|
||||||
node->location.p_x = atoi(line[NODES_NODEX]);
|
node->location.p_x = atoi(line[NODES_NODEX]);
|
||||||
|
|
@ -259,14 +268,15 @@ ResReadNode(nodefile)
|
||||||
|
|
||||||
if (node->type == -1)
|
if (node->type == -1)
|
||||||
{
|
{
|
||||||
TxError("Bad tile type name in %s.nodes file for node %s\n",nodefile,node->name);
|
TxError("Bad tile type name in %s.nodes file for node %s\n",
|
||||||
|
nodefile, node->name);
|
||||||
TxError("Did you use the newest version of ext2sim?\n");
|
TxError("Did you use the newest version of ext2sim?\n");
|
||||||
(void)fclose(fp);
|
fclose(fp);
|
||||||
return(1);
|
return 1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
(void)fclose(fp);
|
fclose(fp);
|
||||||
return(0);
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|
@ -283,12 +293,11 @@ ResReadNode(nodefile)
|
||||||
*/
|
*/
|
||||||
|
|
||||||
int
|
int
|
||||||
gettokens(line,fp)
|
gettokens(line, fp)
|
||||||
char line[][MAXTOKEN];
|
char line[][MAXTOKEN];
|
||||||
FILE *fp;
|
FILE *fp;
|
||||||
|
|
||||||
{
|
{
|
||||||
int i=0,j=0;
|
int i = 0, j = 0;
|
||||||
int c;
|
int c;
|
||||||
|
|
||||||
while ((c = getc(fp)) != EOF && c != '\n')
|
while ((c = getc(fp)) != EOF && c != '\n')
|
||||||
|
|
@ -296,25 +305,25 @@ gettokens(line,fp)
|
||||||
switch(c)
|
switch(c)
|
||||||
{
|
{
|
||||||
case ' ':
|
case ' ':
|
||||||
case ' ' : line[i++][j] = '\0';
|
case ' ' :
|
||||||
j=0;
|
line[i++][j] = '\0';
|
||||||
|
j = 0;
|
||||||
break;
|
break;
|
||||||
default: line[i][j++] = c;
|
default:
|
||||||
|
line[i][j++] = c;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (c == '\n')
|
if (c == '\n')
|
||||||
{
|
{
|
||||||
line[i++][j] = '\0';
|
line[i++][j] = '\0';
|
||||||
j=0;
|
j = 0;
|
||||||
}
|
}
|
||||||
for(j=i;j < MAXLINE;j++)
|
for (j = i; j < MAXLINE; j++)
|
||||||
{
|
|
||||||
line[j][0] = '\0';
|
line[j][0] = '\0';
|
||||||
}
|
|
||||||
return(i);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
return i;
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
*-------------------------------------------------------------------------
|
*-------------------------------------------------------------------------
|
||||||
|
|
@ -359,6 +368,7 @@ ResSimSubckt(line)
|
||||||
|
|
||||||
ResRDevList = device;
|
ResRDevList = device;
|
||||||
device->layout = NULL;
|
device->layout = NULL;
|
||||||
|
device->source = device->drain = device->gate = device->subs = NULL;
|
||||||
|
|
||||||
/* The last argument is the name of the device */
|
/* The last argument is the name of the device */
|
||||||
for (i = 1; line[i][0] != '\0'; i++);
|
for (i = 1; line[i][0] != '\0'; i++);
|
||||||
|
|
@ -466,30 +476,31 @@ ResSimDevice(line, rpersquare, ttype)
|
||||||
|
|
||||||
{
|
{
|
||||||
RDev *device;
|
RDev *device;
|
||||||
int rvalue,i,j,k;
|
int rvalue, i, j, k;
|
||||||
char *newattr,tmpattr[MAXTOKEN];
|
char *newattr, tmpattr[MAXTOKEN];
|
||||||
static int nowarning = TRUE;
|
static int nowarning = TRUE;
|
||||||
float lambda;
|
float lambda;
|
||||||
|
|
||||||
device = (RDev *) mallocMagic((unsigned) (sizeof(RDev)));
|
|
||||||
if ((line[RDEV_WIDTH][0] == '\0') || (line[RDEV_LENGTH][0] == '\0'))
|
if ((line[RDEV_WIDTH][0] == '\0') || (line[RDEV_LENGTH][0] == '\0'))
|
||||||
{
|
{
|
||||||
TxError("error in input file:\n");
|
TxError("error in input file:\n");
|
||||||
return(1);
|
return 1;
|
||||||
}
|
}
|
||||||
else
|
|
||||||
{
|
device = (RDev *)mallocMagic((unsigned)(sizeof(RDev)));
|
||||||
if (nowarning && rpersquare == 0)
|
if (nowarning && rpersquare == 0)
|
||||||
{
|
{
|
||||||
TxError("Warning- FET resistance not included or set to zero in technology file-\n");
|
TxError("Warning: FET resistance not included or "
|
||||||
|
"set to zero in technology file-\n");
|
||||||
TxError("All driven nodes will be extracted\n");
|
TxError("All driven nodes will be extracted\n");
|
||||||
nowarning = FALSE;
|
nowarning = FALSE;
|
||||||
}
|
}
|
||||||
if (MagAtof(line[RDEV_WIDTH]) != 0)
|
if (MagAtof(line[RDEV_WIDTH]) != 0)
|
||||||
device->resistance = MagAtof(line[RDEV_LENGTH]) * rpersquare/MagAtof(line[RDEV_WIDTH]);
|
device->resistance = MagAtof(line[RDEV_LENGTH]) * rpersquare /
|
||||||
|
MagAtof(line[RDEV_WIDTH]);
|
||||||
else
|
else
|
||||||
device->resistance = 0;
|
device->resistance = 0;
|
||||||
}
|
|
||||||
device->status = FALSE;
|
device->status = FALSE;
|
||||||
device->nextDev = ResRDevList;
|
device->nextDev = ResRDevList;
|
||||||
|
|
||||||
|
|
@ -502,16 +513,18 @@ ResSimDevice(line, rpersquare, ttype)
|
||||||
device->rs_dattr=RDEV_NOATTR;
|
device->rs_dattr=RDEV_NOATTR;
|
||||||
device->rs_ttype = ttype;
|
device->rs_ttype = ttype;
|
||||||
|
|
||||||
|
device->gate = device->source = device->drain = device->subs = NULL;
|
||||||
|
|
||||||
/* 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 */
|
||||||
|
|
||||||
for (i=RDEV_ATTR;i < RDEV_ATTR+RDEV_NUM_ATTR;i++)
|
for (i = RDEV_ATTR; i < RDEV_ATTR + RDEV_NUM_ATTR; i++)
|
||||||
{
|
{
|
||||||
if (line[i][0] == '\0') break;
|
if (line[i][0] == '\0') break;
|
||||||
k=0;
|
k = 0;
|
||||||
tmpattr[k++]='"';
|
tmpattr[k++] = '"';
|
||||||
for (j=2;line[i][j] != '\0';j++)
|
for (j = 2; line[i][j] != '\0'; j++)
|
||||||
{
|
{
|
||||||
if (line[i][j] == ',')
|
if (line[i][j] == ',')
|
||||||
{
|
{
|
||||||
|
|
@ -524,29 +537,35 @@ ResSimDevice(line, rpersquare, ttype)
|
||||||
tmpattr[k++] = line[i][j];
|
tmpattr[k++] = line[i][j];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
tmpattr[k++]='"';
|
tmpattr[k++] = '"';
|
||||||
tmpattr[k++]='\0';
|
tmpattr[k++] = '\0';
|
||||||
newattr = (char *) mallocMagic((unsigned) k);
|
newattr = (char *)mallocMagic((unsigned)k);
|
||||||
strncpy(newattr,tmpattr,k);
|
strncpy(newattr, tmpattr, k);
|
||||||
switch (line[i][0])
|
switch (line[i][0])
|
||||||
{
|
{
|
||||||
case 'g': device->rs_gattr = newattr; break;
|
case 'g':
|
||||||
case 's': device->rs_sattr = newattr; break;
|
device->rs_gattr = newattr;
|
||||||
case 'd': device->rs_dattr = newattr; break;
|
break;
|
||||||
default: TxError("Bad fet attribute\n");
|
case 's':
|
||||||
|
device->rs_sattr = newattr;
|
||||||
|
break;
|
||||||
|
case 'd':
|
||||||
|
device->rs_dattr = newattr;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
TxError("Bad fet attribute\n");
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
ResRDevList = device;
|
ResRDevList = device;
|
||||||
device->layout = NULL;
|
device->layout = NULL;
|
||||||
rvalue = ResSimNewNode(line[GATE],GATE,device) +
|
rvalue = ResSimNewNode(line[GATE], GATE, device) +
|
||||||
ResSimNewNode(line[SOURCE],SOURCE,device) +
|
ResSimNewNode(line[SOURCE], SOURCE, device) +
|
||||||
ResSimNewNode(line[DRAIN],DRAIN,device);
|
ResSimNewNode(line[DRAIN], DRAIN, device);
|
||||||
|
|
||||||
return(rvalue);
|
return rvalue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
*-------------------------------------------------------------------------
|
*-------------------------------------------------------------------------
|
||||||
*
|
*
|
||||||
|
|
@ -573,32 +592,36 @@ ResSimNewNode(line, type, device)
|
||||||
if (line[0] == '\0')
|
if (line[0] == '\0')
|
||||||
{
|
{
|
||||||
TxError("Missing device connection\n");
|
TxError("Missing device connection\n");
|
||||||
return(1);
|
return 1;
|
||||||
}
|
}
|
||||||
entry = HashFind(&ResNodeTable, line);
|
entry = HashFind(&ResNodeTable, line);
|
||||||
node = ResInitializeNode(entry);
|
node = ResInitializeNode(entry);
|
||||||
tptr = (devPtr *) mallocMagic((unsigned) (sizeof(devPtr)));
|
tptr = (devPtr *)mallocMagic((unsigned)(sizeof(devPtr)));
|
||||||
tptr->thisDev = device;
|
tptr->thisDev = device;
|
||||||
tptr->nextDev = node->firstDev;
|
tptr->nextDev = node->firstDev;
|
||||||
node->firstDev = tptr;
|
node->firstDev = tptr;
|
||||||
tptr->terminal = type;
|
tptr->terminal = type;
|
||||||
switch(type)
|
switch(type)
|
||||||
{
|
{
|
||||||
case GATE: device->gate = node;
|
case GATE:
|
||||||
|
device->gate = node;
|
||||||
break;
|
break;
|
||||||
case SOURCE: device->source = node;
|
case SOURCE:
|
||||||
|
device->source = node;
|
||||||
break;
|
break;
|
||||||
case DRAIN: device->drain = node;
|
case DRAIN:
|
||||||
|
device->drain = node;
|
||||||
break;
|
break;
|
||||||
case SUBS: device->subs = node;
|
case SUBS:
|
||||||
|
device->subs = node;
|
||||||
break;
|
break;
|
||||||
default: TxError("Bad Terminal Specifier\n");
|
default:
|
||||||
|
TxError("Bad Terminal Specifier\n");
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
return(0);
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
*-------------------------------------------------------------------------
|
*-------------------------------------------------------------------------
|
||||||
*
|
*
|
||||||
|
|
@ -619,55 +642,54 @@ ResSimCapacitor(line)
|
||||||
char line[][MAXTOKEN];
|
char line[][MAXTOKEN];
|
||||||
|
|
||||||
{
|
{
|
||||||
HashEntry *entry1,*entry2;
|
HashEntry *entry1, *entry2;
|
||||||
ResSimNode *node1,*node2;
|
ResSimNode *node1, *node2;
|
||||||
|
|
||||||
if (line[COUPLETERMINAL1][0] == 0 || line[COUPLETERMINAL2][0] == 0)
|
if (line[COUPLETERMINAL1][0] == 0 || line[COUPLETERMINAL2][0] == 0)
|
||||||
{
|
{
|
||||||
TxError("Bad Capacitor\n");
|
TxError("Bad Capacitor\n");
|
||||||
return(1);
|
return(1);
|
||||||
}
|
}
|
||||||
entry1 = HashFind(&ResNodeTable,line[COUPLETERMINAL1]);
|
entry1 = HashFind(&ResNodeTable, line[COUPLETERMINAL1]);
|
||||||
node1 = ResInitializeNode(entry1);
|
node1 = ResInitializeNode(entry1);
|
||||||
if (ResOptionsFlags & ResOpt_Signal)
|
if (ResOptionsFlags & ResOpt_Signal)
|
||||||
{
|
{
|
||||||
node1->capacitance += MagAtof(line[COUPLEVALUE]);
|
node1->capacitance += MagAtof(line[COUPLEVALUE]);
|
||||||
if (strcmp(line[COUPLETERMINAL2],"GND") == 0 ||
|
if (strcmp(line[COUPLETERMINAL2], "GND") == 0 ||
|
||||||
strcmp(line[COUPLETERMINAL2],"Vdd") == 0)
|
strcmp(line[COUPLETERMINAL2], "Vdd") == 0)
|
||||||
{
|
{
|
||||||
return(0);
|
return 0;
|
||||||
}
|
}
|
||||||
entry2 = HashFind(&ResNodeTable,line[COUPLETERMINAL2]);
|
entry2 = HashFind(&ResNodeTable, line[COUPLETERMINAL2]);
|
||||||
node2 = ResInitializeNode(entry2);
|
node2 = ResInitializeNode(entry2);
|
||||||
node2->capacitance += MagAtof(line[COUPLEVALUE]);
|
node2->capacitance += MagAtof(line[COUPLEVALUE]);
|
||||||
return(0);
|
return 0;
|
||||||
}
|
}
|
||||||
if (strcmp(line[COUPLETERMINAL2],"GND") == 0 )
|
if (strcmp(line[COUPLETERMINAL2], "GND") == 0)
|
||||||
{
|
{
|
||||||
node1->capacitance += MagAtof(line[COUPLEVALUE]);
|
node1->capacitance += MagAtof(line[COUPLEVALUE]);
|
||||||
return(0);
|
return 0;
|
||||||
}
|
}
|
||||||
if (strcmp(line[COUPLETERMINAL2],"Vdd") == 0 )
|
if (strcmp(line[COUPLETERMINAL2], "Vdd") == 0)
|
||||||
{
|
{
|
||||||
node1->cap_vdd += MagAtof(line[COUPLEVALUE]);
|
node1->cap_vdd += MagAtof(line[COUPLEVALUE]);
|
||||||
return(0);
|
return 0;
|
||||||
}
|
}
|
||||||
entry2 = HashFind(&ResNodeTable,line[COUPLETERMINAL2]);
|
entry2 = HashFind(&ResNodeTable, line[COUPLETERMINAL2]);
|
||||||
node2 = ResInitializeNode(entry2);
|
node2 = ResInitializeNode(entry2);
|
||||||
if (strcmp(line[COUPLETERMINAL1],"GND") == 0 )
|
if (strcmp(line[COUPLETERMINAL1], "GND") == 0)
|
||||||
{
|
{
|
||||||
node2->capacitance += MagAtof(line[COUPLEVALUE]);
|
node2->capacitance += MagAtof(line[COUPLEVALUE]);
|
||||||
return(0);
|
return 0;
|
||||||
}
|
}
|
||||||
if (strcmp(line[COUPLETERMINAL1],"Vdd") == 0 )
|
if (strcmp(line[COUPLETERMINAL1], "Vdd") == 0)
|
||||||
{
|
{
|
||||||
node2->cap_vdd += MagAtof(line[COUPLEVALUE]);
|
node2->cap_vdd += MagAtof(line[COUPLEVALUE]);
|
||||||
return(0);
|
return 0;
|
||||||
}
|
}
|
||||||
node1->cap_couple += MagAtof(line[COUPLEVALUE]);
|
node1->cap_couple += MagAtof(line[COUPLEVALUE]);
|
||||||
node2->cap_couple += MagAtof(line[COUPLEVALUE]);
|
node2->cap_couple += MagAtof(line[COUPLEVALUE]);
|
||||||
return(0);
|
return 0;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -688,7 +710,6 @@ ResSimCapacitor(line)
|
||||||
int
|
int
|
||||||
ResSimResistor(line)
|
ResSimResistor(line)
|
||||||
char line[][MAXTOKEN];
|
char line[][MAXTOKEN];
|
||||||
|
|
||||||
{
|
{
|
||||||
HashEntry *entry;
|
HashEntry *entry;
|
||||||
ResSimNode *node;
|
ResSimNode *node;
|
||||||
|
|
@ -696,21 +717,19 @@ ResSimResistor(line)
|
||||||
if (line[RESNODENAME][0] == 0)
|
if (line[RESNODENAME][0] == 0)
|
||||||
{
|
{
|
||||||
TxError("Bad Resistor\n");
|
TxError("Bad Resistor\n");
|
||||||
return(1);
|
return 1;
|
||||||
}
|
}
|
||||||
entry = HashFind(&ResNodeTable,line[RESNODENAME]);
|
entry = HashFind(&ResNodeTable, line[RESNODENAME]);
|
||||||
node = ResInitializeNode(entry);
|
node = ResInitializeNode(entry);
|
||||||
if (node->resistance != 0)
|
if (node->resistance != 0)
|
||||||
{
|
{
|
||||||
TxError("Duplicate Resistance Entries\n");
|
TxError("Duplicate Resistance Entries\n");
|
||||||
return(1);
|
return 1;
|
||||||
}
|
}
|
||||||
node->resistance = MagAtof(line[NODERESISTANCE]);
|
node->resistance = MagAtof(line[NODERESISTANCE]);
|
||||||
return(0);
|
return(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
*-------------------------------------------------------------------------
|
*-------------------------------------------------------------------------
|
||||||
*
|
*
|
||||||
|
|
@ -727,8 +746,8 @@ ResSimResistor(line)
|
||||||
*/
|
*/
|
||||||
|
|
||||||
int
|
int
|
||||||
ResSimAttribute(aname,avalue,rootname,readextfile)
|
ResSimAttribute(aname, avalue, rootname, readextfile)
|
||||||
char *aname,*avalue,*rootname;
|
char *aname, *avalue, *rootname;
|
||||||
int *readextfile;
|
int *readextfile;
|
||||||
|
|
||||||
{
|
{
|
||||||
|
|
@ -741,43 +760,43 @@ ResSimAttribute(aname,avalue,rootname,readextfile)
|
||||||
if (aname[0] == 0)
|
if (aname[0] == 0)
|
||||||
{
|
{
|
||||||
TxError("Bad Resistor\n");
|
TxError("Bad Resistor\n");
|
||||||
return(1);
|
return 1;
|
||||||
}
|
}
|
||||||
entry = HashFind(&ResNodeTable,aname);
|
entry = HashFind(&ResNodeTable, aname);
|
||||||
node = ResInitializeNode(entry);
|
node = ResInitializeNode(entry);
|
||||||
if (strncmp(avalue,"res:skip",8) == 0)
|
if (strncmp(avalue, "res:skip", 8) == 0)
|
||||||
{
|
{
|
||||||
if (node->status & FORCE)
|
if (node->status & FORCE)
|
||||||
{
|
{
|
||||||
TxError("Warning: Node %s is both forced and skipped\n",aname);
|
TxError("Warning: Node %s is both forced and skipped\n", aname);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
node->status |= SKIP;
|
node->status |= SKIP;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if (strncmp(avalue,"res:force",9) == 0)
|
else if (strncmp(avalue, "res:force", 9) == 0)
|
||||||
{
|
{
|
||||||
if (node->status & SKIP)
|
if (node->status & SKIP)
|
||||||
{
|
{
|
||||||
TxError("Warning: Node %s is both skipped and forced \n",aname);
|
TxError("Warning: Node %s is both skipped and forced \n", aname);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
node->status |= FORCE;
|
node->status |= FORCE;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if (strncmp(avalue,"res:min=",8) == 0)
|
else if (strncmp(avalue, "res:min=", 8) == 0)
|
||||||
{
|
{
|
||||||
node->status |= MINSIZE;
|
node->status |= MINSIZE;
|
||||||
for(i=0,avalue += 8; *avalue != '\0' && *avalue != ','; avalue++)
|
for (i = 0, avalue += 8; *avalue != '\0' && *avalue != ','; avalue++)
|
||||||
{
|
{
|
||||||
digit[i++] = *avalue;
|
digit[i++] = *avalue;
|
||||||
}
|
}
|
||||||
digit[i++]='\0';
|
digit[i++] = '\0';
|
||||||
node->minsizeres=MagAtof(digit);
|
node->minsizeres = MagAtof(digit);
|
||||||
}
|
}
|
||||||
else if (strncmp(avalue,"res:drive",9) == 0 &&
|
else if (strncmp(avalue, "res:drive", 9) == 0 &&
|
||||||
(ResOptionsFlags & ResOpt_Signal))
|
(ResOptionsFlags & ResOpt_Signal))
|
||||||
{
|
{
|
||||||
if (*readextfile == 0)
|
if (*readextfile == 0)
|
||||||
|
|
@ -793,12 +812,13 @@ ResSimAttribute(aname,avalue,rootname,readextfile)
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
if (notwarned)
|
if (notwarned)
|
||||||
TxError("Drivepoint for %s not defined in %s.ext; is it defined in a child cell?\n",node->name,rootname);
|
TxError("Drivepoint for %s not defined in %s.ext; is it "
|
||||||
|
"defined in a child cell?\n", node->name, rootname);
|
||||||
notwarned = FALSE;
|
notwarned = FALSE;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#ifdef ARIEL
|
#ifdef ARIEL
|
||||||
else if (strncmp(avalue,"res:fix",7) == 0 &&
|
else if (strncmp(avalue, "res:fix", 7) == 0 &&
|
||||||
(ResOptionsFlags & ResOpt_Power))
|
(ResOptionsFlags & ResOpt_Power))
|
||||||
{
|
{
|
||||||
if (*readextfile == 0)
|
if (*readextfile == 0)
|
||||||
|
|
@ -808,14 +828,13 @@ ResSimAttribute(aname,avalue,rootname,readextfile)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
if (avalue = strchr(avalue,','))
|
if (avalue = strchr(avalue, ','))
|
||||||
{
|
{
|
||||||
(void) ResSimAttribute(aname,avalue+1,rootname,readextfile);
|
ResSimAttribute(aname, avalue + 1, rootname, readextfile);
|
||||||
}
|
}
|
||||||
return(0);
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
*-------------------------------------------------------------------------
|
*-------------------------------------------------------------------------
|
||||||
*
|
*
|
||||||
|
|
@ -844,18 +863,19 @@ ResSimProcessDrivePoints(filename)
|
||||||
HashEntry *entry;
|
HashEntry *entry;
|
||||||
ResSimNode *node;
|
ResSimNode *node;
|
||||||
|
|
||||||
fp = PaOpen(filename,"r",".ext",".",(char *) NULL,(char **) NULL);
|
fp = PaOpen(filename, "r", ".ext", ".", (char *)NULL, (char **)NULL);
|
||||||
if (fp == NULL)
|
if (fp == NULL)
|
||||||
{
|
{
|
||||||
TxError("Cannot open file %s%s\n",filename,".ext");
|
TxError("Cannot open file %s%s\n", filename, ".ext");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
while (gettokens(line,fp) != 0)
|
while (gettokens(line,fp) != 0)
|
||||||
{
|
{
|
||||||
if (strncmp(line[RES_EXT_ATTR],"attr",4) != 0 ||
|
if (strncmp(line[RES_EXT_ATTR], "attr", 4) != 0 ||
|
||||||
strncmp(line[RES_EXT_ATTR_TEXT],"\"res:drive\"",11) != 0) continue;
|
strncmp(line[RES_EXT_ATTR_TEXT], "\"res:drive\"", 11) != 0)
|
||||||
|
continue;
|
||||||
|
|
||||||
entry = HashFind(&ResNodeTable,line[RES_EXT_ATTR_NAME]);
|
entry = HashFind(&ResNodeTable, line[RES_EXT_ATTR_NAME]);
|
||||||
node = ResInitializeNode(entry);
|
node = ResInitializeNode(entry);
|
||||||
node->drivepoint.p_x = atoi(line[RES_EXT_ATTR_X]);
|
node->drivepoint.p_x = atoi(line[RES_EXT_ATTR_X]);
|
||||||
node->drivepoint.p_y = atoi(line[RES_EXT_ATTR_Y]);
|
node->drivepoint.p_y = atoi(line[RES_EXT_ATTR_Y]);
|
||||||
|
|
@ -863,7 +883,6 @@ ResSimProcessDrivePoints(filename)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
*-------------------------------------------------------------------------
|
*-------------------------------------------------------------------------
|
||||||
*
|
*
|
||||||
|
|
@ -886,44 +905,45 @@ void
|
||||||
ResSimProcessFixPoints(filename)
|
ResSimProcessFixPoints(filename)
|
||||||
char *filename;
|
char *filename;
|
||||||
{
|
{
|
||||||
char line[MAXLINE][MAXTOKEN],*label,*c;
|
char line[MAXLINE][MAXTOKEN], *label, *c;
|
||||||
FILE *fp;
|
FILE *fp;
|
||||||
ResFixPoint *thisfix;
|
ResFixPoint *thisfix;
|
||||||
|
|
||||||
fp = PaOpen(filename,"r",".ext",".",(char *) NULL,(char **) NULL);
|
fp = PaOpen(filename, "r", ".ext", ".", (char *)NULL, (char **)NULL);
|
||||||
if (fp == NULL)
|
if (fp == NULL)
|
||||||
{
|
{
|
||||||
TxError("Cannot open file %s%s\n",filename,".ext");
|
TxError("Cannot open file %s%s\n", filename, ".ext");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
while (gettokens(line,fp) != 0)
|
while (gettokens(line, fp) != 0)
|
||||||
{
|
{
|
||||||
if (strncmp(line[RES_EXT_ATTR],"attr",4) != 0 ||
|
if (strncmp(line[RES_EXT_ATTR], "attr", 4) != 0 ||
|
||||||
strncmp(line[RES_EXT_ATTR_TEXT],"\"res:fix",8) != 0) continue;
|
strncmp(line[RES_EXT_ATTR_TEXT], "\"res:fix", 8) != 0)
|
||||||
|
continue;
|
||||||
label = line[RES_EXT_ATTR_TEXT];
|
label = line[RES_EXT_ATTR_TEXT];
|
||||||
label += 8;
|
label += 8;
|
||||||
if (*label == ':') label++;
|
if (*label == ':') label++;
|
||||||
if ((c=strrchr(label,'"')) != NULL) *c='\0';
|
if ((c=strrchr(label, '"')) != NULL) *c = '\0';
|
||||||
else if (*label == '\0');
|
else if (*label != '\0')
|
||||||
else
|
|
||||||
{
|
{
|
||||||
TxError("Bad res:fix attribute label %s\n",
|
TxError("Bad res:fix attribute label %s\n",
|
||||||
line[RES_EXT_ATTR_TEXT]);
|
line[RES_EXT_ATTR_TEXT]);
|
||||||
*label ='\0';
|
*label ='\0';
|
||||||
}
|
}
|
||||||
thisfix = (ResFixPoint *) mallocMagic((unsigned) (sizeof(ResFixPoint)+strlen(label)));
|
thisfix = (ResFixPoint *)mallocMagic((unsigned)(sizeof(ResFixPoint)
|
||||||
|
+ strlen(label)));
|
||||||
thisfix->fp_next = ResFixList;
|
thisfix->fp_next = ResFixList;
|
||||||
ResFixList = thisfix;
|
ResFixList = thisfix;
|
||||||
thisfix->fp_loc.p_x = atoi(line[RES_EXT_ATTR_X]);
|
thisfix->fp_loc.p_x = atoi(line[RES_EXT_ATTR_X]);
|
||||||
thisfix->fp_loc.p_y = atoi(line[RES_EXT_ATTR_Y]);
|
thisfix->fp_loc.p_y = atoi(line[RES_EXT_ATTR_Y]);
|
||||||
thisfix->fp_ttype = DBTechNoisyNameType(line[RES_EXT_ATTR_TILE]);
|
thisfix->fp_ttype = DBTechNoisyNameType(line[RES_EXT_ATTR_TILE]);
|
||||||
thisfix->fp_tile=NULL;
|
thisfix->fp_tile = NULL;
|
||||||
strcpy(thisfix->fp_name,label);
|
strcpy(thisfix->fp_name, label);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
*-------------------------------------------------------------------------
|
*-------------------------------------------------------------------------
|
||||||
*
|
*
|
||||||
* ResSimMerge-- Processes = line in sim file
|
* ResSimMerge-- Processes = line in sim file
|
||||||
|
|
@ -950,19 +970,19 @@ ResSimMerge(line)
|
||||||
TxError("Bad node alias line\n");
|
TxError("Bad node alias line\n");
|
||||||
return(1);
|
return(1);
|
||||||
}
|
}
|
||||||
node = ResInitializeNode(HashFind(&ResNodeTable,line[ALIASNAME]));
|
node = ResInitializeNode(HashFind(&ResNodeTable, line[ALIASNAME]));
|
||||||
node->status |= FORWARD;
|
node->status |= FORWARD;
|
||||||
node->forward = ResInitializeNode(HashFind(&ResNodeTable,line[REALNAME]));
|
node->forward = ResInitializeNode(HashFind(&ResNodeTable, line[REALNAME]));
|
||||||
node->forward->resistance += node->resistance;
|
node->forward->resistance += node->resistance;
|
||||||
node->forward->capacitance += node->capacitance;
|
node->forward->capacitance += node->capacitance;
|
||||||
while (node->firstDev != NULL)
|
while (node->firstDev != NULL)
|
||||||
{
|
{
|
||||||
ptr=node->firstDev;
|
ptr = node->firstDev;
|
||||||
node->firstDev = node->firstDev->nextDev;
|
node->firstDev = node->firstDev->nextDev;
|
||||||
ptr->nextDev = node->forward->firstDev;
|
ptr->nextDev = node->forward->firstDev;
|
||||||
node->forward->firstDev = ptr;
|
node->forward->firstDev = ptr;
|
||||||
}
|
}
|
||||||
return(0);
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|
@ -986,8 +1006,8 @@ ResInitializeNode(entry)
|
||||||
|
|
||||||
if ((node = (ResSimNode *) HashGetValue(entry)) == NULL)
|
if ((node = (ResSimNode *) HashGetValue(entry)) == NULL)
|
||||||
{
|
{
|
||||||
node = (ResSimNode *) mallocMagic((unsigned)(sizeof(ResSimNode)));
|
node = (ResSimNode *)mallocMagic((unsigned)(sizeof(ResSimNode)));
|
||||||
HashSetValue(entry,(char *) node);
|
HashSetValue(entry, (char *) node);
|
||||||
node->nextnode = ResOriginalNodes;
|
node->nextnode = ResOriginalNodes;
|
||||||
ResOriginalNodes = node;
|
ResOriginalNodes = node;
|
||||||
node->status = FALSE;
|
node->status = FALSE;
|
||||||
|
|
@ -1004,12 +1024,12 @@ ResInitializeNode(entry)
|
||||||
node->drivepoint.p_y = INFINITY;
|
node->drivepoint.p_y = INFINITY;
|
||||||
node->location.p_x = INFINITY;
|
node->location.p_x = INFINITY;
|
||||||
node->location.p_y = INFINITY;
|
node->location.p_y = INFINITY;
|
||||||
node->rs_sublist[0]=NULL;
|
node->rs_sublist[0] = NULL;
|
||||||
node->rs_sublist[1]=NULL;
|
node->rs_sublist[1] = NULL;
|
||||||
}
|
}
|
||||||
while (node->status & FORWARD)
|
while (node->status & FORWARD)
|
||||||
{
|
{
|
||||||
node = node->forward;
|
node = node->forward;
|
||||||
}
|
}
|
||||||
return(node);
|
return node;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -203,7 +203,7 @@ CmdExtResis(win, cmd)
|
||||||
TxCommand *cmd;
|
TxCommand *cmd;
|
||||||
{
|
{
|
||||||
int i, j, k, option, value, saveFlags;
|
int i, j, k, option, value, saveFlags;
|
||||||
static int init=1;
|
static int init = 1;
|
||||||
static float tolerance, tdiTolerance, fhFrequency;
|
static float tolerance, tdiTolerance, fhFrequency;
|
||||||
CellDef *mainDef;
|
CellDef *mainDef;
|
||||||
CellUse *selectedUse;
|
CellUse *selectedUse;
|
||||||
|
|
@ -264,6 +264,17 @@ typedef enum {
|
||||||
init = 0;
|
init = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Initialize ResGlobalParams */
|
||||||
|
gparams.rg_ttype = TT_SPACE;
|
||||||
|
gparams.rg_Tdi = 0.0;
|
||||||
|
gparams.rg_nodecap = 0.0;
|
||||||
|
gparams.rg_maxres = 0.0;
|
||||||
|
gparams.rg_bigdevres = 0;
|
||||||
|
gparams.rg_tilecount = 0;
|
||||||
|
gparams.rg_status = 0;
|
||||||
|
gparams.rg_devloc = NULL;
|
||||||
|
gparams.rg_name = NULL;
|
||||||
|
|
||||||
option = (cmd->tx_argc > 1) ? Lookup(cmd->tx_argv[1], cmdExtresisCmd)
|
option = (cmd->tx_argc > 1) ? Lookup(cmd->tx_argv[1], cmdExtresisCmd)
|
||||||
: RES_RUN;
|
: RES_RUN;
|
||||||
|
|
||||||
|
|
@ -979,7 +990,7 @@ ResCheckSimNodes(celldef, resisdata)
|
||||||
t1->drain != t2->source)) break;
|
t1->drain != t2->source)) break;
|
||||||
|
|
||||||
/* do parallel combination */
|
/* do parallel combination */
|
||||||
if (cumRes != 0.0 && t2->resistance != 0.0)
|
if ((cumRes != 0.0) && (t2->resistance != 0.0))
|
||||||
{
|
{
|
||||||
cumRes = (cumRes * t2->resistance) /
|
cumRes = (cumRes * t2->resistance) /
|
||||||
(cumRes + t2->resistance);
|
(cumRes + t2->resistance);
|
||||||
|
|
@ -1023,25 +1034,25 @@ ResCheckSimNodes(celldef, resisdata)
|
||||||
gparams.rg_ttype = node->rs_ttype;
|
gparams.rg_ttype = node->rs_ttype;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (gparams.rg_devloc == NULL && node->status & FORCE)
|
if ((gparams.rg_devloc == NULL) && (node->status & FORCE))
|
||||||
{
|
{
|
||||||
TxError("Node %s has force label but no drive point or "
|
TxError("Node %s has force label but no drive point or "
|
||||||
"driving device\n",node->name);
|
"driving device\n",node->name);
|
||||||
}
|
}
|
||||||
if (minRes == FLT_MAX || gparams.rg_devloc == NULL)
|
if ((minRes == FLT_MAX) || (gparams.rg_devloc == NULL))
|
||||||
{
|
{
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
gparams.rg_bigdevres = (int)minRes*OHMSTOMILLIOHMS;
|
gparams.rg_bigdevres = (int)minRes * OHMSTOMILLIOHMS;
|
||||||
if (rctol == 0.0 || tol == 0.0)
|
if ((rctol == 0.0) || (tol == 0.0))
|
||||||
{
|
{
|
||||||
ftolerance = 0.0;
|
ftolerance = 0.0;
|
||||||
rctolerance = 0.0;
|
rctolerance = 0.0;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
ftolerance = minRes/tol;
|
ftolerance = minRes / tol;
|
||||||
rctolerance = minRes/rctol;
|
rctolerance = minRes / rctol;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|
@ -1049,7 +1060,7 @@ ResCheckSimNodes(celldef, resisdata)
|
||||||
* resistance? If so, extract net.
|
* resistance? If so, extract net.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
if (node->resistance > ftolerance || node->status & FORCE ||
|
if ((node->resistance > ftolerance) || (node->status & FORCE) ||
|
||||||
(ResOpt_ExtractAll & ResOptionsFlags))
|
(ResOpt_ExtractAll & ResOptionsFlags))
|
||||||
{
|
{
|
||||||
ResFixPoint fp;
|
ResFixPoint fp;
|
||||||
|
|
@ -1200,7 +1211,7 @@ ResFixUpConnections(simDev, layoutDev, simNode, nodename)
|
||||||
|
|
||||||
if (simDev->gate == simNode)
|
if (simDev->gate == simNode)
|
||||||
{
|
{
|
||||||
if ((gate=layoutDev->rd_fet_gate) != NULL)
|
if ((gate = layoutDev->rd_fet_gate) != NULL)
|
||||||
{
|
{
|
||||||
/* Cosmetic addition: If the layout device already has a */
|
/* Cosmetic addition: If the layout device already has a */
|
||||||
/* name, the new one won't be used, so we decrement resNodeNum */
|
/* name, the new one won't be used, so we decrement resNodeNum */
|
||||||
|
|
|
||||||
File diff suppressed because it is too large
Load Diff
|
|
@ -417,11 +417,12 @@ HeapAdd(heap, pKey, id)
|
||||||
{
|
{
|
||||||
/* If odd then new entry is the right half of a pair */
|
/* If odd then new entry is the right half of a pair */
|
||||||
cmp = i;
|
cmp = i;
|
||||||
if (i & 1)
|
if ((i & 1) && (i != 1))
|
||||||
KEY_LE_COND(keyType, list, i, i-1, cmp = i-1);
|
KEY_LE_COND(keyType, list, i, i-1, cmp = i-1);
|
||||||
|
|
||||||
/* Find parent. If 0 then at the root so quit */
|
/* Find parent. If 0 then at the root so quit */
|
||||||
if ((i >>= 1) == 0) return;
|
if ((i >>= 1) == 0) return;
|
||||||
|
|
||||||
KEY_LE_COND(keyType, list, cmp, i, return);
|
KEY_LE_COND(keyType, list, cmp, i, return);
|
||||||
list[0] = list[cmp]; list[cmp] = list[i]; list[i] = list[0];
|
list[0] = list[cmp]; list[cmp] = list[i]; list[i] = list[0];
|
||||||
heapify(heap, cmp);
|
heapify(heap, cmp);
|
||||||
|
|
@ -434,11 +435,12 @@ HeapAdd(heap, pKey, id)
|
||||||
{
|
{
|
||||||
/* If odd then new entry is the right half of a pair */
|
/* If odd then new entry is the right half of a pair */
|
||||||
cmp = i;
|
cmp = i;
|
||||||
if (i & 1)
|
if ((i & 1) && (i != 1))
|
||||||
KEY_GE_COND(keyType, list, i, i-1, cmp = i-1);
|
KEY_GE_COND(keyType, list, i, i-1, cmp = i-1);
|
||||||
|
|
||||||
/* Find parent. If 0 then at the root so quit */
|
/* Find parent. If 0 then at the root so quit */
|
||||||
if ((i >>= 1) == 0) return;
|
if ((i >>= 1) == 0) return;
|
||||||
|
|
||||||
KEY_GE_COND(keyType, list, cmp, i, return);
|
KEY_GE_COND(keyType, list, cmp, i, return);
|
||||||
list[0] = list[cmp]; list[cmp] = list[i]; list[i] = list[0];
|
list[0] = list[cmp]; list[cmp] = list[i]; list[i] = list[0];
|
||||||
heapify(heap, cmp);
|
heapify(heap, cmp);
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue