Additional work to clean up the code and make some things less

confusing.  Saving work here while rebasing to changes in master.
This commit is contained in:
R. Timothy Edwards 2026-02-03 17:30:19 -05:00
parent 727649b308
commit bad0b67ce8
14 changed files with 762 additions and 627 deletions

134
README
View File

@ -150,3 +150,137 @@ to be analyzed. . .
Will need a simpler hierarchical layout example. Will need a simpler hierarchical layout example.
---------------------------------------------------------------------
For now, work on analyzing the code to understand how the points of
entry (above) and exit (below) are handled. My understanding of my
previous work (which has been a while) is that there is *no* dealing
with exit points, and entry points only consider labeled ports.
Confirm this, then strategize on how to rewrite this such that any
given cell can find its exit points by looking at its .ext file
"merge" records, and its entry points by looking at its parent's
.ext file "merge" records to itself. The full list of parent uses
can be used to find all potential points of entry (some of which
might not be used in a given instance of the cell). Overlaps must
be detected and handled.
The current process stack looks like:
ResMain.c: extExtractStack()
ResRex.c: ExtResisForDef()
ResRex.c: ResCheckExtNodes()
ResRex.c: ResProcessNode()
ResMain.c: ResExtractNet()
ResSimple.c: ResDoSimplify()
ResRex.c: ResWriteExtFile()
RexExtractNet() does the following:
(loop over devices)
resMakeDevFunc()
ResShaveContacts()
ResConnectWithSD()
ResDissolveContacts()
(loop over planes)
ResAddPlumbing()
ResMakePortBreakpoints()
ResMakeLabelBreakpoints()
ResFindNewContactTiles()
ResPreProcessDevices()
ResProcessTiles()
ResEachTile()
(Then work through ResNodeQueue stack)
The relevant parts here to what needs to be added functionally are the
two routines ResMakePortBreakpoints() and ResMakeLabelBreakpoints()
These two routines should be run *only* on the top level cell of a layout,
since there is no other information specifying what it connects to.
Otherwise, I need two new routines which effectively do the same thing:
ResMakeBreakpointsUp()
ResMakeBreakpointsDown()
I have a question as to whether these really are supposed to be
"breakpoints" or if that is an appropriate designation for a terminal.
Both routines above call ResAddBreakpointFunc() which calls NEWPORT()
(macro). This is different than a breakpoint, which has NEWBREAK,
so I should probably rename the routines above to make them correct.
Each resInfo record (attached to a tile) has a "breakList" and a
"portList". But---"resAllPortNodes()" creates a NEWBREAK for every
entry in portList, and ResMakeLabelBreakpoints() calls
ResAddBreakpointFunc(), although the latter calls NEWPORT. This seems
circular and could be a case of "I did this when I didn't know what I
was doing". "resAllPortNodes()" is called at the end of ResEachTile().
Another question: ResMakePortBreakpoints() does not check the cell def but
works from the node list created by reading the .ext file, where any node
that has a "port" entry is flagged. But all ports are labels, so wouldn't
ResMakeLabelBreakpoints() create a redundant entry?
Note check at ResProcesNode() for node->status & REDUNDANT; It is not clear
to me what REDUNDANT ought to be doing in the ResReadExt code. Possibly it
should just be eliminated, and replaced by forcing EXTRACT_DOUNIQUE. For
R-C extraction there should never be two of the same node name in different
places. "node_uq0" would be just a name, like "node.n0"; it should not
matter that the label is for a junction or a terminal.
The routines appear to assume one "drive point" and multiple "terminals".
This would be a typical digital setup. The node can have a single
"drivepoint" position. This is not particularly meaningful for analog.
Maybe it makes sense to pre-partition nets so that they all end up with
the single-driver, multiple-terminal form? The idea that a net has multiple
drivers means that there are multiple points of attachment to that net from
outside. But it may be sufficient just to arbitrarily pick one node as the
driver and declare all the rest to be terminals.
------------------------
At what point in the call stack above is it possible to know whether the
current cell def is a top level cell or not? Should be possible for
anything with "def" in its argument list.
Top level cell has def->cd_parents->cu_parent = 0?
What prevents a breakpoint from being considered dangling and getting
removed? Answer: The node is marked with RES_NODE_ORIGIN. This origin
is placed at the position of a port, and if breakpoints are added, then
only the resInfo record at the origin position keeps RES_NODE_ORIGIN,
and that keeps the record from being pruned from the node. Will likely
need a different flag, such as "RES_NODE_SINK".
Seems like this should run after basic extraction and before simplification.
If a list of parent and child connection points exists after reading the
.ext files, then the connection points can be located and the resInfo
at the connection point can be set to be a sink. That may involve adding
a junction, which might be as simple as just calling ResProcessJunction()?
Or more likely, need a new handler (in ResJunct.c) to process a sink point.
Note that "ResProcessJunction()" requires two connecting tiles, which would
not be the case with a sink.
Analyze how these junction processor routines work. The resInfo field of
"tp" is searched, but the resInfo field of "tile" gets the new breakpoint.
Need to keep in mind the difference between ResNodeList, which has entries
of type "resNode" (which is basically a sub-node), and ResOriginalNodes,
which has entries of type "ResExtNode". Particularly confusing is
ResOriginalNodes vs. ResOriginNode. . . may want to change something, like
referring to the originals as Nets?
(Cleaned up a bunch of mess in the code meanwhile.)
Added RES_NODE_SINK and handling, but nothing defines it yet. It will
prevent nodes having the flag from being merged or simplified away, like
RES_NODE_ORIGIN.
Now need a routine that reads the "merge" lines from .ext files and
creates sinks.
Currently resAllPortNodes() runs at the end of ResEachTile().
It takes the Info record attached to the tile, runs through the portList,
and adds a new breakpoint. . . to the same tile. There is no check of
whether the port intersects the tile, which is probably wrong.
Time to start working with some simple examples.

View File

