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:
parent
727649b308
commit
bad0b67ce8
134
README
134
README
|
|
@ -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.
|
||||||
|
|
|
||||||
|
|
@ -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
|
||||||
|
|
|
||||||
|
|
@ -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);
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -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)
|
||||||
|
|
|
||||||
|
|
@ -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);
|
||||||
|
|
|
||||||
124
resis/ResMain.c
124
resis/ResMain.c
|
|
@ -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;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -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 */
|
||||||
|
|
|
||||||
|
|
@ -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)
|
||||||
{
|
{
|
||||||
|
|
|
||||||
|
|
@ -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);
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -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)
|
||||||
{
|
{
|
||||||
|
|
|
||||||
124
resis/ResRex.c
124
resis/ResRex.c
|
|
@ -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;
|
||||||
|
|
|
||||||
|
|
@ -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;
|
||||||
|
|
|
||||||
184
resis/ResUtils.c
184
resis/ResUtils.c
|
|
@ -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;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
421
resis/resis.h
421
resis/resis.h
|
|
@ -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; \
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue