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.
|
||||
|
||||
---------------------------------------------------------------------
|
||||
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 DOCAPACITANCE 2
|
||||
#define DOCOUPLING 3
|
||||
#define DOLENGTH 4
|
||||
#define DOLOCAL 5
|
||||
#define DORESISTANCE 6
|
||||
#define DOLABELCHECK 7
|
||||
#define DOALIASES 8
|
||||
#define DOUNIQUE 9
|
||||
#define DOEXTRESIST 10
|
||||
#define DOEXTRESIST 4
|
||||
#define DOLENGTH 5
|
||||
#define DOLOCAL 6
|
||||
#define DORESISTANCE 7
|
||||
#define DOLABELCHECK 8
|
||||
#define DOALIASES 9
|
||||
#define DOUNIQUE 10
|
||||
#define DOEXTRESIST2 11
|
||||
|
||||
#define LENCLEAR 0
|
||||
#define LENDRIVER 1
|
||||
|
|
@ -974,13 +975,14 @@ CmdExtract(
|
|||
"all all options",
|
||||
"capacitance extract substrate capacitance",
|
||||
"coupling extract coupling capacitance",
|
||||
"extresist extract resistance",
|
||||
"length compute driver-receiver pathlengths",
|
||||
"local put all generated files in the current directory",
|
||||
"lumped estimate lumped resistance",
|
||||
"labelcheck check for connections through sticky labels",
|
||||
"aliases output all net name aliases",
|
||||
"unique ensure unique node names during extraction",
|
||||
"resistance extract resistance",
|
||||
"resistance extract resistance (same as \"do extresist\")",
|
||||
NULL
|
||||
};
|
||||
static const char * const cmdExtLength[] =
|
||||
|
|
@ -1286,7 +1288,7 @@ CmdExtract(
|
|||
TxPrintf("%s label check\n", OPTSET(EXT_DOLABELCHECK));
|
||||
TxPrintf("%s aliases\n", OPTSET(EXT_DOALIASES));
|
||||
TxPrintf("%s unique\n", OPTSET(EXT_DOUNIQUE));
|
||||
TxPrintf("%s resistance\n", OPTSET(EXT_DOEXTRESIST));
|
||||
TxPrintf("%s resistance (extresist)\n", OPTSET(EXT_DOEXTRESIST));
|
||||
return;
|
||||
#undef OPTSET
|
||||
}
|
||||
|
|
@ -1317,7 +1319,8 @@ CmdExtract(
|
|||
case DOLABELCHECK: option = EXT_DOLABELCHECK; break;
|
||||
case DOALIASES: option = EXT_DOALIASES; break;
|
||||
case DOUNIQUE: option = EXT_DOUNIQUE; break;
|
||||
case DOEXTRESIST: option = EXT_DOEXTRESIST; break;
|
||||
case DOEXTRESIST:
|
||||
case DOEXTRESIST2: option = EXT_DOEXTRESIST; break;
|
||||
case DOLOCAL:
|
||||
/* "extract do local" and "extract no local" are kept for
|
||||
* backwards compatibility, but now effectively implement
|
||||
|
|
|
|||
|
|
@ -46,22 +46,22 @@ resNodeIsPort(node, x, y, tile)
|
|||
Rect *rect;
|
||||
Point p;
|
||||
resPort *pl, *lp;
|
||||
tileJunk *junk = (tileJunk *)TiGetClientPTR(tile);
|
||||
resInfo *info = (resInfo *)TiGetClientPTR(tile);
|
||||
|
||||
p.p_x = x;
|
||||
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);
|
||||
if (GEO_ENCLOSE(&p, rect))
|
||||
{
|
||||
node->rn_name = pl->rp_nodename;
|
||||
if (junk->portList == pl)
|
||||
junk->portList = pl->rp_nextPort;
|
||||
if (info->portList == pl)
|
||||
info->portList = pl->rp_nextPort;
|
||||
else
|
||||
{
|
||||
for (lp = junk->portList; lp && (lp->rp_nextPort != pl);
|
||||
for (lp = info->portList; lp && (lp->rp_nextPort != pl);
|
||||
lp = lp->rp_nextPort);
|
||||
lp->rp_nextPort = pl->rp_nextPort;
|
||||
}
|
||||
|
|
@ -77,7 +77,8 @@ resNodeIsPort(node, x, y, tile)
|
|||
* resAllPortNodes --
|
||||
*
|
||||
* 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;
|
||||
resNode *resptr;
|
||||
resPort *pl;
|
||||
tileJunk *junk = (tileJunk *)TiGetClientPTR(tile);
|
||||
resInfo *info = (resInfo *)TiGetClientPTR(tile);
|
||||
|
||||
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;
|
||||
y = pl->rp_loc.p_y;
|
||||
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_noderes = 0;
|
||||
resptr->rn_name = pl->rp_nodename;
|
||||
|
|
@ -225,7 +226,7 @@ ResEachTile(tile, startpoint)
|
|||
int xj, yj, i;
|
||||
bool merged;
|
||||
tElement *tcell;
|
||||
tileJunk *tstructs= (tileJunk *)TiGetClientPTR(tile);
|
||||
resInfo *tstructs= (resInfo *)TiGetClientPTR(tile);
|
||||
ExtDevice *devptr;
|
||||
int sides;
|
||||
|
||||
|
|
@ -262,7 +263,7 @@ ResEachTile(tile, startpoint)
|
|||
int x = startpoint->p_x;
|
||||
int y = startpoint->p_y;
|
||||
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_noderes = 0;
|
||||
ResAddToQueue(resptr, &ResNodeQueue);
|
||||
|
|
@ -278,7 +279,7 @@ ResEachTile(tile, startpoint)
|
|||
* 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)
|
||||
{
|
||||
|
|
@ -291,7 +292,7 @@ ResEachTile(tile, startpoint)
|
|||
tcell->te_thist = tstructs->deviceList;
|
||||
tcell->te_nextt = NULL;
|
||||
|
||||
InitializeNode(resptr, x, y, RES_NODE_JUNCTION);
|
||||
InitializeResNode(resptr, x, y, RES_NODE_JUNCTION);
|
||||
resptr->rn_te = tcell;
|
||||
ResAddToQueue(resptr, &ResNodeQueue);
|
||||
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);
|
||||
|
||||
|
|
|
|||
|
|
@ -64,7 +64,7 @@ ResSanityChecks(nodename, resistorList, nodeList, devlist)
|
|||
for (node = nodeList; node != NULL; node=node->rn_more)
|
||||
{
|
||||
node->rn_status &= ~RES_REACHED_NODE;
|
||||
if (node->rn_why == RES_NODE_ORIGIN)
|
||||
if (node->rn_why & RES_NODE_ORIGIN)
|
||||
STACKPUSH((ClientData) node, resSanityStack);
|
||||
}
|
||||
for (resistor = resistorList; resistor != NULL; resistor = resistor->rr_nextResistor)
|
||||
|
|
|
|||
|
|
@ -52,7 +52,7 @@ ResNewSDDevice(tile, tp, xj, yj, direction, PendingList)
|
|||
resDevice *resDev;
|
||||
tElement *tcell;
|
||||
int newnode;
|
||||
tileJunk *j;
|
||||
resInfo *ri;
|
||||
|
||||
newnode = FALSE;
|
||||
|
||||
|
|
@ -62,9 +62,9 @@ ResNewSDDevice(tile, tp, xj, yj, direction, PendingList)
|
|||
*/
|
||||
if (TiGetClient(tp) == CLIENTDEFAULT) return;
|
||||
|
||||
j = (tileJunk *) TiGetClientPTR(tp);
|
||||
resDev = j->deviceList;
|
||||
if ((j->sourceEdge & direction) != 0)
|
||||
ri = (resInfo *) TiGetClientPTR(tp);
|
||||
resDev = ri->deviceList;
|
||||
if ((ri->sourceEdge & direction) != 0)
|
||||
{
|
||||
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->te_nextt = NULL;
|
||||
tcell->te_thist = j->deviceList;
|
||||
InitializeNode(resptr, xj, yj, RES_NODE_DEVICE);
|
||||
tcell->te_thist = ri->deviceList;
|
||||
InitializeResNode(resptr, xj, yj, RES_NODE_DEVICE);
|
||||
resptr->rn_te = tcell;
|
||||
ResAddToQueue(resptr, PendingList);
|
||||
}
|
||||
|
|
@ -125,11 +125,11 @@ ResNewSubDevice(tile, tp, xj, yj, direction, PendingList)
|
|||
resDevice *resDev;
|
||||
tElement *tcell;
|
||||
int newnode;
|
||||
tileJunk *j;
|
||||
resInfo *ri;
|
||||
|
||||
newnode = FALSE;
|
||||
j = (tileJunk *) TiGetClientPTR(tp);
|
||||
resDev = j->deviceList;
|
||||
ri = (resInfo *) TiGetClientPTR(tp);
|
||||
resDev = ri->deviceList;
|
||||
|
||||
/* Arrived at a device that has a terminal connected to substrate */
|
||||
/* 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->te_nextt = NULL;
|
||||
tcell->te_thist = j->deviceList;
|
||||
InitializeNode(resptr, xj, yj, RES_NODE_DEVICE);
|
||||
tcell->te_thist = ri->deviceList;
|
||||
InitializeResNode(resptr, xj, yj, RES_NODE_DEVICE);
|
||||
resptr->rn_te = tcell;
|
||||
ResAddToQueue(resptr, PendingList);
|
||||
}
|
||||
|
|
@ -181,8 +181,8 @@ ResProcessJunction(tile, tp, xj, yj, NodeList)
|
|||
ResJunction *junction;
|
||||
resNode *resptr;
|
||||
jElement *jcell;
|
||||
tileJunk *j0 = (tileJunk *)TiGetClientPTR(tile);
|
||||
tileJunk *j2 = (tileJunk *)TiGetClientPTR(tp);
|
||||
resInfo *ri0 = (resInfo *)TiGetClientPTR(tile);
|
||||
resInfo *ri2 = (resInfo *)TiGetClientPTR(tp);
|
||||
|
||||
#ifdef PARANOID
|
||||
if (tile == tp)
|
||||
|
|
@ -191,12 +191,12 @@ ResProcessJunction(tile, tp, xj, yj, NodeList)
|
|||
return;
|
||||
}
|
||||
#endif
|
||||
if (j2->tj_status & RES_TILE_DONE) return;
|
||||
if (ri2->ri_status & RES_TILE_DONE) return;
|
||||
resptr = (resNode *) mallocMagic((unsigned)(sizeof(resNode)));
|
||||
resptr->rn_te = (tElement *) NULL;
|
||||
junction = (ResJunction *) mallocMagic((unsigned)(sizeof(ResJunction)));
|
||||
jcell = (jElement *) mallocMagic((unsigned)(sizeof(jElement)));
|
||||
InitializeNode(resptr, xj, yj, RES_NODE_JUNCTION);
|
||||
InitializeResNode(resptr, xj, yj, RES_NODE_JUNCTION);
|
||||
resptr->rn_je = jcell;
|
||||
ResAddToQueue(resptr, NodeList);
|
||||
|
||||
|
|
@ -208,10 +208,10 @@ ResProcessJunction(tile, tp, xj, yj, NodeList)
|
|||
junction->rj_Tile[1] = tp;
|
||||
junction->rj_loc.p_x =xj;
|
||||
junction->rj_loc.p_y =yj;
|
||||
junction->rj_nextjunction[0] = j0->junctionList;
|
||||
j0->junctionList = junction;
|
||||
junction->rj_nextjunction[1] = j2->junctionList;
|
||||
j2->junctionList = junction;
|
||||
junction->rj_nextjunction[0] = ri0->junctionList;
|
||||
ri0->junctionList = junction;
|
||||
junction->rj_nextjunction[1] = ri2->junctionList;
|
||||
ri2->junctionList = junction;
|
||||
|
||||
NEWBREAK(junction->rj_jnode,tile, junction->rj_loc.p_x,
|
||||
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 */
|
||||
ResContactPoint *ResContactList = NULL; /* Contacts */
|
||||
resNode *ResNodeQueue = NULL; /* Pending nodes */
|
||||
resNode *ResOriginNode = NULL; /* node where R=0 */
|
||||
resNode *ResNodeAtOrigin = NULL; /* node where R=0 */
|
||||
resNode *resCurrentNode;
|
||||
int ResTileCount = 0; /* Number of tiles rn_status */
|
||||
extern ExtRegion *ResFirst();
|
||||
extern Tile *FindStartTile();
|
||||
extern int ResEachTile();
|
||||
extern ResExtNode *ResInitializeNode();
|
||||
TileTypeBitMask ResSDTypesBitMask;
|
||||
TileTypeBitMask ResSubTypesBitMask;
|
||||
|
||||
|
|
@ -184,7 +183,7 @@ ResDissolveContacts(contacts)
|
|||
* ResMakePortBreakpoints --
|
||||
*
|
||||
* 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
|
||||
* not be assumed to be "hanging" nodes.
|
||||
*
|
||||
|
|
@ -205,7 +204,7 @@ ResMakePortBreakpoints(def)
|
|||
int ResAddBreakpointFunc(); /* Forward Declaration */
|
||||
|
||||
HashStartSearch(&hs);
|
||||
while((entry = HashNext(&ResNodeTable,&hs)) != NULL)
|
||||
while((entry = HashNext(&ResNodeTable, &hs)) != NULL)
|
||||
{
|
||||
node = (ResExtNode *)HashGetValue(entry);
|
||||
if (node->status & PORTNODE)
|
||||
|
|
@ -266,7 +265,7 @@ ResMakePortBreakpoints(def)
|
|||
* ResMakeLabelBreakpoints --
|
||||
*
|
||||
* 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
|
||||
* cell will be retained and become the endpoint of a net.
|
||||
*
|
||||
|
|
@ -292,7 +291,7 @@ ResMakeLabelBreakpoints(def, resisdata)
|
|||
if (*(slab->lab_text) == '\0') continue;
|
||||
|
||||
entry = HashFind(&ResNodeTable, slab->lab_text);
|
||||
node = ResInitializeNode(entry);
|
||||
node = ResExtInitNode(entry);
|
||||
|
||||
/* If the drivepoint position changes and the drivepoint is */
|
||||
/* in the "resisdata" record, then make sure the tile type */
|
||||
|
|
@ -344,7 +343,7 @@ ResMakeLabelBreakpoints(def, resisdata)
|
|||
*
|
||||
* 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) */
|
||||
ResExtNode *node;
|
||||
{
|
||||
tileJunk *junk;
|
||||
resInfo *info;
|
||||
|
||||
if (TiGetClient(tile) == CLIENTDEFAULT)
|
||||
return 0;
|
||||
|
|
@ -430,15 +429,15 @@ ResFindNewContactTiles(contacts)
|
|||
if ((IsSplit(tile) && TTMaskHasType(&mask, TiGetRightType(tile)))
|
||||
|| TTMaskHasType(&mask, TiGetLeftType(tile)))
|
||||
{
|
||||
tileJunk *j = (tileJunk *)TiGetClientPTR(tile);
|
||||
resInfo *ri = (resInfo *)TiGetClientPTR(tile);
|
||||
cElement *ce;
|
||||
|
||||
ce = (cElement *) mallocMagic((unsigned) (sizeof(cElement)));
|
||||
contacts->cp_tile[contacts->cp_currentcontact] = tile;
|
||||
ce->ce_thisc = contacts;
|
||||
ce->ce_nextc = j->contactList;
|
||||
ce->ce_nextc = ri->contactList;
|
||||
(contacts->cp_currentcontact) += 1;
|
||||
j->contactList = ce;
|
||||
ri->contactList = ce;
|
||||
}
|
||||
else if (!IsSplit(tile))
|
||||
{
|
||||
|
|
@ -452,15 +451,15 @@ ResFindNewContactTiles(contacts)
|
|||
*/
|
||||
if (TTMaskIntersect(DBResidueMask(ttype), &mask))
|
||||
{
|
||||
tileJunk *j = (tileJunk *)TiGetClientPTR(tile);
|
||||
resInfo *ri = (resInfo *)TiGetClientPTR(tile);
|
||||
cElement *ce;
|
||||
|
||||
ce = (cElement *) mallocMagic((unsigned) (sizeof(cElement)));
|
||||
contacts->cp_tile[contacts->cp_currentcontact] = tile;
|
||||
ce->ce_thisc = contacts;
|
||||
ce->ce_nextc = j->contactList;
|
||||
ce->ce_nextc = ri->contactList;
|
||||
(contacts->cp_currentcontact) += 1;
|
||||
j->contactList = ce;
|
||||
ri->contactList = ce;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -524,7 +523,7 @@ ResProcessTiles(resisdata, origin)
|
|||
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
|
||||
* because additional junctions or contacts were added
|
||||
*/
|
||||
|
|
@ -542,16 +541,14 @@ ResProcessTiles(resisdata, origin)
|
|||
for (tilenum = 0; tilenum < TILES_PER_JUNCTION; 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;
|
||||
merged |= ResEachTile(tile, (Point *)NULL);
|
||||
}
|
||||
if (merged & ORIGIN) break;
|
||||
}
|
||||
if (merged & ORIGIN) break;
|
||||
rj->rj_status = TRUE;
|
||||
}
|
||||
}
|
||||
|
|
@ -562,16 +559,15 @@ ResProcessTiles(resisdata, origin)
|
|||
{
|
||||
ResContactPoint *cp = workingc->ce_thisc;
|
||||
|
||||
if (merged & ORIGIN) break;
|
||||
if (cp->cp_status == FALSE)
|
||||
{
|
||||
int newstatus = TRUE;
|
||||
for (tilenum = 0; tilenum < cp->cp_currentcontact; 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)
|
||||
{
|
||||
|
|
@ -583,9 +579,7 @@ ResProcessTiles(resisdata, origin)
|
|||
newstatus = FALSE;
|
||||
}
|
||||
}
|
||||
if (merged & ORIGIN) break;
|
||||
}
|
||||
if (merged & ORIGIN) break;
|
||||
cp->cp_status = newstatus;
|
||||
}
|
||||
}
|
||||
|
|
@ -601,15 +595,15 @@ ResProcessTiles(resisdata, origin)
|
|||
ResRemoveFromQueue(resptr2, &ResNodeQueue);
|
||||
resptr2->rn_more = ResNodeList;
|
||||
resptr2->rn_less = NULL;
|
||||
resptr2->rn_status &= ~PENDING;
|
||||
resptr2->rn_status |= FINISHED | MARKED;
|
||||
resptr2->rn_status &= ~RES_PENDING;
|
||||
resptr2->rn_status |= RES_FINISHED | RES_MARKED;
|
||||
if (ResNodeList != NULL)
|
||||
{
|
||||
ResNodeList->rn_less = resptr2;
|
||||
}
|
||||
if (resptr2->rn_noderes == 0)
|
||||
{
|
||||
ResOriginNode=resptr2;
|
||||
ResNodeAtOrigin = resptr2;
|
||||
}
|
||||
ResNodeList = resptr2;
|
||||
ResCleanNode(resptr2, FALSE, &ResNodeList, &ResNodeQueue);
|
||||
|
|
@ -688,7 +682,7 @@ ResCalcPerimOverlap(tile, dev)
|
|||
* resMakeDevFunc --
|
||||
*
|
||||
* Callback function from ResExtractNet. For each device in a node's
|
||||
* device list pulled from the .sim file, find the tile(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
|
||||
* 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 */
|
||||
/* 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 */
|
||||
/* devices (like transistors vs. MiM caps). */
|
||||
|
||||
|
|
@ -1014,7 +1008,7 @@ ResExtractNet(node, resisdata, cellname)
|
|||
ResDevList = NULL;
|
||||
ResNodeQueue = NULL;
|
||||
ResContactList = NULL;
|
||||
ResOriginNode = NULL;
|
||||
ResNodeAtOrigin = NULL;
|
||||
|
||||
/* Pass back network pointers */
|
||||
|
||||
|
|
@ -1169,7 +1163,7 @@ ResExtractNet(node, resisdata, cellname)
|
|||
|
||||
ResDissolveContacts(ResContactList);
|
||||
|
||||
/* Add "junk" fields to tiles */
|
||||
/* Add "resInfo" fields to tiles */
|
||||
|
||||
for (pNum = PL_TECHDEPBASE; pNum < DBNumPlanes; pNum++)
|
||||
{
|
||||
|
|
@ -1182,10 +1176,17 @@ ResExtractNet(node, resisdata, cellname)
|
|||
(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);
|
||||
ResMakeLabelBreakpoints(ResUse->cu_def, resisdata);
|
||||
|
||||
/* Finish preprocessing. */
|
||||
|
||||
ResFindNewContactTiles(ResContactList);
|
||||
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.
|
||||
* 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
|
||||
* for adjoining diffusion. The diffusion tile is returned.
|
||||
*
|
||||
|
|
@ -1450,8 +1451,9 @@ FindStartTile(resisdata, SourcePoint)
|
|||
else
|
||||
{
|
||||
const ClientData ticlient = TiGetClient(tp);
|
||||
const tileJunk *tj = (tileJunk *)CD2PTR(ticlient);
|
||||
if (ticlient != CLIENTDEFAULT && tj->tj_status & RES_TILE_DEV)
|
||||
const resInfo *rinfo = (resInfo *)CD2PTR(ticlient);
|
||||
|
||||
if (ticlient != CLIENTDEFAULT && rinfo->ri_status & RES_TILE_DEV)
|
||||
complex = TRUE;
|
||||
}
|
||||
}
|
||||
|
|
@ -1471,8 +1473,8 @@ FindStartTile(resisdata, SourcePoint)
|
|||
else
|
||||
{
|
||||
const ClientData ticlient = TiGetClient(tp);
|
||||
const tileJunk *tj = (tileJunk *)CD2PTR(ticlient);
|
||||
if (ticlient != CLIENTDEFAULT && tj->tj_status & RES_TILE_DEV)
|
||||
const resInfo *rinfo = (resInfo *)CD2PTR(ticlient);
|
||||
if (ticlient != CLIENTDEFAULT && rinfo->ri_status & RES_TILE_DEV)
|
||||
complex = TRUE;
|
||||
}
|
||||
}
|
||||
|
|
@ -1492,8 +1494,8 @@ FindStartTile(resisdata, SourcePoint)
|
|||
else
|
||||
{
|
||||
const ClientData ticlient = TiGetClient(tp);
|
||||
const tileJunk *tj = (tileJunk *)CD2PTR(ticlient);
|
||||
if (ticlient != CLIENTDEFAULT && tj->tj_status & RES_TILE_DEV)
|
||||
const resInfo *rinfo = (resInfo *)CD2PTR(ticlient);
|
||||
if (ticlient != CLIENTDEFAULT && rinfo->ri_status & RES_TILE_DEV)
|
||||
complex = TRUE;
|
||||
}
|
||||
}
|
||||
|
|
@ -1513,8 +1515,8 @@ FindStartTile(resisdata, SourcePoint)
|
|||
else
|
||||
{
|
||||
const ClientData ticlient = TiGetClient(tp);
|
||||
const tileJunk *tj = (tileJunk *)CD2PTR(ticlient);
|
||||
if (ticlient != CLIENTDEFAULT && tj->tj_status & RES_TILE_DEV)
|
||||
const resInfo *rinfo = (resInfo *)CD2PTR(ticlient);
|
||||
if (ticlient != CLIENTDEFAULT && rinfo->ri_status & RES_TILE_DEV)
|
||||
complex = TRUE;
|
||||
}
|
||||
}
|
||||
|
|
@ -1527,7 +1529,7 @@ FindStartTile(resisdata, SourcePoint)
|
|||
|
||||
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);
|
||||
while (!StackEmpty(devStack))
|
||||
{
|
||||
|
|
@ -1554,12 +1556,12 @@ FindStartTile(resisdata, SourcePoint)
|
|||
const ClientData ticlient = TiGetClient(tp);
|
||||
if (ticlient != CLIENTDEFAULT)
|
||||
{
|
||||
tileJunk *tj = (tileJunk *)CD2PTR(ticlient);
|
||||
if (tj->tj_status & RES_TILE_DEV)
|
||||
resInfo *rinfo = (resInfo *)CD2PTR(ticlient);
|
||||
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);
|
||||
}
|
||||
}
|
||||
|
|
@ -1588,12 +1590,12 @@ FindStartTile(resisdata, SourcePoint)
|
|||
const ClientData ticlient = TiGetClient(tp);
|
||||
if (ticlient != CLIENTDEFAULT)
|
||||
{
|
||||
tileJunk *tj = (tileJunk *)CD2PTR(ticlient);
|
||||
if (tj->tj_status & RES_TILE_DEV)
|
||||
resInfo *rinfo = (resInfo *)CD2PTR(ticlient);
|
||||
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);
|
||||
}
|
||||
}
|
||||
|
|
@ -1622,12 +1624,12 @@ FindStartTile(resisdata, SourcePoint)
|
|||
const ClientData ticlient = TiGetClient(tp);
|
||||
if (ticlient != CLIENTDEFAULT)
|
||||
{
|
||||
tileJunk *tj = (tileJunk *)CD2PTR(ticlient);
|
||||
if (tj->tj_status & RES_TILE_DEV)
|
||||
resInfo *rinfo = (resInfo *)CD2PTR(ticlient);
|
||||
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);
|
||||
}
|
||||
}
|
||||
|
|
@ -1656,12 +1658,12 @@ FindStartTile(resisdata, SourcePoint)
|
|||
const ClientData ticlient = TiGetClient(tp);
|
||||
if (ticlient != CLIENTDEFAULT)
|
||||
{
|
||||
tileJunk *tj = (tileJunk *)CD2PTR(ticlient);
|
||||
if (tj->tj_status & RES_TILE_DEV)
|
||||
resInfo *rinfo = (resInfo *)CD2PTR(ticlient);
|
||||
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);
|
||||
}
|
||||
}
|
||||
|
|
@ -1720,7 +1722,7 @@ FindStartTile(resisdata, SourcePoint)
|
|||
*-------------------------------------------------------------------------
|
||||
*
|
||||
* 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
|
||||
* specified to that the right plane will be searched.
|
||||
*
|
||||
|
|
@ -1756,7 +1758,7 @@ ResGetDevice(pt, type)
|
|||
{
|
||||
if (TTMaskHasType(&ExtCurStyle->exts_deviceMask, TiGetLeftType(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)))
|
||||
{
|
||||
|
|
@ -1764,7 +1766,7 @@ ResGetDevice(pt, type)
|
|||
* error and indicates a problem that needs debugging.
|
||||
*/
|
||||
if (ticlient != CLIENTDEFAULT)
|
||||
return (((tileJunk *)CD2PTR(ticlient))->deviceList);
|
||||
return (((resInfo *)CD2PTR(ticlient))->deviceList);
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -52,9 +52,9 @@ bool ResCalcEastWest();
|
|||
*/
|
||||
|
||||
bool
|
||||
ResCalcTileResistance(tile, junk, pendingList, doneList)
|
||||
ResCalcTileResistance(tile, info, pendingList, doneList)
|
||||
Tile *tile;
|
||||
tileJunk *junk;
|
||||
resInfo *info;
|
||||
resNode **pendingList, **doneList;
|
||||
|
||||
{
|
||||
|
|
@ -67,7 +67,7 @@ ResCalcTileResistance(tile, junk, pendingList, doneList)
|
|||
merged = FALSE;
|
||||
device = FALSE;
|
||||
|
||||
if ((p1 = junk->breakList) == NULL) return FALSE;
|
||||
if ((p1 = info->breakList) == NULL) return FALSE;
|
||||
for (; p1; p1 = p1->br_next)
|
||||
{
|
||||
int x = p1->br_loc.p_x;
|
||||
|
|
@ -133,7 +133,7 @@ ResCalcEastWest(tile, pendingList, doneList, resList)
|
|||
resElement *element;
|
||||
resNode *currNode;
|
||||
float rArea;
|
||||
tileJunk *junk = (tileJunk *)TiGetClientPTR(tile);
|
||||
resInfo *info = (resInfo *)TiGetClientPTR(tile);
|
||||
|
||||
merged = FALSE;
|
||||
height = TOP(tile) - BOTTOM(tile);
|
||||
|
|
@ -143,12 +143,12 @@ ResCalcEastWest(tile, pendingList, doneList, resList)
|
|||
* breakpoint, then return.
|
||||
*/
|
||||
|
||||
p1 = junk->breakList;
|
||||
p1 = info->breakList;
|
||||
if (p1->br_next == NULL)
|
||||
{
|
||||
p1->br_this->rn_float.rn_area += height * (LEFT(tile) - RIGHT(tile));
|
||||
freeMagic((char *)p1);
|
||||
junk->breakList = NULL;
|
||||
info->breakList = NULL;
|
||||
return(merged);
|
||||
}
|
||||
|
||||
|
|
@ -164,14 +164,14 @@ ResCalcEastWest(tile, pendingList, doneList, resList)
|
|||
|
||||
/* Re-sort nodes left to right. */
|
||||
|
||||
ResSortBreaks(&junk->breakList, TRUE);
|
||||
ResSortBreaks(&info->breakList, TRUE);
|
||||
|
||||
/*
|
||||
* Eliminate breakpoints with the same X coordinate and merge
|
||||
* their nodes.
|
||||
*/
|
||||
|
||||
p2= junk->breakList;
|
||||
p2= info->breakList;
|
||||
|
||||
/* 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.
|
||||
*/
|
||||
|
||||
|
|
@ -278,7 +278,7 @@ ResCalcEastWest(tile, pendingList, doneList, resList)
|
|||
|
||||
p2->br_this->rn_float.rn_area += height * (RIGHT(tile) - p2->br_loc.p_x);
|
||||
freeMagic((char *)p2);
|
||||
junk->breakList = NULL;
|
||||
info->breakList = NULL;
|
||||
return merged;
|
||||
}
|
||||
|
||||
|
|
@ -309,7 +309,7 @@ ResCalcNorthSouth(tile, pendingList, doneList, resList)
|
|||
resElement *element;
|
||||
resNode *currNode;
|
||||
float rArea;
|
||||
tileJunk *junk = (tileJunk *)TiGetClientPTR(tile);
|
||||
resInfo *info = (resInfo *)TiGetClientPTR(tile);
|
||||
|
||||
merged = FALSE;
|
||||
width = RIGHT(tile) - LEFT(tile);
|
||||
|
|
@ -319,17 +319,17 @@ ResCalcNorthSouth(tile, pendingList, doneList, resList)
|
|||
* breakpoint, then return.
|
||||
*/
|
||||
|
||||
p1 = junk->breakList;
|
||||
p1 = info->breakList;
|
||||
if (p1->br_next == NULL)
|
||||
{
|
||||
p1->br_this->rn_float.rn_area += width * (TOP(tile) - BOTTOM(tile));
|
||||
freeMagic((char *)p1);
|
||||
junk->breakList = NULL;
|
||||
info->breakList = NULL;
|
||||
return(merged);
|
||||
}
|
||||
|
||||
/* Re-sort nodes south to north. */
|
||||
ResSortBreaks(&junk->breakList, FALSE);
|
||||
ResSortBreaks(&info->breakList, FALSE);
|
||||
|
||||
/* Simplified split tile handling */
|
||||
if (IsSplit(tile))
|
||||
|
|
@ -346,7 +346,7 @@ ResCalcNorthSouth(tile, pendingList, doneList, resList)
|
|||
* their nodes.
|
||||
*/
|
||||
|
||||
p2 = junk->breakList;
|
||||
p2 = info->breakList;
|
||||
|
||||
/* 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.
|
||||
*/
|
||||
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);
|
||||
freeMagic((char *)p2);
|
||||
junk->breakList = NULL;
|
||||
info->breakList = NULL;
|
||||
return(merged);
|
||||
}
|
||||
|
||||
|
|
@ -482,7 +482,7 @@ ResCalcNearDevice(tile, pendingList, doneList, resList)
|
|||
bool merged;
|
||||
int devcount, devedge, deltax, deltay;
|
||||
Breakpoint *p1, *p2, *p3;
|
||||
tileJunk *junk = (tileJunk *)TiGetClientPTR(tile);
|
||||
resInfo *info = (resInfo *)TiGetClientPTR(tile);
|
||||
|
||||
merged = FALSE;
|
||||
|
||||
|
|
@ -491,10 +491,10 @@ ResCalcNearDevice(tile, pendingList, doneList, resList)
|
|||
* breakpoint, then return.
|
||||
*/
|
||||
|
||||
if (junk->breakList->br_next == NULL)
|
||||
if (info->breakList->br_next == NULL)
|
||||
{
|
||||
freeMagic((char *)junk->breakList);
|
||||
junk->breakList = NULL;
|
||||
freeMagic((char *)info->breakList);
|
||||
info->breakList = NULL;
|
||||
return(merged);
|
||||
}
|
||||
|
||||
|
|
@ -503,7 +503,7 @@ ResCalcNearDevice(tile, pendingList, doneList, resList)
|
|||
|
||||
devcount = 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)
|
||||
{
|
||||
|
|
@ -525,9 +525,9 @@ ResCalcNearDevice(tile, pendingList, doneList, resList)
|
|||
(devedge & TOPEDGE) == devedge ||
|
||||
(devedge & BOTTOMEDGE) == devedge)
|
||||
{
|
||||
ResSortBreaks(&junk->breakList,TRUE);
|
||||
ResSortBreaks(&info->breakList,TRUE);
|
||||
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)
|
||||
break;
|
||||
|
|
@ -587,9 +587,9 @@ ResCalcNearDevice(tile, pendingList, doneList, resList)
|
|||
}
|
||||
|
||||
/* Re-sort nodes south to north. */
|
||||
ResSortBreaks(&junk->breakList, FALSE);
|
||||
ResSortBreaks(&info->breakList, FALSE);
|
||||
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)
|
||||
{
|
||||
|
|
@ -684,17 +684,17 @@ ResCalcNearDevice(tile, pendingList, doneList, resList)
|
|||
(RIGHT(tile) - LEFT(tile)) > (TOP(tile) - BOTTOM(tile))))
|
||||
{
|
||||
/* re-sort nodes south to north. */
|
||||
ResSortBreaks(&junk->breakList, FALSE);
|
||||
ResSortBreaks(&info->breakList, FALSE);
|
||||
|
||||
/* 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 &&
|
||||
(p1->br_loc.p_y == BOTTOM(tile) ||
|
||||
p1->br_loc.p_y == TOP(tile)))
|
||||
{
|
||||
p3 = NULL;
|
||||
p2 = junk->breakList;
|
||||
p2 = info->breakList;
|
||||
while (p2 != NULL)
|
||||
{
|
||||
if (p2->br_this == p1->br_this && p2 != p1 &&
|
||||
|
|
@ -703,9 +703,9 @@ ResCalcNearDevice(tile, pendingList, doneList, resList)
|
|||
{
|
||||
if (p3 == NULL)
|
||||
{
|
||||
junk->breakList = p2->br_next;
|
||||
info->breakList = p2->br_next;
|
||||
freeMagic((char *) p2);
|
||||
p2 = junk->breakList;
|
||||
p2 = info->breakList;
|
||||
}
|
||||
else
|
||||
{
|
||||
|
|
@ -727,14 +727,14 @@ ResCalcNearDevice(tile, pendingList, doneList, resList)
|
|||
else
|
||||
{
|
||||
/* 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 &&
|
||||
(p1->br_loc.p_x == LEFT(tile) ||
|
||||
p1->br_loc.p_x == RIGHT(tile)))
|
||||
{
|
||||
p3 = NULL;
|
||||
p2 = junk->breakList;
|
||||
p2 = info->breakList;
|
||||
while (p2 != NULL)
|
||||
{
|
||||
if (p2->br_this == p1->br_this && p2 != p1 &&
|
||||
|
|
@ -743,9 +743,9 @@ ResCalcNearDevice(tile, pendingList, doneList, resList)
|
|||
{
|
||||
if (p3 == NULL)
|
||||
{
|
||||
junk->breakList = p2->br_next;
|
||||
info->breakList = p2->br_next;
|
||||
freeMagic((char *) p2);
|
||||
p2 = junk->breakList;
|
||||
p2 = info->breakList;
|
||||
}
|
||||
else
|
||||
{
|
||||
|
|
@ -805,7 +805,7 @@ ResDoContacts(contact, nodes, resList)
|
|||
int y = contact->cp_center.p_y;
|
||||
|
||||
resptr = (resNode *) mallocMagic((unsigned) (sizeof(resNode)));
|
||||
InitializeNode(resptr, x, y, RES_NODE_CONTACT);
|
||||
InitializeResNode(resptr, x, y, RES_NODE_CONTACT);
|
||||
ResAddToQueue(resptr, nodes);
|
||||
|
||||
ccell = (cElement *) mallocMagic((unsigned) (sizeof(cElement)));
|
||||
|
|
@ -858,7 +858,7 @@ ResDoContacts(contact, nodes, resList)
|
|||
Tile *tile = contact->cp_tile[tilenum];
|
||||
|
||||
resptr = (resNode *) mallocMagic((unsigned) (sizeof(resNode)));
|
||||
InitializeNode(resptr, x, y, RES_NODE_CONTACT);
|
||||
InitializeResNode(resptr, x, y, RES_NODE_CONTACT);
|
||||
ResAddToQueue(resptr, nodes);
|
||||
|
||||
/* Add contact pointer to node */
|
||||
|
|
|
|||
|
|
@ -53,7 +53,7 @@ ResDoneWithNode(resptr)
|
|||
resResistor *rr1;
|
||||
|
||||
resptr2 = NULL;
|
||||
resptr->rn_status |= RESTRUE;
|
||||
resptr->rn_status |= RES_TRUE;
|
||||
status = UNTOUCHED;
|
||||
|
||||
/* are there any resistors? */
|
||||
|
|
@ -93,9 +93,9 @@ ResDoneWithNode(resptr)
|
|||
ResMergeNodes(resptr2, resptr, &ResNodeQueue, &ResNodeList);
|
||||
resptr2->rn_float.rn_area += rr1->rr_float.rr_area;
|
||||
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);
|
||||
}
|
||||
resptr2 = NULL;
|
||||
|
|
@ -108,14 +108,16 @@ ResDoneWithNode(resptr)
|
|||
/* Eliminations that can be only if there are no devices connected */
|
||||
/* to node. Series and dangling connections fall in this group. */
|
||||
|
||||
if ((resptr->rn_te == NULL) && (resptr->rn_why != RES_NODE_ORIGIN)
|
||||
&& (status == UNTOUCHED))
|
||||
if ((status == UNTOUCHED) && (resptr->rn_te == NULL) &&
|
||||
!(resptr->rn_why & (RES_NODE_ORIGIN | RES_NODE_SINK)))
|
||||
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);
|
||||
|
||||
if ((status == UNTOUCHED) && (resptr->rn_why != RES_NODE_ORIGIN))
|
||||
if ((status == UNTOUCHED) &&
|
||||
!(resptr->rn_why & (RES_NODE_ORIGIN | RES_NODE_SINK)))
|
||||
status = ResTriangleCheck(resptr);
|
||||
}
|
||||
|
||||
|
|
@ -242,9 +244,9 @@ ResSeriesCheck(resptr)
|
|||
ResEliminateResistor(rr1, &ResResList);
|
||||
ResCleanNode(resptr, TRUE, &ResNodeList, &ResNodeQueue);
|
||||
status = SINGLE;
|
||||
if (resptr2->rn_status & RESTRUE)
|
||||
if (resptr2->rn_status & RES_TRUE)
|
||||
{
|
||||
resptr2->rn_status &= ~RESTRUE;
|
||||
resptr2->rn_status &= ~RES_TRUE;
|
||||
ResDoneWithNode(resptr2);
|
||||
}
|
||||
resptr2 = NULL;
|
||||
|
|
@ -280,9 +282,9 @@ ResSeriesCheck(resptr)
|
|||
rr1->rr_connection1 = rr2->rr_connection2;
|
||||
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);
|
||||
}
|
||||
resptr2 = NULL;
|
||||
|
|
@ -311,9 +313,9 @@ ResSeriesCheck(resptr)
|
|||
rr1->rr_connection1 = rr2->rr_connection1;
|
||||
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);
|
||||
}
|
||||
resptr2 = NULL;
|
||||
|
|
@ -345,9 +347,9 @@ ResSeriesCheck(resptr)
|
|||
rr1->rr_connection2 = rr2->rr_connection2;
|
||||
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);
|
||||
}
|
||||
resptr2 = NULL;
|
||||
|
|
@ -376,9 +378,9 @@ ResSeriesCheck(resptr)
|
|||
rr1->rr_connection2 = rr2->rr_connection1;
|
||||
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);
|
||||
}
|
||||
resptr2 = NULL;
|
||||
|
|
@ -433,10 +435,10 @@ ResParallelCheck(resptr)
|
|||
ResFixParallel(r1, r2);
|
||||
status = PARALLEL;
|
||||
resptr2 = NULL;
|
||||
if (resptr3->rn_status & RESTRUE)
|
||||
if (resptr3->rn_status & RES_TRUE)
|
||||
{
|
||||
resptr2 = resptr3;
|
||||
resptr2->rn_status &= ~RESTRUE;
|
||||
resptr2->rn_status &= ~RES_TRUE;
|
||||
}
|
||||
ResDoneWithNode(resptr);
|
||||
if (resptr2 != NULL) ResDoneWithNode(resptr2);
|
||||
|
|
@ -531,8 +533,8 @@ ResTriangleCheck(resptr)
|
|||
/* is arbitrarily assigned to the location */
|
||||
/* occupied by the first node. */
|
||||
|
||||
InitializeNode(n3, resptr->rn_loc.p_x, resptr->rn_loc.p_y, TRIANGLE);
|
||||
n3->rn_status = FINISHED | RESTRUE | MARKED;
|
||||
InitializeResNode(n3, resptr->rn_loc.p_x, resptr->rn_loc.p_y, TRIANGLE);
|
||||
n3->rn_status = RES_FINISHED | RES_TRUE | RES_MARKED;
|
||||
|
||||
n3->rn_less = NULL;
|
||||
n3->rn_more = ResNodeList;
|
||||
|
|
@ -580,13 +582,13 @@ ResTriangleCheck(resptr)
|
|||
element->re_nextEl = n3->rn_re;
|
||||
element->re_thisEl = rr3;
|
||||
n3->rn_re = element;
|
||||
if ((n1->rn_status & RESTRUE) == RESTRUE)
|
||||
n1->rn_status &= ~RESTRUE;
|
||||
if ((n1->rn_status & RES_TRUE) == RES_TRUE)
|
||||
n1->rn_status &= ~RES_TRUE;
|
||||
else
|
||||
n1 = NULL;
|
||||
|
||||
if ((n2->rn_status & RESTRUE) == RESTRUE)
|
||||
n2->rn_status &= ~RESTRUE;
|
||||
if ((n2->rn_status & RES_TRUE) == RES_TRUE)
|
||||
n2->rn_status &= ~RES_TRUE;
|
||||
else
|
||||
n2 = NULL;
|
||||
|
||||
|
|
@ -637,15 +639,18 @@ ResMergeNodes(node1, node2, pendingList, doneList)
|
|||
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)
|
||||
node1->rn_why = RES_NODE_ORIGIN;
|
||||
|
||||
if (node2->rn_why & RES_NODE_SINK)
|
||||
node1->rn_why = RES_NODE_SINK;
|
||||
|
||||
/* set node resistance */
|
||||
if (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);
|
||||
ResAddToQueue(node1, pendingList);
|
||||
|
|
@ -654,7 +659,7 @@ ResMergeNodes(node1, node2, pendingList, doneList)
|
|||
node1->rn_float.rn_area += node2->rn_float.rn_area;
|
||||
|
||||
/* combine relevant flags */
|
||||
node1->rn_status |= (node2->rn_status & RN_MAXTDI);
|
||||
node1->rn_status |= (node2->rn_status & RES_MAXTDI);
|
||||
|
||||
/* merge device lists */
|
||||
workingDev = node2->rn_te;
|
||||
|
|
@ -680,13 +685,13 @@ ResMergeNodes(node1, node2, pendingList, doneList)
|
|||
tJunc = workingJunc;
|
||||
for (i = 0; i < TILES_PER_JUNCTION; i++)
|
||||
{
|
||||
tileJunk *junk;
|
||||
resInfo *info;
|
||||
|
||||
tile = tJunc->je_thisj->rj_Tile[i];
|
||||
junk = (tileJunk *) TiGetClientPTR(tile);
|
||||
info = (resInfo *) TiGetClientPTR(tile);
|
||||
|
||||
if ((junk->tj_status & RES_TILE_DONE) == FALSE)
|
||||
ResFixBreakPoint(&junk->breakList, node2, node1);
|
||||
if ((info->ri_status & RES_TILE_DONE) == FALSE)
|
||||
ResFixBreakPoint(&info->breakList, node2, node1);
|
||||
}
|
||||
tJunc->je_thisj->rj_jnode = node1;
|
||||
workingJunc = workingJunc->je_nextj;
|
||||
|
|
@ -703,13 +708,13 @@ ResMergeNodes(node1, node2, pendingList, doneList)
|
|||
{
|
||||
if (workingCon->ce_thisc->cp_cnode[i] == node2)
|
||||
{
|
||||
tileJunk *junk;
|
||||
resInfo *info;
|
||||
|
||||
workingCon->ce_thisc->cp_cnode[i] = node1;
|
||||
tile =tCon->ce_thisc->cp_tile[i];
|
||||
junk = (tileJunk *) TiGetClientPTR(tile);
|
||||
if ((junk->tj_status & RES_TILE_DONE) == FALSE)
|
||||
ResFixBreakPoint(&junk->breakList, node2, node1);
|
||||
info = (resInfo *) TiGetClientPTR(tile);
|
||||
if ((info->ri_status & RES_TILE_DONE) == FALSE)
|
||||
ResFixBreakPoint(&info->breakList, node2, node1);
|
||||
}
|
||||
}
|
||||
workingCon = workingCon->ce_nextc;
|
||||
|
|
@ -749,7 +754,7 @@ ResMergeNodes(node1, node2, pendingList, doneList)
|
|||
tRes->re_nextEl = node1->rn_re;
|
||||
node1->rn_re = tRes;
|
||||
}
|
||||
if ((node2->rn_status & FINISHED) == FINISHED)
|
||||
if ((node2->rn_status & RES_FINISHED) == RES_FINISHED)
|
||||
ResRemoveFromQueue(node2, doneList);
|
||||
else
|
||||
ResRemoveFromQueue(node2, pendingList);
|
||||
|
|
@ -859,7 +864,7 @@ ResEliminateResistor(resistor, homelist)
|
|||
*-------------------------------------------------------------------------
|
||||
*
|
||||
* 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.
|
||||
*
|
||||
* Results:
|
||||
|
|
@ -871,9 +876,9 @@ ResEliminateResistor(resistor, homelist)
|
|||
*/
|
||||
|
||||
void
|
||||
ResCleanNode(resptr, junk, homelist1, homelist2)
|
||||
ResCleanNode(resptr, info, homelist1, homelist2)
|
||||
resNode *resptr;
|
||||
int junk;
|
||||
int info;
|
||||
resNode **homelist1;
|
||||
resNode **homelist2;
|
||||
{
|
||||
|
|
@ -896,7 +901,7 @@ ResCleanNode(resptr, junk, homelist1, homelist2)
|
|||
freeMagic((char *)jcell->je_thisj);
|
||||
freeMagic((char *)jcell);
|
||||
}
|
||||
if (junk == TRUE)
|
||||
if (info == TRUE)
|
||||
{
|
||||
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 KV_TO_mV 1000000
|
||||
|
||||
extern ResExtNode *ResInitializeNode();
|
||||
|
||||
|
||||
/*
|
||||
*-------------------------------------------------------------------------
|
||||
*
|
||||
|
|
@ -58,7 +55,7 @@ ResPrintExtRes(outextfile, resistors, nodename)
|
|||
int nodenum=0;
|
||||
char newname[MAXNAME];
|
||||
HashEntry *entry;
|
||||
ResExtNode *node, *ResInitializeNode();
|
||||
ResExtNode *node;
|
||||
|
||||
for (; resistors != NULL; resistors = resistors->rr_nextResistor)
|
||||
{
|
||||
|
|
@ -73,7 +70,7 @@ ResPrintExtRes(outextfile, resistors, nodename)
|
|||
{
|
||||
(void)sprintf(newname, "%s%s%d", nodename, ".r", nodenum++);
|
||||
entry = HashFind(&ResNodeTable, newname);
|
||||
node = ResInitializeNode(entry);
|
||||
node = ResExtInitNode(entry);
|
||||
resistors->rr_connection1->rn_name = node->name;
|
||||
node->oldname = nodename;
|
||||
}
|
||||
|
|
@ -81,7 +78,7 @@ ResPrintExtRes(outextfile, resistors, nodename)
|
|||
{
|
||||
(void)sprintf(newname, "%s%s%d", nodename, ".r", nodenum++);
|
||||
entry = HashFind(&ResNodeTable, newname);
|
||||
node = ResInitializeNode(entry);
|
||||
node = ResExtInitNode(entry);
|
||||
resistors->rr_connection2->rn_name = node->name;
|
||||
node->oldname = nodename;
|
||||
}
|
||||
|
|
@ -222,7 +219,7 @@ ResPrintExtNode(outextfile, nodelist, node)
|
|||
int nodenum = 0;
|
||||
char newname[MAXNAME+32], tmpname[MAXNAME], *cp;
|
||||
HashEntry *entry;
|
||||
ResExtNode *newnode, *ResInitializeNode();
|
||||
ResExtNode *newnode;
|
||||
bool DoKillNode = TRUE;
|
||||
bool NeedFix = FALSE;
|
||||
resNode *snode;
|
||||
|
|
@ -271,7 +268,7 @@ ResPrintExtNode(outextfile, nodelist, node)
|
|||
|
||||
(void)sprintf(newname, "%s%s%d", tmpname, ".n", nodenum++);
|
||||
entry = HashFind(&ResNodeTable, newname);
|
||||
newnode = ResInitializeNode(entry);
|
||||
newnode = ResExtInitNode(entry);
|
||||
snode->rn_name = newnode->name;
|
||||
newnode->oldname = nodename;
|
||||
}
|
||||
|
|
@ -419,16 +416,16 @@ ResPrintFHNodes(fp, nodelist, nodename, nidx, celldef)
|
|||
else
|
||||
{
|
||||
HashEntry *entry;
|
||||
ResExtNode *simnode;
|
||||
ResExtNode *extnode;
|
||||
|
||||
/* If we process another sim file node while doing this */
|
||||
/* one, mark it as status "REDUNDANT" so we don't duplicate */
|
||||
/* the entry. */
|
||||
|
||||
entry = HashFind(&ResNodeTable, nodeptr->rn_name);
|
||||
simnode = (ResExtNode *)HashGetValue(entry);
|
||||
if (simnode != NULL)
|
||||
simnode->status |= REDUNDANT;
|
||||
extnode = (ResExtNode *)HashGetValue(entry);
|
||||
if (extnode != NULL)
|
||||
extnode->status |= REDUNDANT;
|
||||
}
|
||||
resWriteNodeName(fp, nodeptr);
|
||||
|
||||
|
|
|
|||
|
|
@ -84,8 +84,6 @@ static char rcsid[] __attribute__ ((unused)) = "$Header: /usr/cvsroot/magic-8.0/
|
|||
|
||||
#define MAXDIGIT 20
|
||||
|
||||
ResExtNode *ResInitializeNode();
|
||||
|
||||
ResExtNode *ResOriginalNodes; /*Linked List of Nodes */
|
||||
char RDEV_NOATTR[1] = {'0'};
|
||||
ResFixPoint *ResFixList;
|
||||
|
|
@ -202,11 +200,17 @@ ResReadNode(int argc, char *argv[])
|
|||
ResExtNode *node;
|
||||
|
||||
entry = HashFind(&ResNodeTable, argv[NODES_NODENAME]);
|
||||
node = ResInitializeNode(entry);
|
||||
node = ResExtInitNode(entry);
|
||||
|
||||
node->location.p_x = atoi(argv[NODES_NODEX]);
|
||||
node->location.p_y = atoi(argv[NODES_NODEY]);
|
||||
node->type = DBTechNameType(argv[NODES_NODETYPE]);
|
||||
/* If this node was previously read as a port, then don't change the
|
||||
* location.
|
||||
*/
|
||||
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)
|
||||
{
|
||||
|
|
@ -237,7 +241,7 @@ ResReadPort(int argc,
|
|||
ResExtNode *node;
|
||||
|
||||
entry = HashFind(&ResNodeTable, argv[PORT_NAME]);
|
||||
node = ResInitializeNode(entry);
|
||||
node = ResExtInitNode(entry);
|
||||
|
||||
node->drivepoint.p_x = atoi(argv[PORT_LLX]);
|
||||
node->drivepoint.p_y = atoi(argv[PORT_LLY]);
|
||||
|
|
@ -536,19 +540,19 @@ ResReadCapacitor(int argc,
|
|||
ResExtNode *node1, *node2;
|
||||
|
||||
entry1 = HashFind(&ResNodeTable, argv[COUPLETERMINAL1]);
|
||||
node1 = ResInitializeNode(entry1);
|
||||
node1 = ResExtInitNode(entry1);
|
||||
|
||||
if (ResOptionsFlags & ResOpt_Signal)
|
||||
{
|
||||
node1->capacitance += MagAtof(argv[COUPLEVALUE]);
|
||||
entry2 = HashFind(&ResNodeTable, argv[COUPLETERMINAL2]);
|
||||
node2 = ResInitializeNode(entry2);
|
||||
node2 = ResExtInitNode(entry2);
|
||||
node2->capacitance += MagAtof(argv[COUPLEVALUE]);
|
||||
return 0;
|
||||
}
|
||||
|
||||
entry2 = HashFind(&ResNodeTable, argv[COUPLETERMINAL2]);
|
||||
node2 = ResInitializeNode(entry2);
|
||||
node2 = ResExtInitNode(entry2);
|
||||
|
||||
node1->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
|
||||
* such node exists, one is created.
|
||||
*
|
||||
|
|
@ -637,7 +641,7 @@ ResReadAttribute(ResExtNode *node,
|
|||
*/
|
||||
|
||||
ResExtNode *
|
||||
ResInitializeNode(entry)
|
||||
ResExtInitNode(entry)
|
||||
HashEntry *entry;
|
||||
{
|
||||
ResExtNode *node;
|
||||
|
|
@ -651,7 +655,6 @@ ResInitializeNode(entry)
|
|||
node->status = FALSE;
|
||||
node->forward = (ResExtNode *) NULL;
|
||||
node->capacitance = 0;
|
||||
node->cap_vdd = 0;
|
||||
node->cap_couple = 0;
|
||||
node->resistance = 0;
|
||||
node->type = 0;
|
||||
|
|
@ -662,8 +665,6 @@ ResInitializeNode(entry)
|
|||
node->drivepoint.p_y = INFINITY;
|
||||
node->location.p_x = INFINITY;
|
||||
node->location.p_y = INFINITY;
|
||||
node->rs_sublist[0] = NULL;
|
||||
node->rs_sublist[1] = NULL;
|
||||
}
|
||||
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/tech.h"
|
||||
#include "textio/txcommands.h"
|
||||
#include "resis/resis.h"
|
||||
#include "commands/commands.h"
|
||||
#include "resis/resis.h"
|
||||
|
||||
#define INITFLATSIZE 1024
|
||||
#define MAXNAME 1000
|
||||
|
|
@ -70,10 +71,6 @@ FILE *ResFHFile;
|
|||
|
||||
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))
|
||||
ResCheckExtNodes(celldef, resisdata);
|
||||
|
||||
if (ResOptionsFlags & ResOpt_Stat)
|
||||
if (ResOptionsFlags & ResOpt_Stats)
|
||||
ResPrintStats((ResisData *)NULL, "");
|
||||
}
|
||||
|
||||
|
|
@ -280,10 +277,11 @@ CmdExtResis(win, cmd)
|
|||
"ignore names don't extract these nets",
|
||||
"include names extract only these nets",
|
||||
"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",
|
||||
"fasthenry [freq] extract subcircuit network geometry into .fh file",
|
||||
"fasthenry [freq] extract subcircuit network geometry into .fh file",
|
||||
"geometry extract network centerline geometry (experimental)",
|
||||
"stats print extresist statistics",
|
||||
"help print this message",
|
||||
NULL
|
||||
};
|
||||
|
|
@ -293,8 +291,8 @@ typedef enum {
|
|||
RES_THRESH, RES_TOL,
|
||||
RES_SIMP, RES_EXTOUT, RES_LUMPED, RES_SILENT,
|
||||
RES_SKIP, RES_IGNORE, RES_INCLUDE, RES_BOX, RES_CELL,
|
||||
RES_BLACKBOX, RES_FASTHENRY, RES_GEOMETRY, RES_HELP,
|
||||
RES_RUN
|
||||
RES_BLACKBOX, RES_FASTHENRY, RES_GEOMETRY, RES_STATS,
|
||||
RES_HELP, RES_RUN
|
||||
} ResOptions;
|
||||
|
||||
resisdata = ResInit();
|
||||
|
|
@ -324,7 +322,6 @@ typedef enum {
|
|||
switch (option)
|
||||
{
|
||||
case RES_TOL:
|
||||
ResOptionsFlags |= ResOpt_ExplicitRtol;
|
||||
if (cmd->tx_argc > 2)
|
||||
{
|
||||
resisdata->tdiTolerance = MagAtof(cmd->tx_argv[2]);
|
||||
|
|
@ -412,6 +409,23 @@ typedef enum {
|
|||
ResOptionsFlags &= ~ResOpt_Blackbox;
|
||||
}
|
||||
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:
|
||||
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);
|
||||
|
||||
entry = HashFind(&ResNodeTable, nodename);
|
||||
node = ResInitializeNode(entry);
|
||||
node = ResExtInitNode(entry);
|
||||
|
||||
/* Digital outputs are drivers */
|
||||
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 */
|
||||
/* and a drivepoint. */
|
||||
|
||||
node = ResInitializeNode(entry);
|
||||
node = ResExtInitNode(entry);
|
||||
TxPrintf("Port: name = %s is new node %p\n",
|
||||
lab->lab_text, (void *)node);
|
||||
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
|
||||
* device. The new name is formed by appending .t# to the old name.
|
||||
* ResFixUpConnections--
|
||||
* 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.
|
||||
*
|
||||
* Results:none
|
||||
* Results:
|
||||
* None.
|
||||
*
|
||||
* Side Effects: Allocates new ResExtNodes. Modifies the terminal connections
|
||||
* of ext Devices.
|
||||
* Side Effects:
|
||||
* Allocates new ResExtNodes. Modifies the terminal connections
|
||||
* of devices.
|
||||
*
|
||||
*-------------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
void
|
||||
ResFixUpConnections(simDev, layoutDev, simNode, nodename)
|
||||
RDev *simDev;
|
||||
ResFixUpConnections(extDev, layoutDev, extNode, nodename)
|
||||
RDev *extDev;
|
||||
resDevice *layoutDev;
|
||||
ResExtNode *simNode;
|
||||
ResExtNode *extNode;
|
||||
char *nodename;
|
||||
|
||||
{
|
||||
static char newname[MAXNAME], oldnodename[MAXNAME];
|
||||
int notdecremented;
|
||||
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. */
|
||||
|
||||
if ((ResOptionsFlags & (ResOpt_DoRsmFile | ResOpt_DoExtFile)) == 0)
|
||||
if ((ResOptionsFlags & ResOpt_DoExtFile) == 0)
|
||||
return;
|
||||
|
||||
if (simDev->layout == NULL)
|
||||
if (extDev->layout == NULL)
|
||||
{
|
||||
layoutDev->rd_status |= RES_DEV_SAVE;
|
||||
simDev->layout = layoutDev;
|
||||
extDev->layout = layoutDev;
|
||||
}
|
||||
simDev->status |= TRUE;
|
||||
extDev->status |= TRUE;
|
||||
if (strcmp(nodename, oldnodename) != 0)
|
||||
{
|
||||
strcpy(oldnodename, nodename);
|
||||
|
|
@ -1314,7 +1330,7 @@ ResFixUpConnections(simDev, layoutDev, simNode, nodename)
|
|||
sprintf(newname, "%s%s%d", nodename, ".t", resNodeNum++);
|
||||
notdecremented = TRUE;
|
||||
|
||||
if (simDev->gate == simNode)
|
||||
if (extDev->gate == extNode)
|
||||
{
|
||||
if ((gate = layoutDev->rd_fet_gate) != NULL)
|
||||
{
|
||||
|
|
@ -1326,8 +1342,8 @@ ResFixUpConnections(simDev, layoutDev, simNode, nodename)
|
|||
notdecremented = FALSE;
|
||||
}
|
||||
|
||||
ResFixDevName(newname, GATE, simDev, gate);
|
||||
gate->rn_name = simDev->gate->name;
|
||||
ResFixDevName(newname, GATE, extDev, gate);
|
||||
gate->rn_name = extDev->gate->name;
|
||||
sprintf(newname, "%s%s%d", nodename, ".t", resNodeNum++);
|
||||
}
|
||||
else
|
||||
|
|
@ -1335,10 +1351,10 @@ ResFixUpConnections(simDev, layoutDev, simNode, nodename)
|
|||
TxError("Missing gate connection of device at (%d %d) on net %s\n",
|
||||
layoutDev->rd_inside.r_xbot, layoutDev->rd_inside.r_ybot,
|
||||
nodename);
|
||||
simNode->status |= DONTKILL;
|
||||
extNode->status |= DONTKILL;
|
||||
}
|
||||
}
|
||||
if (simDev->subs == simNode)
|
||||
if (extDev->subs == extNode)
|
||||
{
|
||||
if ((subs = layoutDev->rd_fet_subs) != NULL)
|
||||
{
|
||||
|
|
@ -1347,8 +1363,8 @@ ResFixUpConnections(simDev, layoutDev, simNode, nodename)
|
|||
resNodeNum--;
|
||||
notdecremented = FALSE;
|
||||
}
|
||||
ResFixDevName(newname, SUBS, simDev, subs);
|
||||
subs->rn_name = simDev->subs->name;
|
||||
ResFixDevName(newname, SUBS, extDev, subs);
|
||||
subs->rn_name = extDev->subs->name;
|
||||
sprintf(newname, "%s%s%d", nodename, ".t", resNodeNum++);
|
||||
}
|
||||
else
|
||||
|
|
@ -1356,11 +1372,11 @@ ResFixUpConnections(simDev, layoutDev, simNode, nodename)
|
|||
TxError("Missing substrate connection of device at (%d %d) on net %s\n",
|
||||
layoutDev->rd_inside.r_xbot, layoutDev->rd_inside.r_ybot,
|
||||
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, */
|
||||
/* 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;
|
||||
}
|
||||
|
||||
if (simDev->drain == simNode)
|
||||
if (extDev->drain == extNode)
|
||||
{
|
||||
if ((layoutDev->rd_fet_source != NULL) &&
|
||||
(layoutDev->rd_fet_drain == NULL))
|
||||
{
|
||||
/* Handle source/drain-tied devices */
|
||||
if (simDev->drain == simDev->source)
|
||||
if (extDev->drain == extDev->source)
|
||||
layoutDev->rd_fet_drain = layoutDev->rd_fet_source;
|
||||
}
|
||||
|
||||
|
|
@ -1390,12 +1406,12 @@ ResFixUpConnections(simDev, layoutDev, simNode, nodename)
|
|||
resNodeNum--;
|
||||
notdecremented = FALSE;
|
||||
}
|
||||
ResFixDevName(newname, SOURCE, simDev, source);
|
||||
source->rn_name = simDev->source->name;
|
||||
ResFixDevName(newname, SOURCE, extDev, source);
|
||||
source->rn_name = extDev->source->name;
|
||||
(void)sprintf(newname, "%s%s%d", nodename, ".t", resNodeNum++);
|
||||
if (drain->rn_name != NULL) resNodeNum--;
|
||||
ResFixDevName(newname, DRAIN, simDev, drain);
|
||||
drain->rn_name = simDev->drain->name;
|
||||
ResFixDevName(newname, DRAIN, extDev, drain);
|
||||
drain->rn_name = extDev->drain->name;
|
||||
/* one to each */
|
||||
}
|
||||
else
|
||||
|
|
@ -1403,7 +1419,7 @@ ResFixUpConnections(simDev, layoutDev, simNode, nodename)
|
|||
TxError("Missing terminal connection of device at (%d %d) on net %s\n",
|
||||
layoutDev->rd_inside.r_xbot, layoutDev->rd_inside.r_ybot,
|
||||
nodename);
|
||||
simNode->status |= DONTKILL;
|
||||
extNode->status |= DONTKILL;
|
||||
}
|
||||
}
|
||||
else
|
||||
|
|
@ -1414,7 +1430,7 @@ ResFixUpConnections(simDev, layoutDev, simNode, nodename)
|
|||
{
|
||||
if (source != drain)
|
||||
{
|
||||
if (drain->rn_why & RES_NODE_ORIGIN)
|
||||
if (drain->rn_why & (RES_NODE_ORIGIN | RES_NODE_SINK))
|
||||
{
|
||||
ResMergeNodes(drain, source, &ResNodeQueue,
|
||||
&ResNodeList);
|
||||
|
|
@ -1440,8 +1456,8 @@ ResFixUpConnections(simDev, layoutDev, simNode, nodename)
|
|||
notdecremented = FALSE;
|
||||
}
|
||||
}
|
||||
ResFixDevName(newname, SOURCE, simDev, source);
|
||||
source->rn_name = simDev->source->name;
|
||||
ResFixDevName(newname, SOURCE, extDev, source);
|
||||
source->rn_name = extDev->source->name;
|
||||
|
||||
}
|
||||
else
|
||||
|
|
@ -1449,11 +1465,11 @@ ResFixUpConnections(simDev, layoutDev, simNode, nodename)
|
|||
TxError("Missing terminal connection of device at (%d %d) on net %s\n",
|
||||
layoutDev->rd_inside.r_xbot, layoutDev->rd_inside.r_ybot,
|
||||
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, */
|
||||
/* 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 (source->rn_why & ORIGIN)
|
||||
if (source->rn_why & (RES_NODE_ORIGIN | RES_NODE_SINK))
|
||||
{
|
||||
ResMergeNodes(source, drain, &ResNodeQueue,
|
||||
&ResNodeList);
|
||||
|
|
@ -1501,15 +1517,15 @@ ResFixUpConnections(simDev, layoutDev, simNode, nodename)
|
|||
notdecremented = FALSE;
|
||||
}
|
||||
}
|
||||
ResFixDevName(newname, DRAIN, simDev, drain);
|
||||
drain->rn_name = simDev->drain->name;
|
||||
ResFixDevName(newname, DRAIN, extDev, drain);
|
||||
drain->rn_name = extDev->drain->name;
|
||||
}
|
||||
else
|
||||
{
|
||||
TxError("Missing terminal connection of device at (%d %d) on net %s\n",
|
||||
layoutDev->rd_inside.r_xbot, layoutDev->rd_inside.r_ybot,
|
||||
nodename);
|
||||
simNode->status |= DONTKILL;
|
||||
extNode->status |= DONTKILL;
|
||||
}
|
||||
}
|
||||
else
|
||||
|
|
@ -1545,13 +1561,13 @@ ResFixDevName(line, type, device, layoutnode)
|
|||
if (layoutnode->rn_name != NULL)
|
||||
{
|
||||
entry = HashFind(&ResNodeTable, layoutnode->rn_name);
|
||||
node = ResInitializeNode(entry);
|
||||
node = ResExtInitNode(entry);
|
||||
|
||||
}
|
||||
else
|
||||
{
|
||||
entry = HashFind(&ResNodeTable, line);
|
||||
node = ResInitializeNode(entry);
|
||||
node = ResExtInitNode(entry);
|
||||
}
|
||||
tptr = (devPtr *) mallocMagic((unsigned) (sizeof(devPtr)));
|
||||
tptr->thisDev = device;
|
||||
|
|
|
|||
|
|
@ -77,7 +77,7 @@ ResSimplifyNet(nodelist, biglist, reslist, tolerance)
|
|||
|
||||
if (*nodelist == NULL) return;
|
||||
node = *nodelist;
|
||||
node->rn_status |= MARKED | FINISHED;
|
||||
node->rn_status |= RES_MARKED | RES_FINISHED;
|
||||
*nodelist = node->rn_more;
|
||||
if (node->rn_more != 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.
|
||||
*/
|
||||
|
||||
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;
|
||||
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_connection2->rn_status & MARKED)
|
||||
!= MARKED)
|
||||
if ((resisptr->re_thisEl->rr_connection2->rn_status & RES_MARKED)
|
||||
!= RES_MARKED)
|
||||
{
|
||||
PendingReceivers++;
|
||||
}
|
||||
|
|
@ -180,9 +181,9 @@ ResSimplifyNet(nodelist, biglist, reslist, tolerance)
|
|||
(UnMarkedReceivers == 0 && MarkedReceivers > 1 &&
|
||||
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);
|
||||
otherNode->rn_less = NULL;
|
||||
otherNode->rn_more = *nodelist;
|
||||
|
|
@ -208,9 +209,9 @@ ResSimplifyNet(nodelist, biglist, reslist, tolerance)
|
|||
ResDeleteResPointer(resistor1->rr_connection2, resistor1);
|
||||
ResEliminateResistor(resistor1, reslist);
|
||||
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);
|
||||
otherNode->rn_less= NULL;
|
||||
otherNode->rn_more = *nodelist;
|
||||
|
|
@ -287,12 +288,12 @@ ResSimplifyNet(nodelist, biglist, reslist, tolerance)
|
|||
resisptr->re_nextEl = node2->rn_re;
|
||||
node2->rn_re = resisptr;
|
||||
ResEliminateResistor(resistor2, reslist);
|
||||
otherNode->rn_status |= (node->rn_status & RN_MAXTDI);
|
||||
otherNode->rn_status |= (node->rn_status & RES_MAXTDI);
|
||||
ResCleanNode(node, TRUE, biglist, nodelist);
|
||||
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);
|
||||
node1->rn_less = NULL;
|
||||
node1->rn_more = *nodelist;
|
||||
|
|
@ -301,9 +302,9 @@ ResSimplifyNet(nodelist, biglist, reslist, tolerance)
|
|||
*nodelist = node1;
|
||||
}
|
||||
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);
|
||||
node2->rn_less = NULL;
|
||||
node2->rn_more = *nodelist;
|
||||
|
|
@ -334,7 +335,7 @@ ResSimplifyNet(nodelist, biglist, reslist, tolerance)
|
|||
if (resisptr->re_thisEl->rr_status & RES_DONE_ONCE)
|
||||
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
|
||||
|
|
@ -343,7 +344,7 @@ ResSimplifyNet(nodelist, biglist, reslist, tolerance)
|
|||
if (resisptr->re_thisEl->rr_value > tolerance)
|
||||
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);
|
||||
resisptr->re_thisEl->rr_connection2->rn_less= NULL;
|
||||
resisptr->re_thisEl->rr_connection2->rn_more = *nodelist;
|
||||
|
|
@ -527,7 +528,7 @@ ResScrunchNet(reslist, pendingList, biglist, tolerance)
|
|||
|
||||
ResEliminateResistor(current, 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);
|
||||
node1 = node2;
|
||||
|
|
@ -541,7 +542,7 @@ ResScrunchNet(reslist, pendingList, biglist, tolerance)
|
|||
*/
|
||||
ResRemoveFromQueue(node1, biglist);
|
||||
ResAddToQueue(node1, pendingList);
|
||||
node1->rn_status &= ~(RES_DONE_ONCE | FINISHED);
|
||||
node1->rn_status &= ~(RES_DONE_ONCE | RES_FINISHED);
|
||||
ResDoneWithNode(node1);
|
||||
while (*pendingList != NULL)
|
||||
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");
|
||||
resisdata->rg_Tdi = 0;
|
||||
|
|
@ -905,12 +906,12 @@ ResDoSimplify(tolerance,resisdata)
|
|||
else if (ResOptionsFlags & ResOpt_Tdi)
|
||||
{
|
||||
if ((resisdata->rg_nodecap != -1) &&
|
||||
(totalcap = ResCalculateChildCapacitance(ResOriginNode)) != -1)
|
||||
(totalcap = ResCalculateChildCapacitance(ResNodeAtOrigin)) != -1)
|
||||
{
|
||||
RCDelayStuff *rc = (RCDelayStuff *) ResNodeList->rn_client;
|
||||
|
||||
resisdata->rg_nodecap = totalcap;
|
||||
ResCalculateTDi(ResOriginNode, (resResistor *)NULL,
|
||||
ResCalculateTDi(ResNodeAtOrigin, (resResistor *)NULL,
|
||||
resisdata->rg_bigdevres);
|
||||
if (rc != (RCDelayStuff *)NULL)
|
||||
resisdata->rg_Tdi = rc->rc_Tdi;
|
||||
|
|
@ -927,7 +928,7 @@ ResDoSimplify(tolerance,resisdata)
|
|||
resisdata->rg_Tdi = rc->rc_Tdi;
|
||||
}
|
||||
}
|
||||
slownode->rn_status |= RN_MAXTDI;
|
||||
slownode->rn_status |= RES_MAXTDI;
|
||||
}
|
||||
else
|
||||
resisdata->rg_Tdi = -1;
|
||||
|
|
@ -957,11 +958,11 @@ ResDoSimplify(tolerance,resisdata)
|
|||
for (node = ResNodeList; node != NULL; node = node->rn_more)
|
||||
{
|
||||
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 */
|
||||
/* have time constants less than the tolerance. */
|
||||
|
|
@ -970,22 +971,22 @@ ResDoSimplify(tolerance,resisdata)
|
|||
resisdata->rg_Tdi != -1 &&
|
||||
rctol != 0)
|
||||
{
|
||||
ResPruneTree(ResOriginNode, (rctol + 1) *
|
||||
ResPruneTree(ResNodeAtOrigin, (rctol + 1) *
|
||||
resisdata->rg_bigdevres * resisdata->rg_nodecap / rctol,
|
||||
&ResNodeList, &ResNodeQueue, &ResResList);
|
||||
}
|
||||
ResOriginNode->rn_status &= ~MARKED;
|
||||
if (ResOriginNode->rn_less == NULL)
|
||||
ResNodeList = ResOriginNode->rn_more;
|
||||
ResNodeAtOrigin->rn_status &= ~RES_MARKED;
|
||||
if (ResNodeAtOrigin->rn_less == NULL)
|
||||
ResNodeList = ResNodeAtOrigin->rn_more;
|
||||
else
|
||||
ResOriginNode->rn_less->rn_more = ResOriginNode->rn_more;
|
||||
ResNodeAtOrigin->rn_less->rn_more = ResNodeAtOrigin->rn_more;
|
||||
|
||||
if (ResOriginNode->rn_more != NULL)
|
||||
ResOriginNode->rn_more->rn_less = ResOriginNode->rn_less;
|
||||
if (ResNodeAtOrigin->rn_more != NULL)
|
||||
ResNodeAtOrigin->rn_more->rn_less = ResNodeAtOrigin->rn_less;
|
||||
|
||||
ResOriginNode->rn_more = NULL;
|
||||
ResOriginNode->rn_less = NULL;
|
||||
ResNodeQueue = ResOriginNode;
|
||||
ResNodeAtOrigin->rn_more = NULL;
|
||||
ResNodeAtOrigin->rn_less = NULL;
|
||||
ResNodeQueue = ResNodeAtOrigin;
|
||||
while (ResNodeQueue != NULL)
|
||||
ResSimplifyNet(&ResNodeQueue, &ResNodeList, &ResResList, millitolerance);
|
||||
|
||||
|
|
@ -1022,16 +1023,16 @@ ResSetPathRes(ResisData *resisdata)
|
|||
{
|
||||
if (node->rn_noderes == 0)
|
||||
{
|
||||
ResOriginNode = node;
|
||||
node->rn_status |= FINISHED;
|
||||
ResNodeAtOrigin = node;
|
||||
node->rn_status |= RES_FINISHED;
|
||||
}
|
||||
else
|
||||
{
|
||||
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);
|
||||
if (res == (resDevice *)NULL)
|
||||
|
|
@ -1042,12 +1043,12 @@ ResSetPathRes(ResisData *resisdata)
|
|||
DBWPrintValue(resisdata->rg_devloc->p_y, (MagWindow *)NULL, FALSE));
|
||||
return;
|
||||
}
|
||||
ResOriginNode = res->rd_fet_source;
|
||||
ResOriginNode->rn_why = RES_NODE_ORIGIN;
|
||||
ResOriginNode->rn_noderes = 0;
|
||||
ResNodeAtOrigin = res->rd_fet_source;
|
||||
ResNodeAtOrigin->rn_why = RES_NODE_ORIGIN;
|
||||
ResNodeAtOrigin->rn_noderes = 0;
|
||||
}
|
||||
ASSERT(ResOriginNode != NULL, "ResDoSimplify");
|
||||
resPathNode(ResOriginNode);
|
||||
ASSERT(ResNodeAtOrigin != NULL, "ResDoSimplify");
|
||||
resPathNode(ResNodeAtOrigin);
|
||||
while (HeapRemoveTop(&ResistorHeap,&he))
|
||||
resPathRes((resResistor *)he.he_id);
|
||||
}
|
||||
|
|
@ -1058,7 +1059,7 @@ ResSetPathRes(ResisData *resisdata)
|
|||
*
|
||||
* Given node "node", add every resistor connected to the node, and
|
||||
* 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.
|
||||
*-------------------------------------------------------------------------
|
||||
*/
|
||||
|
|
@ -1070,7 +1071,7 @@ resPathNode(node)
|
|||
{
|
||||
resElement *re;
|
||||
|
||||
node->rn_status |= FINISHED;
|
||||
node->rn_status |= RES_FINISHED;
|
||||
for (re = node->rn_re; re; re = re->re_nextEl)
|
||||
{
|
||||
resResistor *res = re->re_thisEl;
|
||||
|
|
@ -1078,7 +1079,7 @@ resPathNode(node)
|
|||
|
||||
if (res->rr_status & RES_HEAP) continue;
|
||||
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,
|
||||
(char *)res);
|
||||
}
|
||||
|
|
@ -1114,8 +1115,8 @@ resPathRes(res)
|
|||
res->rr_status &= ~RES_MARKED;
|
||||
node0 = res->rr_node[0];
|
||||
node1 = res->rr_node[1];
|
||||
flag0 = node0->rn_status & FINISHED;
|
||||
flag1 = node1->rn_status & FINISHED;
|
||||
flag0 = node0->rn_status & RES_FINISHED;
|
||||
flag1 = node1->rn_status & RES_FINISHED;
|
||||
if (flag0 && flag1)
|
||||
{
|
||||
res->rr_status |= RES_TDI_IGNORE;
|
||||
|
|
|
|||
184
resis/ResUtils.c
184
resis/ResUtils.c
|
|
@ -93,7 +93,7 @@ ResFirst(tile, dinfo, arg)
|
|||
*
|
||||
* resMultiPlaneTerm --
|
||||
*
|
||||
* Callback function to set a junk field
|
||||
* Callback function to set a resInfo field
|
||||
*
|
||||
*--------------------------------------------------------------------------
|
||||
*/
|
||||
|
|
@ -102,13 +102,13 @@ int
|
|||
resMultiPlaneTerm(
|
||||
Tile *tile,
|
||||
TileType dinfo, // Unused (but should be handled)
|
||||
tileJunk *junk2)
|
||||
resInfo *rinfo2)
|
||||
{
|
||||
tileJunk *Junk;
|
||||
resInfo *Info;
|
||||
|
||||
Junk = resAddField(tile);
|
||||
Junk->tj_status |= RES_TILE_SD;
|
||||
junk2->sourceEdge |= OTHERPLANE;
|
||||
Info = resAddField(tile);
|
||||
Info->ri_status |= RES_TILE_SD;
|
||||
rinfo2->sourceEdge |= OTHERPLANE;
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
@ -117,7 +117,7 @@ resMultiPlaneTerm(
|
|||
*
|
||||
* resSubstrateTerm --
|
||||
*
|
||||
* Callback function to set a junk field
|
||||
* Callback function to set a resInfo field
|
||||
*
|
||||
*--------------------------------------------------------------------------
|
||||
*/
|
||||
|
|
@ -128,10 +128,10 @@ resSubstrateTerm(
|
|||
TileType dinfo,
|
||||
ClientData clientdata) /* (unused) */
|
||||
{
|
||||
tileJunk *Junk;
|
||||
resInfo *Info;
|
||||
|
||||
Junk = resAddField(tile);
|
||||
Junk->tj_status |= RES_TILE_SUBS;
|
||||
Info = resAddField(tile);
|
||||
Info->ri_status |= RES_TILE_SUBS;
|
||||
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
|
||||
* 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;
|
||||
|
|
@ -188,7 +188,7 @@ ResAddPlumbing(tile, dinfo, arg)
|
|||
TileType dinfo;
|
||||
ClientData *arg;
|
||||
{
|
||||
tileJunk *Junk, *junk2;
|
||||
resInfo *Info, *rinfo2;
|
||||
static Stack *resDevStack = NULL;
|
||||
TileType loctype, t1;
|
||||
Tile *tp1, *tp2, *source;
|
||||
|
|
@ -208,7 +208,7 @@ ResAddPlumbing(tile, dinfo, arg)
|
|||
loctype = TiGetTypeExact(tile);
|
||||
|
||||
devptr = ExtCurStyle->exts_device[loctype];
|
||||
junk2 = resAddField(tile);
|
||||
rinfo2 = resAddField(tile);
|
||||
if (TTMaskHasType(&(ExtCurStyle->exts_deviceMask), loctype))
|
||||
{
|
||||
int i, nterms, pNum;
|
||||
|
|
@ -249,8 +249,8 @@ ResAddPlumbing(tile, dinfo, arg)
|
|||
resDev->rd_status = 0;
|
||||
resDev->rd_nextDev = (resDevice *)*arg;
|
||||
*arg = (ClientData)resDev;
|
||||
junk2->deviceList = resDev;
|
||||
junk2->tj_status |= RES_TILE_DEV;
|
||||
rinfo2->deviceList = resDev;
|
||||
rinfo2->ri_status |= RES_TILE_DEV;
|
||||
|
||||
for (i = 0; i < nterms - 2; i++)
|
||||
{
|
||||
|
|
@ -263,10 +263,10 @@ ResAddPlumbing(tile, dinfo, arg)
|
|||
if TTMaskHasType(&(devptr->exts_deviceSDTypes[i]),
|
||||
TiGetBottomType(tp2))
|
||||
{
|
||||
junk2->sourceEdge |= TOPEDGE;
|
||||
rinfo2->sourceEdge |= TOPEDGE;
|
||||
source = tp2;
|
||||
Junk = resAddField(source);
|
||||
Junk->tj_status |= RES_TILE_SD;
|
||||
Info = resAddField(source);
|
||||
Info->ri_status |= RES_TILE_SD;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
|
@ -278,10 +278,10 @@ ResAddPlumbing(tile, dinfo, arg)
|
|||
if TTMaskHasType(&(devptr->exts_deviceSDTypes[i]),
|
||||
TiGetTopType(tp2))
|
||||
{
|
||||
junk2->sourceEdge |= BOTTOMEDGE;
|
||||
rinfo2->sourceEdge |= BOTTOMEDGE;
|
||||
source = tp2;
|
||||
Junk = resAddField(source);
|
||||
Junk->tj_status |= RES_TILE_SD;
|
||||
Info = resAddField(source);
|
||||
Info->ri_status |= RES_TILE_SD;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
|
@ -293,10 +293,10 @@ ResAddPlumbing(tile, dinfo, arg)
|
|||
if TTMaskHasType(&(devptr->exts_deviceSDTypes[i]),
|
||||
TiGetLeftType(tp2))
|
||||
{
|
||||
junk2->sourceEdge |= RIGHTEDGE;
|
||||
rinfo2->sourceEdge |= RIGHTEDGE;
|
||||
source = tp2;
|
||||
Junk = resAddField(source);
|
||||
Junk->tj_status |= RES_TILE_SD;
|
||||
Info = resAddField(source);
|
||||
Info->ri_status |= RES_TILE_SD;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
|
@ -309,9 +309,9 @@ ResAddPlumbing(tile, dinfo, arg)
|
|||
TiGetRightType(tp2))
|
||||
{
|
||||
source = tp2;
|
||||
Junk = resAddField(source);
|
||||
Junk->tj_status |= RES_TILE_SD;
|
||||
junk2->sourceEdge |= LEFTEDGE;
|
||||
Info = resAddField(source);
|
||||
Info->ri_status |= RES_TILE_SD;
|
||||
rinfo2->sourceEdge |= LEFTEDGE;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
|
@ -327,7 +327,7 @@ ResAddPlumbing(tile, dinfo, arg)
|
|||
DBSrPaintArea((Tile *)NULL,
|
||||
ResUse->cu_def->cd_planes[pNum],
|
||||
&r, &(devptr->exts_deviceSDTypes[i]),
|
||||
resMultiPlaneTerm, (ClientData)junk2);
|
||||
resMultiPlaneTerm, (ClientData)rinfo2);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -360,10 +360,10 @@ ResAddPlumbing(tile, dinfo, arg)
|
|||
{
|
||||
if (TiGetBottomType(tp2) == t1)
|
||||
{
|
||||
tileJunk *j = resAddField(tp2);
|
||||
if ((j->tj_status & RES_TILE_SD) == 0)
|
||||
resInfo *re = resAddField(tp2);
|
||||
if ((re->ri_status & RES_TILE_SD) == 0)
|
||||
{
|
||||
j->tj_status |= RES_TILE_SD;
|
||||
re->ri_status |= RES_TILE_SD;
|
||||
STACKPUSH((ClientData)tp2, resDevStack);
|
||||
}
|
||||
}
|
||||
|
|
@ -373,10 +373,10 @@ ResAddPlumbing(tile, dinfo, arg)
|
|||
{
|
||||
if (TiGetTopType(tp2) == t1)
|
||||
{
|
||||
tileJunk *j = resAddField(tp2);
|
||||
if ((j->tj_status & RES_TILE_SD) == 0)
|
||||
resInfo *re = resAddField(tp2);
|
||||
if ((re->ri_status & RES_TILE_SD) == 0)
|
||||
{
|
||||
j->tj_status |= RES_TILE_SD;
|
||||
re->ri_status |= RES_TILE_SD;
|
||||
STACKPUSH((ClientData)tp2, resDevStack);
|
||||
}
|
||||
}
|
||||
|
|
@ -386,10 +386,10 @@ ResAddPlumbing(tile, dinfo, arg)
|
|||
{
|
||||
if (TiGetLeftType(tp2) == t1)
|
||||
{
|
||||
tileJunk *j = resAddField(tp2);
|
||||
if ((j->tj_status & RES_TILE_SD) == 0)
|
||||
resInfo *re = resAddField(tp2);
|
||||
if ((re->ri_status & RES_TILE_SD) == 0)
|
||||
{
|
||||
j->tj_status |= RES_TILE_SD;
|
||||
re->ri_status |= RES_TILE_SD;
|
||||
STACKPUSH((ClientData)tp2, resDevStack);
|
||||
}
|
||||
}
|
||||
|
|
@ -399,10 +399,10 @@ ResAddPlumbing(tile, dinfo, arg)
|
|||
{
|
||||
if (TiGetRightType(tp2) == t1)
|
||||
{
|
||||
tileJunk *j = resAddField(tp2);
|
||||
if ((j->tj_status & RES_TILE_SD) == 0)
|
||||
resInfo *re = resAddField(tp2);
|
||||
if ((re->ri_status & RES_TILE_SD) == 0)
|
||||
{
|
||||
j->tj_status |= RES_TILE_SD;
|
||||
re->ri_status |= RES_TILE_SD;
|
||||
STACKPUSH((ClientData)tp2, resDevStack);
|
||||
}
|
||||
}
|
||||
|
|
@ -430,7 +430,7 @@ ResAddPlumbing(tile, dinfo, arg)
|
|||
STACKPUSH((ClientData)tile, resDevStack);
|
||||
while (!StackEmpty(resDevStack))
|
||||
{
|
||||
tileJunk *j0;
|
||||
resInfo *re0;
|
||||
|
||||
tp1 = (Tile *) STACKPOP(resDevStack);
|
||||
if (IsSplit(tp1))
|
||||
|
|
@ -446,17 +446,17 @@ ResAddPlumbing(tile, dinfo, arg)
|
|||
t1 = TiGetTypeExact(tp1);
|
||||
|
||||
devptr = ExtCurStyle->exts_device[t1];
|
||||
j0 = (tileJunk *) TiGetClientPTR(tp1);
|
||||
re0 = (resInfo *) TiGetClientPTR(tp1);
|
||||
/* top */
|
||||
for (tp2 = RT(tp1); RIGHT(tp2) > LEFT(tp1); tp2 = BL(tp2))
|
||||
{
|
||||
if ((TiGetBottomType(tp2) == t1) &&
|
||||
(TiGetClient(tp2) == CLIENTDEFAULT))
|
||||
{
|
||||
Junk = resAddField(tp2);
|
||||
Info = resAddField(tp2);
|
||||
STACKPUSH((ClientData)tp2, resDevStack);
|
||||
Junk->deviceList = resDev;
|
||||
Junk->tj_status |= RES_TILE_DEV;
|
||||
Info->deviceList = resDev;
|
||||
Info->ri_status |= RES_TILE_DEV;
|
||||
|
||||
/* Update device position to point to the lower-leftmost tile */
|
||||
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]),
|
||||
TiGetBottomType(tp2))
|
||||
{
|
||||
Junk = resAddField(tp2);
|
||||
if (Junk->tj_status & RES_TILE_SD)
|
||||
j0->sourceEdge |= TOPEDGE;
|
||||
Info = resAddField(tp2);
|
||||
if (Info->ri_status & RES_TILE_SD)
|
||||
re0->sourceEdge |= TOPEDGE;
|
||||
}
|
||||
}
|
||||
/* bottom */
|
||||
|
|
@ -483,10 +483,10 @@ ResAddPlumbing(tile, dinfo, arg)
|
|||
if ((TiGetTopType(tp2) == t1) &&
|
||||
(TiGetClient(tp2) == CLIENTDEFAULT))
|
||||
{
|
||||
Junk = resAddField(tp2);
|
||||
Info = resAddField(tp2);
|
||||
STACKPUSH((ClientData)tp2, resDevStack);
|
||||
Junk->deviceList = resDev;
|
||||
Junk->tj_status |= RES_TILE_DEV;
|
||||
Info->deviceList = resDev;
|
||||
Info->ri_status |= RES_TILE_DEV;
|
||||
|
||||
/* Update device position to point to the lower-leftmost tile */
|
||||
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]),
|
||||
TiGetTopType(tp2))
|
||||
{
|
||||
Junk = resAddField(tp2);
|
||||
if (Junk->tj_status & RES_TILE_SD)
|
||||
j0->sourceEdge |= BOTTOMEDGE;
|
||||
Info = resAddField(tp2);
|
||||
if (Info->ri_status & RES_TILE_SD)
|
||||
re0->sourceEdge |= BOTTOMEDGE;
|
||||
}
|
||||
}
|
||||
/* right */
|
||||
|
|
@ -513,10 +513,10 @@ ResAddPlumbing(tile, dinfo, arg)
|
|||
if ((TiGetLeftType(tp2) == t1) &&
|
||||
(TiGetClient(tp2) == CLIENTDEFAULT))
|
||||
{
|
||||
Junk = resAddField(tp2);
|
||||
Info = resAddField(tp2);
|
||||
STACKPUSH((ClientData)tp2, resDevStack);
|
||||
Junk->deviceList = resDev;
|
||||
Junk->tj_status |= RES_TILE_DEV;
|
||||
Info->deviceList = resDev;
|
||||
Info->ri_status |= RES_TILE_DEV;
|
||||
|
||||
/* Update device position to point to the lower-leftmost tile */
|
||||
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]),
|
||||
TiGetLeftType(tp2))
|
||||
{
|
||||
Junk = resAddField(tp2);
|
||||
if (Junk->tj_status & RES_TILE_SD)
|
||||
j0->sourceEdge |= RIGHTEDGE;
|
||||
Info = resAddField(tp2);
|
||||
if (Info->ri_status & RES_TILE_SD)
|
||||
re0->sourceEdge |= RIGHTEDGE;
|
||||
}
|
||||
}
|
||||
/* left */
|
||||
|
|
@ -543,10 +543,10 @@ ResAddPlumbing(tile, dinfo, arg)
|
|||
if ((TiGetRightType(tp2) == t1) &&
|
||||
(TiGetClient(tp2) == CLIENTDEFAULT))
|
||||
{
|
||||
Junk = resAddField(tp2);
|
||||
Info = resAddField(tp2);
|
||||
STACKPUSH((ClientData)tp2, resDevStack);
|
||||
Junk->deviceList = resDev;
|
||||
Junk->tj_status |= RES_TILE_DEV;
|
||||
Info->deviceList = resDev;
|
||||
Info->ri_status |= RES_TILE_DEV;
|
||||
|
||||
/* Update device position to point to the lower-leftmost tile */
|
||||
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]),
|
||||
TiGetRightType(tp2))
|
||||
{
|
||||
Junk = resAddField(tp2);
|
||||
if (Junk->tj_status & RES_TILE_SD)
|
||||
j0->sourceEdge |= LEFTEDGE;
|
||||
Info = resAddField(tp2);
|
||||
if (Info->ri_status & RES_TILE_SD)
|
||||
re0->sourceEdge |= LEFTEDGE;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -573,10 +573,10 @@ ResAddPlumbing(tile, dinfo, arg)
|
|||
|
||||
if (source != (Tile *) NULL)
|
||||
{
|
||||
tileJunk *j = (tileJunk *) TiGetClientPTR(source);
|
||||
resInfo *re = (resInfo *) TiGetClientPTR(source);
|
||||
|
||||
STACKPUSH((ClientData)source, resDevStack);
|
||||
j->tj_status &= ~RES_TILE_SD;
|
||||
re->ri_status &= ~RES_TILE_SD;
|
||||
}
|
||||
while (!StackEmpty(resDevStack))
|
||||
{
|
||||
|
|
@ -592,12 +592,12 @@ ResAddPlumbing(tile, dinfo, arg)
|
|||
/* top */
|
||||
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 (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);
|
||||
}
|
||||
}
|
||||
|
|
@ -605,12 +605,12 @@ ResAddPlumbing(tile, dinfo, arg)
|
|||
/* bottom */
|
||||
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 (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);
|
||||
}
|
||||
}
|
||||
|
|
@ -618,12 +618,12 @@ ResAddPlumbing(tile, dinfo, arg)
|
|||
/* right */
|
||||
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 (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);
|
||||
}
|
||||
}
|
||||
|
|
@ -631,12 +631,12 @@ ResAddPlumbing(tile, dinfo, arg)
|
|||
/* left */
|
||||
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 (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);
|
||||
}
|
||||
}
|
||||
|
|
@ -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
|
||||
*
|
||||
|
|
@ -702,7 +702,7 @@ ResPreProcessDevices(TileList, DeviceList, Def)
|
|||
{
|
||||
Tile *tile;
|
||||
ResDevTile *oldTile;
|
||||
tileJunk *tstruct;
|
||||
resInfo *tstruct;
|
||||
TileType tt, residue;
|
||||
int pNum;
|
||||
|
||||
|
|
@ -735,9 +735,9 @@ ResPreProcessDevices(TileList, DeviceList, Def)
|
|||
GOTOPOINT(tile, &(TileList->area.r_ll));
|
||||
|
||||
tt = TiGetType(tile);
|
||||
tstruct = (tileJunk *) TiGetClientPTR(tile);
|
||||
tstruct = (resInfo *) TiGetClientPTR(tile);
|
||||
|
||||
if ((tstruct == (tileJunk *)CLIENTDEFAULT) ||
|
||||
if ((tstruct == (resInfo *)CLIENTDEFAULT) ||
|
||||
(tstruct->deviceList == NULL) ||
|
||||
!TTMaskHasType(&ExtCurStyle->exts_deviceMask, tt))
|
||||
{
|
||||
|
|
@ -745,11 +745,11 @@ ResPreProcessDevices(TileList, DeviceList, Def)
|
|||
TileList->area.r_ll.p_x,
|
||||
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;
|
||||
|
||||
tstruct->tj_status |= RES_TILE_MARK;
|
||||
tstruct->ri_status |= RES_TILE_MARK;
|
||||
rd->rd_perim += TileList->perim;
|
||||
rd->rd_length += TileList->overlap;
|
||||
rd->rd_area += (TileList->area.r_xtop - TileList->area.r_xbot)
|
||||
|
|
@ -851,17 +851,17 @@ ResRemoveFromQueue(node, list)
|
|||
node->rn_less = NULL;
|
||||
}
|
||||
|
||||
tileJunk *
|
||||
resInfo *
|
||||
resAddField(tile)
|
||||
Tile *tile;
|
||||
{
|
||||
ClientData ticlient = TiGetClient(tile);
|
||||
tileJunk *Junk = (tileJunk *)CD2PTR(ticlient);
|
||||
resInfo *Info = (resInfo *)CD2PTR(ticlient);
|
||||
if (ticlient == CLIENTDEFAULT)
|
||||
{
|
||||
Junk = (tileJunk *) mallocMagic((unsigned) (sizeof(tileJunk)));
|
||||
ResJunkInit(Junk);
|
||||
TiSetClientPTR(tile, Junk);
|
||||
Info = (resInfo *) mallocMagic((unsigned) (sizeof(resInfo)));
|
||||
ResInfoInit(Info);
|
||||
TiSetClientPTR(tile, Info);
|
||||
}
|
||||
return Junk;
|
||||
return Info;
|
||||
}
|
||||
|
|
|
|||
421
resis/resis.h
421
resis/resis.h
|
|
@ -1,49 +1,38 @@
|
|||
/* 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.
|
||||
*/
|
||||
/* Header files for resistance extraction */
|
||||
|
||||
#ifndef _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 TILES_PER_JUNCTION 2
|
||||
|
||||
typedef struct contactpoint
|
||||
{
|
||||
struct contactpoint *cp_nextcontact;/* Next contact in linked */
|
||||
/* list. */
|
||||
Point cp_center; /*Center of contact */
|
||||
Rect cp_rect; /* Tile rectangle */
|
||||
Tile *cp_contactTile;
|
||||
/*
|
||||
The following two keep
|
||||
track of the tiles where
|
||||
the contact was before
|
||||
preprocessing, and the
|
||||
next contact in that tile's
|
||||
area.
|
||||
*/
|
||||
|
||||
Tile *cp_tile[LAYERS_PER_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
|
||||
*/
|
||||
struct contactpoint *cp_nextcontact; /* Next contact in linked list. */
|
||||
Point cp_center; /* Center of contact */
|
||||
Rect cp_rect; /* Tile rectangle */
|
||||
Tile *cp_contactTile; /* The following two keep track of
|
||||
* the tiles where the contact was
|
||||
* before preprocessing, and the
|
||||
* next contact in that tile's area.
|
||||
*/
|
||||
Tile *cp_tile[LAYERS_PER_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;
|
||||
|
||||
typedef struct resistor
|
||||
{
|
||||
struct resistor *rr_nextResistor; /* Doubly linked list pointers */
|
||||
struct resistor *rr_nextResistor; /* Doubly linked list pointers */
|
||||
struct resistor *rr_lastResistor;
|
||||
struct resnode *rr_node[2];
|
||||
float rr_value; /* Resistor's value in milliohms */
|
||||
|
|
@ -81,7 +70,7 @@ typedef struct device
|
|||
struct resnode **rd_terminals;
|
||||
int rd_nterms; /* number of terminals in rt_terminals */
|
||||
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_width;
|
||||
int rd_tiles; /* number of tiles in device */
|
||||
|
|
@ -91,8 +80,8 @@ typedef struct device
|
|||
} 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
|
||||
{
|
||||
|
|
@ -104,8 +93,8 @@ typedef struct junction
|
|||
} ResJunction;
|
||||
|
||||
/*
|
||||
* A port is declared for subcircuits; its name overrides any locally-
|
||||
* generated node name.
|
||||
* A port is declared for subcircuits; its name overrides any locally-generated
|
||||
* node name.
|
||||
*/
|
||||
|
||||
typedef struct resport
|
||||
|
|
@ -117,9 +106,9 @@ typedef struct resport
|
|||
} resPort;
|
||||
|
||||
/*
|
||||
?element are 'cons' cells used to make linked lists of their referential
|
||||
structures.
|
||||
*/
|
||||
* *element are 'cons' (in the LISP sense) cells used to make linked lists of
|
||||
* their referential structures.
|
||||
*/
|
||||
|
||||
typedef struct reselement
|
||||
{
|
||||
|
|
@ -153,15 +142,16 @@ typedef struct celement
|
|||
} cElement;
|
||||
|
||||
/*
|
||||
Nodes formed from network. These are linked both forwards and backwords
|
||||
to other nodes. Lists of devices, resistors, junctions, and contacts
|
||||
corresponding to this node are kept.
|
||||
*/
|
||||
* Nodes formed from network. These are linked both forwards and backwards
|
||||
* to other nodes. Lists of devices, resistors, junctions, and contacts
|
||||
* corresponding to this node are kept.
|
||||
*/
|
||||
|
||||
typedef struct resnode
|
||||
{
|
||||
struct resnode *rn_more; /* doubly linked list pointers */
|
||||
struct resnode *rn_less;
|
||||
tElement *rn_te; /* widgets connected to this node */
|
||||
tElement *rn_te; /* widgets connected to this node */
|
||||
resElement *rn_re;
|
||||
jElement *rn_je;
|
||||
cElement *rn_ce;
|
||||
|
|
@ -194,10 +184,10 @@ typedef struct nelement
|
|||
} nElement;
|
||||
|
||||
/*
|
||||
Breakpoints are places on a tile which may serve as sources/sinks of
|
||||
current. When resistance is calculated for a tile. this is calculated
|
||||
between these points.
|
||||
*/
|
||||
* Breakpoints are places on a tile which may serve as sources/sinks of
|
||||
* current. When resistance is calculated for a tile. this is calculated
|
||||
* between these points.
|
||||
*/
|
||||
|
||||
typedef struct breakpoint
|
||||
{
|
||||
|
|
@ -208,31 +198,31 @@ typedef struct breakpoint
|
|||
} Breakpoint;
|
||||
|
||||
/*
|
||||
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,
|
||||
this 1 to 6 adaptor is used.
|
||||
*/
|
||||
* 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,
|
||||
* this 1 to 7 adaptor is used.
|
||||
*/
|
||||
|
||||
typedef struct tilejunk
|
||||
typedef struct resinfo
|
||||
{
|
||||
cElement *contactList; /*widgets connected to this tile */
|
||||
resDevice *deviceList;
|
||||
resPort *portList;
|
||||
ResJunction *junctionList;
|
||||
Breakpoint *breakList;
|
||||
cElement *contactList; /* widgets connected to this tile */
|
||||
resDevice *deviceList; /* devices this tile is part of */
|
||||
resPort *portList; /* ports connected to this tile */
|
||||
ResJunction *junctionList; /* junctions inside the tile */
|
||||
Breakpoint *breakList; /* breakpoints inside the tile */
|
||||
int sourceEdge; /* used in device tiles to keep
|
||||
* of which diffusion edges are
|
||||
* a transistor's source
|
||||
* track of which diffusion edges
|
||||
* are a transistor's source
|
||||
*/
|
||||
int tj_status; /* status of tile processing */
|
||||
} tileJunk;
|
||||
int ri_status; /* status of tile processing */
|
||||
} resInfo;
|
||||
|
||||
/* ResDevTile keeps track of the location and type of devices.
|
||||
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
|
||||
uses the new def to keep track of where it is in the design. It is also
|
||||
used when devices are preproceesed.
|
||||
*/
|
||||
* 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
|
||||
* uses the new def to keep track of where it is in the design. It is also
|
||||
* used when devices are preproceesed.
|
||||
*/
|
||||
|
||||
typedef struct resdevtile
|
||||
{
|
||||
|
|
@ -244,9 +234,11 @@ typedef struct resdevtile
|
|||
int overlap;
|
||||
} 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 */
|
||||
/* extraction. */
|
||||
/*
|
||||
* Linked list structure to use to store the substrate plane from each
|
||||
* extracted CellDef so that they can be returned to the original after
|
||||
* extraction.
|
||||
*/
|
||||
|
||||
struct saveList {
|
||||
Plane *sl_plane;
|
||||
|
|
@ -292,8 +284,7 @@ typedef struct rcdelaystuff
|
|||
float rc_Tdi; /* Tdi for node */
|
||||
} RCDelayStuff;
|
||||
|
||||
|
||||
/* Type declarations */
|
||||
/* More type declarations */
|
||||
|
||||
typedef struct rdev
|
||||
{
|
||||
|
|
@ -319,45 +310,38 @@ typedef struct rdev
|
|||
|
||||
typedef struct resextnode
|
||||
{
|
||||
struct resextnode *nextnode; /* next node in OriginalNodes */
|
||||
struct resextnode *nextnode; /* next node in OriginalNodes */
|
||||
/* linked list. */
|
||||
int status;
|
||||
struct resextnode *forward; /* If node has been merged, this */
|
||||
int status;
|
||||
struct resextnode *forward; /* If node has been merged, this */
|
||||
/* points to the merged node. */
|
||||
float capacitance; /* capacitance between node and */
|
||||
/* GND for power connections */
|
||||
/* and all capacitance for every */
|
||||
/* thing else. */
|
||||
float cap_vdd; /* capacitance to VDD (used for */
|
||||
/* power calculations only */
|
||||
float cap_couple; /* coupling capacitance */
|
||||
float resistance; /* lumped resistance */
|
||||
float minsizeres; /* Minimum size resistor allowed */
|
||||
Point drivepoint; /* optional, user specified drive */
|
||||
float capacitance; /* Capacitance between node and */
|
||||
/* substrate */
|
||||
float cap_couple; /* Coupling capacitance */
|
||||
float resistance; /* Lumped resistance */
|
||||
float minsizeres; /* Minimum size resistor allowed */
|
||||
Point drivepoint; /* optional, user specified drive */
|
||||
/* point for network. */
|
||||
TileType rs_ttype; /* tiletype of drivepoint */
|
||||
Point location; /* location of bottom of leftmost */
|
||||
TileType rs_ttype; /* Tiletype of drivepoint */
|
||||
Point location; /* Location of bottom of leftmost */
|
||||
/* tile in the lowest numbered */
|
||||
/* plane contained in the node . */
|
||||
Rect rs_bbox; /* location of bottom of leftmost */
|
||||
/* plane contained in the node. */
|
||||
Rect rs_bbox; /* Location of bottom of leftmost */
|
||||
/* tile in the lowest numbered */
|
||||
/* plane contained in the node . */
|
||||
TileType type; /* Tile type of tile at location */
|
||||
struct devptr *firstDev; /* linked list of devices */
|
||||
/* plane contained in the node. */
|
||||
TileType type; /* Tile type of tile at location */
|
||||
struct devptr *firstDev; /* Linked list of devices */
|
||||
/* connected to node. */
|
||||
char *name; /* Pointer to name of node stored */
|
||||
char *name; /* Pointer to name of node stored */
|
||||
/* in hash table. */
|
||||
char *oldname; /* Pointer to previous name of */
|
||||
char *oldname; /* Pointer to previous name of */
|
||||
/* node, if it exists */
|
||||
tElement *rs_sublist[2]; /* pointers to Gnd and Vdd sub */
|
||||
/* strate connections,
|
||||
if they exist */
|
||||
} ResExtNode;
|
||||
|
||||
#define RES_SUB_GND 0
|
||||
#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
|
||||
{
|
||||
|
|
@ -378,144 +362,131 @@ typedef struct resfixpoint /* Keeps track of where voltage sources are */
|
|||
char fp_name[1];
|
||||
} 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
|
||||
{
|
||||
float cap[1][2]; /* 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);
|
||||
*/
|
||||
float cap[1][2];
|
||||
} ResCapVal;
|
||||
|
||||
/* node flags */
|
||||
#define RES_REACHED_NODE 0x00200000
|
||||
#define RES_NODE_XADJ 0x00400000
|
||||
#define RES_NODE_YADJ 0x00800000
|
||||
/* Node flags ("rn_status" field) */
|
||||
|
||||
/* type of node flags */
|
||||
#define RES_NODE_JUNCTION 0x00000001
|
||||
#define RES_NODE_DEVICE 0x00000002
|
||||
#define RES_NODE_CONTACT 0x00000004
|
||||
#define RES_NODE_ORIGIN 0x00000008
|
||||
#define RES_TRUE 0x00000001
|
||||
#define RES_PENDING 0x00000002
|
||||
#define RES_FINISHED 0x00000004
|
||||
#define RES_MARKED 0x00000100
|
||||
#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 */
|
||||
#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
|
||||
/* Resistor flags ("rr_status" field) */
|
||||
|
||||
/* device flags */
|
||||
#define RES_DEV_SAVE 0x00000001
|
||||
#define RES_EW 0x00000200
|
||||
#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_NO_LOOP 1
|
||||
#define RES_DO_LAST 0
|
||||
#define RES_DO_FIRST 1
|
||||
#define RES_NO_FLAGS 0
|
||||
|
||||
/* Constants (ResExtNode "status" field) */
|
||||
|
||||
/* Constants */
|
||||
#define FORWARD 0x0000010
|
||||
#define SKIP 0x0000020
|
||||
#define FORCE 0x0000040
|
||||
#define MINSIZE 0x0000080
|
||||
#define DRIVELOC 0x0000100
|
||||
#define PORTNODE 0x0000200
|
||||
#define REDUNDANT 0x0000400
|
||||
#define DONTKILL 0x0000800
|
||||
#define FORWARD 0x0000010
|
||||
#define SKIP 0x0000020
|
||||
#define FORCE 0x0000040
|
||||
#define MINSIZE 0x0000080
|
||||
#define DRIVELOC 0x0000100
|
||||
#define PORTNODE 0x0000200
|
||||
#define REDUNDANT 0x0000400
|
||||
#define DONTKILL 0x0000800
|
||||
|
||||
/* Capacitance table constants */
|
||||
#define RES_CAP_GND 0
|
||||
#define RES_CAP_VDD 1
|
||||
#define RES_CAP_COUPLE 2
|
||||
|
||||
#define OHMSTOMILLIOHMS 1000
|
||||
#define FEMTOTOATTO 1000
|
||||
#define ATTOTOFEMTO 0.001
|
||||
|
||||
#define UNTOUCHED 0
|
||||
#define SERIES 1
|
||||
#define PARALLEL 2
|
||||
#define LOOP 4
|
||||
#define SINGLE 8
|
||||
#define TRIANGLE 32
|
||||
#define UNTOUCHED 0
|
||||
#define SERIES 1
|
||||
#define PARALLEL 2
|
||||
#define LOOP 4
|
||||
#define SINGLE 8
|
||||
#define TRIANGLE 32
|
||||
|
||||
#define RESTRUE 1
|
||||
#define PENDING 2
|
||||
#define FINISHED 4
|
||||
#define LEFTEDGE 1
|
||||
#define RIGHTEDGE 4
|
||||
#define TOPEDGE 8
|
||||
#define BOTTOMEDGE 16
|
||||
#define OTHERPLANE 32
|
||||
|
||||
#define LEFTEDGE 1
|
||||
#define RIGHTEDGE 4
|
||||
#define TOPEDGE 8
|
||||
#define BOTTOMEDGE 16
|
||||
#define OTHERPLANE 32
|
||||
#define GATE 1
|
||||
#define SOURCE 2
|
||||
#define DRAIN 3
|
||||
#define SUBS 4
|
||||
|
||||
#define RN_MAXTDI 0x00001000
|
||||
/* "rg_status" flag */
|
||||
|
||||
#define MARKED 0x00000100
|
||||
#define DRIVEONLY 0x00001000
|
||||
|
||||
#define GATE 1
|
||||
#define SOURCE 2
|
||||
#define DRAIN 3
|
||||
#define SUBS 4
|
||||
/* Magic's normal value of infinity is too small---67108863 is only 67K ohms. */
|
||||
|
||||
#define DRIVEONLY 0x00001000
|
||||
#define ORIGIN 0x00000008
|
||||
|
||||
/* magic's normal value of infinity is too small- */
|
||||
/* 67108863 is only 67K ohms. */
|
||||
|
||||
#define RES_INFINITY 0x3FFFFFFF
|
||||
|
||||
#define ResCheckIntegrity
|
||||
#define RES_INFINITY 0x3FFFFFFF
|
||||
|
||||
/* The following turns on and off various options */
|
||||
|
||||
#define ResOpt_ExtractAll 0x00000002
|
||||
#define ResOpt_Simplify 0x00000004
|
||||
#define ResOpt_DoExtFile 0x00000008
|
||||
#define ResOpt_DoRsmFile 0x00000010
|
||||
#define ResOpt_DoLumpFile 0x00000020
|
||||
#define ResOpt_RunSilent 0x00000040
|
||||
#define ResOpt_ExplicitRtol 0x00000080
|
||||
#define ResOpt_ExplicitTditol 0x00000100
|
||||
#define ResOpt_Tdi 0x00000200
|
||||
#define ResOpt_Stat 0x00000400
|
||||
#define ResOpt_Power 0x00000800
|
||||
#define ResOpt_Signal 0x00001000
|
||||
#define ResOpt_Pname 0x00002000
|
||||
#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
|
||||
#define ResOpt_ExtractAll 0x0001
|
||||
#define ResOpt_Simplify 0x0002
|
||||
#define ResOpt_DoExtFile 0x0004
|
||||
#define ResOpt_DoLumpFile 0x0008
|
||||
#define ResOpt_RunSilent 0x0010
|
||||
#define ResOpt_Stats 0x0020
|
||||
#define ResOpt_Tdi 0x0040
|
||||
#define ResOpt_Signal 0x0080
|
||||
#define ResOpt_Geometry 0x0100
|
||||
#define ResOpt_FastHenry 0x0200
|
||||
#define ResOpt_Blackbox 0x0300
|
||||
#define ResOpt_DoSubstrate 0x0800
|
||||
#define ResOpt_Box 0x1000
|
||||
|
||||
/* Assorted Variables */
|
||||
|
||||
|
|
@ -533,7 +504,7 @@ extern resNode *ResNodeList;
|
|||
extern resDevice *ResDevList;
|
||||
extern ResContactPoint *ResContactList;
|
||||
extern resNode *ResNodeQueue;
|
||||
extern resNode *ResOriginNode;
|
||||
extern resNode *ResNodeAtOrigin;
|
||||
extern resNode *resCurrentNode;
|
||||
extern HashTable ResNodeTable;
|
||||
extern HashTable ResExtDevTable;
|
||||
|
|
@ -548,6 +519,7 @@ extern TileTypeBitMask ResNoMergeMask[NT];
|
|||
extern int ResPortIndex;
|
||||
|
||||
/* Routines used by ResReadExt() */
|
||||
|
||||
extern ResisData *ResInit();
|
||||
extern int ResReadDevice();
|
||||
extern int ResReadCapacitor();
|
||||
|
|
@ -559,12 +531,14 @@ extern int ResReadSubckt();
|
|||
extern int ResProcessNode();
|
||||
extern int ResExtCombineParallel();
|
||||
extern int dbSrConnectStartFunc();
|
||||
extern int ResEach(),ResAddPlumbing(),ResRemovePlumbing();
|
||||
extern int ResEach();
|
||||
extern int ResAddPlumbing();
|
||||
extern int ResRemovePlumbing();
|
||||
extern float ResCalculateChildCapacitance();
|
||||
extern ResDevTile *DBTreeCopyConnectDCS();
|
||||
extern Tile *ResFindTile();
|
||||
extern resDevice *ResGetDevice();
|
||||
extern tileJunk *resAddField();
|
||||
extern resInfo *resAddField();
|
||||
extern int ResCheckPorts();
|
||||
extern int ResCheckBlackbox();
|
||||
extern void ResCheckExtNodes();
|
||||
|
|
@ -575,12 +549,14 @@ extern void ResSortBreaks();
|
|||
extern Plane *extResPrepSubstrate();
|
||||
|
||||
/* C99 compat */
|
||||
|
||||
extern void ExtResisForDef(CellDef *celldef, ResisData *resisdata);
|
||||
extern char *ResExtGetAttribute(char *sptr);
|
||||
extern int ResReadFET(int argc, char *argv[]);
|
||||
extern int ResReadPort(int argc, char *argv[]);
|
||||
extern char *ResExtGetAttribute(char *sptr);
|
||||
|
||||
extern ResExtNode *ResExtInitNode();
|
||||
extern void ResAddToQueue();
|
||||
extern bool ResCalcTileResistance();
|
||||
extern void ResCleanNode();
|
||||
|
|
@ -622,10 +598,9 @@ extern int resWalkleft();
|
|||
extern int resWalkright();
|
||||
extern int resWalkup();
|
||||
|
||||
/* Macros */
|
||||
|
||||
/* macros */
|
||||
|
||||
#define InitializeNode(node,x,y,why) \
|
||||
#define InitializeResNode(node,x,y,why) \
|
||||
{\
|
||||
(node)->rn_te = NULL;\
|
||||
(node)->rn_id=0;\
|
||||
|
|
@ -642,21 +617,21 @@ extern int resWalkup();
|
|||
(node)->rn_re = (resElement *) NULL;\
|
||||
}
|
||||
|
||||
#define ResJunkInit(Junk) \
|
||||
#define ResInfoInit(Info) \
|
||||
{ \
|
||||
Junk->contactList = (cElement *) NULL; \
|
||||
Junk->deviceList = (resDevice *) NULL; \
|
||||
Junk->junctionList = (ResJunction *) NULL; \
|
||||
Junk->breakList = (Breakpoint *) NULL; \
|
||||
Junk->portList = (resPort *) NULL; \
|
||||
Junk->tj_status = FALSE; \
|
||||
Junk->sourceEdge = 0 ; \
|
||||
Info->contactList = (cElement *) NULL; \
|
||||
Info->deviceList = (resDevice *) NULL; \
|
||||
Info->junctionList = (ResJunction *) NULL; \
|
||||
Info->breakList = (Breakpoint *) NULL; \
|
||||
Info->portList = (resPort *) NULL; \
|
||||
Info->ri_status = FALSE; \
|
||||
Info->sourceEdge = 0 ; \
|
||||
}
|
||||
|
||||
#define NEWBREAK(node,tile,px,py,crect)\
|
||||
{\
|
||||
Breakpoint *bp;\
|
||||
tileJunk *jX_ = (tileJunk *)((tile)->ti_client); \
|
||||
resInfo *jX_ = (resInfo *)((tile)->ti_client); \
|
||||
bp = (Breakpoint *) mallocMagic((unsigned)(sizeof(Breakpoint))); \
|
||||
bp->br_next= jX_->breakList; \
|
||||
bp->br_this = (node); \
|
||||
|
|
@ -669,7 +644,7 @@ extern int resWalkup();
|
|||
#define NEWPORT(node,tile)\
|
||||
{\
|
||||
resPort *rp;\
|
||||
tileJunk *pX_ = (tileJunk *)((tile)->ti_client); \
|
||||
resInfo *pX_ = (resInfo *)((tile)->ti_client); \
|
||||
rp = (resPort *) mallocMagic((unsigned)(sizeof(resPort))); \
|
||||
rp->rp_nextPort = pX_->portList; \
|
||||
rp->rp_bbox = node->rs_bbox; \
|
||||
|
|
|
|||
Loading…
Reference in New Issue