@ -925,13 +925,14 @@ cmdExpandFunc(
#define DOALL 1 #define DOALL 1
#define DOCAPACITANCE 2 #define DOCAPACITANCE 2
#define DOCOUPLING 3 #define DOCOUPLING 3
#define DOLENGTH 4 #define DOEXTRESIST 4
#define DOLOCAL 5 #define DOLENGTH 5
#define DORESISTANCE 6 #define DOLOCAL 6
#define DOLABELCHECK 7 #define DORESISTANCE 7
#define DOALIASES 8 #define DOLABELCHECK 8
#define DOUNIQUE 9 #define DOALIASES 9
#define DOEXTRESIST 10 #define DOUNIQUE 10
#define DOEXTRESIST2 11
#define LENCLEAR 0 #define LENCLEAR 0
#define LENDRIVER 1 #define LENDRIVER 1
@ -974,13 +975,14 @@ CmdExtract(
"all all options", "all all options",
"capacitance extract substrate capacitance", "capacitance extract substrate capacitance",
"coupling extract coupling capacitance", "coupling extract coupling capacitance",
"extresist extract resistance",
"length compute driver-receiver pathlengths", "length compute driver-receiver pathlengths",
"local put all generated files in the current directory", "local put all generated files in the current directory",
"lumped estimate lumped resistance", "lumped estimate lumped resistance",
"labelcheck check for connections through sticky labels", "labelcheck check for connections through sticky labels",
"aliases output all net name aliases", "aliases output all net name aliases",
"unique ensure unique node names during extraction", "unique ensure unique node names during extraction",
"resistance extract resistance", "resistance extract resistance (same as \"do extresist\")",
NULL NULL
}; };
static const char * const cmdExtLength[] = static const char * const cmdExtLength[] =
@ -1286,7 +1288,7 @@ CmdExtract(
TxPrintf("%s label check\n", OPTSET(EXT_DOLABELCHECK)); TxPrintf("%s label check\n", OPTSET(EXT_DOLABELCHECK));
TxPrintf("%s aliases\n", OPTSET(EXT_DOALIASES)); TxPrintf("%s aliases\n", OPTSET(EXT_DOALIASES));
TxPrintf("%s unique\n", OPTSET(EXT_DOUNIQUE)); TxPrintf("%s unique\n", OPTSET(EXT_DOUNIQUE));
TxPrintf("%s resistance\n", OPTSET(EXT_DOEXTRESIST)); TxPrintf("%s resistance (extresist)\n", OPTSET(EXT_DOEXTRESIST));
return; return;
#undef OPTSET #undef OPTSET
} }
@ -1317,7 +1319,8 @@ CmdExtract(
case DOLABELCHECK: option = EXT_DOLABELCHECK; break; case DOLABELCHECK: option = EXT_DOLABELCHECK; break;
case DOALIASES: option = EXT_DOALIASES; break; case DOALIASES: option = EXT_DOALIASES; break;
case DOUNIQUE: option = EXT_DOUNIQUE; break; case DOUNIQUE: option = EXT_DOUNIQUE; break;
case DOEXTRESIST: option = EXT_DOEXTRESIST; break; case DOEXTRESIST:
case DOEXTRESIST2: option = EXT_DOEXTRESIST; break;
case DOLOCAL: case DOLOCAL:
/* "extract do local" and "extract no local" are kept for /* "extract do local" and "extract no local" are kept for
* backwards compatibility, but now effectively implement * backwards compatibility, but now effectively implement

View File

@ -46,22 +46,22 @@ resNodeIsPort(node, x, y, tile)
Rect *rect; Rect *rect;
Point p; Point p;
resPort *pl, *lp; resPort *pl, *lp;
tileJunk *junk = (tileJunk *)TiGetClientPTR(tile); resInfo *info = (resInfo *)TiGetClientPTR(tile);
p.p_x = x; p.p_x = x;
p.p_y = y; p.p_y = y;
for (pl = junk->portList; pl; pl = pl->rp_nextPort) for (pl = info->portList; pl; pl = pl->rp_nextPort)
{ {
rect = &(pl->rp_bbox); rect = &(pl->rp_bbox);
if (GEO_ENCLOSE(&p, rect)) if (GEO_ENCLOSE(&p, rect))
{ {
node->rn_name = pl->rp_nodename; node->rn_name = pl->rp_nodename;
if (junk->portList == pl) if (info->portList == pl)
junk->portList = pl->rp_nextPort; info->portList = pl->rp_nextPort;
else else
{ {
for (lp = junk->portList; lp && (lp->rp_nextPort != pl); for (lp = info->portList; lp && (lp->rp_nextPort != pl);
lp = lp->rp_nextPort); lp = lp->rp_nextPort);
lp->rp_nextPort = pl->rp_nextPort; lp->rp_nextPort = pl->rp_nextPort;
} }
@ -77,7 +77,8 @@ resNodeIsPort(node, x, y, tile)
* resAllPortNodes -- * resAllPortNodes --
* *
* Generate new nodes and breakpoints for every unused port declared * Generate new nodes and breakpoints for every unused port declared
* on a tile. * on a tile. However, if "startpoint" is inside the port position,
* then it has already been processed, so ignore it.
* *
*-------------------------------------------------------------------------- *--------------------------------------------------------------------------
*/ */
@ -90,15 +91,15 @@ resAllPortNodes(tile, list)
int x, y; int x, y;
resNode *resptr; resNode *resptr;
resPort *pl; resPort *pl;
tileJunk *junk = (tileJunk *)TiGetClientPTR(tile); resInfo *info = (resInfo *)TiGetClientPTR(tile);
free_magic1_t mm1 = freeMagic1_init(); free_magic1_t mm1 = freeMagic1_init();
for (pl = junk->portList; pl; pl = pl->rp_nextPort) for (pl = info->portList; pl; pl = pl->rp_nextPort)
{ {
x = pl->rp_loc.p_x; x = pl->rp_loc.p_x;
y = pl->rp_loc.p_y; y = pl->rp_loc.p_y;
resptr = (resNode *) mallocMagic((unsigned)(sizeof(resNode))); resptr = (resNode *) mallocMagic((unsigned)(sizeof(resNode)));
InitializeNode(resptr, x, y, RES_NODE_ORIGIN); InitializeResNode(resptr, x, y, RES_NODE_ORIGIN);
resptr->rn_status = TRUE; resptr->rn_status = TRUE;
resptr->rn_noderes = 0; resptr->rn_noderes = 0;
resptr->rn_name = pl->rp_nodename; resptr->rn_name = pl->rp_nodename;
@ -225,7 +226,7 @@ ResEachTile(tile, startpoint)
int xj, yj, i; int xj, yj, i;
bool merged; bool merged;
tElement *tcell; tElement *tcell;
tileJunk *tstructs= (tileJunk *)TiGetClientPTR(tile); resInfo *tstructs= (resInfo *)TiGetClientPTR(tile);
ExtDevice *devptr; ExtDevice *devptr;
int sides; int sides;
@ -262,7 +263,7 @@ ResEachTile(tile, startpoint)
int x = startpoint->p_x; int x = startpoint->p_x;
int y = startpoint->p_y; int y = startpoint->p_y;
resptr = (resNode *) mallocMagic((unsigned)(sizeof(resNode))); resptr = (resNode *) mallocMagic((unsigned)(sizeof(resNode)));
InitializeNode(resptr, x, y, RES_NODE_ORIGIN); InitializeResNode(resptr, x, y, RES_NODE_ORIGIN);
resptr->rn_status = TRUE; resptr->rn_status = TRUE;
resptr->rn_noderes = 0; resptr->rn_noderes = 0;
ResAddToQueue(resptr, &ResNodeQueue); ResAddToQueue(resptr, &ResNodeQueue);
@ -278,7 +279,7 @@ ResEachTile(tile, startpoint)
* for single tile device, but not as good for multiple ones. * for single tile device, but not as good for multiple ones.
*/ */
if (tstructs->tj_status & RES_TILE_DEV) if (tstructs->ri_status & RES_TILE_DEV)
{ {
if (tstructs->deviceList->rd_fet_gate == NULL) if (tstructs->deviceList->rd_fet_gate == NULL)
{ {
@ -291,7 +292,7 @@ ResEachTile(tile, startpoint)
tcell->te_thist = tstructs->deviceList; tcell->te_thist = tstructs->deviceList;
tcell->te_nextt = NULL; tcell->te_nextt = NULL;
InitializeNode(resptr, x, y, RES_NODE_JUNCTION); InitializeResNode(resptr, x, y, RES_NODE_JUNCTION);
resptr->rn_te = tcell; resptr->rn_te = tcell;
ResAddToQueue(resptr, &ResNodeQueue); ResAddToQueue(resptr, &ResNodeQueue);
resNodeIsPort(resptr, x, y, tile); resNodeIsPort(resptr, x, y, tile);
@ -516,7 +517,7 @@ ResEachTile(tile, startpoint)
} }
} }
tstructs->tj_status |= RES_TILE_DONE; tstructs->ri_status |= RES_TILE_DONE;
resAllPortNodes(tile, &ResNodeQueue); resAllPortNodes(tile, &ResNodeQueue);

View File

@ -64,7 +64,7 @@ ResSanityChecks(nodename, resistorList, nodeList, devlist)
for (node = nodeList; node != NULL; node=node->rn_more) for (node = nodeList; node != NULL; node=node->rn_more)
{ {
node->rn_status &= ~RES_REACHED_NODE; node->rn_status &= ~RES_REACHED_NODE;
if (node->rn_why == RES_NODE_ORIGIN) if (node->rn_why & RES_NODE_ORIGIN)
STACKPUSH((ClientData) node, resSanityStack); STACKPUSH((ClientData) node, resSanityStack);
} }
for (resistor = resistorList; resistor != NULL; resistor = resistor->rr_nextResistor) for (resistor = resistorList; resistor != NULL; resistor = resistor->rr_nextResistor)

View File

@ -52,7 +52,7 @@ ResNewSDDevice(tile, tp, xj, yj, direction, PendingList)
resDevice *resDev; resDevice *resDev;
tElement *tcell; tElement *tcell;
int newnode; int newnode;
tileJunk *j; resInfo *ri;
newnode = FALSE; newnode = FALSE;
@ -62,9 +62,9 @@ ResNewSDDevice(tile, tp, xj, yj, direction, PendingList)
*/ */
if (TiGetClient(tp) == CLIENTDEFAULT) return; if (TiGetClient(tp) == CLIENTDEFAULT) return;
j = (tileJunk *) TiGetClientPTR(tp); ri = (resInfo *) TiGetClientPTR(tp);
resDev = j->deviceList; resDev = ri->deviceList;
if ((j->sourceEdge & direction) != 0) if ((ri->sourceEdge & direction) != 0)
{ {
if (resDev->rd_fet_source == (resNode *) NULL) if (resDev->rd_fet_source == (resNode *) NULL)
{ {
@ -94,8 +94,8 @@ ResNewSDDevice(tile, tp, xj, yj, direction, PendingList)
{ {
tcell = (tElement *) mallocMagic((unsigned)(sizeof(tElement))); tcell = (tElement *) mallocMagic((unsigned)(sizeof(tElement)));
tcell->te_nextt = NULL; tcell->te_nextt = NULL;
tcell->te_thist = j->deviceList; tcell->te_thist = ri->deviceList;
InitializeNode(resptr, xj, yj, RES_NODE_DEVICE); InitializeResNode(resptr, xj, yj, RES_NODE_DEVICE);
resptr->rn_te = tcell; resptr->rn_te = tcell;
ResAddToQueue(resptr, PendingList); ResAddToQueue(resptr, PendingList);
} }
@ -125,11 +125,11 @@ ResNewSubDevice(tile, tp, xj, yj, direction, PendingList)
resDevice *resDev; resDevice *resDev;
tElement *tcell; tElement *tcell;
int newnode; int newnode;
tileJunk *j; resInfo *ri;
newnode = FALSE; newnode = FALSE;
j = (tileJunk *) TiGetClientPTR(tp); ri = (resInfo *) TiGetClientPTR(tp);
resDev = j->deviceList; resDev = ri->deviceList;
/* Arrived at a device that has a terminal connected to substrate */ /* Arrived at a device that has a terminal connected to substrate */
/* that is not a FET bulk terminal (e.g., varactor, diode). */ /* that is not a FET bulk terminal (e.g., varactor, diode). */
@ -150,8 +150,8 @@ ResNewSubDevice(tile, tp, xj, yj, direction, PendingList)
{ {
tcell = (tElement *) mallocMagic((unsigned)(sizeof(tElement))); tcell = (tElement *) mallocMagic((unsigned)(sizeof(tElement)));
tcell->te_nextt = NULL; tcell->te_nextt = NULL;
tcell->te_thist = j->deviceList; tcell->te_thist = ri->deviceList;
InitializeNode(resptr, xj, yj, RES_NODE_DEVICE); InitializeResNode(resptr, xj, yj, RES_NODE_DEVICE);
resptr->rn_te = tcell; resptr->rn_te = tcell;
ResAddToQueue(resptr, PendingList); ResAddToQueue(resptr, PendingList);
} }
@ -181,8 +181,8 @@ ResProcessJunction(tile, tp, xj, yj, NodeList)
ResJunction *junction; ResJunction *junction;
resNode *resptr; resNode *resptr;
jElement *jcell; jElement *jcell;
tileJunk *j0 = (tileJunk *)TiGetClientPTR(tile); resInfo *ri0 = (resInfo *)TiGetClientPTR(tile);
tileJunk *j2 = (tileJunk *)TiGetClientPTR(tp); resInfo *ri2 = (resInfo *)TiGetClientPTR(tp);
#ifdef PARANOID #ifdef PARANOID
if (tile == tp) if (tile == tp)
@ -191,12 +191,12 @@ ResProcessJunction(tile, tp, xj, yj, NodeList)
return; return;
} }
#endif #endif
if (j2->tj_status & RES_TILE_DONE) return; if (ri2->ri_status & RES_TILE_DONE) return;
resptr = (resNode *) mallocMagic((unsigned)(sizeof(resNode))); resptr = (resNode *) mallocMagic((unsigned)(sizeof(resNode)));
resptr->rn_te = (tElement *) NULL; resptr->rn_te = (tElement *) NULL;
junction = (ResJunction *) mallocMagic((unsigned)(sizeof(ResJunction))); junction = (ResJunction *) mallocMagic((unsigned)(sizeof(ResJunction)));
jcell = (jElement *) mallocMagic((unsigned)(sizeof(jElement))); jcell = (jElement *) mallocMagic((unsigned)(sizeof(jElement)));
InitializeNode(resptr, xj, yj, RES_NODE_JUNCTION); InitializeResNode(resptr, xj, yj, RES_NODE_JUNCTION);
resptr->rn_je = jcell; resptr->rn_je = jcell;
ResAddToQueue(resptr, NodeList); ResAddToQueue(resptr, NodeList);
@ -208,10 +208,10 @@ ResProcessJunction(tile, tp, xj, yj, NodeList)
junction->rj_Tile[1] = tp; junction->rj_Tile[1] = tp;
junction->rj_loc.p_x =xj; junction->rj_loc.p_x =xj;
junction->rj_loc.p_y =yj; junction->rj_loc.p_y =yj;
junction->rj_nextjunction[0] = j0->junctionList; junction->rj_nextjunction[0] = ri0->junctionList;
j0->junctionList = junction; ri0->junctionList = junction;
junction->rj_nextjunction[1] = j2->junctionList; junction->rj_nextjunction[1] = ri2->junctionList;
j2->junctionList = junction; ri2->junctionList = junction;
NEWBREAK(junction->rj_jnode,tile, junction->rj_loc.p_x, NEWBREAK(junction->rj_jnode,tile, junction->rj_loc.p_x,
junction->rj_loc.p_y, NULL); junction->rj_loc.p_y, NULL);

View File

@ -35,13 +35,12 @@ 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 *ResNodeAtOrigin = 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 ExtRegion *ResFirst(); extern ExtRegion *ResFirst();
extern Tile *FindStartTile(); extern Tile *FindStartTile();
extern int ResEachTile(); extern int ResEachTile();
extern ResExtNode *ResInitializeNode();
TileTypeBitMask ResSDTypesBitMask; TileTypeBitMask ResSDTypesBitMask;
TileTypeBitMask ResSubTypesBitMask; TileTypeBitMask ResSubTypesBitMask;
@ -184,7 +183,7 @@ ResDissolveContacts(contacts)
* ResMakePortBreakpoints -- * ResMakePortBreakpoints --
* *
* Search for nodes which are ports, and force them to be breakpoints * Search for nodes which are ports, and force them to be breakpoints
* in the "tileJunk" field of their respective tiles in ResUse. This * in the "resInfo" field of their respective tiles in ResUse. This
* ensures that connected nodes that stretch between two ports will * ensures that connected nodes that stretch between two ports will
* not be assumed to be "hanging" nodes. * not be assumed to be "hanging" nodes.
* *
@ -205,7 +204,7 @@ ResMakePortBreakpoints(def)
int ResAddBreakpointFunc(); /* Forward Declaration */ int ResAddBreakpointFunc(); /* Forward Declaration */
HashStartSearch(&hs); HashStartSearch(&hs);
while((entry = HashNext(&ResNodeTable,&hs)) != NULL) while((entry = HashNext(&ResNodeTable, &hs)) != NULL)
{ {
node = (ResExtNode *)HashGetValue(entry); node = (ResExtNode *)HashGetValue(entry);
if (node->status & PORTNODE) if (node->status & PORTNODE)
@ -266,7 +265,7 @@ ResMakePortBreakpoints(def)
* ResMakeLabelBreakpoints -- * ResMakeLabelBreakpoints --
* *
* Search for labels that are part of a node, and force them to be * Search for labels that are part of a node, and force them to be
* breakpoints in the "tileJunk" field of their respective tiles in * breakpoints in the "resInfo" field of their respective tiles in
* ResUse. This ensures (among other things) that pins of a top level * ResUse. This ensures (among other things) that pins of a top level
* cell will be retained and become the endpoint of a net. * cell will be retained and become the endpoint of a net.
* *
@ -292,7 +291,7 @@ ResMakeLabelBreakpoints(def, resisdata)
if (*(slab->lab_text) == '\0') continue; if (*(slab->lab_text) == '\0') continue;
entry = HashFind(&ResNodeTable, slab->lab_text); entry = HashFind(&ResNodeTable, slab->lab_text);
node = ResInitializeNode(entry); node = ResExtInitNode(entry);
/* If the drivepoint position changes and the drivepoint is */ /* If the drivepoint position changes and the drivepoint is */
/* in the "resisdata" record, then make sure the tile type */ /* in the "resisdata" record, then make sure the tile type */
@ -344,7 +343,7 @@ ResMakeLabelBreakpoints(def, resisdata)
* *
* ResAddBreakpointFunc -- * ResAddBreakpointFunc --
* *
* Add a breakpoint to the "tileJunk" structure of the tile * Add a breakpoint to the "resInfo" structure of the tile
* *
*---------------------------------------------------------------------------- *----------------------------------------------------------------------------
*/ */
@ -355,7 +354,7 @@ ResAddBreakpointFunc(tile, dinfo, node)
TileType dinfo; /* (unused) */ TileType dinfo; /* (unused) */
ResExtNode *node; ResExtNode *node;
{ {
tileJunk *junk; resInfo *info;
if (TiGetClient(tile) == CLIENTDEFAULT) if (TiGetClient(tile) == CLIENTDEFAULT)
return 0; return 0;
@ -430,15 +429,15 @@ ResFindNewContactTiles(contacts)
if ((IsSplit(tile) && TTMaskHasType(&mask, TiGetRightType(tile))) if ((IsSplit(tile) && TTMaskHasType(&mask, TiGetRightType(tile)))
|| TTMaskHasType(&mask, TiGetLeftType(tile))) || TTMaskHasType(&mask, TiGetLeftType(tile)))
{ {
tileJunk *j = (tileJunk *)TiGetClientPTR(tile); resInfo *ri = (resInfo *)TiGetClientPTR(tile);
cElement *ce; cElement *ce;
ce = (cElement *) mallocMagic((unsigned) (sizeof(cElement))); ce = (cElement *) mallocMagic((unsigned) (sizeof(cElement)));
contacts->cp_tile[contacts->cp_currentcontact] = tile; contacts->cp_tile[contacts->cp_currentcontact] = tile;
ce->ce_thisc = contacts; ce->ce_thisc = contacts;
ce->ce_nextc = j->contactList; ce->ce_nextc = ri->contactList;
(contacts->cp_currentcontact) += 1; (contacts->cp_currentcontact) += 1;
j->contactList = ce; ri->contactList = ce;
} }
else if (!IsSplit(tile)) else if (!IsSplit(tile))
{ {
@ -452,15 +451,15 @@ ResFindNewContactTiles(contacts)
*/ */
if (TTMaskIntersect(DBResidueMask(ttype), &mask)) if (TTMaskIntersect(DBResidueMask(ttype), &mask))
{ {
tileJunk *j = (tileJunk *)TiGetClientPTR(tile); resInfo *ri = (resInfo *)TiGetClientPTR(tile);
cElement *ce; cElement *ce;
ce = (cElement *) mallocMagic((unsigned) (sizeof(cElement))); ce = (cElement *) mallocMagic((unsigned) (sizeof(cElement)));
contacts->cp_tile[contacts->cp_currentcontact] = tile; contacts->cp_tile[contacts->cp_currentcontact] = tile;
ce->ce_thisc = contacts; ce->ce_thisc = contacts;
ce->ce_nextc = j->contactList; ce->ce_nextc = ri->contactList;
(contacts->cp_currentcontact) += 1; (contacts->cp_currentcontact) += 1;
j->contactList = ce; ri->contactList = ce;
} }
} }
} }
@ -524,7 +523,7 @@ ResProcessTiles(resisdata, origin)
while (ResNodeQueue != NULL) while (ResNodeQueue != NULL)
{ {
/* /*
* merged keeps track of whether another node gets merged into * "merged" keeps track of whether another node gets merged into
* the current one. If it does, then the node must be processed * the current one. If it does, then the node must be processed
* because additional junctions or contacts were added * because additional junctions or contacts were added
*/ */
@ -542,16 +541,14 @@ ResProcessTiles(resisdata, 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 *)TiGetClientPTR(tile); resInfo *ri = (resInfo *)TiGetClientPTR(tile);
if ((j->tj_status & RES_TILE_DONE) == 0) if ((ri->ri_status & RES_TILE_DONE) == 0)
{ {
resCurrentNode = resptr2; resCurrentNode = resptr2;
merged |= ResEachTile(tile, (Point *)NULL); merged |= ResEachTile(tile, (Point *)NULL);
} }
if (merged & ORIGIN) break;
} }
if (merged & ORIGIN) break;
rj->rj_status = TRUE; rj->rj_status = TRUE;
} }
} }
@ -562,16 +559,15 @@ ResProcessTiles(resisdata, origin)
{ {
ResContactPoint *cp = workingc->ce_thisc; ResContactPoint *cp = workingc->ce_thisc;
if (merged & ORIGIN) break;
if (cp->cp_status == FALSE) if (cp->cp_status == FALSE)
{ {
int newstatus = TRUE; int newstatus = TRUE;
for (tilenum = 0; tilenum < cp->cp_currentcontact; tilenum++) for (tilenum = 0; tilenum < cp->cp_currentcontact; tilenum++)
{ {
Tile *tile = cp->cp_tile[tilenum]; Tile *tile = cp->cp_tile[tilenum];
tileJunk *j = (tileJunk *) TiGetClientPTR(tile); resInfo *ri = (resInfo *) TiGetClientPTR(tile);
if ((j->tj_status & RES_TILE_DONE) == 0) if ((ri->ri_status & RES_TILE_DONE) == 0)
{ {
if (cp->cp_cnode[tilenum] == resptr2) if (cp->cp_cnode[tilenum] == resptr2)
{ {
@ -583,9 +579,7 @@ ResProcessTiles(resisdata, origin)
newstatus = FALSE; newstatus = FALSE;
} }
} }
if (merged & ORIGIN) break;
} }
if (merged & ORIGIN) break;
cp->cp_status = newstatus; cp->cp_status = newstatus;
} }
} }
@ -601,15 +595,15 @@ ResProcessTiles(resisdata, origin)
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 &= ~RES_PENDING;
resptr2->rn_status |= FINISHED | MARKED; resptr2->rn_status |= RES_FINISHED | RES_MARKED;
if (ResNodeList != NULL) if (ResNodeList != NULL)
{ {
ResNodeList->rn_less = resptr2; ResNodeList->rn_less = resptr2;
} }
if (resptr2->rn_noderes == 0) if (resptr2->rn_noderes == 0)
{ {
ResOriginNode=resptr2; ResNodeAtOrigin = resptr2;
} }
ResNodeList = resptr2; ResNodeList = resptr2;
ResCleanNode(resptr2, FALSE, &ResNodeList, &ResNodeQueue); ResCleanNode(resptr2, FALSE, &ResNodeList, &ResNodeQueue);
@ -688,7 +682,7 @@ ResCalcPerimOverlap(tile, dev)
* resMakeDevFunc -- * resMakeDevFunc --
* *
* Callback function from ResExtractNet. For each device in a node's * Callback function from ResExtractNet. For each device in a node's
* device list pulled from the .sim file, find the tile(s) corresponding * device list pulled from the .ext file, find the tile(s) corresponding
* to the device in the source tree, and fill out the complete device * to the device in the source tree, and fill out the complete device
* record (namely the full device area). * record (namely the full device area).
* *
@ -726,7 +720,7 @@ resMakeDevFunc(tile, dinfo, cx)
/* If more than one tile type extracts to the same device, then */ /* If more than one tile type extracts to the same device, then */
/* the device type may be different from what was recorded when */ /* the device type may be different from what was recorded when */
/* the sim file was read. Restricted to the plane of the */ /* the .ext file was read. Restricted to the plane of the */
/* original type to avoid conflict with completely different */ /* original type to avoid conflict with completely different */
/* devices (like transistors vs. MiM caps). */ /* devices (like transistors vs. MiM caps). */
@ -1014,7 +1008,7 @@ ResExtractNet(node, resisdata, cellname)
ResDevList = NULL; ResDevList = NULL;
ResNodeQueue = NULL; ResNodeQueue = NULL;
ResContactList = NULL; ResContactList = NULL;
ResOriginNode = NULL; ResNodeAtOrigin = NULL;
/* Pass back network pointers */ /* Pass back network pointers */
@ -1169,7 +1163,7 @@ ResExtractNet(node, resisdata, cellname)
ResDissolveContacts(ResContactList); ResDissolveContacts(ResContactList);
/* Add "junk" fields to tiles */ /* Add "resInfo" fields to tiles */
for (pNum = PL_TECHDEPBASE; pNum < DBNumPlanes; pNum++) for (pNum = PL_TECHDEPBASE; pNum < DBNumPlanes; pNum++)
{ {
@ -1182,10 +1176,17 @@ ResExtractNet(node, resisdata, cellname)
(ClientData) &ResDevList); (ClientData) &ResDevList);
} }
/* Finish preprocessing. */ /* If this is a top-level cell, then determine where connections
* are made into the cell from ports. Otherwise, determine points
* of entry by looking at how all parent cells connect to this
* cell.
*/
ResMakePortBreakpoints(ResUse->cu_def); ResMakePortBreakpoints(ResUse->cu_def);
ResMakeLabelBreakpoints(ResUse->cu_def, resisdata); ResMakeLabelBreakpoints(ResUse->cu_def, resisdata);
/* Finish preprocessing. */
ResFindNewContactTiles(ResContactList); ResFindNewContactTiles(ResContactList);
ResPreProcessDevices(DevTiles, ResDevList, ResUse->cu_def); ResPreProcessDevices(DevTiles, ResDevList, ResUse->cu_def);
@ -1309,7 +1310,7 @@ ResGetTileFunc(tile, dinfo, tpptr)
*------------------------------------------------------------------------- *-------------------------------------------------------------------------
* *
* FindStartTile-- To start the extraction, we need to find the first driver. * FindStartTile-- To start the extraction, we need to find the first driver.
* The sim file gives us the location of a point in or near (within 1 * The .ext file gives us the location of a point in or near (within 1
* unit) of the device. FindStartTile looks for the device, then * unit) of the device. FindStartTile looks for the device, then
* for adjoining diffusion. The diffusion tile is returned. * for adjoining diffusion. The diffusion tile is returned.
* *
@ -1450,8 +1451,9 @@ FindStartTile(resisdata, SourcePoint)
else else
{ {
const ClientData ticlient = TiGetClient(tp); const ClientData ticlient = TiGetClient(tp);
const tileJunk *tj = (tileJunk *)CD2PTR(ticlient); const resInfo *rinfo = (resInfo *)CD2PTR(ticlient);
if (ticlient != CLIENTDEFAULT && tj->tj_status & RES_TILE_DEV)
if (ticlient != CLIENTDEFAULT && rinfo->ri_status & RES_TILE_DEV)
complex = TRUE; complex = TRUE;
} }
} }
@ -1471,8 +1473,8 @@ FindStartTile(resisdata, SourcePoint)
else else
{ {
const ClientData ticlient = TiGetClient(tp); const ClientData ticlient = TiGetClient(tp);
const tileJunk *tj = (tileJunk *)CD2PTR(ticlient); const resInfo *rinfo = (resInfo *)CD2PTR(ticlient);
if (ticlient != CLIENTDEFAULT && tj->tj_status & RES_TILE_DEV) if (ticlient != CLIENTDEFAULT && rinfo->ri_status & RES_TILE_DEV)
complex = TRUE; complex = TRUE;
} }
} }
@ -1492,8 +1494,8 @@ FindStartTile(resisdata, SourcePoint)
else else
{ {
const ClientData ticlient = TiGetClient(tp); const ClientData ticlient = TiGetClient(tp);
const tileJunk *tj = (tileJunk *)CD2PTR(ticlient); const resInfo *rinfo = (resInfo *)CD2PTR(ticlient);
if (ticlient != CLIENTDEFAULT && tj->tj_status & RES_TILE_DEV) if (ticlient != CLIENTDEFAULT && rinfo->ri_status & RES_TILE_DEV)
complex = TRUE; complex = TRUE;
} }
} }
@ -1513,8 +1515,8 @@ FindStartTile(resisdata, SourcePoint)
else else
{ {
const ClientData ticlient = TiGetClient(tp); const ClientData ticlient = TiGetClient(tp);
const tileJunk *tj = (tileJunk *)CD2PTR(ticlient); const resInfo *rinfo = (resInfo *)CD2PTR(ticlient);
if (ticlient != CLIENTDEFAULT && tj->tj_status & RES_TILE_DEV) if (ticlient != CLIENTDEFAULT && rinfo->ri_status & RES_TILE_DEV)
complex = TRUE; complex = TRUE;
} }
} }
@ -1527,7 +1529,7 @@ FindStartTile(resisdata, SourcePoint)
if (devStack == NULL) devStack = StackNew(8); if (devStack == NULL) devStack = StackNew(8);
((tileJunk *)TiGetClientPTR(tile))->tj_status |= RES_TILE_PUSHED; ((resInfo *)TiGetClientPTR(tile))->ri_status |= RES_TILE_PUSHED;
STACKPUSH((ClientData)tile, devStack); STACKPUSH((ClientData)tile, devStack);
while (!StackEmpty(devStack)) while (!StackEmpty(devStack))
{ {
@ -1554,12 +1556,12 @@ FindStartTile(resisdata, SourcePoint)
const ClientData ticlient = TiGetClient(tp); const ClientData ticlient = TiGetClient(tp);
if (ticlient != CLIENTDEFAULT) if (ticlient != CLIENTDEFAULT)
{ {
tileJunk *tj = (tileJunk *)CD2PTR(ticlient); resInfo *rinfo = (resInfo *)CD2PTR(ticlient);
if (tj->tj_status & RES_TILE_DEV) if (rinfo->ri_status & RES_TILE_DEV)
{ {
if (!(tj->tj_status & RES_TILE_PUSHED)) if (!(rinfo->ri_status & RES_TILE_PUSHED))
{ {
tj->tj_status |= RES_TILE_PUSHED; rinfo->ri_status |= RES_TILE_PUSHED;
STACKPUSH((ClientData)tp, devStack); STACKPUSH((ClientData)tp, devStack);
} }
} }
@ -1588,12 +1590,12 @@ FindStartTile(resisdata, SourcePoint)
const ClientData ticlient = TiGetClient(tp); const ClientData ticlient = TiGetClient(tp);
if (ticlient != CLIENTDEFAULT) if (ticlient != CLIENTDEFAULT)
{ {
tileJunk *tj = (tileJunk *)CD2PTR(ticlient); resInfo *rinfo = (resInfo *)CD2PTR(ticlient);
if (tj->tj_status & RES_TILE_DEV) if (rinfo->ri_status & RES_TILE_DEV)
{ {
if (!(tj->tj_status & RES_TILE_PUSHED)) if (!(rinfo->ri_status & RES_TILE_PUSHED))
{ {
tj->tj_status |= RES_TILE_PUSHED; rinfo->ri_status |= RES_TILE_PUSHED;
STACKPUSH((ClientData)tp, devStack); STACKPUSH((ClientData)tp, devStack);
} }
} }
@ -1622,12 +1624,12 @@ FindStartTile(resisdata, SourcePoint)
const ClientData ticlient = TiGetClient(tp); const ClientData ticlient = TiGetClient(tp);
if (ticlient != CLIENTDEFAULT) if (ticlient != CLIENTDEFAULT)
{ {
tileJunk *tj = (tileJunk *)CD2PTR(ticlient); resInfo *rinfo = (resInfo *)CD2PTR(ticlient);
if (tj->tj_status & RES_TILE_DEV) if (rinfo->ri_status & RES_TILE_DEV)
{ {
if (!(tj->tj_status & RES_TILE_PUSHED)) if (!(rinfo->ri_status & RES_TILE_PUSHED))
{ {
tj->tj_status |= RES_TILE_PUSHED; rinfo->ri_status |= RES_TILE_PUSHED;
STACKPUSH((ClientData)tp, devStack); STACKPUSH((ClientData)tp, devStack);
} }
} }
@ -1656,12 +1658,12 @@ FindStartTile(resisdata, SourcePoint)
const ClientData ticlient = TiGetClient(tp); const ClientData ticlient = TiGetClient(tp);
if (ticlient != CLIENTDEFAULT) if (ticlient != CLIENTDEFAULT)
{ {
tileJunk *tj = (tileJunk *)CD2PTR(ticlient); resInfo *rinfo = (resInfo *)CD2PTR(ticlient);
if (tj->tj_status & RES_TILE_DEV) if (rinfo->ri_status & RES_TILE_DEV)
{ {
if (!(tj->tj_status & RES_TILE_PUSHED)) if (!(rinfo->ri_status & RES_TILE_PUSHED))
{ {
tj->tj_status |= RES_TILE_PUSHED; rinfo->ri_status |= RES_TILE_PUSHED;
STACKPUSH((ClientData)tp, devStack); STACKPUSH((ClientData)tp, devStack);
} }
} }
@ -1720,7 +1722,7 @@ FindStartTile(resisdata, SourcePoint)
*------------------------------------------------------------------------- *-------------------------------------------------------------------------
* *
* ResGetDevice -- Once the net is extracted, we still have to equate * ResGetDevice -- Once the net is extracted, we still have to equate
* the sim file devices with the layout devices. ResGetDevice * the .ext file devices with the layout devices. ResGetDevice
* looks for a device at the given location. "type" is also * looks for a device at the given location. "type" is also
* specified to that the right plane will be searched. * specified to that the right plane will be searched.
* *
@ -1756,7 +1758,7 @@ ResGetDevice(pt, type)
{ {
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 *)CD2PTR(ticlient))->deviceList); return (((resInfo *)CD2PTR(ticlient))->deviceList);
} }
else if (TTMaskHasType(&ExtCurStyle->exts_deviceMask, TiGetType(tile))) else if (TTMaskHasType(&ExtCurStyle->exts_deviceMask, TiGetType(tile)))
{ {
@ -1764,7 +1766,7 @@ ResGetDevice(pt, type)
* error and indicates a problem that needs debugging. * error and indicates a problem that needs debugging.
*/ */
if (ticlient != CLIENTDEFAULT) if (ticlient != CLIENTDEFAULT)
return (((tileJunk *)CD2PTR(ticlient))->deviceList); return (((resInfo *)CD2PTR(ticlient))->deviceList);
} }
return NULL; return NULL;
} }

View File

@ -52,9 +52,9 @@ bool ResCalcEastWest();
*/ */
bool bool
ResCalcTileResistance(tile, junk, pendingList, doneList) ResCalcTileResistance(tile, info, pendingList, doneList)
Tile *tile; Tile *tile;
tileJunk *junk; resInfo *info;
resNode **pendingList, **doneList; resNode **pendingList, **doneList;
{ {
@ -67,7 +67,7 @@ ResCalcTileResistance(tile, junk, pendingList, doneList)
merged = FALSE; merged = FALSE;
device = FALSE; device = FALSE;
if ((p1 = junk->breakList) == NULL) return FALSE; if ((p1 = info->breakList) == NULL) return FALSE;
for (; p1; p1 = p1->br_next) for (; p1; p1 = p1->br_next)
{ {
int x = p1->br_loc.p_x; int x = p1->br_loc.p_x;
@ -133,7 +133,7 @@ ResCalcEastWest(tile, pendingList, doneList, resList)
resElement *element; resElement *element;
resNode *currNode; resNode *currNode;
float rArea; float rArea;
tileJunk *junk = (tileJunk *)TiGetClientPTR(tile); resInfo *info = (resInfo *)TiGetClientPTR(tile);
merged = FALSE; merged = FALSE;
height = TOP(tile) - BOTTOM(tile); height = TOP(tile) - BOTTOM(tile);
@ -143,12 +143,12 @@ ResCalcEastWest(tile, pendingList, doneList, resList)
* breakpoint, then return. * breakpoint, then return.
*/ */
p1 = junk->breakList; p1 = info->breakList;
if (p1->br_next == NULL) if (p1->br_next == NULL)
{ {
p1->br_this->rn_float.rn_area += height * (LEFT(tile) - RIGHT(tile)); p1->br_this->rn_float.rn_area += height * (LEFT(tile) - RIGHT(tile));
freeMagic((char *)p1); freeMagic((char *)p1);
junk->breakList = NULL; info->breakList = NULL;
return(merged); return(merged);
} }
@ -164,14 +164,14 @@ ResCalcEastWest(tile, pendingList, doneList, resList)
/* Re-sort nodes left to right. */ /* Re-sort nodes left to right. */
ResSortBreaks(&junk->breakList, TRUE); ResSortBreaks(&info->breakList, TRUE);
/* /*
* Eliminate breakpoints with the same X coordinate and merge * Eliminate breakpoints with the same X coordinate and merge
* their nodes. * their nodes.
*/ */
p2= junk->breakList; p2= info->breakList;
/* Add extra left area to leftmost node */ /* Add extra left area to leftmost node */
@ -213,7 +213,7 @@ ResCalcEastWest(tile, pendingList, doneList, resList)
} }
/* /*
* Was the node used in another junk or breakpoint? * Was the node used in another info or breakpoint?
* If so, replace the old node with the new one. * If so, replace the old node with the new one.
*/ */
@ -278,7 +278,7 @@ ResCalcEastWest(tile, pendingList, doneList, resList)
p2->br_this->rn_float.rn_area += height * (RIGHT(tile) - p2->br_loc.p_x); p2->br_this->rn_float.rn_area += height * (RIGHT(tile) - p2->br_loc.p_x);
freeMagic((char *)p2); freeMagic((char *)p2);
junk->breakList = NULL; info->breakList = NULL;
return merged; return merged;
} }
@ -309,7 +309,7 @@ ResCalcNorthSouth(tile, pendingList, doneList, resList)
resElement *element; resElement *element;
resNode *currNode; resNode *currNode;
float rArea; float rArea;
tileJunk *junk = (tileJunk *)TiGetClientPTR(tile); resInfo *info = (resInfo *)TiGetClientPTR(tile);
merged = FALSE; merged = FALSE;
width = RIGHT(tile) - LEFT(tile); width = RIGHT(tile) - LEFT(tile);
@ -319,17 +319,17 @@ ResCalcNorthSouth(tile, pendingList, doneList, resList)
* breakpoint, then return. * breakpoint, then return.
*/ */
p1 = junk->breakList; p1 = info->breakList;
if (p1->br_next == NULL) if (p1->br_next == NULL)
{ {
p1->br_this->rn_float.rn_area += width * (TOP(tile) - BOTTOM(tile)); p1->br_this->rn_float.rn_area += width * (TOP(tile) - BOTTOM(tile));
freeMagic((char *)p1); freeMagic((char *)p1);
junk->breakList = NULL; info->breakList = NULL;
return(merged); return(merged);
} }
/* Re-sort nodes south to north. */ /* Re-sort nodes south to north. */
ResSortBreaks(&junk->breakList, FALSE); ResSortBreaks(&info->breakList, FALSE);
/* Simplified split tile handling */ /* Simplified split tile handling */
if (IsSplit(tile)) if (IsSplit(tile))
@ -346,7 +346,7 @@ ResCalcNorthSouth(tile, pendingList, doneList, resList)
* their nodes. * their nodes.
*/ */
p2 = junk->breakList; p2 = info->breakList;
/* Add extra left area to leftmost node */ /* Add extra left area to leftmost node */
@ -388,7 +388,7 @@ ResCalcNorthSouth(tile, pendingList, doneList, resList)
} }
/* /*
* Was the node used in another junk or breakpoint? * Was the node used in another info or breakpoint?
* If so, replace the old node with the new one. * If so, replace the old node with the new one.
*/ */
p3 = p2->br_next; p3 = p2->br_next;
@ -449,7 +449,7 @@ ResCalcNorthSouth(tile, pendingList, doneList, resList)
} }
p2->br_this->rn_float.rn_area += width * (TOP(tile) - p2->br_loc.p_y); p2->br_this->rn_float.rn_area += width * (TOP(tile) - p2->br_loc.p_y);
freeMagic((char *)p2); freeMagic((char *)p2);
junk->breakList = NULL; info->breakList = NULL;
return(merged); return(merged);
} }
@ -482,7 +482,7 @@ ResCalcNearDevice(tile, pendingList, doneList, resList)
bool merged; bool merged;
int devcount, devedge, deltax, deltay; int devcount, devedge, deltax, deltay;
Breakpoint *p1, *p2, *p3; Breakpoint *p1, *p2, *p3;
tileJunk *junk = (tileJunk *)TiGetClientPTR(tile); resInfo *info = (resInfo *)TiGetClientPTR(tile);
merged = FALSE; merged = FALSE;
@ -491,10 +491,10 @@ ResCalcNearDevice(tile, pendingList, doneList, resList)
* breakpoint, then return. * breakpoint, then return.
*/ */
if (junk->breakList->br_next == NULL) if (info->breakList->br_next == NULL)
{ {
freeMagic((char *)junk->breakList); freeMagic((char *)info->breakList);
junk->breakList = NULL; info->breakList = NULL;
return(merged); return(merged);
} }
@ -503,7 +503,7 @@ ResCalcNearDevice(tile, pendingList, doneList, resList)
devcount = 0; devcount = 0;
devedge = 0; devedge = 0;
for (p1 = junk->breakList; p1 != NULL; p1 = p1->br_next) for (p1 = info->breakList; p1 != NULL; p1 = p1->br_next)
{ {
if (p1->br_this->rn_why == RES_NODE_DEVICE) if (p1->br_this->rn_why == RES_NODE_DEVICE)
{ {
@ -525,9 +525,9 @@ ResCalcNearDevice(tile, pendingList, doneList, resList)
(devedge & TOPEDGE) == devedge || (devedge & TOPEDGE) == devedge ||
(devedge & BOTTOMEDGE) == devedge) (devedge & BOTTOMEDGE) == devedge)
{ {
ResSortBreaks(&junk->breakList,TRUE); ResSortBreaks(&info->breakList,TRUE);
p2 = NULL; p2 = NULL;
for (p1 = junk->breakList; p1 != NULL; p1 = p1->br_next) for (p1 = info->breakList; p1 != NULL; p1 = p1->br_next)
{ {
if (p1->br_this->rn_why == RES_NODE_DEVICE) if (p1->br_this->rn_why == RES_NODE_DEVICE)
break; break;
@ -587,9 +587,9 @@ ResCalcNearDevice(tile, pendingList, doneList, resList)
} }
/* Re-sort nodes south to north. */ /* Re-sort nodes south to north. */
ResSortBreaks(&junk->breakList, FALSE); ResSortBreaks(&info->breakList, FALSE);
p2 = NULL; p2 = NULL;
for (p1 = junk->breakList; p1 != NULL; p1 = p1->br_next) for (p1 = info->breakList; p1 != NULL; p1 = p1->br_next)
{ {
if (p1->br_this->rn_why == RES_NODE_DEVICE) if (p1->br_this->rn_why == RES_NODE_DEVICE)
{ {
@ -684,17 +684,17 @@ ResCalcNearDevice(tile, pendingList, doneList, resList)
(RIGHT(tile) - LEFT(tile)) > (TOP(tile) - BOTTOM(tile)))) (RIGHT(tile) - LEFT(tile)) > (TOP(tile) - BOTTOM(tile))))
{ {
/* re-sort nodes south to north. */ /* re-sort nodes south to north. */
ResSortBreaks(&junk->breakList, FALSE); ResSortBreaks(&info->breakList, FALSE);
/* eliminate duplicate S/D pointers */ /* eliminate duplicate S/D pointers */
for (p1 = junk->breakList; p1 != NULL; p1 = p1->br_next) for (p1 = info->breakList; p1 != NULL; p1 = p1->br_next)
{ {
if (p1->br_this->rn_why == RES_NODE_DEVICE && if (p1->br_this->rn_why == RES_NODE_DEVICE &&
(p1->br_loc.p_y == BOTTOM(tile) || (p1->br_loc.p_y == BOTTOM(tile) ||
p1->br_loc.p_y == TOP(tile))) p1->br_loc.p_y == TOP(tile)))
{ {
p3 = NULL; p3 = NULL;
p2 = junk->breakList; p2 = info->breakList;
while (p2 != NULL) while (p2 != NULL)
{ {
if (p2->br_this == p1->br_this && p2 != p1 && if (p2->br_this == p1->br_this && p2 != p1 &&
@ -703,9 +703,9 @@ ResCalcNearDevice(tile, pendingList, doneList, resList)
{ {
if (p3 == NULL) if (p3 == NULL)
{ {
junk->breakList = p2->br_next; info->breakList = p2->br_next;
freeMagic((char *) p2); freeMagic((char *) p2);
p2 = junk->breakList; p2 = info->breakList;
} }
else else
{ {
@ -727,14 +727,14 @@ ResCalcNearDevice(tile, pendingList, doneList, resList)
else else
{ {
/* Eliminate duplicate S/D pointers */ /* Eliminate duplicate S/D pointers */
for (p1 = junk->breakList; p1 != NULL; p1 = p1->br_next) for (p1 = info->breakList; p1 != NULL; p1 = p1->br_next)
{ {
if (p1->br_this->rn_why == RES_NODE_DEVICE && if (p1->br_this->rn_why == RES_NODE_DEVICE &&
(p1->br_loc.p_x == LEFT(tile) || (p1->br_loc.p_x == LEFT(tile) ||
p1->br_loc.p_x == RIGHT(tile))) p1->br_loc.p_x == RIGHT(tile)))
{ {
p3 = NULL; p3 = NULL;
p2 = junk->breakList; p2 = info->breakList;
while (p2 != NULL) while (p2 != NULL)
{ {
if (p2->br_this == p1->br_this && p2 != p1 && if (p2->br_this == p1->br_this && p2 != p1 &&
@ -743,9 +743,9 @@ ResCalcNearDevice(tile, pendingList, doneList, resList)
{ {
if (p3 == NULL) if (p3 == NULL)
{ {
junk->breakList = p2->br_next; info->breakList = p2->br_next;
freeMagic((char *) p2); freeMagic((char *) p2);
p2 = junk->breakList; p2 = info->breakList;
} }
else else
{ {
@ -805,7 +805,7 @@ ResDoContacts(contact, nodes, resList)
int y = contact->cp_center.p_y; int y = contact->cp_center.p_y;
resptr = (resNode *) mallocMagic((unsigned) (sizeof(resNode))); resptr = (resNode *) mallocMagic((unsigned) (sizeof(resNode)));
InitializeNode(resptr, x, y, RES_NODE_CONTACT); InitializeResNode(resptr, x, y, RES_NODE_CONTACT);
ResAddToQueue(resptr, nodes); ResAddToQueue(resptr, nodes);
ccell = (cElement *) mallocMagic((unsigned) (sizeof(cElement))); ccell = (cElement *) mallocMagic((unsigned) (sizeof(cElement)));
@ -858,7 +858,7 @@ ResDoContacts(contact, nodes, resList)
Tile *tile = contact->cp_tile[tilenum]; Tile *tile = contact->cp_tile[tilenum];
resptr = (resNode *) mallocMagic((unsigned) (sizeof(resNode))); resptr = (resNode *) mallocMagic((unsigned) (sizeof(resNode)));
InitializeNode(resptr, x, y, RES_NODE_CONTACT); InitializeResNode(resptr, x, y, RES_NODE_CONTACT);
ResAddToQueue(resptr, nodes); ResAddToQueue(resptr, nodes);
/* Add contact pointer to node */ /* Add contact pointer to node */

View File

@ -53,7 +53,7 @@ ResDoneWithNode(resptr)
resResistor *rr1; resResistor *rr1;
resptr2 = NULL; resptr2 = NULL;
resptr->rn_status |= RESTRUE; resptr->rn_status |= RES_TRUE;
status = UNTOUCHED; status = UNTOUCHED;
/* are there any resistors? */ /* are there any resistors? */
@ -93,9 +93,9 @@ ResDoneWithNode(resptr)
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 & RESTRUE) == RESTRUE) if ((resptr2->rn_status & RES_TRUE) == RES_TRUE)
{ {
resptr2->rn_status &= ~RESTRUE; resptr2->rn_status &= ~RES_TRUE;
ResDoneWithNode(resptr2); ResDoneWithNode(resptr2);
} }
resptr2 = NULL; resptr2 = NULL;
@ -108,14 +108,16 @@ ResDoneWithNode(resptr)
/* 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 ((status == UNTOUCHED) && (resptr->rn_te == NULL) &&
&& (status == UNTOUCHED)) !(resptr->rn_why & (RES_NODE_ORIGIN | RES_NODE_SINK)))
status = ResSeriesCheck(resptr); status = ResSeriesCheck(resptr);
if ((status == UNTOUCHED) && (resptr->rn_why != RES_NODE_ORIGIN)) if ((status == UNTOUCHED) &&
!(resptr->rn_why & (RES_NODE_ORIGIN | RES_NODE_SINK)))
status = ResParallelCheck(resptr); status = ResParallelCheck(resptr);
if ((status == UNTOUCHED) && (resptr->rn_why != RES_NODE_ORIGIN)) if ((status == UNTOUCHED) &&
!(resptr->rn_why & (RES_NODE_ORIGIN | RES_NODE_SINK)))
status = ResTriangleCheck(resptr); status = ResTriangleCheck(resptr);
} }
@ -242,9 +244,9 @@ ResSeriesCheck(resptr)
ResEliminateResistor(rr1, &ResResList); ResEliminateResistor(rr1, &ResResList);
ResCleanNode(resptr, TRUE, &ResNodeList, &ResNodeQueue); ResCleanNode(resptr, TRUE, &ResNodeList, &ResNodeQueue);
status = SINGLE; status = SINGLE;
if (resptr2->rn_status & RESTRUE) if (resptr2->rn_status & RES_TRUE)
{ {
resptr2->rn_status &= ~RESTRUE; resptr2->rn_status &= ~RES_TRUE;
ResDoneWithNode(resptr2); ResDoneWithNode(resptr2);
} }
resptr2 = NULL; resptr2 = NULL;
@ -280,9 +282,9 @@ ResSeriesCheck(resptr)
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 & RESTRUE) == RESTRUE) if ((resptr2->rn_status & RES_TRUE) == RES_TRUE)
{ {
resptr2->rn_status &= ~RESTRUE; resptr2->rn_status &= ~RES_TRUE;
ResDoneWithNode(resptr2); ResDoneWithNode(resptr2);
} }
resptr2 = NULL; resptr2 = NULL;
@ -311,9 +313,9 @@ ResSeriesCheck(resptr)
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 & RESTRUE) == RESTRUE) if ((resptr2->rn_status & RES_TRUE) == RES_TRUE)
{ {
resptr2->rn_status &= ~RESTRUE; resptr2->rn_status &= ~RES_TRUE;
ResDoneWithNode(resptr2); ResDoneWithNode(resptr2);
} }
resptr2 = NULL; resptr2 = NULL;
@ -345,9 +347,9 @@ ResSeriesCheck(resptr)
rr1->rr_connection2 = rr2->rr_connection2; rr1->rr_connection2 = rr2->rr_connection2;
ResFixRes(resptr, resptr2, resptr3, rr2, rr1); ResFixRes(resptr, resptr2, resptr3, rr2, rr1);
} }
if ((resptr2->rn_status & RESTRUE) == RESTRUE) if ((resptr2->rn_status & RES_TRUE) == RES_TRUE)
{ {
resptr2->rn_status &= ~RESTRUE; resptr2->rn_status &= ~RES_TRUE;
ResDoneWithNode(resptr2); ResDoneWithNode(resptr2);
} }
resptr2 = NULL; resptr2 = NULL;
@ -376,9 +378,9 @@ ResSeriesCheck(resptr)
rr1->rr_connection2 = rr2->rr_connection1; rr1->rr_connection2 = rr2->rr_connection1;
ResFixRes(resptr, resptr2, resptr3, rr2, rr1); ResFixRes(resptr, resptr2, resptr3, rr2, rr1);
} }
if ((resptr2->rn_status & RESTRUE) == RESTRUE) if ((resptr2->rn_status & RES_TRUE) == RES_TRUE)
{ {
resptr2->rn_status &= ~RESTRUE; resptr2->rn_status &= ~RES_TRUE;
ResDoneWithNode(resptr2); ResDoneWithNode(resptr2);
} }
resptr2 = NULL; resptr2 = NULL;
@ -433,10 +435,10 @@ ResParallelCheck(resptr)
ResFixParallel(r1, r2); ResFixParallel(r1, r2);
status = PARALLEL; status = PARALLEL;
resptr2 = NULL; resptr2 = NULL;
if (resptr3->rn_status & RESTRUE) if (resptr3->rn_status & RES_TRUE)
{ {
resptr2 = resptr3; resptr2 = resptr3;
resptr2->rn_status &= ~RESTRUE; resptr2->rn_status &= ~RES_TRUE;
} }
ResDoneWithNode(resptr); ResDoneWithNode(resptr);
if (resptr2 != NULL) ResDoneWithNode(resptr2); if (resptr2 != NULL) ResDoneWithNode(resptr2);
@ -531,8 +533,8 @@ ResTriangleCheck(resptr)
/* 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); InitializeResNode(n3, resptr->rn_loc.p_x, resptr->rn_loc.p_y, TRIANGLE);
n3->rn_status = FINISHED | RESTRUE | MARKED; n3->rn_status = RES_FINISHED | RES_TRUE | RES_MARKED;
n3->rn_less = NULL; n3->rn_less = NULL;
n3->rn_more = ResNodeList; n3->rn_more = ResNodeList;
@ -580,13 +582,13 @@ ResTriangleCheck(resptr)
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 & RESTRUE) == RESTRUE) if ((n1->rn_status & RES_TRUE) == RES_TRUE)
n1->rn_status &= ~RESTRUE; n1->rn_status &= ~RES_TRUE;
else else
n1 = NULL; n1 = NULL;
if ((n2->rn_status & RESTRUE) == RESTRUE) if ((n2->rn_status & RES_TRUE) == RES_TRUE)
n2->rn_status &= ~RESTRUE; n2->rn_status &= ~RES_TRUE;
else else
n2 = NULL; n2 = NULL;
@ -637,15 +639,18 @@ ResMergeNodes(node1, node2, pendingList, doneList)
return; return;
} }
/* don't want to merge away startpoint */ /* don't want to merge away start or end points */
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;
if (node2->rn_why & RES_NODE_SINK)
node1->rn_why = RES_NODE_SINK;
/* 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 & RES_FINISHED) != RES_FINISHED)
{ {
ResRemoveFromQueue(node1, pendingList); ResRemoveFromQueue(node1, pendingList);
ResAddToQueue(node1, pendingList); ResAddToQueue(node1, pendingList);
@ -654,7 +659,7 @@ ResMergeNodes(node1, node2, pendingList, doneList)
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 & RES_MAXTDI);
/* merge device lists */ /* merge device lists */
workingDev = node2->rn_te; workingDev = node2->rn_te;
@ -680,13 +685,13 @@ ResMergeNodes(node1, node2, pendingList, doneList)
tJunc = workingJunc; tJunc = workingJunc;
for (i = 0; i < TILES_PER_JUNCTION; i++) for (i = 0; i < TILES_PER_JUNCTION; i++)
{ {
tileJunk *junk; resInfo *info;
tile = tJunc->je_thisj->rj_Tile[i]; tile = tJunc->je_thisj->rj_Tile[i];
junk = (tileJunk *) TiGetClientPTR(tile); info = (resInfo *) TiGetClientPTR(tile);
if ((junk->tj_status & RES_TILE_DONE) == FALSE) if ((info->ri_status & RES_TILE_DONE) == FALSE)
ResFixBreakPoint(&junk->breakList, node2, node1); ResFixBreakPoint(&info->breakList, node2, node1);
} }
tJunc->je_thisj->rj_jnode = node1; tJunc->je_thisj->rj_jnode = node1;
workingJunc = workingJunc->je_nextj; workingJunc = workingJunc->je_nextj;
@ -703,13 +708,13 @@ ResMergeNodes(node1, node2, pendingList, doneList)
{ {
if (workingCon->ce_thisc->cp_cnode[i] == node2) if (workingCon->ce_thisc->cp_cnode[i] == node2)
{ {
tileJunk *junk; resInfo *info;
workingCon->ce_thisc->cp_cnode[i] = node1; workingCon->ce_thisc->cp_cnode[i] = node1;
tile =tCon->ce_thisc->cp_tile[i]; tile =tCon->ce_thisc->cp_tile[i];
junk = (tileJunk *) TiGetClientPTR(tile); info = (resInfo *) TiGetClientPTR(tile);
if ((junk->tj_status & RES_TILE_DONE) == FALSE) if ((info->ri_status & RES_TILE_DONE) == FALSE)
ResFixBreakPoint(&junk->breakList, node2, node1); ResFixBreakPoint(&info->breakList, node2, node1);
} }
} }
workingCon = workingCon->ce_nextc; workingCon = workingCon->ce_nextc;
@ -749,7 +754,7 @@ ResMergeNodes(node1, node2, pendingList, doneList)
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 & RES_FINISHED) == RES_FINISHED)
ResRemoveFromQueue(node2, doneList); ResRemoveFromQueue(node2, doneList);
else else
ResRemoveFromQueue(node2, pendingList); ResRemoveFromQueue(node2, pendingList);
@ -859,7 +864,7 @@ ResEliminateResistor(resistor, homelist)
*------------------------------------------------------------------------- *-------------------------------------------------------------------------
* *
* ResCleanNode--removes the linked lists of junctions and contacts after * ResCleanNode--removes the linked lists of junctions and contacts after
* they are no longer needed. If the 'junk' option is used, * they are no longer needed. If the 'info' option is used,
* the node is eradicated. * the node is eradicated.
* *
* Results: * Results:
@ -871,9 +876,9 @@ ResEliminateResistor(resistor, homelist)
*/ */
void void
ResCleanNode(resptr, junk, homelist1, homelist2) ResCleanNode(resptr, info, homelist1, homelist2)
resNode *resptr; resNode *resptr;
int junk; int info;
resNode **homelist1; resNode **homelist1;
resNode **homelist2; resNode **homelist2;
{ {
@ -896,7 +901,7 @@ ResCleanNode(resptr, junk, homelist1, homelist2)
freeMagic((char *)jcell->je_thisj); freeMagic((char *)jcell->je_thisj);
freeMagic((char *)jcell); freeMagic((char *)jcell);
} }
if (junk == TRUE) if (info == TRUE)
{ {
if (resptr->rn_client != (ClientData)NULL) if (resptr->rn_client != (ClientData)NULL)
{ {

View File

@ -33,9 +33,6 @@ static char rcsid[] __attribute__ ((unused)) = "$Header: /usr/cvsroot/magic-8.0/
#define MAXNAME 1000 #define MAXNAME 1000
#define KV_TO_mV 1000000 #define KV_TO_mV 1000000
extern ResExtNode *ResInitializeNode();
/* /*
*------------------------------------------------------------------------- *-------------------------------------------------------------------------
* *
@ -58,7 +55,7 @@ ResPrintExtRes(outextfile, resistors, nodename)
int nodenum=0; int nodenum=0;
char newname[MAXNAME]; char newname[MAXNAME];
HashEntry *entry; HashEntry *entry;
ResExtNode *node, *ResInitializeNode(); ResExtNode *node;
for (; resistors != NULL; resistors = resistors->rr_nextResistor) for (; resistors != NULL; resistors = resistors->rr_nextResistor)
{ {
@ -73,7 +70,7 @@ ResPrintExtRes(outextfile, resistors, nodename)
{ {
(void)sprintf(newname, "%s%s%d", nodename, ".r", nodenum++); (void)sprintf(newname, "%s%s%d", nodename, ".r", nodenum++);
entry = HashFind(&ResNodeTable, newname); entry = HashFind(&ResNodeTable, newname);
node = ResInitializeNode(entry); node = ResExtInitNode(entry);
resistors->rr_connection1->rn_name = node->name; resistors->rr_connection1->rn_name = node->name;
node->oldname = nodename; node->oldname = nodename;
} }
@ -81,7 +78,7 @@ ResPrintExtRes(outextfile, resistors, nodename)
{ {
(void)sprintf(newname, "%s%s%d", nodename, ".r", nodenum++); (void)sprintf(newname, "%s%s%d", nodename, ".r", nodenum++);
entry = HashFind(&ResNodeTable, newname); entry = HashFind(&ResNodeTable, newname);
node = ResInitializeNode(entry); node = ResExtInitNode(entry);
resistors->rr_connection2->rn_name = node->name; resistors->rr_connection2->rn_name = node->name;
node->oldname = nodename; node->oldname = nodename;
} }
@ -222,7 +219,7 @@ ResPrintExtNode(outextfile, nodelist, node)
int nodenum = 0; int nodenum = 0;
char newname[MAXNAME+32], tmpname[MAXNAME], *cp; char newname[MAXNAME+32], tmpname[MAXNAME], *cp;
HashEntry *entry; HashEntry *entry;
ResExtNode *newnode, *ResInitializeNode(); ResExtNode *newnode;
bool DoKillNode = TRUE; bool DoKillNode = TRUE;
bool NeedFix = FALSE; bool NeedFix = FALSE;
resNode *snode; resNode *snode;
@ -271,7 +268,7 @@ ResPrintExtNode(outextfile, nodelist, node)
(void)sprintf(newname, "%s%s%d", tmpname, ".n", nodenum++); (void)sprintf(newname, "%s%s%d", tmpname, ".n", nodenum++);
entry = HashFind(&ResNodeTable, newname); entry = HashFind(&ResNodeTable, newname);
newnode = ResInitializeNode(entry); newnode = ResExtInitNode(entry);
snode->rn_name = newnode->name; snode->rn_name = newnode->name;
newnode->oldname = nodename; newnode->oldname = nodename;
} }
@ -419,16 +416,16 @@ ResPrintFHNodes(fp, nodelist, nodename, nidx, celldef)
else else
{ {
HashEntry *entry; HashEntry *entry;
ResExtNode *simnode; ResExtNode *extnode;
/* If we process another sim file node while doing this */ /* If we process another sim file node while doing this */
/* one, mark it as status "REDUNDANT" so we don't duplicate */ /* one, mark it as status "REDUNDANT" so we don't duplicate */
/* the entry. */ /* the entry. */
entry = HashFind(&ResNodeTable, nodeptr->rn_name); entry = HashFind(&ResNodeTable, nodeptr->rn_name);
simnode = (ResExtNode *)HashGetValue(entry); extnode = (ResExtNode *)HashGetValue(entry);
if (simnode != NULL) if (extnode != NULL)
simnode->status |= REDUNDANT; extnode->status |= REDUNDANT;
} }
resWriteNodeName(fp, nodeptr); resWriteNodeName(fp, nodeptr);

View File

@ -84,8 +84,6 @@ static char rcsid[] __attribute__ ((unused)) = "$Header: /usr/cvsroot/magic-8.0/
#define MAXDIGIT 20 #define MAXDIGIT 20
ResExtNode *ResInitializeNode();
ResExtNode *ResOriginalNodes; /*Linked List of Nodes */ ResExtNode *ResOriginalNodes; /*Linked List of Nodes */
char RDEV_NOATTR[1] = {'0'}; char RDEV_NOATTR[1] = {'0'};
ResFixPoint *ResFixList; ResFixPoint *ResFixList;
@ -202,11 +200,17 @@ ResReadNode(int argc, char *argv[])
ResExtNode *node; ResExtNode *node;
entry = HashFind(&ResNodeTable, argv[NODES_NODENAME]); entry = HashFind(&ResNodeTable, argv[NODES_NODENAME]);
node = ResInitializeNode(entry); node = ResExtInitNode(entry);
node->location.p_x = atoi(argv[NODES_NODEX]); /* If this node was previously read as a port, then don't change the
node->location.p_y = atoi(argv[NODES_NODEY]); * location.
node->type = DBTechNameType(argv[NODES_NODETYPE]); */
if (!(node->status & PORTNODE))
{
node->location.p_x = atoi(argv[NODES_NODEX]);
node->location.p_y = atoi(argv[NODES_NODEY]);
node->type = DBTechNameType(argv[NODES_NODETYPE]);
}
if (node->type == -1) if (node->type == -1)
{ {
@ -237,7 +241,7 @@ ResReadPort(int argc,
ResExtNode *node; ResExtNode *node;
entry = HashFind(&ResNodeTable, argv[PORT_NAME]); entry = HashFind(&ResNodeTable, argv[PORT_NAME]);
node = ResInitializeNode(entry); node = ResExtInitNode(entry);
node->drivepoint.p_x = atoi(argv[PORT_LLX]); node->drivepoint.p_x = atoi(argv[PORT_LLX]);
node->drivepoint.p_y = atoi(argv[PORT_LLY]); node->drivepoint.p_y = atoi(argv[PORT_LLY]);
@ -536,19 +540,19 @@ ResReadCapacitor(int argc,
ResExtNode *node1, *node2; ResExtNode *node1, *node2;
entry1 = HashFind(&ResNodeTable, argv[COUPLETERMINAL1]); entry1 = HashFind(&ResNodeTable, argv[COUPLETERMINAL1]);
node1 = ResInitializeNode(entry1); node1 = ResExtInitNode(entry1);
if (ResOptionsFlags & ResOpt_Signal) if (ResOptionsFlags & ResOpt_Signal)
{ {
node1->capacitance += MagAtof(argv[COUPLEVALUE]); node1->capacitance += MagAtof(argv[COUPLEVALUE]);
entry2 = HashFind(&ResNodeTable, argv[COUPLETERMINAL2]); entry2 = HashFind(&ResNodeTable, argv[COUPLETERMINAL2]);
node2 = ResInitializeNode(entry2); node2 = ResExtInitNode(entry2);
node2->capacitance += MagAtof(argv[COUPLEVALUE]); node2->capacitance += MagAtof(argv[COUPLEVALUE]);
return 0; return 0;
} }
entry2 = HashFind(&ResNodeTable, argv[COUPLETERMINAL2]); entry2 = HashFind(&ResNodeTable, argv[COUPLETERMINAL2]);
node2 = ResInitializeNode(entry2); node2 = ResExtInitNode(entry2);
node1->cap_couple += MagAtof(argv[COUPLEVALUE]); node1->cap_couple += MagAtof(argv[COUPLEVALUE]);
node2->cap_couple += MagAtof(argv[COUPLEVALUE]); node2->cap_couple += MagAtof(argv[COUPLEVALUE]);
@ -625,7 +629,7 @@ ResReadAttribute(ResExtNode *node,
/* /*
*------------------------------------------------------------------------- *-------------------------------------------------------------------------
* *
* ResInitializeNode -- * ResExtInitNode --
* Gets the node corresponding to a given hash table entry. If no * Gets the node corresponding to a given hash table entry. If no
* such node exists, one is created. * such node exists, one is created.
* *
@ -637,7 +641,7 @@ ResReadAttribute(ResExtNode *node,
*/ */
ResExtNode * ResExtNode *
ResInitializeNode(entry) ResExtInitNode(entry)
HashEntry *entry; HashEntry *entry;
{ {
ResExtNode *node; ResExtNode *node;
@ -651,7 +655,6 @@ ResInitializeNode(entry)
node->status = FALSE; node->status = FALSE;
node->forward = (ResExtNode *) NULL; node->forward = (ResExtNode *) NULL;
node->capacitance = 0; node->capacitance = 0;
node->cap_vdd = 0;
node->cap_couple = 0; node->cap_couple = 0;
node->resistance = 0; node->resistance = 0;
node->type = 0; node->type = 0;
@ -662,8 +665,6 @@ 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[1] = NULL;
} }
while (node->status & FORWARD) while (node->status & FORWARD)
{ {

View File

@ -30,7 +30,8 @@ static char rcsid[] __attribute__ ((unused)) = "$Header: /usr/cvsroot/magic-8.0/
#include "utils/utils.h" #include "utils/utils.h"
#include "utils/tech.h" #include "utils/tech.h"
#include "textio/txcommands.h" #include "textio/txcommands.h"
#include "resis/resis.h" #include "commands/commands.h"
#include "resis/resis.h"
#define INITFLATSIZE 1024 #define INITFLATSIZE 1024
#define MAXNAME 1000 #define MAXNAME 1000
@ -70,10 +71,6 @@ FILE *ResFHFile;
int ResPortIndex; /* Port ordering to backannotate into magic */ int ResPortIndex; /* Port ordering to backannotate into magic */
/* external declarations */
extern ResExtNode *ResInitializeNode();
extern CellUse *CmdGetSelectedCell();
/* /*
*------------------------------------------------------------------------- *-------------------------------------------------------------------------
* *
@ -131,7 +128,7 @@ ExtResisForDef(celldef, resisdata)
DBIsSubcircuit(celldef)) DBIsSubcircuit(celldef))
ResCheckExtNodes(celldef, resisdata); ResCheckExtNodes(celldef, resisdata);
if (ResOptionsFlags & ResOpt_Stat) if (ResOptionsFlags & ResOpt_Stats)
ResPrintStats((ResisData *)NULL, ""); ResPrintStats((ResisData *)NULL, "");
} }
@ -280,10 +277,11 @@ CmdExtResis(win, cmd)
"ignore names don't extract these nets", "ignore names don't extract these nets",
"include names extract only these nets", "include names extract only these nets",
"box type extract the signal under the box on layer type", "box type extract the signal under the box on layer type",
"cell cellname extract the network for the cell named cellname", "cell cellname extract the network for the cell named cellname",
"blackbox [on/off] treat subcircuits with ports as black boxes", "blackbox [on/off] treat subcircuits with ports as black boxes",
"fasthenry [freq] extract subcircuit network geometry into .fh file", "fasthenry [freq] extract subcircuit network geometry into .fh file",
"geometry extract network centerline geometry (experimental)", "geometry extract network centerline geometry (experimental)",
"stats print extresist statistics",
"help print this message", "help print this message",
NULL NULL
}; };
@ -293,8 +291,8 @@ typedef enum {
RES_THRESH, RES_TOL, RES_THRESH, RES_TOL,
RES_SIMP, RES_EXTOUT, RES_LUMPED, RES_SILENT, RES_SIMP, RES_EXTOUT, RES_LUMPED, RES_SILENT,
RES_SKIP, RES_IGNORE, RES_INCLUDE, RES_BOX, RES_CELL, RES_SKIP, RES_IGNORE, RES_INCLUDE, RES_BOX, RES_CELL,
RES_BLACKBOX, RES_FASTHENRY, RES_GEOMETRY, RES_HELP, RES_BLACKBOX, RES_FASTHENRY, RES_GEOMETRY, RES_STATS,
RES_RUN RES_HELP, RES_RUN
} ResOptions; } ResOptions;
resisdata = ResInit(); resisdata = ResInit();
@ -324,7 +322,6 @@ typedef enum {
switch (option) switch (option)
{ {
case RES_TOL: case RES_TOL:
ResOptionsFlags |= ResOpt_ExplicitRtol;
if (cmd->tx_argc > 2) if (cmd->tx_argc > 2)
{ {
resisdata->tdiTolerance = MagAtof(cmd->tx_argv[2]); resisdata->tdiTolerance = MagAtof(cmd->tx_argv[2]);
@ -412,6 +409,23 @@ typedef enum {
ResOptionsFlags &= ~ResOpt_Blackbox; ResOptionsFlags &= ~ResOpt_Blackbox;
} }
return; return;
case RES_STATS:
if (cmd->tx_argc == 2)
{
value = (ResOptionsFlags & ResOpt_Stats) ?
TRUE : FALSE;
TxPrintf("%s\n", onOff[value]);
}
else
{
value = Lookup(cmd->tx_argv[2], onOff);
if (value)
ResOptionsFlags |= ResOpt_Stats;
else
ResOptionsFlags &= ~ResOpt_Stats;
}
return;
case RES_SIMP: case RES_SIMP:
if (cmd->tx_argc == 2) if (cmd->tx_argc == 2)
{ {
@ -784,7 +798,7 @@ resPortFunc(scx, lab, tpath, result)
sprintf(nodename, "%s/%s", scx->scx_use->cu_id, lab->lab_text); sprintf(nodename, "%s/%s", scx->scx_use->cu_id, lab->lab_text);
entry = HashFind(&ResNodeTable, nodename); entry = HashFind(&ResNodeTable, nodename);
node = ResInitializeNode(entry); node = ResExtInitNode(entry);
/* Digital outputs are drivers */ /* Digital outputs are drivers */
if (pclass == PORT_CLASS_OUTPUT) node->status |= FORCE; if (pclass == PORT_CLASS_OUTPUT) node->status |= FORCE;
@ -916,7 +930,7 @@ ResCheckPorts(cellDef)
/* We have to make sure it's listed as a separate node */ /* We have to make sure it's listed as a separate node */
/* and a drivepoint. */ /* and a drivepoint. */
node = ResInitializeNode(entry); node = ResExtInitNode(entry);
TxPrintf("Port: name = %s is new node %p\n", TxPrintf("Port: name = %s is new node %p\n",
lab->lab_text, (void *)node); lab->lab_text, (void *)node);
TxPrintf("Location is (%d, %d); drivepoint (%d, %d)\n", TxPrintf("Location is (%d, %d); drivepoint (%d, %d)\n",
@ -1271,42 +1285,44 @@ ResCheckExtNodes(celldef, resisdata)
/* /*
*------------------------------------------------------------------------- *-------------------------------------------------------------------------
* *
* ResFixUpConnections-- Changes the connection to a terminal of the sim * ResFixUpConnections--
* device. The new name is formed by appending .t# to the old name. * Changes the connection to a terminal of a device.
* The new name is formed by appending .t# to the old name.
* The new name is added to the hash table of node names. * The new name is added to the hash table of node names.
* *
* Results:none * Results:
* None.
* *
* Side Effects: Allocates new ResExtNodes. Modifies the terminal connections * Side Effects:
* of ext Devices. * Allocates new ResExtNodes. Modifies the terminal connections
* of devices.
* *
*------------------------------------------------------------------------- *-------------------------------------------------------------------------
*/ */
void void
ResFixUpConnections(simDev, layoutDev, simNode, nodename) ResFixUpConnections(extDev, layoutDev, extNode, nodename)
RDev *simDev; RDev *extDev;
resDevice *layoutDev; resDevice *layoutDev;
ResExtNode *simNode; ResExtNode *extNode;
char *nodename; char *nodename;
{ {
static char newname[MAXNAME], oldnodename[MAXNAME]; static char newname[MAXNAME], oldnodename[MAXNAME];
int notdecremented; int notdecremented;
resNode *gate, *source, *drain, *subs; resNode *gate, *source, *drain, *subs;
/* If we aren't doing output (i.e. this is just a statistical run) */ /* If we aren't doing output (i.e. this is just a statistical run) */
/* don't patch up networks. This cuts down on memory use. */ /* don't patch up networks. This cuts down on memory use. */
if ((ResOptionsFlags & (ResOpt_DoRsmFile | ResOpt_DoExtFile)) == 0) if ((ResOptionsFlags & ResOpt_DoExtFile) == 0)
return; return;
if (simDev->layout == NULL) if (extDev->layout == NULL)
{ {
layoutDev->rd_status |= RES_DEV_SAVE; layoutDev->rd_status |= RES_DEV_SAVE;
simDev->layout = layoutDev; extDev->layout = layoutDev;
} }
simDev->status |= TRUE; extDev->status |= TRUE;
if (strcmp(nodename, oldnodename) != 0) if (strcmp(nodename, oldnodename) != 0)
{ {
strcpy(oldnodename, nodename); strcpy(oldnodename, nodename);
@ -1314,7 +1330,7 @@ ResFixUpConnections(simDev, layoutDev, simNode, nodename)
sprintf(newname, "%s%s%d", nodename, ".t", resNodeNum++); sprintf(newname, "%s%s%d", nodename, ".t", resNodeNum++);
notdecremented = TRUE; notdecremented = TRUE;
if (simDev->gate == simNode) if (extDev->gate == extNode)
{ {
if ((gate = layoutDev->rd_fet_gate) != NULL) if ((gate = layoutDev->rd_fet_gate) != NULL)
{ {
@ -1326,8 +1342,8 @@ ResFixUpConnections(simDev, layoutDev, simNode, nodename)
notdecremented = FALSE; notdecremented = FALSE;
} }
ResFixDevName(newname, GATE, simDev, gate); ResFixDevName(newname, GATE, extDev, gate);
gate->rn_name = simDev->gate->name; gate->rn_name = extDev->gate->name;
sprintf(newname, "%s%s%d", nodename, ".t", resNodeNum++); sprintf(newname, "%s%s%d", nodename, ".t", resNodeNum++);
} }
else else
@ -1335,10 +1351,10 @@ ResFixUpConnections(simDev, layoutDev, simNode, nodename)
TxError("Missing gate connection of device at (%d %d) on net %s\n", TxError("Missing gate connection of device at (%d %d) on net %s\n",
layoutDev->rd_inside.r_xbot, layoutDev->rd_inside.r_ybot, layoutDev->rd_inside.r_xbot, layoutDev->rd_inside.r_ybot,
nodename); nodename);
simNode->status |= DONTKILL; extNode->status |= DONTKILL;
} }
} }
if (simDev->subs == simNode) if (extDev->subs == extNode)
{ {
if ((subs = layoutDev->rd_fet_subs) != NULL) if ((subs = layoutDev->rd_fet_subs) != NULL)
{ {
@ -1347,8 +1363,8 @@ ResFixUpConnections(simDev, layoutDev, simNode, nodename)
resNodeNum--; resNodeNum--;
notdecremented = FALSE; notdecremented = FALSE;
} }
ResFixDevName(newname, SUBS, simDev, subs); ResFixDevName(newname, SUBS, extDev, subs);
subs->rn_name = simDev->subs->name; subs->rn_name = extDev->subs->name;
sprintf(newname, "%s%s%d", nodename, ".t", resNodeNum++); sprintf(newname, "%s%s%d", nodename, ".t", resNodeNum++);
} }
else else
@ -1356,11 +1372,11 @@ ResFixUpConnections(simDev, layoutDev, simNode, nodename)
TxError("Missing substrate connection of device at (%d %d) on net %s\n", TxError("Missing substrate connection of device at (%d %d) on net %s\n",
layoutDev->rd_inside.r_xbot, layoutDev->rd_inside.r_ybot, layoutDev->rd_inside.r_xbot, layoutDev->rd_inside.r_ybot,
nodename); nodename);
simNode->status |= DONTKILL; extNode->status |= DONTKILL;
} }
} }
if (simDev->source == simNode) if (extDev->source == extNode)
{ {
/* Check for devices with only one terminal. If it was cast as drain, */ /* Check for devices with only one terminal. If it was cast as drain, */
/* then swap it with the source so that the code below handles it */ /* then swap it with the source so that the code below handles it */
@ -1372,13 +1388,13 @@ ResFixUpConnections(simDev, layoutDev, simNode, nodename)
layoutDev->rd_fet_drain = (struct resnode *)NULL; layoutDev->rd_fet_drain = (struct resnode *)NULL;
} }
if (simDev->drain == simNode) if (extDev->drain == extNode)
{ {
if ((layoutDev->rd_fet_source != NULL) && if ((layoutDev->rd_fet_source != NULL) &&
(layoutDev->rd_fet_drain == NULL)) (layoutDev->rd_fet_drain == NULL))
{ {
/* Handle source/drain-tied devices */ /* Handle source/drain-tied devices */
if (simDev->drain == simDev->source) if (extDev->drain == extDev->source)
layoutDev->rd_fet_drain = layoutDev->rd_fet_source; layoutDev->rd_fet_drain = layoutDev->rd_fet_source;
} }
@ -1390,12 +1406,12 @@ ResFixUpConnections(simDev, layoutDev, simNode, nodename)
resNodeNum--; resNodeNum--;
notdecremented = FALSE; notdecremented = FALSE;
} }
ResFixDevName(newname, SOURCE, simDev, source); ResFixDevName(newname, SOURCE, extDev, source);
source->rn_name = simDev->source->name; source->rn_name = extDev->source->name;
(void)sprintf(newname, "%s%s%d", nodename, ".t", resNodeNum++); (void)sprintf(newname, "%s%s%d", nodename, ".t", resNodeNum++);
if (drain->rn_name != NULL) resNodeNum--; if (drain->rn_name != NULL) resNodeNum--;
ResFixDevName(newname, DRAIN, simDev, drain); ResFixDevName(newname, DRAIN, extDev, drain);
drain->rn_name = simDev->drain->name; drain->rn_name = extDev->drain->name;
/* one to each */ /* one to each */
} }
else else
@ -1403,7 +1419,7 @@ ResFixUpConnections(simDev, layoutDev, simNode, nodename)
TxError("Missing terminal connection of device at (%d %d) on net %s\n", TxError("Missing terminal connection of device at (%d %d) on net %s\n",
layoutDev->rd_inside.r_xbot, layoutDev->rd_inside.r_ybot, layoutDev->rd_inside.r_xbot, layoutDev->rd_inside.r_ybot,
nodename); nodename);
simNode->status |= DONTKILL; extNode->status |= DONTKILL;
} }
} }
else else
@ -1414,7 +1430,7 @@ ResFixUpConnections(simDev, layoutDev, simNode, nodename)
{ {
if (source != drain) if (source != drain)
{ {
if (drain->rn_why & RES_NODE_ORIGIN) if (drain->rn_why & (RES_NODE_ORIGIN | RES_NODE_SINK))
{ {
ResMergeNodes(drain, source, &ResNodeQueue, ResMergeNodes(drain, source, &ResNodeQueue,
&ResNodeList); &ResNodeList);
@ -1440,8 +1456,8 @@ ResFixUpConnections(simDev, layoutDev, simNode, nodename)
notdecremented = FALSE; notdecremented = FALSE;
} }
} }
ResFixDevName(newname, SOURCE, simDev, source); ResFixDevName(newname, SOURCE, extDev, source);
source->rn_name = simDev->source->name; source->rn_name = extDev->source->name;
} }
else else
@ -1449,11 +1465,11 @@ ResFixUpConnections(simDev, layoutDev, simNode, nodename)
TxError("Missing terminal connection of device at (%d %d) on net %s\n", TxError("Missing terminal connection of device at (%d %d) on net %s\n",
layoutDev->rd_inside.r_xbot, layoutDev->rd_inside.r_ybot, layoutDev->rd_inside.r_xbot, layoutDev->rd_inside.r_ybot,
nodename); nodename);
simNode->status |= DONTKILL; extNode->status |= DONTKILL;
} }
} }
} }
else if (simDev->drain == simNode) else if (extDev->drain == extNode)
{ {
/* Check for devices with only one terminal. If it was cast as source, */ /* Check for devices with only one terminal. If it was cast as source, */
/* then swap it with the drain so that the code below handles it */ /* then swap it with the drain so that the code below handles it */
@ -1471,7 +1487,7 @@ ResFixUpConnections(simDev, layoutDev, simNode, nodename)
{ {
if (drain != source) if (drain != source)
{ {
if (source->rn_why & ORIGIN) if (source->rn_why & (RES_NODE_ORIGIN | RES_NODE_SINK))
{ {
ResMergeNodes(source, drain, &ResNodeQueue, ResMergeNodes(source, drain, &ResNodeQueue,
&ResNodeList); &ResNodeList);
@ -1501,15 +1517,15 @@ ResFixUpConnections(simDev, layoutDev, simNode, nodename)
notdecremented = FALSE; notdecremented = FALSE;
} }
} }
ResFixDevName(newname, DRAIN, simDev, drain); ResFixDevName(newname, DRAIN, extDev, drain);
drain->rn_name = simDev->drain->name; drain->rn_name = extDev->drain->name;
} }
else else
{ {
TxError("Missing terminal connection of device at (%d %d) on net %s\n", TxError("Missing terminal connection of device at (%d %d) on net %s\n",
layoutDev->rd_inside.r_xbot, layoutDev->rd_inside.r_ybot, layoutDev->rd_inside.r_xbot, layoutDev->rd_inside.r_ybot,
nodename); nodename);
simNode->status |= DONTKILL; extNode->status |= DONTKILL;
} }
} }
else else
@ -1545,13 +1561,13 @@ ResFixDevName(line, type, device, layoutnode)
if (layoutnode->rn_name != NULL) if (layoutnode->rn_name != NULL)
{ {
entry = HashFind(&ResNodeTable, layoutnode->rn_name); entry = HashFind(&ResNodeTable, layoutnode->rn_name);
node = ResInitializeNode(entry); node = ResExtInitNode(entry);
} }
else else
{ {
entry = HashFind(&ResNodeTable, line); entry = HashFind(&ResNodeTable, line);
node = ResInitializeNode(entry); node = ResExtInitNode(entry);
} }
tptr = (devPtr *) mallocMagic((unsigned) (sizeof(devPtr))); tptr = (devPtr *) mallocMagic((unsigned) (sizeof(devPtr)));
tptr->thisDev = device; tptr->thisDev = device;

View File

@ -77,7 +77,7 @@ ResSimplifyNet(nodelist, biglist, reslist, tolerance)
if (*nodelist == NULL) return; if (*nodelist == NULL) return;
node = *nodelist; node = *nodelist;
node->rn_status |= MARKED | FINISHED; node->rn_status |= RES_MARKED | RES_FINISHED;
*nodelist = node->rn_more; *nodelist = node->rn_more;
if (node->rn_more != NULL) if (node->rn_more != NULL)
node->rn_more->rn_less = (resNode *) NULL; node->rn_more->rn_less = (resNode *) NULL;
@ -138,7 +138,8 @@ ResSimplifyNet(nodelist, biglist, reslist, tolerance)
* more than 1, delete the current resistor to break the deadlock. * more than 1, delete the current resistor to break the deadlock.
*/ */
if (numreceive == 0 && numdrive == 1 && node->rn_why != RES_NODE_ORIGIN) if (numreceive == 0 && numdrive == 1 &&
!(node->rn_why & (RES_NODE_ORIGIN | RES_NODE_SINK)))
{ {
resistor1->rr_status |= RES_DEADEND; resistor1->rr_status |= RES_DEADEND;
if (resistor1->rr_value < tolerance) if (resistor1->rr_value < tolerance)
@ -155,8 +156,8 @@ ResSimplifyNet(nodelist, biglist, reslist, tolerance)
{ {
if (resisptr->re_thisEl->rr_connection1 == otherNode) if (resisptr->re_thisEl->rr_connection1 == otherNode)
{ {
if ((resisptr->re_thisEl->rr_connection2->rn_status & MARKED) if ((resisptr->re_thisEl->rr_connection2->rn_status & RES_MARKED)
!= MARKED) != RES_MARKED)
{ {
PendingReceivers++; PendingReceivers++;
} }
@ -180,9 +181,9 @@ ResSimplifyNet(nodelist, biglist, reslist, tolerance)
(UnMarkedReceivers == 0 && MarkedReceivers > 1 && (UnMarkedReceivers == 0 && MarkedReceivers > 1 &&
resistor2 == resistor1 && PendingReceivers == 0)) resistor2 == resistor1 && PendingReceivers == 0))
{ {
if (otherNode->rn_status & MARKED) if (otherNode->rn_status & RES_MARKED)
{ {
otherNode->rn_status &= ~MARKED; otherNode->rn_status &= ~RES_MARKED;
ResRemoveFromQueue(otherNode, biglist); ResRemoveFromQueue(otherNode, biglist);
otherNode->rn_less = NULL; otherNode->rn_less = NULL;
otherNode->rn_more = *nodelist; otherNode->rn_more = *nodelist;
@ -208,9 +209,9 @@ ResSimplifyNet(nodelist, biglist, reslist, tolerance)
ResDeleteResPointer(resistor1->rr_connection2, resistor1); ResDeleteResPointer(resistor1->rr_connection2, resistor1);
ResEliminateResistor(resistor1, reslist); ResEliminateResistor(resistor1, reslist);
ResMergeNodes(otherNode, node, nodelist, biglist); ResMergeNodes(otherNode, node, nodelist, biglist);
if (otherNode->rn_status & MARKED) if (otherNode->rn_status & RES_MARKED)
{ {
otherNode->rn_status &= ~MARKED; otherNode->rn_status &= ~RES_MARKED;
ResRemoveFromQueue(otherNode, biglist); ResRemoveFromQueue(otherNode, biglist);
otherNode->rn_less= NULL; otherNode->rn_less= NULL;
otherNode->rn_more = *nodelist; otherNode->rn_more = *nodelist;
@ -287,12 +288,12 @@ ResSimplifyNet(nodelist, biglist, reslist, tolerance)
resisptr->re_nextEl = node2->rn_re; resisptr->re_nextEl = node2->rn_re;
node2->rn_re = resisptr; node2->rn_re = resisptr;
ResEliminateResistor(resistor2, reslist); ResEliminateResistor(resistor2, reslist);
otherNode->rn_status |= (node->rn_status & RN_MAXTDI); otherNode->rn_status |= (node->rn_status & RES_MAXTDI);
ResCleanNode(node, TRUE, biglist, nodelist); ResCleanNode(node, TRUE, biglist, nodelist);
node1->rn_status &= ~RES_DONE_ONCE; node1->rn_status &= ~RES_DONE_ONCE;
if (node1->rn_status & MARKED) if (node1->rn_status & RES_MARKED)
{ {
node1->rn_status &= ~MARKED; node1->rn_status &= ~RES_MARKED;
ResRemoveFromQueue(node1, biglist); ResRemoveFromQueue(node1, biglist);
node1->rn_less = NULL; node1->rn_less = NULL;
node1->rn_more = *nodelist; node1->rn_more = *nodelist;
@ -301,9 +302,9 @@ ResSimplifyNet(nodelist, biglist, reslist, tolerance)
*nodelist = node1; *nodelist = node1;
} }
node2->rn_status &= ~RES_DONE_ONCE; node2->rn_status &= ~RES_DONE_ONCE;
if (node2->rn_status & MARKED) if (node2->rn_status & RES_MARKED)
{ {
node2->rn_status &= ~MARKED; node2->rn_status &= ~RES_MARKED;
ResRemoveFromQueue(node2, biglist); ResRemoveFromQueue(node2, biglist);
node2->rn_less = NULL; node2->rn_less = NULL;
node2->rn_more = *nodelist; node2->rn_more = *nodelist;
@ -334,7 +335,7 @@ ResSimplifyNet(nodelist, biglist, reslist, tolerance)
if (resisptr->re_thisEl->rr_status & RES_DONE_ONCE) if (resisptr->re_thisEl->rr_status & RES_DONE_ONCE)
continue; continue;
if (resisptr->re_thisEl->rr_connection2->rn_status & MARKED) if (resisptr->re_thisEl->rr_connection2->rn_status & RES_MARKED)
{ {
/* /*
* Mark big resistors so we only process them * Mark big resistors so we only process them
@ -343,7 +344,7 @@ ResSimplifyNet(nodelist, biglist, reslist, tolerance)
if (resisptr->re_thisEl->rr_value > tolerance) if (resisptr->re_thisEl->rr_value > tolerance)
resisptr->re_thisEl->rr_status |= RES_DONE_ONCE; resisptr->re_thisEl->rr_status |= RES_DONE_ONCE;
resisptr->re_thisEl->rr_connection2->rn_status &= ~MARKED; resisptr->re_thisEl->rr_connection2->rn_status &= ~RES_MARKED;
ResRemoveFromQueue(resisptr->re_thisEl->rr_connection2, biglist); ResRemoveFromQueue(resisptr->re_thisEl->rr_connection2, biglist);
resisptr->re_thisEl->rr_connection2->rn_less= NULL; resisptr->re_thisEl->rr_connection2->rn_less= NULL;
resisptr->re_thisEl->rr_connection2->rn_more = *nodelist; resisptr->re_thisEl->rr_connection2->rn_more = *nodelist;
@ -527,7 +528,7 @@ ResScrunchNet(reslist, pendingList, biglist, tolerance)
ResEliminateResistor(current, reslist); ResEliminateResistor(current, reslist);
ResAddResistorToList(working, reslist); ResAddResistorToList(working, reslist);
if (node2->rn_why & RES_NODE_ORIGIN) if (node2->rn_why & (RES_NODE_ORIGIN | RES_NODE_SINK))
{ {
ResMergeNodes(node2, node1, pendingList, biglist); ResMergeNodes(node2, node1, pendingList, biglist);
node1 = node2; node1 = node2;
@ -541,7 +542,7 @@ ResScrunchNet(reslist, pendingList, biglist, tolerance)
*/ */
ResRemoveFromQueue(node1, biglist); ResRemoveFromQueue(node1, biglist);
ResAddToQueue(node1, pendingList); ResAddToQueue(node1, pendingList);
node1->rn_status &= ~(RES_DONE_ONCE | FINISHED); node1->rn_status &= ~(RES_DONE_ONCE | RES_FINISHED);
ResDoneWithNode(node1); ResDoneWithNode(node1);
while (*pendingList != NULL) while (*pendingList != NULL)
ResSimplifyNet(pendingList, biglist, reslist, tolerance); ResSimplifyNet(pendingList, biglist, reslist, tolerance);
@ -897,7 +898,7 @@ ResDoSimplify(tolerance,resisdata)
------*/ ------*/
} }
if (ResOriginNode == NULL) if (ResNodeAtOrigin == NULL)
{ {
TxError("Error: Network simplification: Failed to to get origin node.\n"); TxError("Error: Network simplification: Failed to to get origin node.\n");
resisdata->rg_Tdi = 0; resisdata->rg_Tdi = 0;
@ -905,12 +906,12 @@ ResDoSimplify(tolerance,resisdata)
else if (ResOptionsFlags & ResOpt_Tdi) else if (ResOptionsFlags & ResOpt_Tdi)
{ {
if ((resisdata->rg_nodecap != -1) && if ((resisdata->rg_nodecap != -1) &&
(totalcap = ResCalculateChildCapacitance(ResOriginNode)) != -1) (totalcap = ResCalculateChildCapacitance(ResNodeAtOrigin)) != -1)
{ {
RCDelayStuff *rc = (RCDelayStuff *) ResNodeList->rn_client; RCDelayStuff *rc = (RCDelayStuff *) ResNodeList->rn_client;
resisdata->rg_nodecap = totalcap; resisdata->rg_nodecap = totalcap;
ResCalculateTDi(ResOriginNode, (resResistor *)NULL, ResCalculateTDi(ResNodeAtOrigin, (resResistor *)NULL,
resisdata->rg_bigdevres); resisdata->rg_bigdevres);
if (rc != (RCDelayStuff *)NULL) if (rc != (RCDelayStuff *)NULL)
resisdata->rg_Tdi = rc->rc_Tdi; resisdata->rg_Tdi = rc->rc_Tdi;
@ -927,7 +928,7 @@ ResDoSimplify(tolerance,resisdata)
resisdata->rg_Tdi = rc->rc_Tdi; resisdata->rg_Tdi = rc->rc_Tdi;
} }
} }
slownode->rn_status |= RN_MAXTDI; slownode->rn_status |= RES_MAXTDI;
} }
else else
resisdata->rg_Tdi = -1; resisdata->rg_Tdi = -1;
@ -957,11 +958,11 @@ ResDoSimplify(tolerance,resisdata)
for (node = ResNodeList; node != NULL; node = node->rn_more) for (node = ResNodeList; node != NULL; node = node->rn_more)
{ {
if (node->rn_noderes == 0) if (node->rn_noderes == 0)
ResOriginNode = node; ResNodeAtOrigin = node;
node->rn_status |= FINISHED; node->rn_status |= RES_FINISHED;
} }
if (ResOriginNode != NULL) if (ResNodeAtOrigin != NULL)
{ {
/* if Tdi is enabled, prune all branches whose end nodes */ /* if Tdi is enabled, prune all branches whose end nodes */
/* have time constants less than the tolerance. */ /* have time constants less than the tolerance. */
@ -970,22 +971,22 @@ ResDoSimplify(tolerance,resisdata)
resisdata->rg_Tdi != -1 && resisdata->rg_Tdi != -1 &&
rctol != 0) rctol != 0)
{ {
ResPruneTree(ResOriginNode, (rctol + 1) * ResPruneTree(ResNodeAtOrigin, (rctol + 1) *
resisdata->rg_bigdevres * resisdata->rg_nodecap / rctol, resisdata->rg_bigdevres * resisdata->rg_nodecap / rctol,
&ResNodeList, &ResNodeQueue, &ResResList); &ResNodeList, &ResNodeQueue, &ResResList);
} }
ResOriginNode->rn_status &= ~MARKED; ResNodeAtOrigin->rn_status &= ~RES_MARKED;
if (ResOriginNode->rn_less == NULL) if (ResNodeAtOrigin->rn_less == NULL)
ResNodeList = ResOriginNode->rn_more; ResNodeList = ResNodeAtOrigin->rn_more;
else else
ResOriginNode->rn_less->rn_more = ResOriginNode->rn_more; ResNodeAtOrigin->rn_less->rn_more = ResNodeAtOrigin->rn_more;
if (ResOriginNode->rn_more != NULL) if (ResNodeAtOrigin->rn_more != NULL)
ResOriginNode->rn_more->rn_less = ResOriginNode->rn_less; ResNodeAtOrigin->rn_more->rn_less = ResNodeAtOrigin->rn_less;
ResOriginNode->rn_more = NULL; ResNodeAtOrigin->rn_more = NULL;
ResOriginNode->rn_less = NULL; ResNodeAtOrigin->rn_less = NULL;
ResNodeQueue = ResOriginNode; ResNodeQueue = ResNodeAtOrigin;
while (ResNodeQueue != NULL) while (ResNodeQueue != NULL)
ResSimplifyNet(&ResNodeQueue, &ResNodeList, &ResResList, millitolerance); ResSimplifyNet(&ResNodeQueue, &ResNodeList, &ResResList, millitolerance);
@ -1022,16 +1023,16 @@ ResSetPathRes(ResisData *resisdata)
{ {
if (node->rn_noderes == 0) if (node->rn_noderes == 0)
{ {
ResOriginNode = node; ResNodeAtOrigin = node;
node->rn_status |= FINISHED; node->rn_status |= RES_FINISHED;
} }
else else
{ {
node->rn_noderes = RES_INFINITY; node->rn_noderes = RES_INFINITY;
node->rn_status &= ~FINISHED; node->rn_status &= ~RES_FINISHED;
} }
} }
if (ResOriginNode == NULL) if (ResNodeAtOrigin == NULL)
{ {
resDevice *res = ResGetDevice(resisdata->rg_devloc, resisdata->rg_ttype); resDevice *res = ResGetDevice(resisdata->rg_devloc, resisdata->rg_ttype);
if (res == (resDevice *)NULL) if (res == (resDevice *)NULL)
@ -1042,12 +1043,12 @@ ResSetPathRes(ResisData *resisdata)
DBWPrintValue(resisdata->rg_devloc->p_y, (MagWindow *)NULL, FALSE)); DBWPrintValue(resisdata->rg_devloc->p_y, (MagWindow *)NULL, FALSE));
return; return;
} }
ResOriginNode = res->rd_fet_source; ResNodeAtOrigin = res->rd_fet_source;
ResOriginNode->rn_why = RES_NODE_ORIGIN; ResNodeAtOrigin->rn_why = RES_NODE_ORIGIN;
ResOriginNode->rn_noderes = 0; ResNodeAtOrigin->rn_noderes = 0;
} }
ASSERT(ResOriginNode != NULL, "ResDoSimplify"); ASSERT(ResNodeAtOrigin != NULL, "ResDoSimplify");
resPathNode(ResOriginNode); resPathNode(ResNodeAtOrigin);
while (HeapRemoveTop(&ResistorHeap,&he)) while (HeapRemoveTop(&ResistorHeap,&he))
resPathRes((resResistor *)he.he_id); resPathRes((resResistor *)he.he_id);
} }
@ -1058,7 +1059,7 @@ ResSetPathRes(ResisData *resisdata)
* *
* Given node "node", add every resistor connected to the node, and * Given node "node", add every resistor connected to the node, and
* for which the node on the other side has not been processed, to * for which the node on the other side has not been processed, to
* the heap. Node is marked with FINISHED to prevent going 'round * the heap. Node is marked with RES_FINISHED to prevent going 'round
* and 'round loops. * and 'round loops.
*------------------------------------------------------------------------- *-------------------------------------------------------------------------
*/ */
@ -1070,7 +1071,7 @@ resPathNode(node)
{ {
resElement *re; resElement *re;
node->rn_status |= FINISHED; node->rn_status |= RES_FINISHED;
for (re = node->rn_re; re; re = re->re_nextEl) for (re = node->rn_re; re; re = re->re_nextEl)
{ {
resResistor *res = re->re_thisEl; resResistor *res = re->re_thisEl;
@ -1078,7 +1079,7 @@ resPathNode(node)
if (res->rr_status & RES_HEAP) continue; if (res->rr_status & RES_HEAP) continue;
if ((node2 = res->rr_node[0]) == node) node2 = res->rr_node[1]; if ((node2 = res->rr_node[0]) == node) node2 = res->rr_node[1];
if ((node2->rn_status & FINISHED) == 0) if ((node2->rn_status & RES_FINISHED) == 0)
HeapAddInt(&ResistorHeap, node->rn_noderes + res->rr_value, HeapAddInt(&ResistorHeap, node->rn_noderes + res->rr_value,
(char *)res); (char *)res);
} }
@ -1114,8 +1115,8 @@ resPathRes(res)
res->rr_status &= ~RES_MARKED; res->rr_status &= ~RES_MARKED;
node0 = res->rr_node[0]; node0 = res->rr_node[0];
node1 = res->rr_node[1]; node1 = res->rr_node[1];
flag0 = node0->rn_status & FINISHED; flag0 = node0->rn_status & RES_FINISHED;
flag1 = node1->rn_status & FINISHED; flag1 = node1->rn_status & RES_FINISHED;
if (flag0 && flag1) if (flag0 && flag1)
{ {
res->rr_status |= RES_TDI_IGNORE; res->rr_status |= RES_TDI_IGNORE;

View File

@ -93,7 +93,7 @@ ResFirst(tile, dinfo, arg)
* *
* resMultiPlaneTerm -- * resMultiPlaneTerm --
* *
* Callback function to set a junk field * Callback function to set a resInfo field
* *
*-------------------------------------------------------------------------- *--------------------------------------------------------------------------
*/ */
@ -102,13 +102,13 @@ int
resMultiPlaneTerm( resMultiPlaneTerm(
Tile *tile, Tile *tile,
TileType dinfo, // Unused (but should be handled) TileType dinfo, // Unused (but should be handled)
tileJunk *junk2) resInfo *rinfo2)
{ {
tileJunk *Junk; resInfo *Info;
Junk = resAddField(tile); Info = resAddField(tile);
Junk->tj_status |= RES_TILE_SD; Info->ri_status |= RES_TILE_SD;
junk2->sourceEdge |= OTHERPLANE; rinfo2->sourceEdge |= OTHERPLANE;
return 0; return 0;
} }
@ -117,7 +117,7 @@ resMultiPlaneTerm(
* *
* resSubstrateTerm -- * resSubstrateTerm --
* *
* Callback function to set a junk field * Callback function to set a resInfo field
* *
*-------------------------------------------------------------------------- *--------------------------------------------------------------------------
*/ */
@ -128,10 +128,10 @@ resSubstrateTerm(
TileType dinfo, TileType dinfo,
ClientData clientdata) /* (unused) */ ClientData clientdata) /* (unused) */
{ {
tileJunk *Junk; resInfo *Info;
Junk = resAddField(tile); Info = resAddField(tile);
Junk->tj_status |= RES_TILE_SUBS; Info->ri_status |= RES_TILE_SUBS;
return 0; return 0;
} }
@ -168,7 +168,7 @@ ResEach(tile, dinfo, pNum, arg)
/* /*
*------------------------------------------------------------------------- *-------------------------------------------------------------------------
* *
* ResAddPlumbing-- Each tile is a tileJunk structure associated with it * ResAddPlumbing-- Each tile has a resInfo structure associated with it
* to keep track of various things used by the extractor. ResAddPlumbing * to keep track of various things used by the extractor. ResAddPlumbing
* adds this structure and sets the tile's ClientData field to point to it. * adds this structure and sets the tile's ClientData field to point to it.
* If the tile is a device, then a device structure is also added; * If the tile is a device, then a device structure is also added;
@ -188,7 +188,7 @@ ResAddPlumbing(tile, dinfo, arg)
TileType dinfo; TileType dinfo;
ClientData *arg; ClientData *arg;
{ {
tileJunk *Junk, *junk2; resInfo *Info, *rinfo2;
static Stack *resDevStack = NULL; static Stack *resDevStack = NULL;
TileType loctype, t1; TileType loctype, t1;
Tile *tp1, *tp2, *source; Tile *tp1, *tp2, *source;
@ -208,7 +208,7 @@ ResAddPlumbing(tile, dinfo, arg)
loctype = TiGetTypeExact(tile); loctype = TiGetTypeExact(tile);
devptr = ExtCurStyle->exts_device[loctype]; devptr = ExtCurStyle->exts_device[loctype];
junk2 = resAddField(tile); rinfo2 = resAddField(tile);
if (TTMaskHasType(&(ExtCurStyle->exts_deviceMask), loctype)) if (TTMaskHasType(&(ExtCurStyle->exts_deviceMask), loctype))
{ {
int i, nterms, pNum; int i, nterms, pNum;
@ -249,8 +249,8 @@ ResAddPlumbing(tile, dinfo, arg)
resDev->rd_status = 0; resDev->rd_status = 0;
resDev->rd_nextDev = (resDevice *)*arg; resDev->rd_nextDev = (resDevice *)*arg;
*arg = (ClientData)resDev; *arg = (ClientData)resDev;
junk2->deviceList = resDev; rinfo2->deviceList = resDev;
junk2->tj_status |= RES_TILE_DEV; rinfo2->ri_status |= RES_TILE_DEV;
for (i = 0; i < nterms - 2; i++) for (i = 0; i < nterms - 2; i++)
{ {
@ -263,10 +263,10 @@ ResAddPlumbing(tile, dinfo, arg)
if TTMaskHasType(&(devptr->exts_deviceSDTypes[i]), if TTMaskHasType(&(devptr->exts_deviceSDTypes[i]),
TiGetBottomType(tp2)) TiGetBottomType(tp2))
{ {
junk2->sourceEdge |= TOPEDGE; rinfo2->sourceEdge |= TOPEDGE;
source = tp2; source = tp2;
Junk = resAddField(source); Info = resAddField(source);
Junk->tj_status |= RES_TILE_SD; Info->ri_status |= RES_TILE_SD;
break; break;
} }
} }
@ -278,10 +278,10 @@ ResAddPlumbing(tile, dinfo, arg)
if TTMaskHasType(&(devptr->exts_deviceSDTypes[i]), if TTMaskHasType(&(devptr->exts_deviceSDTypes[i]),
TiGetTopType(tp2)) TiGetTopType(tp2))
{ {
junk2->sourceEdge |= BOTTOMEDGE; rinfo2->sourceEdge |= BOTTOMEDGE;
source = tp2; source = tp2;
Junk = resAddField(source); Info = resAddField(source);
Junk->tj_status |= RES_TILE_SD; Info->ri_status |= RES_TILE_SD;
break; break;
} }
} }
@ -293,10 +293,10 @@ ResAddPlumbing(tile, dinfo, arg)
if TTMaskHasType(&(devptr->exts_deviceSDTypes[i]), if TTMaskHasType(&(devptr->exts_deviceSDTypes[i]),
TiGetLeftType(tp2)) TiGetLeftType(tp2))
{ {
junk2->sourceEdge |= RIGHTEDGE; rinfo2->sourceEdge |= RIGHTEDGE;
source = tp2; source = tp2;
Junk = resAddField(source); Info = resAddField(source);
Junk->tj_status |= RES_TILE_SD; Info->ri_status |= RES_TILE_SD;
break; break;
} }
} }
@ -309,9 +309,9 @@ ResAddPlumbing(tile, dinfo, arg)
TiGetRightType(tp2)) TiGetRightType(tp2))
{ {
source = tp2; source = tp2;
Junk = resAddField(source); Info = resAddField(source);
Junk->tj_status |= RES_TILE_SD; Info->ri_status |= RES_TILE_SD;
junk2->sourceEdge |= LEFTEDGE; rinfo2->sourceEdge |= LEFTEDGE;
break; break;
} }
} }
@ -327,7 +327,7 @@ ResAddPlumbing(tile, dinfo, arg)
DBSrPaintArea((Tile *)NULL, DBSrPaintArea((Tile *)NULL,
ResUse->cu_def->cd_planes[pNum], ResUse->cu_def->cd_planes[pNum],
&r, &(devptr->exts_deviceSDTypes[i]), &r, &(devptr->exts_deviceSDTypes[i]),
resMultiPlaneTerm, (ClientData)junk2); resMultiPlaneTerm, (ClientData)rinfo2);
} }
} }
@ -360,10 +360,10 @@ ResAddPlumbing(tile, dinfo, arg)
{ {
if (TiGetBottomType(tp2) == t1) if (TiGetBottomType(tp2) == t1)
{ {
tileJunk *j = resAddField(tp2); resInfo *re = resAddField(tp2);
if ((j->tj_status & RES_TILE_SD) == 0) if ((re->ri_status & RES_TILE_SD) == 0)
{ {
j->tj_status |= RES_TILE_SD; re->ri_status |= RES_TILE_SD;
STACKPUSH((ClientData)tp2, resDevStack); STACKPUSH((ClientData)tp2, resDevStack);
} }
} }
@ -373,10 +373,10 @@ ResAddPlumbing(tile, dinfo, arg)
{ {
if (TiGetTopType(tp2) == t1) if (TiGetTopType(tp2) == t1)
{ {
tileJunk *j = resAddField(tp2); resInfo *re = resAddField(tp2);
if ((j->tj_status & RES_TILE_SD) == 0) if ((re->ri_status & RES_TILE_SD) == 0)
{ {
j->tj_status |= RES_TILE_SD; re->ri_status |= RES_TILE_SD;
STACKPUSH((ClientData)tp2, resDevStack); STACKPUSH((ClientData)tp2, resDevStack);
} }
} }
@ -386,10 +386,10 @@ ResAddPlumbing(tile, dinfo, arg)
{ {
if (TiGetLeftType(tp2) == t1) if (TiGetLeftType(tp2) == t1)
{ {
tileJunk *j = resAddField(tp2); resInfo *re = resAddField(tp2);
if ((j->tj_status & RES_TILE_SD) == 0) if ((re->ri_status & RES_TILE_SD) == 0)
{ {
j->tj_status |= RES_TILE_SD; re->ri_status |= RES_TILE_SD;
STACKPUSH((ClientData)tp2, resDevStack); STACKPUSH((ClientData)tp2, resDevStack);
} }
} }
@ -399,10 +399,10 @@ ResAddPlumbing(tile, dinfo, arg)
{ {
if (TiGetRightType(tp2) == t1) if (TiGetRightType(tp2) == t1)
{ {
tileJunk *j = resAddField(tp2); resInfo *re = resAddField(tp2);
if ((j->tj_status & RES_TILE_SD) == 0) if ((re->ri_status & RES_TILE_SD) == 0)
{ {
j->tj_status |= RES_TILE_SD; re->ri_status |= RES_TILE_SD;
STACKPUSH((ClientData)tp2, resDevStack); STACKPUSH((ClientData)tp2, resDevStack);
} }
} }
@ -430,7 +430,7 @@ ResAddPlumbing(tile, dinfo, arg)
STACKPUSH((ClientData)tile, resDevStack); STACKPUSH((ClientData)tile, resDevStack);
while (!StackEmpty(resDevStack)) while (!StackEmpty(resDevStack))
{ {
tileJunk *j0; resInfo *re0;
tp1 = (Tile *) STACKPOP(resDevStack); tp1 = (Tile *) STACKPOP(resDevStack);
if (IsSplit(tp1)) if (IsSplit(tp1))
@ -446,17 +446,17 @@ ResAddPlumbing(tile, dinfo, arg)
t1 = TiGetTypeExact(tp1); t1 = TiGetTypeExact(tp1);
devptr = ExtCurStyle->exts_device[t1]; devptr = ExtCurStyle->exts_device[t1];
j0 = (tileJunk *) TiGetClientPTR(tp1); re0 = (resInfo *) TiGetClientPTR(tp1);
/* top */ /* top */
for (tp2 = RT(tp1); RIGHT(tp2) > LEFT(tp1); tp2 = BL(tp2)) for (tp2 = RT(tp1); RIGHT(tp2) > LEFT(tp1); tp2 = BL(tp2))
{ {
if ((TiGetBottomType(tp2) == t1) && if ((TiGetBottomType(tp2) == t1) &&
(TiGetClient(tp2) == CLIENTDEFAULT)) (TiGetClient(tp2) == CLIENTDEFAULT))
{ {
Junk = resAddField(tp2); Info = resAddField(tp2);
STACKPUSH((ClientData)tp2, resDevStack); STACKPUSH((ClientData)tp2, resDevStack);
Junk->deviceList = resDev; Info->deviceList = resDev;
Junk->tj_status |= RES_TILE_DEV; Info->ri_status |= RES_TILE_DEV;
/* Update device position to point to the lower-leftmost tile */ /* Update device position to point to the lower-leftmost tile */
if ((tp2->ti_ll.p_x < resDev->rd_inside.r_ll.p_x) || if ((tp2->ti_ll.p_x < resDev->rd_inside.r_ll.p_x) ||
@ -472,9 +472,9 @@ ResAddPlumbing(tile, dinfo, arg)
else if TTMaskHasType(&(devptr->exts_deviceSDTypes[0]), else if TTMaskHasType(&(devptr->exts_deviceSDTypes[0]),
TiGetBottomType(tp2)) TiGetBottomType(tp2))
{ {
Junk = resAddField(tp2); Info = resAddField(tp2);
if (Junk->tj_status & RES_TILE_SD) if (Info->ri_status & RES_TILE_SD)
j0->sourceEdge |= TOPEDGE; re0->sourceEdge |= TOPEDGE;
} }
} }
/* bottom */ /* bottom */
@ -483,10 +483,10 @@ ResAddPlumbing(tile, dinfo, arg)
if ((TiGetTopType(tp2) == t1) && if ((TiGetTopType(tp2) == t1) &&
(TiGetClient(tp2) == CLIENTDEFAULT)) (TiGetClient(tp2) == CLIENTDEFAULT))
{ {
Junk = resAddField(tp2); Info = resAddField(tp2);
STACKPUSH((ClientData)tp2, resDevStack); STACKPUSH((ClientData)tp2, resDevStack);
Junk->deviceList = resDev; Info->deviceList = resDev;
Junk->tj_status |= RES_TILE_DEV; Info->ri_status |= RES_TILE_DEV;
/* Update device position to point to the lower-leftmost tile */ /* Update device position to point to the lower-leftmost tile */
if ((tp2->ti_ll.p_x < resDev->rd_inside.r_ll.p_x) || if ((tp2->ti_ll.p_x < resDev->rd_inside.r_ll.p_x) ||
@ -502,9 +502,9 @@ ResAddPlumbing(tile, dinfo, arg)
else if TTMaskHasType(&(devptr->exts_deviceSDTypes[0]), else if TTMaskHasType(&(devptr->exts_deviceSDTypes[0]),
TiGetTopType(tp2)) TiGetTopType(tp2))
{ {
Junk = resAddField(tp2); Info = resAddField(tp2);
if (Junk->tj_status & RES_TILE_SD) if (Info->ri_status & RES_TILE_SD)
j0->sourceEdge |= BOTTOMEDGE; re0->sourceEdge |= BOTTOMEDGE;
} }
} }
/* right */ /* right */
@ -513,10 +513,10 @@ ResAddPlumbing(tile, dinfo, arg)
if ((TiGetLeftType(tp2) == t1) && if ((TiGetLeftType(tp2) == t1) &&
(TiGetClient(tp2) == CLIENTDEFAULT)) (TiGetClient(tp2) == CLIENTDEFAULT))
{ {
Junk = resAddField(tp2); Info = resAddField(tp2);
STACKPUSH((ClientData)tp2, resDevStack); STACKPUSH((ClientData)tp2, resDevStack);
Junk->deviceList = resDev; Info->deviceList = resDev;
Junk->tj_status |= RES_TILE_DEV; Info->ri_status |= RES_TILE_DEV;
/* Update device position to point to the lower-leftmost tile */ /* Update device position to point to the lower-leftmost tile */
if ((tp2->ti_ll.p_x < resDev->rd_inside.r_ll.p_x) || if ((tp2->ti_ll.p_x < resDev->rd_inside.r_ll.p_x) ||
@ -532,9 +532,9 @@ ResAddPlumbing(tile, dinfo, arg)
else if TTMaskHasType(&(devptr->exts_deviceSDTypes[0]), else if TTMaskHasType(&(devptr->exts_deviceSDTypes[0]),
TiGetLeftType(tp2)) TiGetLeftType(tp2))
{ {
Junk = resAddField(tp2); Info = resAddField(tp2);
if (Junk->tj_status & RES_TILE_SD) if (Info->ri_status & RES_TILE_SD)
j0->sourceEdge |= RIGHTEDGE; re0->sourceEdge |= RIGHTEDGE;
} }
} }
/* left */ /* left */
@ -543,10 +543,10 @@ ResAddPlumbing(tile, dinfo, arg)
if ((TiGetRightType(tp2) == t1) && if ((TiGetRightType(tp2) == t1) &&
(TiGetClient(tp2) == CLIENTDEFAULT)) (TiGetClient(tp2) == CLIENTDEFAULT))
{ {
Junk = resAddField(tp2); Info = resAddField(tp2);
STACKPUSH((ClientData)tp2, resDevStack); STACKPUSH((ClientData)tp2, resDevStack);
Junk->deviceList = resDev; Info->deviceList = resDev;
Junk->tj_status |= RES_TILE_DEV; Info->ri_status |= RES_TILE_DEV;
/* Update device position to point to the lower-leftmost tile */ /* Update device position to point to the lower-leftmost tile */
if ((tp2->ti_ll.p_x < resDev->rd_inside.r_ll.p_x) || if ((tp2->ti_ll.p_x < resDev->rd_inside.r_ll.p_x) ||
@ -562,9 +562,9 @@ ResAddPlumbing(tile, dinfo, arg)
else if TTMaskHasType(&(devptr->exts_deviceSDTypes[0]), else if TTMaskHasType(&(devptr->exts_deviceSDTypes[0]),
TiGetRightType(tp2)) TiGetRightType(tp2))
{ {
Junk = resAddField(tp2); Info = resAddField(tp2);
if (Junk->tj_status & RES_TILE_SD) if (Info->ri_status & RES_TILE_SD)
j0->sourceEdge |= LEFTEDGE; re0->sourceEdge |= LEFTEDGE;
} }
} }
} }
@ -573,10 +573,10 @@ ResAddPlumbing(tile, dinfo, arg)
if (source != (Tile *) NULL) if (source != (Tile *) NULL)
{ {
tileJunk *j = (tileJunk *) TiGetClientPTR(source); resInfo *re = (resInfo *) TiGetClientPTR(source);
STACKPUSH((ClientData)source, resDevStack); STACKPUSH((ClientData)source, resDevStack);
j->tj_status &= ~RES_TILE_SD; re->ri_status &= ~RES_TILE_SD;
} }
while (!StackEmpty(resDevStack)) while (!StackEmpty(resDevStack))
{ {
@ -592,12 +592,12 @@ ResAddPlumbing(tile, dinfo, arg)
/* top */ /* top */
for (tp2 = RT(tp1); RIGHT(tp2) > LEFT(tp1); tp2 = BL(tp2)) for (tp2 = RT(tp1); RIGHT(tp2) > LEFT(tp1); tp2 = BL(tp2))
{ {
tileJunk *j2 = (tileJunk *) TiGetClientPTR(tp2); resInfo *re2 = (resInfo *) TiGetClientPTR(tp2);
if (TiGetBottomType(tp2) == t1) if (TiGetBottomType(tp2) == t1)
{ {
if (j2->tj_status & RES_TILE_SD) if (re2->ri_status & RES_TILE_SD)
{ {
j2->tj_status &= ~RES_TILE_SD; re2->ri_status &= ~RES_TILE_SD;
STACKPUSH((ClientData)tp2, resDevStack); STACKPUSH((ClientData)tp2, resDevStack);
} }
} }
@ -605,12 +605,12 @@ ResAddPlumbing(tile, dinfo, arg)
/* bottom */ /* bottom */
for(tp2 = LB(tp1); LEFT(tp2) < RIGHT(tp1); tp2 = TR(tp2)) for(tp2 = LB(tp1); LEFT(tp2) < RIGHT(tp1); tp2 = TR(tp2))
{ {
tileJunk *j2 = (tileJunk *) TiGetClientPTR(tp2); resInfo *re2 = (resInfo *) TiGetClientPTR(tp2);
if (TiGetTopType(tp2) == t1) if (TiGetTopType(tp2) == t1)
{ {
if (j2->tj_status & RES_TILE_SD) if (re2->ri_status & RES_TILE_SD)
{ {
j2->tj_status &= ~RES_TILE_SD; re2->ri_status &= ~RES_TILE_SD;
STACKPUSH((ClientData)tp2, resDevStack); STACKPUSH((ClientData)tp2, resDevStack);
} }
} }
@ -618,12 +618,12 @@ ResAddPlumbing(tile, dinfo, arg)
/* right */ /* right */
for (tp2 = TR(tp1); TOP(tp2) > BOTTOM(tp1); tp2 = LB(tp2)) for (tp2 = TR(tp1); TOP(tp2) > BOTTOM(tp1); tp2 = LB(tp2))
{ {
tileJunk *j2 = (tileJunk *) TiGetClientPTR(tp2); resInfo *re2 = (resInfo *) TiGetClientPTR(tp2);
if (TiGetLeftType(tp2) == t1) if (TiGetLeftType(tp2) == t1)
{ {
if (j2->tj_status & RES_TILE_SD) if (re2->ri_status & RES_TILE_SD)
{ {
j2->tj_status &= ~RES_TILE_SD; re2->ri_status &= ~RES_TILE_SD;
STACKPUSH((ClientData)tp2, resDevStack); STACKPUSH((ClientData)tp2, resDevStack);
} }
} }
@ -631,12 +631,12 @@ ResAddPlumbing(tile, dinfo, arg)
/* left */ /* left */
for (tp2 = BL(tp1); BOTTOM(tp2) < TOP(tp1); tp2 = RT(tp2)) for (tp2 = BL(tp1); BOTTOM(tp2) < TOP(tp1); tp2 = RT(tp2))
{ {
tileJunk *j2 = (tileJunk *) TiGetClientPTR(tp2); resInfo *re2 = (resInfo *) TiGetClientPTR(tp2);
if (TiGetRightType(tp2) == t1) if (TiGetRightType(tp2) == t1)
{ {
if (j2->tj_status & RES_TILE_SD) if (re2->ri_status & RES_TILE_SD)
{ {
j2->tj_status &= ~RES_TILE_SD; re2->ri_status &= ~RES_TILE_SD;
STACKPUSH((ClientData)tp2, resDevStack); STACKPUSH((ClientData)tp2, resDevStack);
} }
} }
@ -650,7 +650,7 @@ ResAddPlumbing(tile, dinfo, arg)
/* /*
*------------------------------------------------------------------------- *-------------------------------------------------------------------------
* *
* ResRemovePlumbing-- Removes and deallocates all the tileJunk fields. * ResRemovePlumbing-- Removes and deallocates all the resInfo fields.
* *
* Results: returns 0 * Results: returns 0
* *
@ -702,7 +702,7 @@ ResPreProcessDevices(TileList, DeviceList, Def)
{ {
Tile *tile; Tile *tile;
ResDevTile *oldTile; ResDevTile *oldTile;
tileJunk *tstruct; resInfo *tstruct;
TileType tt, residue; TileType tt, residue;
int pNum; int pNum;
@ -735,9 +735,9 @@ ResPreProcessDevices(TileList, DeviceList, Def)
GOTOPOINT(tile, &(TileList->area.r_ll)); GOTOPOINT(tile, &(TileList->area.r_ll));
tt = TiGetType(tile); tt = TiGetType(tile);
tstruct = (tileJunk *) TiGetClientPTR(tile); tstruct = (resInfo *) TiGetClientPTR(tile);
if ((tstruct == (tileJunk *)CLIENTDEFAULT) || if ((tstruct == (resInfo *)CLIENTDEFAULT) ||
(tstruct->deviceList == NULL) || (tstruct->deviceList == NULL) ||
!TTMaskHasType(&ExtCurStyle->exts_deviceMask, tt)) !TTMaskHasType(&ExtCurStyle->exts_deviceMask, tt))
{ {
@ -745,11 +745,11 @@ ResPreProcessDevices(TileList, DeviceList, Def)
TileList->area.r_ll.p_x, TileList->area.r_ll.p_x,
TileList->area.r_ll.p_y); TileList->area.r_ll.p_y);
} }
else if ((tstruct->tj_status & RES_TILE_MARK) == 0) else if ((tstruct->ri_status & RES_TILE_MARK) == 0)
{ {
resDevice *rd = tstruct->deviceList; resDevice *rd = tstruct->deviceList;
tstruct->tj_status |= RES_TILE_MARK; tstruct->ri_status |= RES_TILE_MARK;
rd->rd_perim += TileList->perim; rd->rd_perim += TileList->perim;
rd->rd_length += TileList->overlap; rd->rd_length += TileList->overlap;
rd->rd_area += (TileList->area.r_xtop - TileList->area.r_xbot) rd->rd_area += (TileList->area.r_xtop - TileList->area.r_xbot)
@ -851,17 +851,17 @@ ResRemoveFromQueue(node, list)
node->rn_less = NULL; node->rn_less = NULL;
} }
tileJunk * resInfo *
resAddField(tile) resAddField(tile)
Tile *tile; Tile *tile;
{ {
ClientData ticlient = TiGetClient(tile); ClientData ticlient = TiGetClient(tile);
tileJunk *Junk = (tileJunk *)CD2PTR(ticlient); resInfo *Info = (resInfo *)CD2PTR(ticlient);
if (ticlient == CLIENTDEFAULT) if (ticlient == CLIENTDEFAULT)
{ {
Junk = (tileJunk *) mallocMagic((unsigned) (sizeof(tileJunk))); Info = (resInfo *) mallocMagic((unsigned) (sizeof(resInfo)));
ResJunkInit(Junk); ResInfoInit(Info);
TiSetClientPTR(tile, Junk); TiSetClientPTR(tile, Info);
} }
return Junk; return Info;
} }

View File

@ -1,49 +1,38 @@
/* Header files for resistance extraction */ /* Header files for resistance extraction */
/* Type declarations */
/* contact points: keeps track where contacts are and what tiles they
refer to both before and after processing.
*/
#ifndef _MAGIC__RESIS__RESIS_H #ifndef _MAGIC__RESIS__RESIS_H
#define _MAGIC__RESIS__RESIS_H #define _MAGIC__RESIS__RESIS_H
/*
* Contact points: keeps track where contacts are and what tiles they refer to both
* before and after processing.
*/
#define LAYERS_PER_CONTACT 4 #define LAYERS_PER_CONTACT 4
#define TILES_PER_JUNCTION 2 #define TILES_PER_JUNCTION 2
typedef struct contactpoint typedef struct contactpoint
{ {
struct contactpoint *cp_nextcontact;/* Next contact in linked */ struct contactpoint *cp_nextcontact; /* Next contact in linked list. */
/* list. */ Point cp_center; /* Center of contact */
Point cp_center; /*Center of contact */ Rect cp_rect; /* Tile rectangle */
Rect cp_rect; /* Tile rectangle */ Tile *cp_contactTile; /* The following two keep track of
Tile *cp_contactTile; * the tiles where the contact was
/* * before preprocessing, and the
The following two keep * next contact in that tile's area.
track of the tiles where */
the contact was before Tile *cp_tile[LAYERS_PER_CONTACT];
preprocessing, and the int cp_currentcontact; /* keeps track of tile being processed */
next contact in that tile's TileType cp_type; /* Type of contact */
area. int cp_width; /* Width (in x) of contact region */
*/ int cp_height; /* Height (in y) of contact region */
struct resnode *cp_cnode[LAYERS_PER_CONTACT]; /* this contact's nodes */
Tile *cp_tile[LAYERS_PER_CONTACT]; int cp_status; /* status of processing on this contact */
int cp_currentcontact; /* keeps track of tile
being processed
*/
TileType cp_type; /* Type of contact */
int cp_width; /* Width (in x) of contact region */
int cp_height; /* Height (in y) of contact region */
struct resnode *cp_cnode[LAYERS_PER_CONTACT];/* this contact's nodes */
int cp_status; /* status of processing on
this contact
*/
} ResContactPoint; } ResContactPoint;
typedef struct resistor typedef struct resistor
{ {
struct resistor *rr_nextResistor; /* Doubly linked list pointers */ struct resistor *rr_nextResistor; /* Doubly linked list pointers */
struct resistor *rr_lastResistor; struct resistor *rr_lastResistor;
struct resnode *rr_node[2]; struct resnode *rr_node[2];
float rr_value; /* Resistor's value in milliohms */ float rr_value; /* Resistor's value in milliohms */
@ -81,7 +70,7 @@ typedef struct device
struct resnode **rd_terminals; struct resnode **rd_terminals;
int rd_nterms; /* number of terminals in rt_terminals */ int rd_nterms; /* number of terminals in rt_terminals */
int rd_perim; /* info about device */ int rd_perim; /* info about device */
int rd_area; /* used in .ext and .sim file */ int rd_area; /* used in .ext file */
int rd_length; /* patches. */ int rd_length; /* patches. */
int rd_width; int rd_width;
int rd_tiles; /* number of tiles in device */ int rd_tiles; /* number of tiles in device */
@ -91,8 +80,8 @@ typedef struct device
} resDevice; } resDevice;
/* /*
a junction is formed when two tiles that connect are next to one another. * A junction is formed when two tiles that connect are next to one another.
*/ */
typedef struct junction typedef struct junction
{ {
@ -104,8 +93,8 @@ typedef struct junction
} ResJunction; } ResJunction;
/* /*
* A port is declared for subcircuits; its name overrides any locally- * A port is declared for subcircuits; its name overrides any locally-generated
* generated node name. * node name.
*/ */
typedef struct resport typedef struct resport
@ -117,9 +106,9 @@ typedef struct resport
} resPort; } resPort;
/* /*
?element are 'cons' cells used to make linked lists of their referential * *element are 'cons' (in the LISP sense) cells used to make linked lists of
structures. * their referential structures.
*/ */
typedef struct reselement typedef struct reselement
{ {
@ -153,15 +142,16 @@ typedef struct celement
} cElement; } cElement;
/* /*
Nodes formed from network. These are linked both forwards and backwords * Nodes formed from network. These are linked both forwards and backwards
to other nodes. Lists of devices, resistors, junctions, and contacts * to other nodes. Lists of devices, resistors, junctions, and contacts
corresponding to this node are kept. * corresponding to this node are kept.
*/ */
typedef struct resnode typedef struct resnode
{ {
struct resnode *rn_more; /* doubly linked list pointers */ struct resnode *rn_more; /* doubly linked list pointers */
struct resnode *rn_less; struct resnode *rn_less;
tElement *rn_te; /* widgets connected to this node */ tElement *rn_te; /* widgets connected to this node */
resElement *rn_re; resElement *rn_re;
jElement *rn_je; jElement *rn_je;
cElement *rn_ce; cElement *rn_ce;
@ -194,10 +184,10 @@ typedef struct nelement
} nElement; } nElement;
/* /*
Breakpoints are places on a tile which may serve as sources/sinks of * Breakpoints are places on a tile which may serve as sources/sinks of
current. When resistance is calculated for a tile. this is calculated * current. When resistance is calculated for a tile. this is calculated
between these points. * between these points.
*/ */
typedef struct breakpoint typedef struct breakpoint
{ {
@ -208,31 +198,31 @@ typedef struct breakpoint
} Breakpoint; } Breakpoint;
/* /*
Each tile needs to keep track of the following things associated with it. * Each tile needs to keep track of the following things associated with it.
Since there are too many things to fit in the single ti_client field, * Since there are too many things to fit in the single ti_client field,
this 1 to 6 adaptor is used. * this 1 to 7 adaptor is used.
*/ */
typedef struct tilejunk typedef struct resinfo
{ {
cElement *contactList; /*widgets connected to this tile */ cElement *contactList; /* widgets connected to this tile */
resDevice *deviceList; resDevice *deviceList; /* devices this tile is part of */
resPort *portList; resPort *portList; /* ports connected to this tile */
ResJunction *junctionList; ResJunction *junctionList; /* junctions inside the tile */
Breakpoint *breakList; Breakpoint *breakList; /* breakpoints inside the tile */
int sourceEdge; /* used in device tiles to keep int sourceEdge; /* used in device tiles to keep
* of which diffusion edges are * track of which diffusion edges
* a transistor's source * are a transistor's source
*/ */
int tj_status; /* status of tile processing */ int ri_status; /* status of tile processing */
} tileJunk; } resInfo;
/* ResDevTile keeps track of the location and type of devices. /* ResDevTile keeps track of the location and type of devices.
These areas are painted into our copied def after the tree is totally * These areas are painted into our copied def after the tree is totally
flattened. (They can't be painted right away becasue the copy routine * flattened. (They can't be painted right away becasue the copy routine
uses the new def to keep track of where it is in the design. It is also * uses the new def to keep track of where it is in the design. It is also
used when devices are preproceesed. * used when devices are preproceesed.
*/ */
typedef struct resdevtile typedef struct resdevtile
{ {
@ -244,9 +234,11 @@ typedef struct resdevtile
int overlap; int overlap;
} ResDevTile; } ResDevTile;
/* Linked list structure to use to store the substrate plane from each */ /*
/* extracted CellDef so that they can be returned to the original after */ * Linked list structure to use to store the substrate plane from each
/* extraction. */ * extracted CellDef so that they can be returned to the original after
* extraction.
*/
struct saveList { struct saveList {
Plane *sl_plane; Plane *sl_plane;
@ -292,8 +284,7 @@ typedef struct rcdelaystuff
float rc_Tdi; /* Tdi for node */ float rc_Tdi; /* Tdi for node */
} RCDelayStuff; } RCDelayStuff;
/* More type declarations */
/* Type declarations */
typedef struct rdev typedef struct rdev
{ {
@ -319,45 +310,38 @@ typedef struct rdev
typedef struct resextnode typedef struct resextnode
{ {
struct resextnode *nextnode; /* next node in OriginalNodes */ struct resextnode *nextnode; /* next node in OriginalNodes */
/* linked list. */ /* linked list. */
int status; int status;
struct resextnode *forward; /* If node has been merged, this */ struct resextnode *forward; /* If node has been merged, this */
/* points to the merged node. */ /* points to the merged node. */
float capacitance; /* capacitance between node and */ float capacitance; /* Capacitance between node and */
/* GND for power connections */ /* substrate */
/* and all capacitance for every */ float cap_couple; /* Coupling capacitance */
/* thing else. */ float resistance; /* Lumped resistance */
float cap_vdd; /* capacitance to VDD (used for */ float minsizeres; /* Minimum size resistor allowed */
/* power calculations only */ Point drivepoint; /* optional, user specified drive */
float cap_couple; /* coupling capacitance */
float resistance; /* lumped resistance */
float minsizeres; /* Minimum size resistor allowed */
Point drivepoint; /* optional, user specified drive */
/* point for network. */ /* point for network. */
TileType rs_ttype; /* tiletype of drivepoint */ TileType rs_ttype; /* Tiletype of drivepoint */
Point location; /* location of bottom of leftmost */ Point location; /* Location of bottom of leftmost */
/* tile in the lowest numbered */ /* tile in the lowest numbered */
/* plane contained in the node . */ /* plane contained in the node. */
Rect rs_bbox; /* location of bottom of leftmost */ Rect rs_bbox; /* Location of bottom of leftmost */
/* tile in the lowest numbered */ /* tile in the lowest numbered */
/* plane contained in the node . */ /* plane contained in the node. */
TileType type; /* Tile type of tile at location */ TileType type; /* Tile type of tile at location */
struct devptr *firstDev; /* linked list of devices */ struct devptr *firstDev; /* Linked list of devices */
/* connected to node. */ /* connected to node. */
char *name; /* Pointer to name of node stored */ char *name; /* Pointer to name of node stored */
/* in hash table. */ /* in hash table. */
char *oldname; /* Pointer to previous name of */ char *oldname; /* Pointer to previous name of */
/* node, if it exists */ /* node, if it exists */
tElement *rs_sublist[2]; /* pointers to Gnd and Vdd sub */
/* strate connections,
if they exist */
} ResExtNode; } ResExtNode;
#define RES_SUB_GND 0 #define RES_SUB_GND 0
#define RES_SUB_VDD 1 #define RES_SUB_VDD 1
/* `cons' cell for linked list of devices connected to node */ /* `cons' cell for linked list of devices connected to node */
typedef struct devptr typedef struct devptr
{ {
@ -378,144 +362,131 @@ typedef struct resfixpoint /* Keeps track of where voltage sources are */
char fp_name[1]; char fp_name[1];
} ResFixPoint; } ResFixPoint;
/*
* Multipliers telling what portion of capacitance is to Vdd and what part is
* to ground. Right now, coupling capacitance is counted twice, so
* cap[0] + cap[1] = (c_vdd + c_gnd + 2 * c_couple) / (c_vdd + c_gnd + c_couple);
*/
typedef struct capval typedef struct capval
{ {
float cap[1][2]; /* multipliers telling what portion of capacitance is float cap[1][2];
to Vdd and what part is to ground. Right now,
coupling capacitance is counted twice, so
cap[0]+cap[1] = (c_vdd+c_gnd+2*c_couple)/
(c_vdd+c_gnd+c_couple);
*/
} ResCapVal; } ResCapVal;
/* node flags */ /* Node flags ("rn_status" field) */
#define RES_REACHED_NODE 0x00200000
#define RES_NODE_XADJ 0x00400000
#define RES_NODE_YADJ 0x00800000
/* type of node flags */ #define RES_TRUE 0x00000001
#define RES_NODE_JUNCTION 0x00000001 #define RES_PENDING 0x00000002
#define RES_NODE_DEVICE 0x00000002 #define RES_FINISHED 0x00000004
#define RES_NODE_CONTACT 0x00000004 #define RES_MARKED 0x00000100
#define RES_NODE_ORIGIN 0x00000008 #define RES_MAXTDI 0x00001000
#define RES_DONE_ONCE 0x00002000
#define RES_REACHED_NODE 0x00200000
#define RES_NODE_XADJ 0x00400000
#define RES_NODE_YADJ 0x00800000
/* resistor flags */ /* Resistor flags ("rr_status" field) */
#define RES_DEADEND 0x00001000
#define RES_DONE_ONCE 0x00002000
#define RES_MARKED 0x00000100
#define RES_EW 0x00000200
#define RES_NS 0x00000400
#define RES_DIAGONAL 0x00000800
#define RES_TDI_IGNORE 0x00010000
#define RES_REACHED_RESISTOR 0x00100000
#define RES_HEAP 0x00200000
/* device flags */ #define RES_EW 0x00000200
#define RES_DEV_SAVE 0x00000001 #define RES_NS 0x00000400
#define RES_DIAGONAL 0x00000800
#define RES_DEADEND 0x00001000
#define RES_TDI_IGNORE 0x00010000
#define RES_REACHED_RESISTOR 0x00100000
#define RES_HEAP 0x00200000
/* Note that RES_DONE_ONCE and RES_MARKED are used both for rn_status and
* rr_status, and these bit values must not collide with any other field
* values.
*/
/* Device flags ("rd_status" field) */
#define RES_DEV_SAVE 0x00000001
/* Type of node flags ("why" field) */
#define RES_NODE_JUNCTION 0x00000001
#define RES_NODE_DEVICE 0x00000002
#define RES_NODE_CONTACT 0x00000004
#define RES_NODE_ORIGIN 0x00000008
#define RES_NODE_SINK 0x00000010
/* Flags for tiles ("ri_status" field) */
#define RES_TILE_SUBS 0x01 /* A tile which is part of a substrate region. */
#define RES_TILE_SD 0x02 /* A tile which is part of a source/drain region. */
#define RES_TILE_DEV 0x04 /* A tile which is actually a device */
#define RES_TILE_DONE 0x08 /* Indicates whether tile has been processed */
#define RES_TILE_MARK 0x10 /* A temporary marking flag */
#define RES_TILE_PUSHED 0x20 /* Another temporary marking flag */
/* Tree walking flags */
/* flags for tiles */
/* A tile which is part of a substrate region. */
#define RES_TILE_SUBS 0x01
/* A tile which is part of a source/drain region. */
#define RES_TILE_SD 0x02
/* A tile which is actually a device */
#define RES_TILE_DEV 0x04
/* Indicates whether the tile has been processed or not */
#define RES_TILE_DONE 0x08
/*a temporary marking flag */
#define RES_TILE_MARK 0x10
/*another temporary marking flag */
#define RES_TILE_PUSHED 0x20
/* tree walking flags */
#define RES_LOOP_OK 1 #define RES_LOOP_OK 1
#define RES_NO_LOOP 1 #define RES_NO_LOOP 1
#define RES_DO_LAST 0 #define RES_DO_LAST 0
#define RES_DO_FIRST 1 #define RES_DO_FIRST 1
#define RES_NO_FLAGS 0 #define RES_NO_FLAGS 0
/* Constants (ResExtNode "status" field) */
/* Constants */ #define FORWARD 0x0000010
#define FORWARD 0x0000010 #define SKIP 0x0000020
#define SKIP 0x0000020 #define FORCE 0x0000040
#define FORCE 0x0000040 #define MINSIZE 0x0000080
#define MINSIZE 0x0000080 #define DRIVELOC 0x0000100
#define DRIVELOC 0x0000100 #define PORTNODE 0x0000200
#define PORTNODE 0x0000200 #define REDUNDANT 0x0000400
#define REDUNDANT 0x0000400 #define DONTKILL 0x0000800
#define DONTKILL 0x0000800
/* Capacitance table constants */ /* Capacitance table constants */
#define RES_CAP_GND 0
#define RES_CAP_VDD 1
#define RES_CAP_COUPLE 2
#define OHMSTOMILLIOHMS 1000 #define OHMSTOMILLIOHMS 1000
#define FEMTOTOATTO 1000 #define FEMTOTOATTO 1000
#define ATTOTOFEMTO 0.001 #define ATTOTOFEMTO 0.001
#define UNTOUCHED 0 #define UNTOUCHED 0
#define SERIES 1 #define SERIES 1
#define PARALLEL 2 #define PARALLEL 2
#define LOOP 4 #define LOOP 4
#define SINGLE 8 #define SINGLE 8
#define TRIANGLE 32 #define TRIANGLE 32
#define RESTRUE 1 #define LEFTEDGE 1
#define PENDING 2 #define RIGHTEDGE 4
#define FINISHED 4 #define TOPEDGE 8
#define BOTTOMEDGE 16
#define OTHERPLANE 32
#define LEFTEDGE 1 #define GATE 1
#define RIGHTEDGE 4 #define SOURCE 2
#define TOPEDGE 8 #define DRAIN 3
#define BOTTOMEDGE 16 #define SUBS 4
#define OTHERPLANE 32
#define RN_MAXTDI 0x00001000 /* "rg_status" flag */
#define MARKED 0x00000100 #define DRIVEONLY 0x00001000
#define GATE 1 /* Magic's normal value of infinity is too small---67108863 is only 67K ohms. */
#define SOURCE 2
#define DRAIN 3
#define SUBS 4
#define DRIVEONLY 0x00001000 #define RES_INFINITY 0x3FFFFFFF
#define ORIGIN 0x00000008
/* magic's normal value of infinity is too small- */
/* 67108863 is only 67K ohms. */
#define RES_INFINITY 0x3FFFFFFF
#define ResCheckIntegrity
/* The following turns on and off various options */ /* The following turns on and off various options */
#define ResOpt_ExtractAll 0x00000002 #define ResOpt_ExtractAll 0x0001
#define ResOpt_Simplify 0x00000004 #define ResOpt_Simplify 0x0002
#define ResOpt_DoExtFile 0x00000008 #define ResOpt_DoExtFile 0x0004
#define ResOpt_DoRsmFile 0x00000010 #define ResOpt_DoLumpFile 0x0008
#define ResOpt_DoLumpFile 0x00000020 #define ResOpt_RunSilent 0x0010
#define ResOpt_RunSilent 0x00000040 #define ResOpt_Stats 0x0020
#define ResOpt_ExplicitRtol 0x00000080 #define ResOpt_Tdi 0x0040
#define ResOpt_ExplicitTditol 0x00000100 #define ResOpt_Signal 0x0080
#define ResOpt_Tdi 0x00000200 #define ResOpt_Geometry 0x0100
#define ResOpt_Stat 0x00000400 #define ResOpt_FastHenry 0x0200
#define ResOpt_Power 0x00000800 #define ResOpt_Blackbox 0x0300
#define ResOpt_Signal 0x00001000 #define ResOpt_DoSubstrate 0x0800
#define ResOpt_Pname 0x00002000 #define ResOpt_Box 0x1000
#define ResOpt_Geometry 0x00004000
#define ResOpt_FastHenry 0x00008000
#define ResOpt_Blackbox 0x00010000
#define ResOpt_Dump 0x00020000
#define ResOpt_DoSubstrate 0x00040000
#define ResOpt_CMOS 0x00800000
#define ResOpt_Bipolar 0x01000000
#define ResOpt_Box 0x02000000
#define ResOpt_VDisplay 0x10000000
#define ResOpt_IDisplay 0x20000000
#define ResOpt_PDisplay 0x40000000
/* Assorted Variables */ /* Assorted Variables */
@ -533,7 +504,7 @@ extern resNode *ResNodeList;
extern resDevice *ResDevList; extern resDevice *ResDevList;
extern ResContactPoint *ResContactList; extern ResContactPoint *ResContactList;
extern resNode *ResNodeQueue; extern resNode *ResNodeQueue;
extern resNode *ResOriginNode; extern resNode *ResNodeAtOrigin;
extern resNode *resCurrentNode; extern resNode *resCurrentNode;
extern HashTable ResNodeTable; extern HashTable ResNodeTable;
extern HashTable ResExtDevTable; extern HashTable ResExtDevTable;
@ -548,6 +519,7 @@ extern TileTypeBitMask ResNoMergeMask[NT];
extern int ResPortIndex; extern int ResPortIndex;
/* Routines used by ResReadExt() */ /* Routines used by ResReadExt() */
extern ResisData *ResInit(); extern ResisData *ResInit();
extern int ResReadDevice(); extern int ResReadDevice();
extern int ResReadCapacitor(); extern int ResReadCapacitor();
@ -559,12 +531,14 @@ extern int ResReadSubckt();
extern int ResProcessNode(); extern int ResProcessNode();
extern int ResExtCombineParallel(); extern int ResExtCombineParallel();
extern int dbSrConnectStartFunc(); extern int dbSrConnectStartFunc();
extern int ResEach(),ResAddPlumbing(),ResRemovePlumbing(); extern int ResEach();
extern int ResAddPlumbing();
extern int ResRemovePlumbing();
extern float ResCalculateChildCapacitance(); extern float ResCalculateChildCapacitance();
extern ResDevTile *DBTreeCopyConnectDCS(); extern ResDevTile *DBTreeCopyConnectDCS();
extern Tile *ResFindTile(); extern Tile *ResFindTile();
extern resDevice *ResGetDevice(); extern resDevice *ResGetDevice();
extern tileJunk *resAddField(); extern resInfo *resAddField();
extern int ResCheckPorts(); extern int ResCheckPorts();
extern int ResCheckBlackbox(); extern int ResCheckBlackbox();
extern void ResCheckExtNodes(); extern void ResCheckExtNodes();
@ -575,12 +549,14 @@ extern void ResSortBreaks();
extern Plane *extResPrepSubstrate(); extern Plane *extResPrepSubstrate();
/* C99 compat */ /* C99 compat */
extern void ExtResisForDef(CellDef *celldef, ResisData *resisdata); extern void ExtResisForDef(CellDef *celldef, ResisData *resisdata);
extern char *ResExtGetAttribute(char *sptr); extern char *ResExtGetAttribute(char *sptr);
extern int ResReadFET(int argc, char *argv[]); extern int ResReadFET(int argc, char *argv[]);
extern int ResReadPort(int argc, char *argv[]); extern int ResReadPort(int argc, char *argv[]);
extern char *ResExtGetAttribute(char *sptr); extern char *ResExtGetAttribute(char *sptr);
extern ResExtNode *ResExtInitNode();
extern void ResAddToQueue(); extern void ResAddToQueue();
extern bool ResCalcTileResistance(); extern bool ResCalcTileResistance();
extern void ResCleanNode(); extern void ResCleanNode();
@ -622,10 +598,9 @@ extern int resWalkleft();
extern int resWalkright(); extern int resWalkright();
extern int resWalkup(); extern int resWalkup();
/* Macros */
/* macros */ #define InitializeResNode(node,x,y,why) \
#define InitializeNode(node,x,y,why) \
{\ {\
(node)->rn_te = NULL;\ (node)->rn_te = NULL;\
(node)->rn_id=0;\ (node)->rn_id=0;\
@ -642,21 +617,21 @@ extern int resWalkup();
(node)->rn_re = (resElement *) NULL;\ (node)->rn_re = (resElement *) NULL;\
} }
#define ResJunkInit(Junk) \ #define ResInfoInit(Info) \
{ \ { \
Junk->contactList = (cElement *) NULL; \ Info->contactList = (cElement *) NULL; \
Junk->deviceList = (resDevice *) NULL; \ Info->deviceList = (resDevice *) NULL; \
Junk->junctionList = (ResJunction *) NULL; \ Info->junctionList = (ResJunction *) NULL; \
Junk->breakList = (Breakpoint *) NULL; \ Info->breakList = (Breakpoint *) NULL; \
Junk->portList = (resPort *) NULL; \ Info->portList = (resPort *) NULL; \
Junk->tj_status = FALSE; \ Info->ri_status = FALSE; \
Junk->sourceEdge = 0 ; \ Info->sourceEdge = 0 ; \
} }
#define NEWBREAK(node,tile,px,py,crect)\ #define NEWBREAK(node,tile,px,py,crect)\
{\ {\
Breakpoint *bp;\ Breakpoint *bp;\
tileJunk *jX_ = (tileJunk *)((tile)->ti_client); \ resInfo *jX_ = (resInfo *)((tile)->ti_client); \
bp = (Breakpoint *) mallocMagic((unsigned)(sizeof(Breakpoint))); \ bp = (Breakpoint *) mallocMagic((unsigned)(sizeof(Breakpoint))); \
bp->br_next= jX_->breakList; \ bp->br_next= jX_->breakList; \
bp->br_this = (node); \ bp->br_this = (node); \
@ -669,7 +644,7 @@ extern int resWalkup();
#define NEWPORT(node,tile)\ #define NEWPORT(node,tile)\
{\ {\
resPort *rp;\ resPort *rp;\
tileJunk *pX_ = (tileJunk *)((tile)->ti_client); \ resInfo *pX_ = (resInfo *)((tile)->ti_client); \
rp = (resPort *) mallocMagic((unsigned)(sizeof(resPort))); \ rp = (resPort *) mallocMagic((unsigned)(sizeof(resPort))); \
rp->rp_nextPort = pX_->portList; \ rp->rp_nextPort = pX_->portList; \
rp->rp_bbox = node->rs_bbox; \ rp->rp_bbox = node->rs_bbox; \